def test_simple_substitute_param(self): def diffeq(m, t, i): return m.dxdt[t, i] == t * m.x[t, i - 1] ** 2 + m.y ** 2 + m.x[t, i + 1] + m.x[t, i - 1] m = self.m t = IndexTemplate(m.TIME) e = diffeq(m, t, 2) self.assertTrue(isinstance(e, EXPR._ExpressionBase)) _map = {} E = substitute_template_expression(e, substitute_getitem_with_param, _map) self.assertIsNot(e, E) self.assertEqual(len(_map), 3) idx1 = _GetItemIndexer(m.x[t, 1]) self.assertIs(idx1._base, m.x) self.assertEqual(len(idx1._args), 2) self.assertIs(idx1._args[0], t) self.assertEqual(idx1._args[1], 1) self.assertIn(idx1, _map) idx2 = _GetItemIndexer(m.dxdt[t, 2]) self.assertIs(idx2._base, m.dxdt) self.assertEqual(len(idx2._args), 2) self.assertIs(idx2._args[0], t) self.assertEqual(idx2._args[1], 2) self.assertIn(idx2, _map) idx3 = _GetItemIndexer(m.x[t, 3]) self.assertIs(idx3._base, m.x) self.assertEqual(len(idx3._args), 2) self.assertIs(idx3._args[0], t) self.assertEqual(idx3._args[1], 3) self.assertIn(idx3, _map) self.assertFalse(idx1 == idx2) self.assertFalse(idx1 == idx3) self.assertFalse(idx2 == idx3) idx4 = _GetItemIndexer(m.x[t, 2]) self.assertNotIn(idx4, _map) t.set_value(5) self.assertEqual((e._args[0](), e._args[1]()), (10, 136)) self.assertEqual(str(E), "dxdt[{TIME},2] == {TIME} * x[{TIME},1]**2.0 + y**2.0 + x[{TIME},3] + x[{TIME},1]") _map[idx1].set_value(value(m.x[value(t), 1])) _map[idx2].set_value(value(m.dxdt[value(t), 2])) _map[idx3].set_value(value(m.x[value(t), 3])) self.assertEqual((E._args[0](), E._args[1]()), (10, 136)) _map[idx1].set_value(12) _map[idx2].set_value(34) self.assertEqual((E._args[0](), E._args[1]()), (34, 738))
def _test_template_scalar_with_set(self): m = self.m t = IndexTemplate(m.I) e = m.s[t] self.assertIs(type(e), EXPR.GetItemExpression) self.assertIs(e._base, m.s) self.assertEqual(tuple(e.args), (t,)) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(5) self.assertRaises(TypeError, e) self.assertIs(e.resolve_template(), m.s[5]) t.set_value(None)
def test_simple_substitute_index(self): def diffeq(m, t, i): return m.dxdt[t, i] == t * m.x[t, i] ** 2 + m.y ** 2 m = self.m t = IndexTemplate(m.TIME) e = diffeq(m, t, 2) t.set_value(5) self.assertTrue(isinstance(e, EXPR._ExpressionBase)) self.assertEqual((e._args[0](), e._args[1]()), (10, 126)) E = substitute_template_expression(e, substitute_template_with_value) self.assertIsNot(e, E) self.assertEqual(str(E), "dxdt[5,2] == 5.0 * x[5,2]**2.0 + y**2.0")
def test_nested_template_operation(self): m = self.m t = IndexTemplate(m.I) e = m.x[t + m.P[t + 1]] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.x) self.assertEqual(len(e._args), 1) self.assertIs(type(e._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[0], t) self.assertIs(type(e._args[0]._args[1]), EXPR._GetItemExpression) self.assertIs(type(e._args[0]._args[1]._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[1]._args[0]._args[0], t)
def test_substitute_casadi_intrinsic1(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = m.v[t] templatemap = {} e3 = substitute_pyomo2casadi(e, templatemap) self.assertIs(type(e3), casadi.SX) m.del_component('y')
def test_nested_template_operation(self): m = self.m t = IndexTemplate(m.I) e = m.x[t + m.P[t + 1]] self.assertIs(type(e), EXPR.GetItemExpression) self.assertIs(e._base, m.x) self.assertEqual(e.nargs(), 1) self.assertTrue(isinstance(e.arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(0), t) self.assertIs(type(e.arg(0).arg(1)), EXPR.GetItemExpression) self.assertTrue( isinstance(e.arg(0).arg(1).arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(1).arg(0).arg(0), t)
def test_template_expr(self): m = ConcreteModel() m.I = RangeSet(1, 9) m.x = Var(m.I, initialize=lambda m, i: i + 1) m.P = Param(m.I, initialize=lambda m, i: 10 - i, mutable=True) t = IndexTemplate(m.I) e = m.x[t + m.P[t + 1]] + 3 self.assertRaises(TemplateExpressionError, evaluate_expression, e) self.assertRaises(TemplateExpressionError, evaluate_expression, e, constant=True)
def test_unsupported_pyomo4_expressions(self): EXPR.set_expression_tree_format(expr_common.Mode.pyomo4_trees) m = self.m t = IndexTemplate(m.t) # Check multiplication by constant e = 5 * m.dv[t] == m.v[t] with self.assertRaises(TypeError): _check_productexpression(e, 0) EXPR.set_expression_tree_format(expr_common._default_mode)
def test_substitute_casadi_intrinsic3(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = sin(m.dv[t] + m.v[t]) + log(m.v[t] * m.y + m.dv[t]**2) templatemap = {} e3 = substitute_pyomo2casadi(e, templatemap) self.assertIs(e3.arg(0)._fcn, casadi.sin) self.assertIs(e3.arg(1)._fcn, casadi.log) m.del_component('y')
def test_substitute_casadi_intrinsic1(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = m.v[t] templatemap = {} e2 = substitute_template_expression( e, substitute_getitem_with_casadi_sym, templatemap) e3 = substitute_intrinsic_function( e2, substitute_intrinsic_function_with_casadi) self.assertIs(type(e3), casadi.SX) m.del_component('y')
def test_substitute_casadi_intrinsic4(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = m.v[t] * sin(m.dv[t] + m.v[t]) * t templatemap = {} e3 = substitute_pyomo2casadi(e, templatemap) self.assertIs(type(e3.arg(0).arg(0)), casadi.SX) self.assertIs(e3.arg(0).arg(1)._fcn, casadi.sin) self.assertIs(type(e3.arg(1)), IndexTemplate) m.del_component('y')
def test_nonRHS_vars(self): m = self.m m.v2 = Var(m.t) m.dv2 = DerivativeVar(m.v2) m.p = Param(initialize=5) t = IndexTemplate(m.t) def _con(m, t): return m.dv2[t] == 10 + m.p m.con = Constraint(m.t, rule=_con) mysim = Simulator(m,package='casadi') self.assertEqual(len(mysim._templatemap), 1) self.assertEqual(mysim._diffvars[0], _GetItemIndexer(m.v2[t])) m.del_component('con')
def test_substitute_casadi_intrinsic3(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = sin(m.dv[t] + m.v[t]) + log(m.v[t] * m.y + m.dv[t]**2) templatemap = {} e2 = substitute_template_expression( e, substitute_getitem_with_casadi_sym, templatemap) e3 = substitute_intrinsic_function( e2, substitute_intrinsic_function_with_casadi) self.assertIs(e3._args[0]._operator, casadi.sin) self.assertIs(e3._args[1]._operator, casadi.log) m.del_component('y')
def test_time_indexed_algebraic(self): m = self.m m.a = Var(m.t) def _diffeq(m, t): return m.dv[t] == m.v[t]**2 + m.a[t] m.con = Constraint(m.t, rule=_diffeq) mysim = Simulator(m) t = IndexTemplate(m.t) self.assertEqual(len(mysim._algvars), 1) self.assertTrue(_GetItemIndexer(m.a[t]) in mysim._algvars) self.assertEqual(len(mysim._alglist), 0) m.del_component('con')
def test_substitute_casadi_sym(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = m.dv[t] + m.v[t] + m.y + t templatemap = {} e2 = substitute_pyomo2casadi(e, templatemap) self.assertEqual(len(templatemap), 2) self.assertIs(type(e2.arg(0)), casadi.SX) self.assertIs(type(e2.arg(1)), casadi.SX) self.assertIsNot(type(e2.arg(2)), casadi.SX) self.assertIs(type(e2.arg(3)), IndexTemplate) m.del_component('y')
def test_substitute_casadi_intrinsic4(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = m.v[t] * sin(m.dv[t] + m.v[t]) * t templatemap = {} e2 = substitute_template_expression( e, substitute_getitem_with_casadi_sym, templatemap) e3 = substitute_intrinsic_function( e2, substitute_intrinsic_function_with_casadi) self.assertIs(type(e3._numerator[0]), casadi.SX) self.assertIs(e3._numerator[1]._operator, casadi.sin) self.assertIs(type(e3._numerator[2]), IndexTemplate) m.del_component('y')
def test_sim_initialization_single_index(self): m = self.m m.w = Var(m.t) m.dw = DerivativeVar(m.w) t = IndexTemplate(m.t) def _deq1(m, i): return m.dv[i] == m.v[i] m.deq1 = Constraint(m.t, rule=_deq1) def _deq2(m, i): return m.dw[i] == m.v[i] m.deq2 = Constraint(m.t, rule=_deq2) mysim = Simulator(m) self.assertIs(mysim._contset, m.t) self.assertEqual(len(mysim._diffvars), 2) self.assertEqual(mysim._diffvars[0], _GetItemIndexer(m.v[t])) self.assertEqual(mysim._diffvars[1], _GetItemIndexer(m.w[t])) self.assertEqual(len(mysim._derivlist), 2) self.assertEqual(mysim._derivlist[0], _GetItemIndexer(m.dv[t])) self.assertEqual(mysim._derivlist[1], _GetItemIndexer(m.dw[t])) self.assertEqual(len(mysim._templatemap), 1) self.assertTrue(_GetItemIndexer(m.v[t]) in mysim._templatemap) self.assertFalse(_GetItemIndexer(m.w[t]) in mysim._templatemap) self.assertEqual(len(mysim._rhsdict), 2) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dv[t])], Param)) self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dv[t])].name, 'v[{t}]') self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw[t])], Param)) self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw[t])].name, 'v[{t}]') self.assertEqual(len(mysim._rhsfun(0, [0, 0])), 2) self.assertIsNone(mysim._tsim) self.assertIsNone(mysim._simsolution) m.del_component('deq1') m.del_component('deq2') m.del_component('dw') m.del_component('w')
def test_substitute_casadi_intrinsic3(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = sin(m.dv[t] + m.v[t]) + log(m.v[t] * m.y + m.dv[t]**2) templatemap = {} #e2 = substitute_template_expression( # e, substitute_getitem_with_casadi_sym, templatemap) #e3 = substitute_intrinsic_function( # e2, substitute_intrinsic_function_with_casadi) e3 = substitute_pyomo2casadi(e, templatemap) self.assertIs(e3.arg(0)._fcn, casadi.sin) self.assertIs(e3.arg(1)._fcn, casadi.log) m.del_component('y')
def test_substitute_casadi_sym(self): m = self.m m.y = Var() t = IndexTemplate(m.t) e = m.dv[t] + m.v[t] + m.y + t templatemap = {} e2 = substitute_template_expression( e, substitute_getitem_with_casadi_sym, templatemap) self.assertEqual(len(templatemap), 2) self.assertIs(type(e2._args[0]), casadi.SX) self.assertIs(type(e2._args[1]), casadi.SX) self.assertIsNot(type(e2._args[2]), casadi.SX) self.assertIs(type(e2._args[3]), IndexTemplate) m.del_component('y')
def test_check_viewsumexpression(self): m = self.m m.p = Param(initialize=5) m.mp = Param(initialize=5, mutable=True) m.y = Var() m.z = Var() t = IndexTemplate(m.t) e = m.dv[t] + m.y + m.z == m.v[t] temp = _check_viewsumexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR.SumExpression) self.assertIs(type(temp[1].arg(0)), EXPR.GetItemExpression) self.assertIs(type(temp[1].arg(1)), EXPR.MonomialTermExpression) self.assertEqual(-1, temp[1].arg(1).arg(0)) self.assertIs(m.y, temp[1].arg(1).arg(1)) self.assertIs(type(temp[1].arg(2)), EXPR.MonomialTermExpression) self.assertEqual(-1, temp[1].arg(2).arg(0)) self.assertIs(m.z, temp[1].arg(2).arg(1)) e = m.v[t] == m.y + m.dv[t] + m.z temp = _check_viewsumexpression(e, 1) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR.SumExpression) self.assertIs(type(temp[1].arg(0)), EXPR.GetItemExpression) self.assertIs(type(temp[1].arg(1)), EXPR.MonomialTermExpression) self.assertIs(m.y, temp[1].arg(1).arg(1)) self.assertIs(type(temp[1].arg(2)), EXPR.MonomialTermExpression) self.assertIs(m.z, temp[1].arg(2).arg(1)) e = 5 * m.dv[t] + 5 * m.y - m.z == m.v[t] temp = _check_viewsumexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR.ProductExpression) self.assertIs(type(temp[1].arg(0).arg(0)), EXPR.GetItemExpression) self.assertIs(m.y, temp[1].arg(0).arg(1).arg(1)) self.assertIs(m.z, temp[1].arg(0).arg(2).arg(1)) e = 2 + 5 * m.y - m.z == m.v[t] temp = _check_viewsumexpression(e, 0) self.assertIs(temp, None)
def _test_template_scalar_with_set(self): m = self.m t = IndexTemplate(m.I) e = m.s[t] self.assertIs(type(e), EXPR.GetItemExpression) self.assertIs(e._base, m.s) self.assertEqual(tuple(e.args), (t, )) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(5) self.assertRaises(TypeError, e) self.assertIs(e.resolve_template(), m.s[5]) t.set_value(None)
def test_check_sumexpression(self): m = self.m m.p = Param(initialize=5) m.mp = Param(initialize=5, mutable=True) m.y = Var() m.z = Var() t = IndexTemplate(m.t) e = m.dv[t] + m.y + m.z == m.v[t] temp = _check_sumexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._SumExpression) self.assertIs(m.y, temp[1]._args[1]) self.assertEqual(temp[1]._coef[1], -1) self.assertIs(m.z, temp[1]._args[2]) self.assertEqual(temp[1]._coef[2], -1) e = m.v[t] == m.y + m.dv[t] + m.z temp = _check_sumexpression(e, 1) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._SumExpression) self.assertIs(m.y, temp[1]._args[1]) self.assertEqual(temp[1]._coef[1], -1) self.assertIs(m.z, temp[1]._args[2]) self.assertEqual(temp[1]._coef[2], -1) e = 5 * m.dv[t] + 5 * m.y - m.z == m.v[t] temp = _check_sumexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) self.assertEqual(temp[1]._coef, 0.2) self.assertIs(m.y, temp[1]._numerator[0]._args[1]) self.assertEqual(temp[1]._numerator[0]._coef[1], -5) self.assertIs(m.z, temp[1]._numerator[0]._args[2]) self.assertEqual(temp[1]._numerator[0]._coef[2], 1) e = 2 + 5 * m.y - m.z == m.v[t] temp = _check_sumexpression(e, 0) self.assertIs(temp, None)
def test_separable_diffeq_case9(self): m = self.m m.w = Var(m.t, m.s) m.dw = DerivativeVar(m.w) m.p = Param(initialize=5) m.mp = Param(initialize=5, mutable=True) m.y = Var() t = IndexTemplate(m.t) def _deqv(m, i): return m.v[i]**2 + m.v[i] == -m.dv[i] m.deqv = Constraint(m.t, rule=_deqv) def _deqw(m, i, j): return m.w[i, j]**2 + m.w[i, j] == -m.dw[i, j] m.deqw = Constraint(m.t, m.s, rule=_deqw) mysim = Simulator(m) self.assertEqual(len(mysim._diffvars), 4) self.assertEqual(mysim._diffvars[0], _GetItemIndexer(m.v[t])) self.assertEqual(mysim._diffvars[1], _GetItemIndexer(m.w[t, 1])) self.assertEqual(mysim._diffvars[2], _GetItemIndexer(m.w[t, 2])) self.assertEqual(len(mysim._derivlist), 4) self.assertEqual(mysim._derivlist[0], _GetItemIndexer(m.dv[t])) self.assertEqual(mysim._derivlist[1], _GetItemIndexer(m.dw[t, 1])) self.assertEqual(mysim._derivlist[2], _GetItemIndexer(m.dw[t, 2])) self.assertEqual(len(mysim._rhsdict), 4) m.del_component('deqv') m.del_component('deqw') m.del_component('deqv_index') m.del_component('deqw_index')
def __init__(self, m, package='scipy'): self._intpackage = package if self._intpackage not in ['scipy', 'casadi']: raise DAE_Error( "Unrecognized simulator package %s. Please select from " "%s" % (self._intpackage, ['scipy', 'casadi'])) if self._intpackage == 'scipy': if not scipy_available: # Converting this to a warning so that Simulator initialization # can be tested even when scipy is unavailable logger.warning("The scipy module is not available. You may " "build the Simulator object but you will not " "be able to run the simulation.") else: if not casadi_available: # Initializing the simulator for use with casadi requires # access to casadi objects. Therefore, we must throw an error # here instead of a warning. raise ValueError("The casadi module is not available. " "Cannot simulate model.") # Check for active Blocks and throw error if any are found if len(list(m.component_data_objects(Block, active=True, descend_into=False))): raise DAE_Error("The Simulator cannot handle hierarchical models " "at the moment.") temp = m.component_map(ContinuousSet) if len(temp) != 1: raise DAE_Error( "Currently the simulator may only be applied to " "Pyomo models with a single ContinuousSet") # Get the ContinuousSet in the model contset = list(temp.values())[0] # Create a index template for the continuous set cstemplate = IndexTemplate(contset) # Ensure that there is at least one derivative in the model derivs = m.component_map(DerivativeVar) derivs = list(derivs.keys()) if hasattr(m, '_pyomo_dae_reclassified_derivativevars'): for d in m._pyomo_dae_reclassified_derivativevars: derivs.append(d.name) if len(derivs) == 0: raise DAE_Error("Cannot simulate a model with no derivatives") templatemap = {} # Map for template substituter rhsdict = {} # Map of derivative to its RHS templated expr derivlist = [] # Ordered list of derivatives alglist = [] # list of templated algebraic equations # Loop over constraints to find differential equations with separable # RHS. Must find a RHS for every derivative var otherwise ERROR. Build # dictionary of DerivativeVar:RHS equation. for con in m.component_objects(Constraint, active=True): # Skip the discretization equations if model is discretized if '_disc_eq' in con.name: continue # Check dimension of the Constraint. Check if the # Constraint is indexed by the continuous set and # determine its order in the indexing sets if con.dim() == 0: continue elif con._implicit_subsets is None: # Check if the continuous set is the indexing set if con._index is not contset: continue else: csidx = 0 noncsidx = (None,) else: temp = con._implicit_subsets dimsum = 0 csidx = -1 noncsidx = None for s in temp: if s is contset: if csidx != -1: raise DAE_Error( "Cannot simulate the constraint %s because " "it is indexed by duplicate ContinuousSets" % con.name) csidx = dimsum elif noncsidx is None: noncsidx = s else: noncsidx = noncsidx.cross(s) dimsum += s.dimen if csidx == -1: continue # Get the rule used to construct the constraint conrule = con.rule for i in noncsidx: # Insert the index template and call the rule to # create a templated expression if i is None: tempexp = conrule(m, cstemplate) else: if not isinstance(i, tuple): i = (i,) tempidx = i[0:csidx] + (cstemplate,) + i[csidx:] tempexp = conrule(m, *tempidx) # Check to make sure it's an EqualityExpression if not type(tempexp) is EXPR.EqualityExpression: continue # Check to make sure it's a differential equation with # separable RHS args = None # Case 1: m.dxdt[t] = RHS if type(tempexp.arg(0)) is EXPR.GetItemExpression: args = _check_getitemexpression(tempexp, 0) # Case 2: RHS = m.dxdt[t] if args is None: if type(tempexp.arg(1)) is EXPR.GetItemExpression: args = _check_getitemexpression(tempexp, 1) # Case 3: m.p*m.dxdt[t] = RHS if args is None: if type(tempexp.arg(0)) is EXPR.ProductExpression or \ type(tempexp.arg(0)) is EXPR.ReciprocalExpression: args = _check_productexpression(tempexp, 0) # Case 4: RHS = m.p*m.dxdt[t] if args is None: if type(tempexp.arg(1)) is EXPR.ProductExpression or \ type(tempexp.arg(1)) is EXPR.ReciprocalExpression: args = _check_productexpression(tempexp, 1) # Case 5: m.dxdt[t] + sum(ELSE) = RHS # or CONSTANT + m.dxdt[t] = RHS if args is None: if type(tempexp.arg(0)) is EXPR.SumExpression: args = _check_viewsumexpression(tempexp, 0) # Case 6: RHS = m.dxdt[t] + sum(ELSE) if args is None: if type(tempexp.arg(1)) is EXPR.SumExpression: args = _check_viewsumexpression(tempexp, 1) # Case 7: RHS = m.p*m.dxdt[t] + CONSTANT # This case will be caught by Case 6 if p is immutable. If # p is mutable then this case will not be detected as a # separable differential equation # Case 8: - dxdt[t] = RHS if args is None: if type(tempexp.arg(0)) is EXPR.NegationExpression: args = _check_negationexpression(tempexp, 0) # Case 9: RHS = - dxdt[t] if args is None: if type(tempexp.arg(1)) is EXPR.NegationExpression: args = _check_negationexpression(tempexp, 1) # At this point if args is not None then args[0] contains # the _GetItemExpression for the DerivativeVar and args[1] # contains the RHS expression. If args is None then the # constraint is considered an algebraic equation if args is None: # Constraint is an algebraic equation or unsupported # differential equation if self._intpackage == 'scipy': raise DAE_Error( "Model contains an algebraic equation or " "unrecognized differential equation. Constraint " "'%s' cannot be simulated using Scipy. If you are " "trying to simulate a DAE model you must use " "CasADi as the integration package." % str(con.name)) tempexp = tempexp.arg(0) - tempexp.arg(1) algexp = substitute_pyomo2casadi(tempexp, templatemap) alglist.append(algexp) continue # Add the differential equation to rhsdict and derivlist dv = args[0] RHS = args[1] dvkey = _GetItemIndexer(dv) if dvkey in rhsdict.keys(): raise DAE_Error( "Found multiple RHS expressions for the " "DerivativeVar %s" % str(dvkey)) derivlist.append(dvkey) if self._intpackage is 'casadi': rhsdict[dvkey] = substitute_pyomo2casadi(RHS, templatemap) else: rhsdict[dvkey] = convert_pyomo2scipy(RHS, templatemap) # Check to see if we found a RHS for every DerivativeVar in # the model # FIXME: Not sure how to rework this for multi-index case # allderivs = derivs.keys() # if set(allderivs) != set(derivlist): # missing = list(set(allderivs)-set(derivlist)) # print("WARNING: Could not find a RHS expression for the " # "following DerivativeVar components "+str(missing)) # Create ordered list of differential variables corresponding # to the list of derivatives. diffvars = [] for deriv in derivlist: sv = deriv._base.get_state_var() diffvars.append(_GetItemIndexer(sv[deriv._args])) # Create ordered list of algebraic variables and time-varying # parameters algvars = [] for item in iterkeys(templatemap): if item._base.name in derivs: # Make sure there are no DerivativeVars in the # template map raise DAE_Error( "Cannot simulate a differential equation with " "multiple DerivativeVars") if item not in diffvars: # Finds time varying parameters and algebraic vars algvars.append(item) if self._intpackage == 'scipy': # Function sent to scipy integrator def _rhsfun(t, x): residual = [] cstemplate.set_value(t) for idx, v in enumerate(diffvars): if v in templatemap: templatemap[v].set_value(x[idx]) for d in derivlist: residual.append(rhsdict[d]()) return residual self._rhsfun = _rhsfun # Add any diffvars not added by expression walker to self._templatemap if self._intpackage == 'casadi': for _id in diffvars: if _id not in templatemap: name = "%s[%s]" % ( _id._base.name, ','.join(str(x) for x in _id._args)) templatemap[_id] = casadi.SX.sym(name) self._contset = contset self._cstemplate = cstemplate self._diffvars = diffvars self._derivlist = derivlist self._templatemap = templatemap self._rhsdict = rhsdict self._alglist = alglist self._algvars = algvars self._model = m self._tsim = None self._simsolution = None # The algebraic vars in the most recent simulation self._simalgvars = None # The time-varying inputs in the most recent simulation self._siminputvars = None
def test_get_check_units_on_all_expressions(self): # this method is going to test all the expression types that should work # to be defensive, we will also test that we actually have the expected expression type # therefore, if the expression system changes and we get a different expression type, # we will know we need to change these tests uc = units kg = uc.kg m = uc.m model = ConcreteModel() model.x = Var() model.y = Var() model.z = Var() model.p = Param(initialize=42.0, mutable=True) # test equality self._get_check_units_ok(3.0*kg == 1.0*kg, uc, 'kg', expr.EqualityExpression) self._get_check_units_fail(3.0*kg == 2.0*m, uc, expr.EqualityExpression) # test inequality self._get_check_units_ok(3.0*kg <= 1.0*kg, uc, 'kg', expr.InequalityExpression) self._get_check_units_fail(3.0*kg <= 2.0*m, uc, expr.InequalityExpression) self._get_check_units_ok(3.0*kg >= 1.0*kg, uc, 'kg', expr.InequalityExpression) self._get_check_units_fail(3.0*kg >= 2.0*m, uc, expr.InequalityExpression) # test RangedExpression self._get_check_units_ok(inequality(3.0*kg, 4.0*kg, 5.0*kg), uc, 'kg', expr.RangedExpression) self._get_check_units_fail(inequality(3.0*m, 4.0*kg, 5.0*kg), uc, expr.RangedExpression) self._get_check_units_fail(inequality(3.0*kg, 4.0*m, 5.0*kg), uc, expr.RangedExpression) self._get_check_units_fail(inequality(3.0*kg, 4.0*kg, 5.0*m), uc, expr.RangedExpression) # test SumExpression, NPV_SumExpression self._get_check_units_ok(3.0*model.x*kg + 1.0*model.y*kg + 3.65*model.z*kg, uc, 'kg', expr.SumExpression) self._get_check_units_fail(3.0*model.x*kg + 1.0*model.y*m + 3.65*model.z*kg, uc, expr.SumExpression) self._get_check_units_ok(3.0*kg + 1.0*kg + 2.0*kg, uc, 'kg', expr.NPV_SumExpression) self._get_check_units_fail(3.0*kg + 1.0*kg + 2.0*m, uc, expr.NPV_SumExpression) # test ProductExpression, NPV_ProductExpression self._get_check_units_ok(model.x*kg * model.y*m, uc, 'kg * m', expr.ProductExpression) self._get_check_units_ok(3.0*kg * 1.0*m, uc, 'kg * m', expr.NPV_ProductExpression) self._get_check_units_ok(3.0*kg*m, uc, 'kg * m', expr.NPV_ProductExpression) # I don't think that there are combinations that can "fail" for products # test MonomialTermExpression self._get_check_units_ok(model.x*kg, uc, 'kg', expr.MonomialTermExpression) # test DivisionExpression, NPV_DivisionExpression self._get_check_units_ok(1.0/(model.x*kg), uc, '1 / kg', expr.DivisionExpression) self._get_check_units_ok(2.0/kg, uc, '1 / kg', expr.NPV_DivisionExpression) self._get_check_units_ok((model.x*kg)/1.0, uc, 'kg', expr.MonomialTermExpression) self._get_check_units_ok(kg/2.0, uc, 'kg', expr.NPV_DivisionExpression) self._get_check_units_ok(model.y*m/(model.x*kg), uc, 'm / kg', expr.DivisionExpression) self._get_check_units_ok(m/kg, uc, 'm / kg', expr.NPV_DivisionExpression) # I don't think that there are combinations that can "fail" for products # test PowExpression, NPV_PowExpression # ToDo: fix the str representation to combine the powers or the expression system self._get_check_units_ok((model.x*kg**2)**3, uc, 'kg ** 6', expr.PowExpression) # would want this to be kg**6 self._get_check_units_fail(kg**model.x, uc, expr.PowExpression, UnitsError) self._get_check_units_fail(model.x**kg, uc, expr.PowExpression, UnitsError) self._get_check_units_ok(kg**2, uc, 'kg ** 2', expr.NPV_PowExpression) self._get_check_units_fail(3.0**kg, uc, expr.NPV_PowExpression, UnitsError) # test NegationExpression, NPV_NegationExpression self._get_check_units_ok(-(kg*model.x*model.y), uc, 'kg', expr.NegationExpression) self._get_check_units_ok(-kg, uc, 'kg', expr.NPV_NegationExpression) # don't think there are combinations that fan "fail" for negation # test AbsExpression, NPV_AbsExpression self._get_check_units_ok(abs(kg*model.x), uc, 'kg', expr.AbsExpression) self._get_check_units_ok(abs(kg), uc, 'kg', expr.NPV_AbsExpression) # don't think there are combinations that fan "fail" for abs # test the different UnaryFunctionExpression / NPV_UnaryFunctionExpression types # log self._get_check_units_ok(log(3.0*model.x), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(log(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(log(3.0*model.p), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(log(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # log10 self._get_check_units_ok(log10(3.0*model.x), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(log10(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(log10(3.0*model.p), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(log10(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # sin self._get_check_units_ok(sin(3.0*model.x*uc.radians), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(sin(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(sin(3.0*kg*model.x*uc.kg), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(sin(3.0*model.p*uc.radians), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(sin(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # cos self._get_check_units_ok(cos(3.0*model.x*uc.radians), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(cos(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(cos(3.0*kg*model.x*uc.kg), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(cos(3.0*model.p*uc.radians), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(cos(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # tan self._get_check_units_ok(tan(3.0*model.x*uc.radians), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(tan(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(tan(3.0*kg*model.x*uc.kg), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(tan(3.0*model.p*uc.radians), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(tan(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # sin self._get_check_units_ok(sinh(3.0*model.x*uc.radians), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(sinh(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(sinh(3.0*kg*model.x*uc.kg), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(sinh(3.0*model.p*uc.radians), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(sinh(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # cos self._get_check_units_ok(cosh(3.0*model.x*uc.radians), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(cosh(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(cosh(3.0*kg*model.x*uc.kg), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(cosh(3.0*model.p*uc.radians), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(cosh(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # tan self._get_check_units_ok(tanh(3.0*model.x*uc.radians), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(tanh(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_fail(tanh(3.0*kg*model.x*uc.kg), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(tanh(3.0*model.p*uc.radians), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(tanh(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # asin self._get_check_units_ok(asin(3.0*model.x), uc, 'rad', expr.UnaryFunctionExpression) self._get_check_units_fail(asin(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(asin(3.0*model.p), uc, 'rad', expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(asin(3.0*model.p*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # acos self._get_check_units_ok(acos(3.0*model.x), uc, 'rad', expr.UnaryFunctionExpression) self._get_check_units_fail(acos(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(acos(3.0*model.p), uc, 'rad', expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(acos(3.0*model.p*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # atan self._get_check_units_ok(atan(3.0*model.x), uc, 'rad', expr.UnaryFunctionExpression) self._get_check_units_fail(atan(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(atan(3.0*model.p), uc, 'rad', expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(atan(3.0*model.p*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # exp self._get_check_units_ok(exp(3.0*model.x), uc, None, expr.UnaryFunctionExpression) self._get_check_units_fail(exp(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(exp(3.0*model.p), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(exp(3.0*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # sqrt self._get_check_units_ok(sqrt(3.0*model.x), uc, None, expr.UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.x*kg**2), uc, 'kg', expr.UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.x*kg), uc, 'kg ** 0.5', expr.UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.p), uc, None, expr.NPV_UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.p*kg**2), uc, 'kg', expr.NPV_UnaryFunctionExpression) self._get_check_units_ok(sqrt(3.0*model.p*kg), uc, 'kg ** 0.5', expr.NPV_UnaryFunctionExpression) # asinh self._get_check_units_ok(asinh(3.0*model.x), uc, 'rad', expr.UnaryFunctionExpression) self._get_check_units_fail(asinh(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(asinh(3.0*model.p), uc, 'rad', expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(asinh(3.0*model.p*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # acosh self._get_check_units_ok(acosh(3.0*model.x), uc, 'rad', expr.UnaryFunctionExpression) self._get_check_units_fail(acosh(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(acosh(3.0*model.p), uc, 'rad', expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(acosh(3.0*model.p*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # atanh self._get_check_units_ok(atanh(3.0*model.x), uc, 'rad', expr.UnaryFunctionExpression) self._get_check_units_fail(atanh(3.0*kg*model.x), uc, expr.UnaryFunctionExpression, UnitsError) self._get_check_units_ok(atanh(3.0*model.p), uc, 'rad', expr.NPV_UnaryFunctionExpression) self._get_check_units_fail(atanh(3.0*model.p*kg), uc, expr.NPV_UnaryFunctionExpression, UnitsError) # ceil self._get_check_units_ok(ceil(kg*model.x), uc, 'kg', expr.UnaryFunctionExpression) self._get_check_units_ok(ceil(kg), uc, 'kg', expr.NPV_UnaryFunctionExpression) # don't think there are combinations that fan "fail" for ceil # floor self._get_check_units_ok(floor(kg*model.x), uc, 'kg', expr.UnaryFunctionExpression) self._get_check_units_ok(floor(kg), uc, 'kg', expr.NPV_UnaryFunctionExpression) # don't think there are combinations that fan "fail" for floor # test Expr_ifExpression # consistent if, consistent then/else self._get_check_units_ok(expr.Expr_if(IF=model.x*kg + kg >= 2.0*kg, THEN=model.x*kg, ELSE=model.y*kg), uc, 'kg', expr.Expr_ifExpression) # unitless if, consistent then/else self._get_check_units_ok(expr.Expr_if(IF=model.x >= 2.0, THEN=model.x*kg, ELSE=model.y*kg), uc, 'kg', expr.Expr_ifExpression) # consistent if, unitless then/else self._get_check_units_ok(expr.Expr_if(IF=model.x*kg + kg >= 2.0*kg, THEN=model.x, ELSE=model.x), uc, None, expr.Expr_ifExpression) # inconsistent then/else self._get_check_units_fail(expr.Expr_if(IF=model.x >= 2.0, THEN=model.x*m, ELSE=model.y*kg), uc, expr.Expr_ifExpression) # inconsistent then/else NPV self._get_check_units_fail(expr.Expr_if(IF=model.x >= 2.0, THEN=model.p*m, ELSE=model.p*kg), uc, expr.Expr_ifExpression) # inconsistent then/else NPV units only self._get_check_units_fail(expr.Expr_if(IF=model.x >= 2.0, THEN=m, ELSE=kg), uc, expr.Expr_ifExpression) # test IndexTemplate and GetItemExpression model.S = Set() i = IndexTemplate(model.S) j = IndexTemplate(model.S) self._get_check_units_ok(i, uc, None, IndexTemplate) model.mat = Var(model.S, model.S) self._get_check_units_ok(model.mat[i,j+1], uc, None, expr.GetItemExpression) # test ExternalFunctionExpression, NPV_ExternalFunctionExpression model.ef = ExternalFunction(python_callback_function) self._get_check_units_ok(model.ef(model.x, model.y), uc, None, expr.ExternalFunctionExpression) self._get_check_units_ok(model.ef(1.0, 2.0), uc, None, expr.NPV_ExternalFunctionExpression) self._get_check_units_fail(model.ef(model.x*kg, model.y), uc, expr.ExternalFunctionExpression, UnitsError) self._get_check_units_fail(model.ef(2.0*kg, 1.0), uc, expr.NPV_ExternalFunctionExpression, UnitsError)
def test_template_scalar(self): m = self.m t = IndexTemplate(m.I) e = m.x[t] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.x) self.assertEqual(e._args, (t,)) self.assertFalse(e.is_constant()) self.assertFalse(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 1) t.set_value(5) self.assertEqual(e(), 6) self.assertIs(e.resolve_template(), m.x[5]) t.set_value(None) e = m.p[t, 10] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.p) self.assertEqual(e._args, (t, 10)) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(5) self.assertEqual(e(), 510) self.assertIs(e.resolve_template(), m.p[5, 10]) t.set_value(None) e = m.p[5, t] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.p) self.assertEqual(e._args, (5, t)) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(10) self.assertEqual(e(), 510) self.assertIs(e.resolve_template(), m.p[5, 10]) t.set_value(None) e = m.s[t] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.s) self.assertEqual(e._args, (t,)) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(5) self.assertRaises(TypeError, e) self.assertIs(e.resolve_template(), m.s[5]) t.set_value(None)
def test_check_productexpression(self): m = self.m m.p = Param(initialize=5) m.mp = Param(initialize=5, mutable=True) m.y = Var() m.z = Var() t = IndexTemplate(m.t) # Check multiplication by constant e = 5 * m.dv[t] == m.v[t] temp = _check_productexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) e = m.v[t] == 5 * m.dv[t] temp = _check_productexpression(e, 1) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) # Check multiplication by fixed param e = m.p * m.dv[t] == m.v[t] temp = _check_productexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) e = m.v[t] == m.p * m.dv[t] temp = _check_productexpression(e, 1) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) # Check multiplication by mutable param e = m.mp * m.dv[t] == m.v[t] temp = _check_productexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) self.assertIs(m.mp, temp[1]._denominator[0]) e = m.v[t] == m.mp * m.dv[t] temp = _check_productexpression(e, 1) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) self.assertIs(m.mp, temp[1]._denominator[0]) # Check multiplication by var e = m.y * m.dv[t] / m.z == m.v[t] temp = _check_productexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) self.assertIs(m.y, temp[1]._denominator[0]) self.assertIs(m.z, temp[1]._numerator[1]) e = m.v[t] == m.y * m.dv[t] / m.z temp = _check_productexpression(e, 1) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) self.assertIs(m.y, temp[1]._denominator[0]) self.assertIs(m.z, temp[1]._numerator[1]) # Check having the DerivativeVar in the denominator e = m.y / (m.dv[t] * m.z) == m.mp temp = _check_productexpression(e, 0) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) self.assertIs(m.mp, temp[1]._denominator[0]) self.assertIs(m.y, temp[1]._numerator[0]) self.assertIs(m.z, temp[1]._denominator[1]) e = m.mp == m.y / (m.dv[t] * m.z) temp = _check_productexpression(e, 1) self.assertIs(m.dv, temp[0]._base) self.assertIs(type(temp[1]), EXPR._ProductExpression) self.assertIs(m.mp, temp[1]._denominator[0]) self.assertIs(m.y, temp[1]._numerator[0]) self.assertIs(m.z, temp[1]._denominator[1]) # Check expression with no DerivativeVar e = m.v[t] * m.y / m.z == m.v[t] * m.y / m.z temp = _check_productexpression(e, 0) self.assertIsNone(temp) temp = _check_productexpression(e, 1) self.assertIsNone(temp)
def test_clone(self): m = self.m t = IndexTemplate(m.I) E_base = m.x[t + m.P[t + 1]] + m.P[1] E = E_base.clone() self.assertTrue(isinstance(E, EXPR.SumExpressionBase)) e = E.arg(0) self.assertIs(type(e), EXPR.GetItemExpression) self.assertIsNot(e, E_base.arg(0)) self.assertIs(e._base, m.x) self.assertEqual(e.nargs(), 1) self.assertTrue(isinstance(e.arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(0), t) self.assertIs(type(e.arg(0).arg(1)), EXPR.GetItemExpression) self.assertIs(type(e.arg(0).arg(1)), type(E_base.arg(0).arg(0).arg(1))) self.assertIsNot(e.arg(0).arg(1), E_base.arg(0).arg(0).arg(1)) self.assertTrue( isinstance(e.arg(0).arg(1).arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(1).arg(0).arg(0), t) E_base = m.P[1] + m.x[t + m.P[t + 1]] E = E_base.clone() self.assertTrue(isinstance(E, EXPR.SumExpressionBase)) e = E.arg(1) self.assertIs(type(e), EXPR.GetItemExpression) self.assertIsNot(e, E_base.arg(0)) self.assertIs(e._base, m.x) self.assertEqual(e.nargs(), 1) self.assertTrue(isinstance(e.arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(0), t) self.assertIs(type(e.arg(0).arg(1)), EXPR.GetItemExpression) self.assertIs(type(e.arg(0).arg(1)), type(E_base.arg(1).arg(0).arg(1))) self.assertIsNot(e.arg(0).arg(1), E_base.arg(1).arg(0).arg(1)) self.assertTrue( isinstance(e.arg(0).arg(1).arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(1).arg(0).arg(0), t) E_base = m.x[t + m.P[t + 1]] + 1 E = E_base.clone() self.assertTrue(isinstance(E, EXPR.SumExpressionBase)) e = E.arg(0) self.assertIs(type(e), EXPR.GetItemExpression) self.assertIsNot(e, E_base.arg(0)) self.assertIs(e._base, m.x) self.assertEqual(e.nargs(), 1) self.assertTrue(isinstance(e.arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(0), t) self.assertIs(type(e.arg(0).arg(1)), EXPR.GetItemExpression) self.assertIs(type(e.arg(0).arg(1)), type(E_base.arg(0).arg(0).arg(1))) self.assertIsNot(e.arg(0).arg(1), E_base.arg(0).arg(0).arg(1)) self.assertTrue( isinstance(e.arg(0).arg(1).arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(1).arg(0).arg(0), t) E_base = 1 + m.x[t + m.P[t + 1]] E = E_base.clone() self.assertTrue(isinstance(E, EXPR.SumExpressionBase)) e = E.arg(-1) self.assertIs(type(e), EXPR.GetItemExpression) self.assertIsNot(e, E_base.arg(0)) self.assertIs(e._base, m.x) self.assertEqual(e.nargs(), 1) self.assertTrue(isinstance(e.arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(0), t) self.assertIs(type(e.arg(0).arg(1)), EXPR.GetItemExpression) self.assertIs(type(e.arg(0).arg(1)), type(E_base.arg(-1).arg(0).arg(1))) self.assertIsNot(e.arg(0).arg(1), E_base.arg(-1).arg(0).arg(1)) self.assertTrue( isinstance(e.arg(0).arg(1).arg(0), EXPR.SumExpressionBase)) self.assertIs(e.arg(0).arg(1).arg(0).arg(0), t)
def test_sim_initialization_multi_index2(self): m = self.m m.s2 = Set(initialize=[(1, 1), (2, 2)]) m.w1 = Var(m.t, m.s2) m.dw1 = DerivativeVar(m.w1) m.w2 = Var(m.s2, m.t) m.dw2 = DerivativeVar(m.w2) m.w3 = Var([0, 1], m.t, m.s2) m.dw3 = DerivativeVar(m.w3) t = IndexTemplate(m.t) def _deq1(m, t, i, j): return m.dw1[t, i, j] == m.w1[t, i, j] m.deq1 = Constraint(m.t, m.s2, rule=_deq1) def _deq2(m, *idx): return m.dw2[idx] == m.w2[idx] m.deq2 = Constraint(m.s2, m.t, rule=_deq2) def _deq3(m, i, t, j, k): return m.dw3[i, t, j, k] == m.w1[t, j, k] + m.w2[j, k, t] m.deq3 = Constraint([0, 1], m.t, m.s2, rule=_deq3) mysim = Simulator(m) self.assertIs(mysim._contset, m.t) self.assertEqual(len(mysim._diffvars), 8) self.assertTrue(_GetItemIndexer(m.w1[t, 1, 1]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w1[t, 2, 2]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w2[1, 1, t]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w2[2, 2, t]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w3[0, t, 1, 1]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w3[1, t, 2, 2]) in mysim._diffvars) self.assertEqual(len(mysim._derivlist), 8) self.assertTrue(_GetItemIndexer(m.dw1[t, 1, 1]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw1[t, 2, 2]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw2[1, 1, t]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw2[2, 2, t]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw3[0, t, 1, 1]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw3[1, t, 2, 2]) in mysim._derivlist) self.assertEqual(len(mysim._templatemap), 4) self.assertTrue(_GetItemIndexer(m.w1[t, 1, 1]) in mysim._templatemap) self.assertTrue(_GetItemIndexer(m.w1[t, 2, 2]) in mysim._templatemap) self.assertTrue(_GetItemIndexer(m.w2[1, 1, t]) in mysim._templatemap) self.assertTrue(_GetItemIndexer(m.w2[2, 2, t]) in mysim._templatemap) self.assertFalse( _GetItemIndexer(m.w3[0, t, 1, 1]) in mysim._templatemap) self.assertFalse( _GetItemIndexer(m.w3[1, t, 2, 2]) in mysim._templatemap) self.assertEqual(len(mysim._rhsdict), 8) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 1, 1])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 2, 2])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw2[1, 1, t])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw2[2, 2, t])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw3[0, t, 1, 1])], EXPR._SumExpression)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw3[1, t, 2, 2])], EXPR._SumExpression)) self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 1, 1])].name, 'w1[{t},1,1]') self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 2, 2])].name, 'w1[{t},2,2]') self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw2[1, 1, t])].name, 'w2[1,1,{t}]') self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw2[2, 2, t])].name, 'w2[2,2,{t}]') self.assertEqual(len(mysim._rhsfun(0, [0] * 8)), 8) self.assertIsNone(mysim._tsim) self.assertIsNone(mysim._simsolution) m.del_component('deq1') m.del_component('deq1_index') m.del_component('deq2') m.del_component('deq2_index') m.del_component('deq3') m.del_component('deq3_index')
def test_sim_initialization_multi_index(self): m = self.m m.w1 = Var(m.t, m.s) m.dw1 = DerivativeVar(m.w1) m.w2 = Var(m.s, m.t) m.dw2 = DerivativeVar(m.w2) m.w3 = Var([0, 1], m.t, m.s) m.dw3 = DerivativeVar(m.w3) t = IndexTemplate(m.t) def _deq1(m, t, s): return m.dw1[t, s] == m.w1[t, s] m.deq1 = Constraint(m.t, m.s, rule=_deq1) def _deq2(m, s, t): return m.dw2[s, t] == m.w2[s, t] m.deq2 = Constraint(m.s, m.t, rule=_deq2) def _deq3(m, i, t, s): return m.dw3[i, t, s] == m.w1[t, s] + m.w2[i + 1, t] m.deq3 = Constraint([0, 1], m.t, m.s, rule=_deq3) mysim = Simulator(m) self.assertIs(mysim._contset, m.t) self.assertEqual(len(mysim._diffvars), 12) self.assertTrue(_GetItemIndexer(m.w1[t, 1]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w1[t, 3]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w2[1, t]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w2[3, t]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w3[0, t, 1]) in mysim._diffvars) self.assertTrue(_GetItemIndexer(m.w3[1, t, 3]) in mysim._diffvars) self.assertEqual(len(mysim._derivlist), 12) self.assertTrue(_GetItemIndexer(m.dw1[t, 1]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw1[t, 3]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw2[1, t]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw2[3, t]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw3[0, t, 1]) in mysim._derivlist) self.assertTrue(_GetItemIndexer(m.dw3[1, t, 3]) in mysim._derivlist) self.assertEqual(len(mysim._templatemap), 6) self.assertTrue(_GetItemIndexer(m.w1[t, 1]) in mysim._templatemap) self.assertTrue(_GetItemIndexer(m.w1[t, 3]) in mysim._templatemap) self.assertTrue(_GetItemIndexer(m.w2[1, t]) in mysim._templatemap) self.assertTrue(_GetItemIndexer(m.w2[3, t]) in mysim._templatemap) self.assertFalse(_GetItemIndexer(m.w3[0, t, 1]) in mysim._templatemap) self.assertFalse(_GetItemIndexer(m.w3[1, t, 3]) in mysim._templatemap) self.assertEqual(len(mysim._rhsdict), 12) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 1])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 3])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw2[1, t])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw2[3, t])], Param)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw3[0, t, 1])], EXPR._SumExpression)) self.assertTrue( isinstance(mysim._rhsdict[_GetItemIndexer(m.dw3[1, t, 3])], EXPR._SumExpression)) self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 1])].name, 'w1[{t},1]') self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw1[t, 3])].name, 'w1[{t},3]') self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw2[1, t])].name, 'w2[1,{t}]') self.assertEqual(mysim._rhsdict[_GetItemIndexer(m.dw2[3, t])].name, 'w2[3,{t}]') self.assertEqual(len(mysim._rhsfun(0, [0] * 12)), 12) self.assertIsNone(mysim._tsim) self.assertIsNone(mysim._simsolution) m.del_component('deq1') m.del_component('deq1_index') m.del_component('deq2') m.del_component('deq2_index') m.del_component('deq3') m.del_component('deq3_index')
def test_clone(self): m = self.m t = IndexTemplate(m.I) E_base = m.x[t + m.P[t + 1]] + m.P[1] E = E_base.clone() self.assertIs(type(E), EXPR._SumExpression) e = E._args[0] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIsNot(e, E_base._args[0]) self.assertIs(e._base, m.x) self.assertEqual(len(e._args), 1) self.assertIs(type(e._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[0], t) self.assertIs(type(e._args[0]._args[1]), EXPR._GetItemExpression) self.assertIs(type(e._args[0]._args[1]), type(E_base._args[0]._args[0]._args[1])) self.assertIsNot(e._args[0]._args[1], E_base._args[0]._args[0]._args[1]) self.assertIs(type(e._args[0]._args[1]._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[1]._args[0]._args[0], t) E_base = m.P[1] + m.x[t + m.P[t + 1]] E = E_base.clone() self.assertIs(type(E), EXPR._SumExpression) e = E._args[1] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIsNot(e, E_base._args[0]) self.assertIs(e._base, m.x) self.assertEqual(len(e._args), 1) self.assertIs(type(e._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[0], t) self.assertIs(type(e._args[0]._args[1]), EXPR._GetItemExpression) self.assertIs(type(e._args[0]._args[1]), type(E_base._args[1]._args[0]._args[1])) self.assertIsNot(e._args[0]._args[1], E_base._args[1]._args[0]._args[1]) self.assertIs(type(e._args[0]._args[1]._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[1]._args[0]._args[0], t) E_base = m.x[t + m.P[t + 1]] + 1 E = E_base.clone() self.assertIs(type(E), EXPR._SumExpression) e = E._args[0] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIsNot(e, E_base._args[0]) self.assertIs(e._base, m.x) self.assertEqual(len(e._args), 1) self.assertIs(type(e._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[0], t) self.assertIs(type(e._args[0]._args[1]), EXPR._GetItemExpression) self.assertIs(type(e._args[0]._args[1]), type(E_base._args[0]._args[0]._args[1])) self.assertIsNot(e._args[0]._args[1], E_base._args[0]._args[0]._args[1]) self.assertIs(type(e._args[0]._args[1]._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[1]._args[0]._args[0], t) E_base = 1 + m.x[t + m.P[t + 1]] E = E_base.clone() self.assertIs(type(E), EXPR._SumExpression) # Note: in coopr3, the 1 is held in a separate attribute (so # len(_args) is 1), whereas in pyomo4 the constant is a proper # argument. The -1 index works for both modes. e = E._args[-1] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIsNot(e, E_base._args[0]) self.assertIs(e._base, m.x) self.assertEqual(len(e._args), 1) self.assertIs(type(e._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[0], t) self.assertIs(type(e._args[0]._args[1]), EXPR._GetItemExpression) self.assertIs(type(e._args[0]._args[1]), type(E_base._args[-1]._args[0]._args[1])) self.assertIsNot(e._args[0]._args[1], E_base._args[-1]._args[0]._args[1]) self.assertIs(type(e._args[0]._args[1]._args[0]), EXPR._SumExpression) self.assertIs(e._args[0]._args[1]._args[0]._args[0], t)
def test_simple_substitute_param(self): def diffeq(m, t, i): return m.dxdt[t, i] == t*m.x[t, i-1]**2 + m.y**2 + \ m.x[t, i+1] + m.x[t, i-1] m = self.m t = IndexTemplate(m.TIME) e = diffeq(m, t, 2) self.assertTrue(isinstance(e, EXPR._ExpressionBase)) _map = {} E = substitute_template_expression(e, substitute_getitem_with_param, _map) self.assertIsNot(e, E) self.assertEqual(len(_map), 3) idx1 = _GetItemIndexer(m.x[t, 1]) self.assertIs(idx1._base, m.x) self.assertEqual(len(idx1._args), 2) self.assertIs(idx1._args[0], t) self.assertEqual(idx1._args[1], 1) self.assertIn(idx1, _map) idx2 = _GetItemIndexer(m.dxdt[t, 2]) self.assertIs(idx2._base, m.dxdt) self.assertEqual(len(idx2._args), 2) self.assertIs(idx2._args[0], t) self.assertEqual(idx2._args[1], 2) self.assertIn(idx2, _map) idx3 = _GetItemIndexer(m.x[t, 3]) self.assertIs(idx3._base, m.x) self.assertEqual(len(idx3._args), 2) self.assertIs(idx3._args[0], t) self.assertEqual(idx3._args[1], 3) self.assertIn(idx3, _map) self.assertFalse(idx1 == idx2) self.assertFalse(idx1 == idx3) self.assertFalse(idx2 == idx3) idx4 = _GetItemIndexer(m.x[t, 2]) self.assertNotIn(idx4, _map) t.set_value(5) self.assertEqual((e._args[0](), e._args[1]()), (10, 136)) self.assertEqual( str(E), 'dxdt[{TIME},2] == {TIME} * x[{TIME},1]**2.0 + y**2.0 + x[{TIME},3] + x[{TIME},1]' ) _map[idx1].set_value(value(m.x[value(t), 1])) _map[idx2].set_value(value(m.dxdt[value(t), 2])) _map[idx3].set_value(value(m.x[value(t), 3])) self.assertEqual((E._args[0](), E._args[1]()), (10, 136)) _map[idx1].set_value(12) _map[idx2].set_value(34) self.assertEqual((E._args[0](), E._args[1]()), (34, 738))
def test_template_scalar(self): m = self.m t = IndexTemplate(m.I) e = m.x[t] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.x) self.assertEqual(e._args, (t, )) self.assertFalse(e.is_constant()) self.assertFalse(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 1) t.set_value(5) self.assertEqual(e(), 6) self.assertIs(e.resolve_template(), m.x[5]) t.set_value(None) e = m.p[t, 10] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.p) self.assertEqual(e._args, (t, 10)) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(5) self.assertEqual(e(), 510) self.assertIs(e.resolve_template(), m.p[5, 10]) t.set_value(None) e = m.p[5, t] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.p) self.assertEqual(e._args, (5, t)) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(10) self.assertEqual(e(), 510) self.assertIs(e.resolve_template(), m.p[5, 10]) t.set_value(None) e = m.s[t] self.assertIs(type(e), EXPR._GetItemExpression) self.assertIs(e._base, m.s) self.assertEqual(e._args, (t, )) self.assertFalse(e.is_constant()) self.assertTrue(e.is_fixed()) self.assertEqual(e.polynomial_degree(), 0) t.set_value(5) self.assertRaises(TypeError, e) self.assertIs(e.resolve_template(), m.s[5]) t.set_value(None)