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 Andreas Heuermann, 4 years ago

Related ticket: #6181

comment:2 by Andreas Heuermann, 4 years ago

Owner: changed from Mahder Alemseged Gebremedhin to Andreas Heuermann
Status: newassigned

comment:3 by Andreas Heuermann, 4 years ago

Component: Code GenerationBackend

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 Andreas Heuermann, 4 years ago

At least the problem is not working the other way around (any more), see #2963.

comment:5 by Andreas Heuermann, 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.

Last edited 4 years ago by Andreas Heuermann (previous) (diff)

in reply to:  5 ; comment:6 by Karim Adbdelhak, 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.

Last edited 4 years ago by Karim Adbdelhak (previous) (diff)

comment:7 by Andreas Heuermann, 4 years ago

It checks the boolean value of data->simulationInfo->initial which is true during initialization and will get false after it.

in reply to:  7 comment:8 by Karim Adbdelhak, 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.

in reply to:  6 comment:9 by Francesco Casella, 4 years ago

Replying to Karim.Abdelhak:

Replying to AnHeuermann:
Sounds good, but how exactly do we handle initial()? Does it return true in the initial system and false otherwise

Yes.

or does it actually check time == startTime? If it is the first we don't win anything by not removing it.

No.

Version 0, edited 4 years ago by Francesco Casella (next)

comment:10 by Francesco Casella, 4 years ago

Milestone: 1.17.01.18.0

Retargeted to 1.18.0 because of 1.17.0 timed release.

comment:11 by Francesco Casella, 3 years ago

Milestone: 1.18.0

Ticket retargeted after milestone closed

Note: See TracTickets for help on using tickets.