|
| 1 | +import numpy as np |
| 2 | +import pytest |
| 3 | + |
| 4 | +import OMPython |
| 5 | + |
| 6 | + |
| 7 | +@pytest.fixture |
| 8 | +def model_firstorder_content(): |
| 9 | + return """ |
| 10 | +model M |
| 11 | + Real x(start = 1, fixed = true); |
| 12 | + parameter Real a = -1; |
| 13 | +equation |
| 14 | + der(x) = x*a; |
| 15 | +end M; |
| 16 | +""" |
| 17 | + |
| 18 | + |
| 19 | +@pytest.fixture |
| 20 | +def model_firstorder(tmp_path, model_firstorder_content): |
| 21 | + mod = tmp_path / "M.mo" |
| 22 | + mod.write_text(model_firstorder_content) |
| 23 | + return mod |
| 24 | + |
| 25 | + |
| 26 | +@pytest.fixture |
| 27 | +def param(): |
| 28 | + x0 = 1 |
| 29 | + a = -1 |
| 30 | + tau = -1 / a |
| 31 | + stopTime = 5*tau |
| 32 | + |
| 33 | + return { |
| 34 | + 'x0': x0, |
| 35 | + 'a': a, |
| 36 | + 'stopTime': stopTime, |
| 37 | + } |
| 38 | + |
| 39 | + |
| 40 | +def test_runner(model_firstorder, param): |
| 41 | + # create a model using ModelicaSystem |
| 42 | + mod = OMPython.ModelicaSystem() |
| 43 | + mod.model( |
| 44 | + model_file=model_firstorder, |
| 45 | + model_name="M", |
| 46 | + ) |
| 47 | + |
| 48 | + resultfile_mod = mod.getWorkDirectory() / f"{mod.get_model_name()}_res_mod.mat" |
| 49 | + _run_simulation(mod=mod, resultfile=resultfile_mod, param=param) |
| 50 | + |
| 51 | + # run the model using only the runner class |
| 52 | + omcs = OMPython.SessionRunner( |
| 53 | + version=mod.get_session().get_version(), |
| 54 | + ) |
| 55 | + modr = OMPython.ModelicaSystemRunner( |
| 56 | + session=omcs, |
| 57 | + work_directory=mod.getWorkDirectory(), |
| 58 | + ) |
| 59 | + modr.setup( |
| 60 | + model_name="M", |
| 61 | + ) |
| 62 | + |
| 63 | + resultfile_modr = mod.getWorkDirectory() / f"{mod.get_model_name()}_res_modr.mat" |
| 64 | + _run_simulation(mod=modr, resultfile=resultfile_modr, param=param) |
| 65 | + |
| 66 | + # cannot check the content as runner does not have the capability to open a result file |
| 67 | + assert resultfile_mod.size() == resultfile_modr.size() |
| 68 | + |
| 69 | + # check results |
| 70 | + _check_result(mod=mod, resultfile=resultfile_mod, param=param) |
| 71 | + _check_result(mod=mod, resultfile=resultfile_modr, param=param) |
| 72 | + |
| 73 | + |
| 74 | +def _run_simulation(mod, resultfile, param): |
| 75 | + simOptions = {"stopTime": param['stopTime'], "stepSize": 0.1, "tolerance": 1e-8} |
| 76 | + mod.setSimulationOptions(**simOptions) |
| 77 | + mod.simulate(resultfile=resultfile) |
| 78 | + |
| 79 | + assert resultfile.exists() |
| 80 | + |
| 81 | + |
| 82 | +def _check_result(mod, resultfile, param): |
| 83 | + x = mod.getSolutions(resultfile=resultfile, varList="x") |
| 84 | + t, x2 = mod.getSolutions(resultfile=resultfile, varList=["time", "x"]) |
| 85 | + assert (x2 == x).all() |
| 86 | + sol_names = mod.getSolutions(resultfile=resultfile) |
| 87 | + assert isinstance(sol_names, tuple) |
| 88 | + assert "time" in sol_names |
| 89 | + assert "x" in sol_names |
| 90 | + assert "der(x)" in sol_names |
| 91 | + with pytest.raises(OMPython.ModelicaSystemError): |
| 92 | + mod.getSolutions(resultfile=resultfile, varList="thisVariableDoesNotExist") |
| 93 | + assert np.isclose(t[0], 0), "time does not start at 0" |
| 94 | + assert np.isclose(t[-1], param['stopTime']), "time does not end at stopTime" |
| 95 | + x_analytical = param['x0'] * np.exp(param['a']*t) |
| 96 | + assert np.isclose(x, x_analytical, rtol=1e-4).all() |
0 commit comments