Generalzie pyomo model handling#55
Conversation
| - "3.13" | ||
| os: | ||
| - linux | ||
| - win64 |
There was a problem hiding this comment.
Nice, thanks for making this more extensive
| return model, pyo_vars | ||
|
|
||
|
|
||
| def setup_pyo_vars_with_non_standard_indexing_constraints(consumption_data_dict): |
There was a problem hiding this comment.
This version of the function should work for standard and non-standard indexes, right? Can this be renamed to just replace the other setup_pyo_vars?
There was a problem hiding this comment.
yes, but we should explicitly test for both. Technically, we could add the two function as part of parametrize in pytest, but I prefer this to be more explicit. There is no such thing as too many tests...
There was a problem hiding this comment.
Fair enough haha. I wonder if rather than (or in addition to) testing all these cases in calculate_cost, we could add more tests on ut.multiply(pyo_var, np_array) since "multiply" has the most potential for mismatch in the indices. With more variations on ways the Pyo variable indexes could be defined.
There was a problem hiding this comment.
It should handle most use cases... but we can probably explore it and modify as we hit walls. Right now it should use the right indexing regardless of order in multiple (np_aray, pyo_var) or (pyo_var, np_array). Tat should ensure it always pulls right index for each input type.
The bigger issue if we need to start supporting block indexing (e..g m.block[1,2,3,4,5].power) which is more common in IDAES/WaterTAP model structures. Although I think in 99% of cases the power/fuel vars will be indexed directly (var[indx]).
| assert model is not None | ||
|
|
||
|
|
||
| @pytest.mark.skipif(skip_all_tests, reason="Exclude all tests") |
There was a problem hiding this comment.
If adding an additional test case for multiply with Pyomo * numpy:
@pytest.mark.skipif(skip_all_tests, reason="Exclude all tests")
@pytest.mark.parametrize(
"consumption_data, varstr1, varstr2, time_set, expected",
[
# two Pyo variables
(
{"electric": np.ones(96) * 100, "gas": np.ones(96)},
"electric",
"gas",
None,
np.ones(96) * 100,
),
# Pyo variable * numpy charge array on non-standard index
(
{"electric": np.array([100.0, 200.0, 300.0, 400.0])},
"electric",
np.array([0.1, 0.2, 0.3, 0.4]),
[0.0, 900.0, 1800.0, 2700.0],
np.array([10.0, 40.0, 90.0, 160.0]),
),
# Pyo variable * numpy charge array on irregular (non-uniform) index
(
{"electric": np.array([100.0, 200.0, 300.0, 400.0])},
"electric",
np.array([0.1, 0.2, 0.3, 0.4]),
[2.0, 4.0, 5.0, 8.0],
np.array([10.0, 40.0, 90.0, 160.0]),
),
],
)
def test_multiply_pyo(consumption_data, varstr1, varstr2, time_set, expected):
model = pyo.ConcreteModel()
model.T = len(consumption_data[varstr1])
model.t = range(model.T) if time_set is None else time_set
pos = {t: i for i, t in enumerate(model.t)}
for key, val in consumption_data.items():
var = pyo.Var(model.t, bounds=(None, None))
model.add_component(key, var)
for t in model.t:
var[t].fix(float(val[pos[t]]))
var1 = getattr(model, varstr1)
var2 = getattr(model, varstr2) if isinstance(varstr2, str) else varstr2
ut.create_pyomo_model_index_ref(model, var1)
result, model = ut.multiply(var1, var2, model=model, varstr="test")
model.objective = pyo.Objective(expr=0)
solver = pyo.SolverFactory("ipopt")
solver.solve(model)
assert np.allclose([pyo.value(result[t]) for t in model.t], expected)
assert model is not None
| return var[t] == expression1[t] * expression2[t] | ||
|
|
||
| constraint = pyo.Constraint(model.t, rule=const_rule) | ||
| if isinstance(expression1, (pyo.Param, pyo.Var)): |
There was a problem hiding this comment.
Check for a Pyomo IndexedExpression as well?
Fix issue with pyomo model handling.
Right now its assumed pyomo model has a variable t on it which is used for indexing the consumption variable, this is not necessarly true and complicates model handling.
Here we update the costing to automatically extract index set from the consumption variable, and use it through out. This removes the need to find a model.t var or for user to create it.
This additionally fixes tests: