Skip to content

Commit c2da8d2

Browse files
lochelAnHeuermann
andauthored
Fix step sizes for cvode in sc-systems (#1049)
* Fix step sizes for cvode in sc-systems * Make result files unique * Fix segmentation fault in Values.cpp * Fix temp path * Remove previous results for same OMS version * More clean up and copy FMU next to LUA file Co-authored-by: AnHeuermann <andreas.heuermann@liu.se>
1 parent 4b0e0be commit c2da8d2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+621
-558
lines changed

src/OMSimulatorLib/System.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,9 @@ namespace oms
217217

218218
double absoluteTolerance = 1e-4;
219219
double relativeTolerance = 1e-4;
220-
double minimumStepSize = 1e-4;
221-
double maximumStepSize = 1e-1;
222-
double initialStepSize = 1e-4;
220+
double minimumStepSize = 1e-12;
221+
double maximumStepSize = 1e-3;
222+
double initialStepSize = 1e-6;
223223

224224
std::unordered_map<unsigned int /*result file var ID*/, unsigned int /*allVariables ID*/> resultFileMapping;
225225
std::unordered_map<ComRef, bool> exportConnectors;

src/OMSimulatorLib/SystemSC.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "Model.h"
3939
#include "ssd/Tags.h"
4040

41+
#include <sstream>
4142

4243
int oms::cvode_rhs(realtype t, N_Vector y, N_Vector ydot, void* user_data)
4344
{
@@ -134,16 +135,23 @@ oms_status_enu_t oms::SystemSC::setSolverMethod(std::string solver)
134135

135136
oms_status_enu_t oms::SystemSC::exportToSSD_SimulationInformation(pugi::xml_node& node) const
136137
{
138+
std::ostringstream ssAbsoluteTolerance, ssRelativeTolerance, ssMinimumStepSize, ssMaximumStepSize, ssInitialStepSize;
139+
ssAbsoluteTolerance << absoluteTolerance;
140+
ssRelativeTolerance << relativeTolerance;
141+
ssMinimumStepSize << minimumStepSize;
142+
ssMaximumStepSize << maximumStepSize;
143+
ssInitialStepSize << initialStepSize;
144+
137145
/* ssd:SimulationInformation should be added as vendor specific annotations from Version 1.0 */
138146
pugi::xml_node node_simulation_information = node.append_child(oms::ssp::Version1_0::simulation_information);
139147

140148
pugi::xml_node node_solver = node_simulation_information.append_child(oms::ssp::Version1_0::VariableStepSolver);
141149
node_solver.append_attribute("description") = getSolverName().c_str();
142-
node_solver.append_attribute("absoluteTolerance") = std::to_string(absoluteTolerance).c_str();
143-
node_solver.append_attribute("relativeTolerance") = std::to_string(relativeTolerance).c_str();
144-
node_solver.append_attribute("minimumStepSize") = std::to_string(minimumStepSize).c_str();
145-
node_solver.append_attribute("maximumStepSize") = std::to_string(maximumStepSize).c_str();
146-
node_solver.append_attribute("initialStepSize") = std::to_string(initialStepSize).c_str();
150+
node_solver.append_attribute("absoluteTolerance") = ssAbsoluteTolerance.str().c_str();
151+
node_solver.append_attribute("relativeTolerance") = ssRelativeTolerance.str().c_str();
152+
node_solver.append_attribute("minimumStepSize") = ssMinimumStepSize.str().c_str();
153+
node_solver.append_attribute("maximumStepSize") = ssMaximumStepSize.str().c_str();
154+
node_solver.append_attribute("initialStepSize") = ssInitialStepSize.str().c_str();
147155

148156
return oms_status_ok;
149157
}
@@ -299,7 +307,7 @@ oms_status_enu_t oms::SystemSC::initialize()
299307
if (!solverData.cvode.abstol) logError("SUNDIALS_ERROR: N_VNew_Serial() failed - returned NULL pointer");
300308
for (int j=0, k=0; j < fmus.size(); ++j)
301309
for (size_t i=0; i < nStates[j]; ++i, ++k)
302-
NV_Ith_S(solverData.cvode.abstol, k) = 0.01*relativeTolerance*states_nominal[j][i];
310+
NV_Ith_S(solverData.cvode.abstol, k) = 0.01*absoluteTolerance*states_nominal[j][i];
303311
//N_VPrint_Serial(solverData.cvode.abstol);
304312

305313
// Call CVodeCreate to create the solver memory and specify the
@@ -335,28 +343,26 @@ oms_status_enu_t oms::SystemSC::initialize()
335343
flag = CVodeSetLinearSolver(solverData.cvode.mem, solverData.cvode.linSol, solverData.cvode.J);
336344
if (flag < 0) logError("SUNDIALS_ERROR: CVDense() failed with flag = " + std::to_string(flag));
337345

338-
const fmi2_real_t stopTime = 1.0;
339-
double max_h = (stopTime - time) / 10.0;
340-
logInfo("maximum step size for '" + std::string(getFullCref()) + "': " + std::to_string(max_h));
341-
flag = CVodeSetMaxStep(solverData.cvode.mem, max_h);
346+
logInfo("maximum step size for '" + std::string(getFullCref()) + "': " + std::to_string(maximumStepSize));
347+
flag = CVodeSetMaxStep(solverData.cvode.mem, maximumStepSize);
342348
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetMaxStep() failed with flag = " + std::to_string(flag));
343349

344350
// further settings from cpp runtime
345-
flag = CVodeSetInitStep(solverData.cvode.mem, 1e-6); // INITIAL STEPSIZE
351+
flag = CVodeSetInitStep(solverData.cvode.mem, initialStepSize); // INITIAL STEPSIZE
346352
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetInitStep() failed with flag = " + std::to_string(flag));
347-
flag = CVodeSetMaxOrd(solverData.cvode.mem, 5); // MAXIMUM ORDER
353+
flag = CVodeSetMaxOrd(solverData.cvode.mem, 5); // MAXIMUM ORDER
348354
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetMaxOrd() failed with flag = " + std::to_string(flag));
349-
flag = CVodeSetMaxConvFails(solverData.cvode.mem, 100); // MAXIMUM NUMBER OF NONLINEAR CONVERGENCE FAILURES
355+
flag = CVodeSetMaxConvFails(solverData.cvode.mem, 100); // MAXIMUM NUMBER OF NONLINEAR CONVERGENCE FAILURES
350356
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetMaxConvFails() failed with flag = " + std::to_string(flag));
351-
flag = CVodeSetStabLimDet(solverData.cvode.mem, true); // STABILITY DETECTION
357+
flag = CVodeSetStabLimDet(solverData.cvode.mem, true); // STABILITY DETECTION
352358
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetStabLimDet() failed with flag = " + std::to_string(flag));
353-
flag = CVodeSetMinStep(solverData.cvode.mem, 1e-12); // MINIMUM STEPSIZE
359+
flag = CVodeSetMinStep(solverData.cvode.mem, minimumStepSize); // MINIMUM STEPSIZE
354360
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetMinStep() failed with flag = " + std::to_string(flag));
355-
flag = CVodeSetMaxNonlinIters(solverData.cvode.mem, 5); // MAXIMUM NUMBER OF ITERATIONS
361+
flag = CVodeSetMaxNonlinIters(solverData.cvode.mem, 5); // MAXIMUM NUMBER OF ITERATIONS
356362
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetMaxNonlinIters() failed with flag = " + std::to_string(flag));
357-
flag = CVodeSetMaxErrTestFails(solverData.cvode.mem, 100); // MAXIMUM NUMBER OF ERROR TEST FAILURES
363+
flag = CVodeSetMaxErrTestFails(solverData.cvode.mem, 100); // MAXIMUM NUMBER OF ERROR TEST FAILURES
358364
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetMaxErrTestFails() failed with flag = " + std::to_string(flag));
359-
flag = CVodeSetMaxNumSteps(solverData.cvode.mem, 1000); // MAXIMUM NUMBER OF STEPS
365+
flag = CVodeSetMaxNumSteps(solverData.cvode.mem, 1000); // MAXIMUM NUMBER OF STEPS
360366
if (flag < 0) logError("SUNDIALS_ERROR: CVodeSetMaxNumSteps() failed with flag = " + std::to_string(flag));
361367
}
362368

src/OMSimulatorLib/Values.cpp

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -871,36 +871,60 @@ void oms::Values::importParameterMapping(const pugi::xml_node& parameterMapping)
871871

872872
oms_status_enu_t oms::Values::rename(const oms::ComRef& oldCref, const oms::ComRef& newCref)
873873
{
874-
for (const auto &r : realStartValues)
874+
for (auto it=realStartValues.cbegin(); it != realStartValues.cend() /* not hoisted */; /* no increment */)
875875
{
876-
ComRef tail(r.first);
876+
// renaming the keys
877+
ComRef tail(it->first);
877878
ComRef front = tail.pop_front();
878879
if (oldCref == front)
879880
{
880-
realStartValues[newCref + tail] = r.second; // update the newCref
881-
realStartValues.erase(r.first); // delete the old cref
881+
//logInfo("old: " + std::string(it->first));
882+
//logInfo("new: " + std::string(newCref + tail));
883+
//logInfo("value: " + std::to_string(it->second));
884+
realStartValues[newCref + tail] = it->second; // update the newCref
885+
it = realStartValues.erase(it); // delete the old cref
886+
}
887+
else
888+
{
889+
++it;
882890
}
883891
}
884892

885-
for (const auto &i : integerStartValues)
893+
for (auto it=integerStartValues.cbegin(); it != integerStartValues.cend() /* not hoisted */; /* no increment */)
886894
{
887-
ComRef tail(i.first);
895+
// renaming the keys
896+
ComRef tail(it->first);
888897
ComRef front = tail.pop_front();
889898
if (oldCref == front)
890899
{
891-
integerStartValues[newCref + tail] = i.second; // update the newCref
892-
integerStartValues.erase(i.first); // delete the old cref
900+
//logInfo("old: " + std::string(it->first));
901+
//logInfo("new: " + std::string(newCref + tail));
902+
//logInfo("value: " + std::to_string(it->second));
903+
integerStartValues[newCref + tail] = it->second; // update the newCref
904+
it = integerStartValues.erase(it); // delete the old cref
905+
}
906+
else
907+
{
908+
++it;
893909
}
894910
}
895911

896-
for (const auto &b : booleanStartValues)
912+
for (auto it=booleanStartValues.cbegin(); it != booleanStartValues.cend() /* not hoisted */; /* no increment */)
897913
{
898-
ComRef tail(b.first);
914+
// renaming the keys
915+
ComRef tail(it->first);
899916
ComRef front = tail.pop_front();
900917
if (oldCref == front)
901918
{
902-
booleanStartValues[newCref + tail] = b.second; // update the newCref
903-
booleanStartValues.erase(b.first); // delete the old cref
919+
//logInfo("old: " + std::string(it->first));
920+
//logInfo("new: " + std::string(newCref + tail));
921+
//logInfo("value: " + std::to_string(it->second));
922+
booleanStartValues[newCref + tail] = it->second; // update the newCref
923+
it = booleanStartValues.erase(it); // delete the old cref
924+
}
925+
else
926+
{
927+
++it;
904928
}
905929
}
906930

@@ -913,36 +937,60 @@ oms_status_enu_t oms::Values::renameInResources(const oms::ComRef& oldCref, cons
913937
{
914938
for (auto &res : it.allresources)
915939
{
916-
for (const auto &r : res.second.realStartValues)
940+
for (auto it=res.second.realStartValues.cbegin(); it != res.second.realStartValues.cend() /* not hoisted */; /* no increment */)
917941
{
918-
ComRef tail(r.first);
942+
// renaming the keys
943+
ComRef tail(it->first);
919944
ComRef front = tail.pop_front();
920945
if (oldCref == front)
921946
{
922-
res.second.realStartValues[newCref + tail] = r.second; // update the newCref
923-
res.second.realStartValues.erase(r.first); // delete the old cref
947+
//logInfo("old: " + std::string(it->first));
948+
//logInfo("new: " + std::string(newCref + tail));
949+
//logInfo("value: " + std::to_string(it->second));
950+
res.second.realStartValues[newCref + tail] = it->second; // update the newCref
951+
it = res.second.realStartValues.erase(it); // delete the old cref
952+
}
953+
else
954+
{
955+
++it;
924956
}
925957
}
926958

927-
for (const auto &i : res.second.integerStartValues)
959+
for (auto it=res.second.integerStartValues.cbegin(); it != res.second.integerStartValues.cend() /* not hoisted */; /* no increment */)
928960
{
929-
ComRef tail(i.first);
961+
// renaming the keys
962+
ComRef tail(it->first);
930963
ComRef front = tail.pop_front();
931964
if (oldCref == front)
932965
{
933-
res.second.integerStartValues[newCref + tail] = i.second; // update the newCref
934-
res.second.integerStartValues.erase(i.first); // delete the old cref
966+
//logInfo("old: " + std::string(it->first));
967+
//logInfo("new: " + std::string(newCref + tail));
968+
//logInfo("value: " + std::to_string(it->second));
969+
res.second.integerStartValues[newCref + tail] = it->second; // update the newCref
970+
it = res.second.integerStartValues.erase(it); // delete the old cref
971+
}
972+
else
973+
{
974+
++it;
935975
}
936976
}
937977

938-
for (const auto &b : booleanStartValues)
978+
for (auto it=res.second.booleanStartValues.cbegin(); it != res.second.booleanStartValues.cend() /* not hoisted */; /* no increment */)
939979
{
940-
ComRef tail(b.first);
980+
// renaming the keys
981+
ComRef tail(it->first);
941982
ComRef front = tail.pop_front();
942983
if (oldCref == front)
943984
{
944-
res.second.booleanStartValues[newCref + tail] = b.second; // update the newCref
945-
res.second.booleanStartValues.erase(b.first); // delete the old cref
985+
//logInfo("old: " + std::string(it->first));
986+
//logInfo("new: " + std::string(newCref + tail));
987+
//logInfo("value: " + std::to_string(it->second));
988+
res.second.booleanStartValues[newCref + tail] = it->second; // update the newCref
989+
it = res.second.booleanStartValues.erase(it); // delete the old cref
990+
}
991+
else
992+
{
993+
++it;
946994
}
947995
}
948996
}

testsuite/OMSimulator/DualMassOscillator.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ oms_addConnection("DualMassOscillator.root.system1.a1", "DualMassOscillator.root
2525
-- simulation settings
2626
oms_setResultFile("DualMassOscillator", "DualMassOscillator.mat", 100)
2727
oms_setStopTime("DualMassOscillator", 10.0)
28-
oms_setFixedStepSize("DualMassOscillator.root", 1e-3)
28+
oms_setVariableStepSize("DualMassOscillator.root", 1e-12, 1e-12, 1e-3)
2929

3030
oms_instantiate("DualMassOscillator")
3131
oms_setReal("DualMassOscillator.root.system1.x1_start", 0.0)
@@ -45,15 +45,15 @@ oms_terminate("DualMassOscillator")
4545
oms_delete("DualMassOscillator")
4646

4747
-- Result:
48-
-- info: maximum step size for 'DualMassOscillator.root': 0.100000
48+
-- info: maximum step size for 'DualMassOscillator.root': 0.001000
4949
-- info: Result file: DualMassOscillator.mat (bufferSize=100)
5050
-- info: Initialization
5151
-- info: system1.x1: 0.0
5252
-- info: system2.x2: 0.5
5353
-- info: Simulation
54-
-- info: system1.x1: 0.050988622308801
55-
-- info: system2.x2: 0.03162781956834
54+
-- info: system1.x1: 0.051037644866066
55+
-- info: system2.x2: 0.031639500249976
5656
-- info: Final Statistics for 'DualMassOscillator.root':
57-
-- NumSteps = 262 NumRhsEvals = 293 NumLinSolvSetups = 25
58-
-- NumNonlinSolvIters = 292 NumNonlinSolvConvFails = 0 NumErrTestFails = 2
57+
-- NumSteps = 10007 NumRhsEvals = 10008 NumLinSolvSetups = 507
58+
-- NumNonlinSolvIters = 10007 NumNonlinSolvConvFails = 0 NumErrTestFails = 0
5959
-- endResult

testsuite/OMSimulator/Enumeration.lua

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,49 +8,47 @@
88
oms_setCommandLineOption("--suppressPath=true")
99
oms_setTempDirectory("./Enumeration_lua/")
1010

11-
oms_newModel("test")
12-
oms_addSystem("test.root", oms_system_sc)
13-
oms_addSubModel("test.root.A", "../resources/Int1.fmu")
14-
oms_addSubModel("test.root.B", "../resources/Enum1.fmu")
11+
oms_newModel("Enumeration")
12+
oms_addSystem("Enumeration.root", oms_system_sc)
13+
oms_addSubModel("Enumeration.root.A", "../resources/Int1.fmu")
14+
oms_addSubModel("Enumeration.root.B", "../resources/Enum1.fmu")
1515

1616
-- integer to enumeration
17-
oms_addConnection("test.root.A.y", "test.root.B.u")
17+
oms_addConnection("Enumeration.root.A.y", "Enumeration.root.B.u")
1818

19-
oms_setResultFile("test", "test_res.mat")
19+
-- oms_exportDependencyGraphs("Enumeration.root", "Enumeration.root_init.dot", "Enumeration.root_sim.dot", "Enumeration.root_continuous.dot")
20+
-- os.execute("gvpr -c \"N[$.degree==0]{delete(root, $)}\" Enumeration.root_init.dot | dot -Tpdf -o Enumeration.root_init.pdf")
21+
-- os.execute("gvpr -c \"N[$.degree==0]{delete(root, $)}\" Enumeration.root_sim.dot | dot -Tpdf -o Enumeration.root_sim.pdf")
22+
-- os.execute("gvpr -c \"N[$.degree==0]{delete(root, $)}\" Enumeration.root_continuous.dot | dot -Tpdf -o Enumeration.root_continuous.pdf")
2023

21-
-- oms_exportDependencyGraphs("test.root", "test.root_init.dot", "test.root_sim.dot", "test.root_continuous.dot")
22-
-- os.execute("gvpr -c \"N[$.degree==0]{delete(root, $)}\" test.root_init.dot | dot -Tpdf -o test.root_init.pdf")
23-
-- os.execute("gvpr -c \"N[$.degree==0]{delete(root, $)}\" test.root_sim.dot | dot -Tpdf -o test.root_sim.pdf")
24-
-- os.execute("gvpr -c \"N[$.degree==0]{delete(root, $)}\" test.root_continuous.dot | dot -Tpdf -o test.root_continuous.pdf")
25-
26-
oms_instantiate("test")
24+
oms_instantiate("Enumeration")
2725
print("info: Instantiation")
28-
print("info: test.root.A.y : " .. oms_getInteger("test.root.A.y"))
29-
print("info: test.root.B.u : " .. oms_getInteger("test.root.B.u"))
26+
print("info: Enumeration.root.A.y : " .. oms_getInteger("Enumeration.root.A.y"))
27+
print("info: Enumeration.root.B.u : " .. oms_getInteger("Enumeration.root.B.u"))
3028

31-
oms_initialize("test")
29+
oms_initialize("Enumeration")
3230
print("info: Initialization")
33-
print("info: test.root.A.y : " .. oms_getInteger("test.root.A.y"))
34-
print("info: test.root.B.u : " .. oms_getInteger("test.root.B.u"))
31+
print("info: Enumeration.root.A.y : " .. oms_getInteger("Enumeration.root.A.y"))
32+
print("info: Enumeration.root.B.u : " .. oms_getInteger("Enumeration.root.B.u"))
3533

36-
oms_simulate("test")
34+
oms_simulate("Enumeration")
3735
print("info: Simulation")
38-
print("info: test.root.A.y : " .. oms_getInteger("test.root.A.y"))
39-
print("info: test.root.B.u : " .. oms_getInteger("test.root.B.u"))
36+
print("info: Enumeration.root.A.y : " .. oms_getInteger("Enumeration.root.A.y"))
37+
print("info: Enumeration.root.B.u : " .. oms_getInteger("Enumeration.root.B.u"))
4038

41-
oms_terminate("test")
42-
oms_delete("test")
39+
oms_terminate("Enumeration")
40+
oms_delete("Enumeration")
4341

4442
-- Result:
4543
-- info: model doesn't contain any continuous state
4644
-- info: Instantiation
47-
-- info: test.root.A.y : 2
48-
-- info: test.root.B.u : 0
49-
-- info: Result file: test_res.mat (bufferSize=1)
45+
-- info: Enumeration.root.A.y : 2
46+
-- info: Enumeration.root.B.u : 0
47+
-- info: Result file: Enumeration_res.mat (bufferSize=10)
5048
-- info: Initialization
51-
-- info: test.root.A.y : 2
52-
-- info: test.root.B.u : 2
49+
-- info: Enumeration.root.A.y : 2
50+
-- info: Enumeration.root.B.u : 2
5351
-- info: Simulation
54-
-- info: test.root.A.y : 2
55-
-- info: test.root.B.u : 2
52+
-- info: Enumeration.root.A.y : 2
53+
-- info: Enumeration.root.B.u : 2
5654
-- endResult

0 commit comments

Comments
 (0)