def _compile_model(model_folder: str, model_name: str, compiler_options: Dict[str, str]): # Load folders tree = None for folder in [model_folder] + compiler_options.get('library_folders', []): for root, dir, files in os.walk(folder, followlinks=True): for item in fnmatch.filter(files, "*.mo"): logger.info("Parsing {}".format(item)) with open(os.path.join(root, item), 'r') as f: if tree is None: tree = parser.parse(f.read()) else: tree.extend(parser.parse(f.read())) # Compile logger.info("Generating CasADi model") model = generator.generate(tree, model_name, compiler_options) if compiler_options.get('check_balanced', True): model.check_balanced() model.simplify(compiler_options) if compiler_options.get('verbose', False): model.check_balanced() return model
def test_if_else(self): with open(os.path.join(TEST_DIR, 'IfElse.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) casadi_model = gen_casadi.generate(ast_tree, 'IfElse') ref_model = Model() x = ca.MX.sym("x") y1 = ca.MX.sym("y1") y2 = ca.MX.sym("y2") y3 = ca.MX.sym("y3") y_max = ca.MX.sym("y_max") ref_model.inputs = list(map(Variable, [x])) ref_model.outputs = list(map(Variable, [y1, y2, y3])) ref_model.alg_states = list(map(Variable, [y1, y2, y3])) ref_model.parameters = list(map(Variable, [y_max])) ref_model.parameters[0].value = 10 ref_model.equations = [ y1 - ca.if_else(x > 0, 1, 0) * y_max, ca.if_else( x > 1, ca.vertcat(y3 - 100, y2 - y_max), ca.if_else(x > 2, ca.vertcat(y3 - 1000, y2 - y_max - 1), ca.vertcat(y3 - 10000, y2))) ] self.assert_model_equivalent_numeric(ref_model, casadi_model)
def test_matrixexpressions(self): with open(os.path.join(TEST_DIR, 'MatrixExpressions.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) casadi_model = gen_casadi.generate(ast_tree, 'MatrixExpressions') print(casadi_model) ref_model = Model() A = ca.MX.sym("A", 3, 3) b = ca.MX.sym("b", 3) c = ca.MX.sym("c", 3) d = ca.MX.sym("d", 3) C = ca.MX.sym("C", 2, 3) D = ca.MX.sym("D", 3, 2) E = ca.MX.sym("E", 2, 3) I = ca.MX.sym("I", 5, 5) F = ca.MX.sym("F", 3, 3) ref_model.alg_states = list(map(Variable, [A, b, c, d])) ref_model.constants = list(map(Variable, [C, D, E, I, F])) constant_values = [ 1.7 * ca.DM.ones(2, 3), ca.DM.zeros(3, 2), ca.DM.ones(2, 3), ca.DM.eye(5), ca.DM.triplet([0, 1, 2], [0, 1, 2], [1, 2, 3], 3, 3) ] for const, val in zip(ref_model.constants, constant_values): const.value = val ref_model.equations = [ ca.mtimes(A, b) - c, ca.mtimes(A.T, b) - d, F[1, 2] ] self.assert_model_equivalent_numeric(ref_model, casadi_model)
def test_inheritance_symbol_modifiers(self): with open(os.path.join(MODEL_DIR, 'Inheritance.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='Sub')) self.assertEqual(flat_tree.classes['Sub'].symbols['x'].max.value, 30.0)
def test_function_pull(self): with open(os.path.join(MODEL_DIR, 'FunctionPull.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) class_name = 'Level1.Level2.Level3.Function5' comp_ref = ast.ComponentRef.from_string(class_name) flat_tree = tree.flatten(ast_tree, comp_ref) # Check if all referenced functions are pulled in self.assertIn('Level1.Level2.Level3.f', flat_tree.classes) self.assertIn('Level1.Level2.Level3.TestPackage.times2', flat_tree.classes) self.assertIn('Level1.Level2.Level3.TestPackage.square', flat_tree.classes) self.assertNotIn('Level1.Level2.Level3.TestPackage.not_called', flat_tree.classes) # Check if the classes in the flattened tree have the right type self.assertEqual(flat_tree.classes['Function5'].type, 'model') self.assertEqual(flat_tree.classes['Level1.Level2.Level3.f'].type, 'function') self.assertEqual(flat_tree.classes['Level1.Level2.Level3.TestPackage.times2'].type, 'function') self.assertEqual(flat_tree.classes['Level1.Level2.Level3.TestPackage.square'].type, 'function') # Check whether input/output information of functions comes along properly func_t2 = flat_tree.classes['Level1.Level2.Level3.TestPackage.times2'] self.assertIn("input", func_t2.symbols['x'].prefixes) self.assertIn("output", func_t2.symbols['y'].prefixes) # Check if built-in function call statement comes along properly func_f = flat_tree.classes['Level1.Level2.Level3.f'] self.assertEqual(func_f.statements[0].right.operator, '*') # Check if user-specified function call statement comes along properly self.assertEqual(func_f.statements[0].right.operands[0].operator, 'Level1.Level2.Level3.TestPackage.times2')
def test_extends_modification(self): with open(os.path.join(MODEL_DIR, 'ExtendsModification.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='MainModel')) self.assertEqual(flat_tree.classes['MainModel'].symbols['e.HQ.H'].min.name, "e.H_b")
def test_inheritance_instantiation(self): with open(os.path.join(TEST_DIR, 'InheritanceInstantiation.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) casadi_model = gen_casadi.generate(ast_tree, 'C2') ref_model = Model() print(casadi_model) bcomp1_a = ca.MX.sym('bcomp1.a') bcomp1_b = ca.MX.sym('bcomp1.b') bcomp2_a = ca.MX.sym('bcomp2.a') bcomp2_b = ca.MX.sym('bcomp2.b') bcomp3_a = ca.MX.sym('bcomp3.a') bcomp3_b = ca.MX.sym('bcomp3.b') bcomp1_v = ca.MX.sym('bcomp1.v', 3) bcomp2_v = ca.MX.sym('bcomp2.v', 4) bcomp3_v = ca.MX.sym('bcomp3.v', 2) ref_model.states = [] ref_model.der_states = [] ref_model.alg_states = list(map(Variable, [bcomp1_v, bcomp2_v, bcomp3_v])) ref_model.parameters = list(map(Variable, [bcomp1_a, bcomp2_a, bcomp3_a, bcomp1_b, bcomp2_b, bcomp3_b])) ref_model.parameters[0].value = 0 ref_model.parameters[1].value = 0 ref_model.parameters[2].value = 1 ref_model.parameters[3].value = 3 ref_model.parameters[4].value = 4 ref_model.parameters[5].value = 2 ref_model.equations = [] self.assert_model_equivalent_numeric(ref_model, casadi_model)
def test_forloop(self): with open(os.path.join(TEST_DIR, 'ForLoop.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) casadi_model = gen_casadi.generate(ast_tree, 'ForLoop') print(casadi_model) ref_model = Model() x = ca.MX.sym("x", 10) y = ca.MX.sym("y", 10) z = ca.MX.sym("z", 10) u = ca.MX.sym('u', 10, 2) v = ca.MX.sym('v', 2, 10) w = ca.MX.sym('w', 2, 10) b = ca.MX.sym("b") n = ca.MX.sym("n") s = ca.MX.sym('s', 10) Arr = ca.MX.sym('Arr', 2, 2) der_s = ca.MX.sym('der(s)', 10) ref_model.states = list(map(Variable, [s])) ref_model.der_states = list(map(Variable, [der_s])) ref_model.alg_states = list(map(Variable, [x, y, z, u, v, w, b, Arr])) ref_model.parameters = list(map(Variable, [n])) ref_model.parameters[0].value = 10 ref_model.equations = [ ca.horzcat(x - (np.arange(1, 11) + b), w[0, :].T - np.arange(1, 11), w[1, :].T - np.arange(2, 21, 2), u - np.ones((10, 2)), v.T - np.ones((10, 2))), y[0:5] - np.zeros(5), y[5:] - np.ones(5), ca.horzcat(z[0:5] - np.array([2, 2, 2, 2, 2]), z[5:10] - np.array([1, 1, 1, 1, 1])), der_s - np.ones(10), ca.horzcat(Arr[:, 1], Arr[:, 0]) - np.array([[2, 1], [2, 1]])] self.assert_model_equivalent_numeric(ref_model, casadi_model)
def test_attributes(self): with open(os.path.join(TEST_DIR, 'Attributes.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) casadi_model = gen_casadi.generate(ast_tree, 'Attributes') print(casadi_model) ref_model = CasadiSysModel() i = ca.MX.sym("int") b = ca.MX.sym("bool") r = ca.MX.sym("real") der_r = ca.MX.sym("der(real)") i1 = ca.MX.sym("i1") i2 = ca.MX.sym("i2") i3 = ca.MX.sym("i3") i4 = ca.MX.sym("i4") cst = ca.MX.sym("cst") prm = ca.MX.sym("prm") protected_variable = ca.MX.sym("protected_variable") ref_model.states = [r] ref_model.der_states = [der_r] ref_model.alg_states = [i, b, i1, i2, i3, i4, protected_variable] ref_model.inputs = [i1, i2, i3] ref_model.outputs = [i4, protected_variable] ref_model.constants = [cst] ref_model.constant_values = [1] ref_model.parameters = [prm] ref_model.equations = [ i4 - ((i1 + i2) + i3), der_r - (i1 + ca.if_else(b, 1, 0) * i), protected_variable - (i1 + i2) ] self.assert_model_equivalent_numeric(ref_model, casadi_model)
def test_connector_hq(self): with open(os.path.join(TEST_DIR, 'ConnectorHQ.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) casadi_model = gen_casadi.generate(ast_tree, 'System') ref_model = Model() print(casadi_model) a__up__H = ca.MX.sym("a.up.H") a__up__Q = ca.MX.sym("a.up.Q") a__down__H = ca.MX.sym("a.down.H") a__down__Q = ca.MX.sym("a.down.Q") b__up__H = ca.MX.sym("b.up.H") b__up__Q = ca.MX.sym("b.up.Q") b__down__H = ca.MX.sym("b.down.H") b__down__Q = ca.MX.sym("b.down.Q") c__up__H = ca.MX.sym("c.up.H") c__up__Q = ca.MX.sym("c.up.Q") c__down__H = ca.MX.sym("c.down.H") c__down__Q = ca.MX.sym("c.down.Q") qa__down__H = ca.MX.sym("qa.down.H") qa__down__Q = ca.MX.sym("qa.down.Q") p__H = ca.MX.sym("p.H") p__Q = ca.MX.sym("p.Q") hb__up__H = ca.MX.sym("hb.up.H") hb__up__Q = ca.MX.sym("hb.up.Q") zerotest__H = ca.MX.sym("zerotest.H") zerotest__Q = ca.MX.sym("zerotest.Q") ref_model.alg_states = list(map(Variable, [p__H, a__down__H, b__down__H, c__down__H, c__up__H, hb__up__H, a__up__H, b__up__H, qa__down__H, a__up__Q, qa__down__Q, c__down__Q, hb__up__Q, c__up__Q, b__up__Q, b__down__Q, p__Q, a__down__Q, zerotest__H, zerotest__Q])) ref_model.equations = [a__up__H - a__down__H, b__up__H - b__down__H, c__up__H - c__down__H, qa__down__Q, hb__up__H, p__Q, qa__down__H - a__up__H, p__H - c__up__H, a__down__H - b__up__H, c__down__H - b__up__H, b__down__H - hb__up__H, a__up__Q + a__down__Q, b__up__Q + b__down__Q, c__up__Q + c__down__Q, qa__down__Q + a__up__Q, -p__Q + c__up__Q, a__down__Q + (b__up__Q + c__down__Q), b__down__Q + hb__up__Q, zerotest__Q] self.assert_model_equivalent_numeric(ref_model, casadi_model)
def test_redeclare_nested(self): with open(os.path.join(TEST_DIR, 'RedeclareNestedClass.mo.fail_parse'), 'r') as f: txt = f.read() with self.assertRaises(Exception): ast_tree = parser.parse(txt)
def test_inheritance(self): with open(os.path.join(TEST_DIR, 'InheritanceInstantiation.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) flat_tree = tree.flatten(ast_tree, 'C2') self.assertEqual(flat_tree.classes['C2'].symbols['bcomp.b'].value.value, 3.0)
def test_function_call(self): with open(os.path.join(TEST_DIR, 'FunctionCall.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) casadi_model = gen_casadi.generate(ast_tree, 'FunctionCall') print("FunctionCall", casadi_model) ref_model = Model() radius = ca.MX.sym('radius') diameter = radius * 2 circle_properties = ca.Function('circle_properties', [radius], [ 3.14159 * diameter, 3.14159 * radius**2, ca.if_else(3.14159 * radius**2 > 10, 1, 2), ca.if_else(3.14159 * radius**2 > 10, 10, 3.14159 * radius**2), 8, 3, 12 ]) c = ca.MX.sym("c") a = ca.MX.sym("a") d = ca.MX.sym("d") e = ca.MX.sym("e") S1 = ca.MX.sym("S1") S2 = ca.MX.sym("S2") r = ca.MX.sym("r") ref_model.alg_states = list(map(Variable, [c, a, d, e, S1, S2, r])) ref_model.outputs = list(map(Variable, [c, a, d, e, S1, S2])) ref_model.equations = [ ca.vertcat(c, a, d, e, S1, S2) - ca.vertcat(*circle_properties.call([r])[0:-1]) ] self.assert_model_equivalent_numeric(ref_model, casadi_model)
def test_aircraft(self): with open(os.path.join(TEST_DIR, 'Aircraft.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) print('AST TREE\n', ast_tree) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='Aircraft')) print('AST TREE FLAT\n', flat_tree) self.flush()
def test_duplicate_state(self): with open(os.path.join(MODEL_DIR, 'DuplicateState.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) print('AST TREE\n', ast_tree) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='DuplicateState')) print('AST TREE FLAT\n', flat_tree) self.flush()
def test_spring(self): with open(os.path.join(TEST_DIR, 'Spring.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) print('AST TREE\n', ast_tree) flat_tree = tree.flatten(ast_tree, 'Spring') print('AST TREE FLAT\n', flat_tree) self.flush()
def test_estimator(self): with open(os.path.join(MODEL_DIR, './Estimator.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) print('AST TREE\n', ast_tree) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='Estimator')) print('AST TREE FLAT\n', flat_tree) self.flush()
def test_nested_classes(self): with open(os.path.join(MODEL_DIR, 'NestedClasses.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='C2')) self.assertEqual(flat_tree.classes['C2'].symbols['v1'].nominal.value, 1000.0) self.assertEqual(flat_tree.classes['C2'].symbols['v2'].nominal.value, 1000.0)
def test_spring_system(self): with open(os.path.join(MODEL_DIR, 'SpringSystem.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) print('AST TREE\n', ast_tree) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='SpringSystem')) print('AST TREE FLAT\n', flat_tree) self.flush()
def test_inheritance(self): with open(os.path.join(MODEL_DIR, 'InheritanceInstantiation.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='C2')) self.assertEqual(flat_tree.classes['C2'].symbols['bcomp1.b'].value.value, 3.0) self.assertEqual(flat_tree.classes['C2'].symbols['bcomp3.a'].value.value, 1.0) self.assertEqual(flat_tree.classes['C2'].symbols['bcomp3.b'].value.value, 2.0)
def test_bouncing_ball(self): with open(os.path.join(MODEL_DIR, 'BouncingBall.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) print('AST TREE\n', ast_tree) flat_tree = tree.flatten(ast_tree, ast.ComponentRef(name='BouncingBall')) print(flat_tree) print('AST TREE FLAT\n', flat_tree) self.flush()
def test_aircraft(self): with open(os.path.join(TEST_DIR, 'Aircraft.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) # noinspection PyUnusedLocal casadi_model = gen_casadi.generate(ast_tree, 'Aircraft') # noinspection PyUnusedLocal ref_model = Model() self.assertTrue(True)
def test_connector(self): with open(os.path.join(TEST_DIR, 'Connector.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) # states = ast_tree.classes['Aircraft'].states # names = sorted([state.name for state in states]) # names_set = sorted(list(set(names))) # if names != names_set: # raise IOError('{:s} != {:s}'.format(str(names), str(names_set))) self.flush()
def test_parameter_modification_scope(self): with open(os.path.join(MODEL_DIR, 'ParameterScope.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) class_name = 'ScopeTest' comp_ref = ast.ComponentRef.from_string(class_name) flat_tree = tree.flatten(ast_tree, comp_ref) self.assertEqual(flat_tree.classes['ScopeTest'].symbols['nc.p'].value.name, 'p')
def test_extends_order(self): with open(os.path.join(MODEL_DIR, 'ExtendsOrder.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) class_name = 'P.M' comp_ref = ast.ComponentRef.from_string(class_name) flat_tree = tree.flatten(ast_tree, comp_ref) self.assertEqual(flat_tree.classes['M'].symbols['at.m'].value.value, 0.0)
def test_redeclare_in_extends(self): with open(os.path.join(MODEL_DIR, 'RedeclareInExtends.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) class_name = 'ChannelZ' comp_ref = ast.ComponentRef.from_string(class_name) flat_tree = tree.flatten(ast_tree, comp_ref) self.assertIn('down.Z', flat_tree.classes['ChannelZ'].symbols)
def test_nested_symbol_modification(self): with open(os.path.join(MODEL_DIR, 'NestedSymbolModification.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) class_name = 'E' comp_ref = ast.ComponentRef.from_string(class_name) flat_tree = tree.flatten(ast_tree, comp_ref) self.assertEqual(flat_tree.classes['E'].symbols['c.x'].nominal.value, 2.0)
def test_spring(self): with open(os.path.join(TEST_DIR, 'Spring.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) text = gen_sympy.generate(ast_tree, 'Spring') with open(os.path.join(TEST_DIR, 'generated/Spring.py'), 'w') as f: f.write(text) from generated.Spring import Spring as Spring e = Spring() res = e.simulate(x0=[1, 1]) self.flush()
def test_aircraft(self): with open(os.path.join(TEST_DIR, 'Aircraft.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) #text = gen_sympy.generate(ast_tree, 'Aircraft') #with open(os.path.join(TEST_DIR, 'generated/Aircraft.py'), 'w') as f: # f.write(text) # from generated.Aircraft import Aircraft as Aircraft #e = Aircraft() #res = e.simulate() self.flush()
def test_aircraft(self): with open(os.path.join(TEST_DIR, "Aircraft.mo"), "r") as f: txt = f.read() ast_tree = parser.parse(txt) # text = gen_sympy.generate(ast_tree, 'Aircraft') # with open(os.path.join(TEST_DIR, 'generated/Aircraft.py'), 'w') as f: # f.write(text) # from generated.Aircraft import Aircraft as Aircraft # e = Aircraft() # res = e.simulate() self.flush()
def test_estimator(self): with open(os.path.join(TEST_DIR, 'Estimator.mo'), 'r') as f: txt = f.read() ast_tree = parser.parse(txt) text = gen_sympy.generate(ast_tree, 'Estimator') with open(os.path.join(TEST_DIR, 'generated/Estimator.py'), 'w') as f: f.write(text) from generated.Estimator import Estimator as Estimator e = Estimator() res = e.simulate(x0=[1]) self.flush()
def test_spring(self): with open(os.path.join(TEST_DIR, "Spring.mo"), "r") as f: txt = f.read() ast_tree = parser.parse(txt) text = gen_sympy.generate(ast_tree, "Spring") with open(os.path.join(TEST_DIR, "generated/Spring.py"), "w") as f: f.write(text) from generated.Spring import Spring as Spring e = Spring() res = e.simulate(x0=[1, 1]) self.flush()
def test_estimator(self): with open(os.path.join(TEST_DIR, "Estimator.mo"), "r") as f: txt = f.read() ast_tree = parser.parse(txt) text = gen_sympy.generate(ast_tree, "Estimator") with open(os.path.join(TEST_DIR, "generated/Estimator.py"), "w") as f: f.write(text) from generated.Estimator import Estimator as Estimator e = Estimator() res = e.simulate(x0=[1]) self.flush()
def test_connector(self): with open(os.path.join(TEST_DIR, "Connector.mo"), "r") as f: txt = f.read() ast_tree = parser.parse(txt) # print(ast_tree) flat_tree = tree.flatten(ast_tree, "Aircraft") # print(flat_tree) walker = tree.TreeWalker() classes = ast_tree.classes root = ast_tree.classes["Aircraft"] instantiator = tree.Instatiator(classes=classes) walker.walk(instantiator, root) print(instantiator.res[root].symbols.keys()) print(instantiator.res[root]) # print('INSTANTIATOR\n-----------\n\n') # print(instantiator.res[root]) # connectExpander = tree.ConnectExpander(classes=classes) # walker.walk(connectExpander, instantiator.res[root]) # print('CONNECT EXPANDER\n-----------\n\n') # print(connectExpander.new_class) # text = gen_sympy.generate(ast_tree, 'Aircraft') # print(text) # with open(os.path.join(TEST_DIR, 'generated/Connect.py'), 'w') as f: # f.write(text) # from generated.Connect import Aircraft as Aircraft # e = Aircraft() # res = e.simulate() self.flush()