Opened 4 years ago
Last modified 3 years ago
#6186 assigned defect
Assert triggered during initialization despite "not initial()" if-statement
Reported by: | Andreas Heuermann | Owned by: | Andreas Heuermann |
---|---|---|---|
Priority: | high | Milestone: | |
Component: | Backend | Version: | v1.17.0-dev |
Keywords: | assert, initial, algorithm | Cc: | Karim Adbdelhak |
Description
When formulating an assert that is not allowed to be checked during initialization omc will check it any way and the assert triggers.
See following example:
loadString(" model missingInitial Real x; equation x = time; if not initial() then assert(not x==0, \"This assert is not allowed to trigger during initalization.\",level=AssertionLevel.warning); end if; end missingInitial; "); getErrorString(); setCommandLineOptions("-d=newInst,optdaedump --removeSimpleEquations=none"); getErrorString(); simulate(missingInitial); getErrorString();
assert | warning | The following assertion has been violated during initialization at time 0.000000 | | | | not x == 0.0 assert | warning | This assert is not allowed to trigger during initalization. LOG_SUCCESS | info | The initialization finished successfully without homotopy method. LOG_SUCCESS | info | The simulation finished successfully.
Change History (11)
comment:1 by , 4 years ago
comment:2 by , 4 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:3 by , 4 years ago
Component: | Code Generation → Backend |
---|
At the start of the backend:
unknown partition ======================================== Variables (1) ======================================== 1: x:VARIABLE() type: Real Equations (2, 1) ======================================== 1/1 (1): x = time [dynamic |0|0|0|0|] 2/2 (0): if not initial() then end if [unknown |0|0|0|0|] Simple Equations (1, 0) ======================================== 1/1 (0): algorithm assert(if not initial() then not x == 0.0 else true, "This assert is not allowed to trigger during initalization."); [dynamic |0|0|0|0|]
At the end of the backend:
unknown partition ======================================== Variables (1) ======================================== 1: x:VARIABLE() type: Real Equations (1, 1) ======================================== 1/1 (1): x = time [dynamic |0|0|0|0|] Matching ======================================== 1 variables and equations var 1 is solved in eqn 1 StrongComponents ======================================== {1:1} BackendDAEType: initialization unspecified partition ======================================== Variables (1) ======================================== 1: x:VARIABLE() type: Real Equations (1, 1) ======================================== 1/1 (1): x = time [dynamic |0|0|0|0|] Simple Equations (1, 0) ======================================== 1/1 (0): algorithm assert(not x == 0.0, "This assert is not allowed to trigger during initalization."); [dynamic |0|0|0|0|] Matching ======================================== 1 variables and equations var 1 is solved in eqn 1 StrongComponents ======================================== {1:1} BackendDAEType: simulation
This is looking good. The simulation system has the assert (simplified because not intitial()
will always be true
) and the initial system doesn't have the assert at all.
So the problem musst occur somewhere in code generation (or even simulation runtime).
comment:4 by , 4 years ago
At least the problem is not working the other way around (any more), see #2963.
follow-up: 6 comment:5 by , 4 years ago
If I enable LOG_INIT
we can see that the assert is evaluated at the end of initialization:
LOG_INIT | info | ### START INITIALIZATION ### LOG_INIT | info | updating min-values LOG_INIT | info | updating max-values LOG_INIT | info | updating nominal-values LOG_INIT | info | updating primary start-values LOG_INIT | info | initialization method: symbolic [solves the initialization problem symbolically - default] LOG_INIT_HOMOTOPY | info | Model contains homotopy operator: Use adaptive homotopy method to solve initialization problem. To disable initialization with homotopy operator use \"-noHomotopyOnFirstTry\". LOG_INIT | info | ### END INITIALIZATION ### assert | warning | The following assertion has been violated during initialization at time 0.000000 | | | | not x == 0.0 assert | warning | This assert is not allowed to trigger during initalization. LOG_SUCCESS | info | The initialization finished successfully without homotopy method. LOG_SUCCESS | info | The simulation finished successfully.
Problem is that we update discrete variables directly after "### END INITIALIZATION ###"
is printed, but before we set data->simulationInfo->initial = 0 /* false */;
.
So missingInitial_functionDAE()
get's called and is thinking that it is still inside the initialization process. But the assert itself will not check if it is called during initialization or not. So every call to missingInitial_functionDAE()
where time=0
will trigger the assert.
But I can't find a smart way to resolve this. I can't remove the call to updateDiscreteSystem
or change the way it works. We have a separation between initial and simulation equations, but we call simulation equations before the first step from the solver is started, to obtain all sort of values.
So the easy fix could be to keep assert(if not initial() then not x == 0.0 else true)
and don't simplify this in the backend.
follow-up: 9 comment:6 by , 4 years ago
Replying to AnHeuermann:
So the easy fix could be to keep
assert(if not initial() then not x == 0.0 else true)
and don't simplify this in the backend.
Sounds good, but how exactly do we handle initial()
? Does it return true
in the initial system and false
otherwise, or does it actually check time == startTime
? If it is the first we don't win anything by not removing it.
follow-up: 8 comment:7 by , 4 years ago
It checks the boolean value of data->simulationInfo->initial
which is true during initialization and will get false after it.
comment:8 by , 4 years ago
Replying to AnHeuermann:
It checks the boolean value of
data->simulationInfo->initial
which is true during initialization and will get false after it.
Okay, i suppose it gets changed to false
at the same point we print "### END INITIALIZATION ###"
so it should work the way you proposed!
It could be that we need to update some modules to this change since all modules after that think that there are no initial()
calls to handle.
comment:9 by , 4 years ago
Replying to Karim.Abdelhak:
Replying to AnHeuermann:
Sounds good, but how exactly do we handleinitial()
? Does it returntrue
in the initial system andfalse
otherwise
Yes.
or does it actually check
time == startTime
? If it is the first we don't win anything by not removing it.
No.
Normally, all the equations end up both in the initial and regular systems, except when initial()
is used. In that case, the output of that function is used to tell which equations (or expressions) need to end up in the initial systems, and which need to end up in the regular system.
comment:10 by , 4 years ago
Milestone: | 1.17.0 → 1.18.0 |
---|
Retargeted to 1.18.0 because of 1.17.0 timed release.
Related ticket: #6181