Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Algebraic Loops over FMUs failing #808

Open
AnHeuermann opened this issue Sep 15, 2020 · 6 comments
Open

Algebraic Loops over FMUs failing #808

AnHeuermann opened this issue Sep 15, 2020 · 6 comments
Assignees
Labels

Comments

@AnHeuermann
Copy link
Member

AnHeuermann commented Sep 15, 2020

Description

I have a non-linear algebraic loop with three variables and equations

  a   + b   + c    = 0;
  2*a - 3*b + 2*c  = 9;
  a*a + b*b + c*c  = 5;

with Solution a≈0.635425, b≈-1.8, c≈1.16458 or a≈1.16458, b≈-1.8, c≈0.635425.
When splitting the loop into two FMUs OMSimulator detects the loop, but can't solve it.

Steps to reproduce the behavior

I used this mos script to test:

loadModel(Modelica);

loadString("model loopOverFMUsA
  Real a, b, c;
  Modelica.Blocks.Interfaces.RealOutput a_out;
  Modelica.Blocks.Interfaces.RealOutput b_out;
  Modelica.Blocks.Interfaces.RealInput c_in;
equation
  c = c_in;
  // Eq. 1 and 2 of loop
  a + b + c=0;
  2*a - 3*b + 2*c=9;
  a_out = a;
  b_out = b;
end loopOverFMUsA;
"); getErrorString();

loadString("model loopOverFMUsB
  Real a, b, c;
  Modelica.Blocks.Interfaces.RealInput a_in;
  Modelica.Blocks.Interfaces.RealInput b_in;
  Modelica.Blocks.Interfaces.RealOutput c_out;
equation
  a = a_in;
  b = b_in;
  // Equation 3 of loop
  a*a + b*b + c*c=5;
  c_out = c;
end loopOverFMUsB;
"); getErrorString();

buildModelFMU(loopOverFMUsA, fmuType="me"); getErrorString();
buildModelFMU(loopOverFMUsB, fmuType="me"); getErrorString();

writeFile("loopsOverFMUs.lua","
oms_setTempDirectory(\"./temp/\")
oms_newModel(\"loopOverFMUs\")
oms_addSystem(\"loopOverFMUs.root\", oms_system_sc)

-- instantiate FMUs
oms_addSubModel(\"loopOverFMUs.root.A\", \"loopOverFMUsA.fmu\")
oms_addSubModel(\"loopOverFMUs.root.B\", \"loopOverFMUsB.fmu\")

-- connections: A -> B
oms_addConnection(\"loopOverFMUs.root.A.a_out\", \"loopOverFMUs.root.B.a_in\")
oms_addConnection(\"loopOverFMUs.root.A.b_out\", \"loopOverFMUs.root.B.b_in\")
oms_addConnection(\"loopOverFMUs.root.A.c_in\", \"loopOverFMUs.root.B.c_out\")

-- simulation settings
oms_setResultFile(\"loopOverFMUs\", \"loopOverFMUs.csv\")
oms_setStartTime(\"loopOverFMUs\", 0)
oms_setStopTime(\"loopOverFMUs\", 0.1)

oms_instantiate(\"loopOverFMUs\")
--oms_setReal(\"loopOverFMUs.root.system1.x_start\", 2.5)

oms_initialize(\"loopOverFMUs\")
oms_simulate(\"loopOverFMUs\")
oms_terminate(\"loopOverFMUs\")
oms_delete(\"loopOverFMUs\")
"); getErrorString();

system("OMSimulator loopsOverFMUs.lua"); getErrorString();

Output:

$ omc loopsOverFMUs.mos
 omc loopsOverFMUs.mos
true
true
""
true
""
"/mnt/d/workspace/EMISIYS/Demonstratores/myTest/loopOverFMUsA.fmu"
""
"/mnt/d/workspace/EMISIYS/Demonstratores/myTest/loopOverFMUsB.fmu"
""
true
""
info:    Set temp directory to    "/mnt/d/workspace/EMISIYS/Demonstratores/myTest"
info:    Set working directory to "/mnt/d/workspace/EMISIYS/Demonstratores/myTest"
info:    Set temp directory to    "/mnt/d/workspace/EMISIYS/Demonstratores/myTest/temp"
info:    New model "loopOverFMUs" with corresponding temp directory "/mnt/d/workspace/EMISIYS/Demonstratores/myTest/temp/loopOverFMUs-qwaomow6"
error:   [fmiLogger] module FMI2XML: XML element 'ScalarVariable': could not parse value for enumeration attribute 'causality'='none'
error:   [fmiLogger] module FMI2XML: XML element 'ScalarVariable': could not parse value for enumeration attribute 'causality'='none'
info:    model doesn't contain any continuous state
info:    Result file: loopOverFMUs.csv (bufferSize=1)
warning: Alg. loop (size 3)
error:   [solveAlgLoop] max. number of iterations (10) exceeded at time = 0.100000
Segmentation fault
139
""

In addition to the failing algebraic loop OMSimulator fails to unload all data and has a segmentation fault. Output from gdb:

Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x7ff8000000000000) at malloc.c:3103
3103    malloc.c: No such file or directory.
(gdb) bt
#0  __GI___libc_free (mem=0x7ff8000000000000) at malloc.c:3103
#1  0x00007ffff3a3d185 in deInitializeDataStruc (data=0x9f9620) at simulation/solver/model_help.c:1166
#2  0x00007ffff3a325eb in fmi2FreeInstance () from /mnt/d/workspace/EMISIYS/Demonstratores/myTest/temp/loopOverFMUs-906c32y3/temp/0002_B/binaries/linux64/loopOverFMUsB.so
#3  0x00000000005e7e55 in fmi2_capi_free_instance (fmu=0x9f9250) at /mnt/d/ubuntu/OpenModelica/OMSimulator/3rdParty/FMIL/src/CAPI/src/FMI2/fmi2_capi.c:402
#4  0x00000000005779fd in oms::ComponentFMUME::terminate (this=0x9f2650) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/ComponentFMUME.cpp:525
#5  0x000000000051d3ca in oms::SystemSC::terminate (this=0x9e7230) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/SystemSC.cpp:334
#6  0x000000000059c08e in oms::Model::terminate (this=0x9e6ff0) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/Model.cpp:599
#7  0x00000000004bfc8f in oms_terminate (cref_=<optimized out>) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/OMSimulator.cpp:1123
#8  0x00000000004a0167 in OMSimulatorLua_oms_terminate (L=0x9dc688) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/../OMSimulatorLua/OMSimulatorLua.c:936
#9  0x0000000000630bf6 in luaD_precall (L=0x9dc688, func=0x9dbdb0, nresults=0) at ldo.c:434
#10 0x000000000063c4cd in luaV_execute (L=0x9dc688) at lvm.c:1134
#11 0x0000000000630e54 in luaD_call (L=0x9dc688, func=<optimized out>, nResults=<optimized out>) at ldo.c:499
#12 luaD_callnoyield (L=0x9dc688, func=<optimized out>, nResults=<optimized out>) at ldo.c:509
#13 0x000000000063008e in luaD_rawrunprotected (L=0x9dc688, f=0x62e5b0 <f_call>, ud=0x7fffffffd910) at ldo.c:142
#14 0x000000000063142b in luaD_pcall (L=0x9dc688, func=0x0, u=0x9f0bf0, old_top=16, ef=140737281170361) at ldo.c:729
#15 0x000000000062e520 in lua_pcallk (L=0x9dc688, nargs=<optimized out>, nresults=0, errfunc=<optimized out>, ctx=<optimized out>, k=0x9f8e00) at lapi.c:968
#16 0x00000000004bb0d5 in oms_RunFile (filename_=<optimized out>) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/OMSimulator.cpp:1101
#17 0x0000000000595578 in oms::Flags::SetCommandLineOption (cmd=...) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/Flags.cpp:165
#18 0x00000000004a5b4c in oms_setCommandLineOption (cmd=0x9d8be0 "loopsOverFMUs.lua") at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulatorLib/OMSimulator.cpp:373
#19 0x000000000049caee in main (argc=<optimized out>, argv=0x7fffffffdd98) at /mnt/d/ubuntu/OpenModelica/OMSimulator/src/OMSimulator/main.cpp:45

EDIT: This segmentation fault is caused by the FMU exporting tool OpenModelica.

Expected behavior

Version and OS

  • Version: OMSimulator v2.1.0-dev-152-g63ee20c-linux
  • OS: Ubuntu 18.04 on WSL2 on Windows 10
@AnHeuermann
Copy link
Member Author

AnHeuermann commented Sep 18, 2020

I tested again with a newer version of OpenModelica and OMSimulator (was using an old version for the first output).

The problem is the iteration process for the non-linear loop between FMUs A and B.

The generated code for the FMUs is looking good:
FMU A:

c := c_in;
b := 3/5*c + 0.4*c -1.8 -c; [ = -1.8]
a := -b -c;
b_out := b;
a_out := a;

FMU B:

a := a_in;
b := b_in;
c := abs(sqrt(5-a*a + b*b));
c_out := c;

The newest problem:
The iteration process is going into the wrong direction. It tries with some values for a and b with 5-(a*a+b*b)<=0 what will result in a assert.

warning: Alg. loop (size 3)
warning: B (logStatusWarning): The following assertion has been violated during initialization at time 0.000000
assert            | debug   | Model error: Argument of sqrt(5.0 - (a_in ^ 2.0 + b_in ^ 2.0)) was -1.48 should be >= 0
getBestJumpBuffer got mmc_jumper=(nil), globalJumpBuffer=(nil)
Aborted
134

TODOs:

@sjoelund
Copy link
Member

It shouldn't matter that it's going in the wrong direction. Fix the generated FMU; we should never call abort() inside of an FMU :)

@AnHeuermann
Copy link
Member Author

Good point. But I'm not sure what the best approach would be for that. I've created a ticket for this to continue the discussion there: https://trac.openmodelica.org/OpenModelica/ticket/6125#ticket

@AnHeuermann
Copy link
Member Author

AnHeuermann commented Sep 21, 2020

Related PR: OpenModelica/OpenModelica#6757

@lochel
Copy link
Member

lochel commented Feb 10, 2021

@AnHeuermann What is the status?

@AnHeuermann
Copy link
Member Author

I should re-run my example. But it is not really a good one.
We still have asserts and are not treating the returned error codes in a good way. Ideally it should be possible for OMSimulator to solve this loop, even though the initial iteration will trigger the asserts because 5-a*a + b*b<0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants