Opened 5 years ago
Last modified 4 years ago
#6181 new defect
Boolean incorrectly evaluated and asserts, implying negative time?
| Reported by: | Owned by: | Andreas Heuermann | |
|---|---|---|---|
| Priority: | high | Milestone: | |
| Component: | Run-time | Version: | v1.17.0-dev |
| Keywords: | Cc: | Karim Adbdelhak |
Description (last modified by )
The following asserts time is less than zero. Did not assert in previous versions of OMC
model DebugInitialValue model BooleanPulse input Real width(start=0.5); output Boolean y; equation y = time < width; end BooleanPulse; class DayNightCycle parameter Real earth_day_period=24; Real daylight_ratio; BooleanPulse daylight(width=daylight_ratio); end DayNightCycle; parameter Real ratio_start=0; Real _ratio; DayNightCycle cycle(daylight_ratio=_ratio); //FAILS. Will work if changed to daylight_ratio=0 here. algorithm _ratio := ratio_start; if not initial() then assert(cycle.daylight.y==false,"oops",level=AssertionLevel.warning); end if; end DebugInitialValue;
Change History (13)
comment:1 by , 5 years ago
| Component: | *unknown* → Run-time |
|---|---|
| Description: | modified (diff) |
| Owner: | changed from to |
follow-up: 7 comment:2 by , 5 years ago
comment:3 by , 5 years ago
This model will work:
model DebugInitialValue
model BooleanPulse
input Real width(start=0.5);
output Boolean y;
equation
y = time < width;
end BooleanPulse;
class DayNightCycle
parameter Real earth_day_period=24;
Real daylight_ratio;
BooleanPulse daylight(width=daylight_ratio);
end DayNightCycle;
parameter Real ratio_start=0;
Real _ratio;
DayNightCycle cycle(daylight_ratio=_ratio); //FAILS. Will work if changed to daylight_ratio=0 here.
equation
_ratio = ratio_start;
algorithm
if not initial() then
assert(cycle.daylight.y==false,"oops",level=AssertionLevel.warning);
end if;
end DebugInitialValue;
follow-up: 6 comment:4 by , 5 years ago
| Cc: | added |
|---|---|
| Milestone: | 1.16.1 → 1.17.0 |
| Version: | v1.16.0-dev → v1.17.0-dev |
@kabdelhak What is your opinion? Is the initial version of the model from the ticket description valid Modelica code?
I think using an algorithm section in such a way prevents the compiler from ordering the equations correctly.
I think it is not allowed to do anything in between steps of an algorithm section at all. We have to treat it as is.
follow-up: 9 comment:5 by , 5 years ago
following asserts time is less than zero
Btw, my assert time is 0:
messages = "assert | warning | The following assertion has been violated during initialization at time 0.000000 | | | | cycle.daylight.y == false assert | warning | oops
@craig.fletcher What OS and version are you using?
follow-up: 8 comment:6 by , 5 years ago
Replying to AnHeuermann:
I think it is not allowed to do anything in between steps of an algorithm section at all. We have to treat it as is.
Yes we are not allowed to split up algorithms. If you define an algorithm it will be executed exactly how you defined it (sometimes it will be inverted as a whole, but that is very rare. And the order still is kept, just in reverse).
If you want the order to be determined by the tool, you have to use equations.
comment:7 by , 5 years ago
I'm sorry but there are several things I don't understand about this example.
First of all, we are checking an assert during initialization even though the assert statement is found in an if clause with not initial() conditions. So, the assert condition shouldn't be checked (and possibly triggered) during initialization in the first place.
Second, "An algorithm section is treated as an atomic vector-equation, which is sorted together with all other equations. For the sorting process (BLT), every algorithm section with N different left-hand side variables, is treated as an atomic N-dimensional vector-equation containing all variables appearing in the algorithm section." (Section 11.1.2 of the Specification).
During simulation, the algorithm section (which must conceptually be kept together!) computes _ratio and needs cycle.daylight.y to compute the condition of the assert statement, so it should be computed after computing cycle.daylight.y, not before.
Do I miss something?
comment:8 by , 5 years ago
Replying to Karim.Abdelhak:
Yes we are not allowed to split up algorithms. If you define an algorithm it will be executed exactly how you defined it (sometimes it will be inverted as a whole
Yes, using some Newton iteration
And the order still is kept, just in reverse
I'm not sure what do you mean by "in reverse". The order is kept, and an iterative strategy will be used to solve it backwards. Is that what you mean?
For example 10 = myfunction(x) will actually invert the function, but it will basically do it by (smart) trial and error, adjusting x and computing myfunction(x) at each step until the output matches 10.
comment:9 by , 5 years ago
Replying to AnHeuermann:
following asserts time is less than zero
Btw, my assert time is
0:
messages = "assert | warning | The following assertion has been violated during initialization at time 0.000000 | | | | cycle.daylight.y == false assert | warning | oops@craig.fletcher What OS and version are you using?
Details as follows:
Distributor ID: Ubuntu
Description: Ubuntu 18.04.5 LTS
Release: 18.04
Codename: bionic
libomc_1.16.0-1_amd64.deb
libomcsimulation_1.16.0-1_amd64.deb
omc_1.16.0-1_amd64.deb
omc-common_1.16.0-1_all.deb
omc-doc_1.12.0-1_all.deb
omlib-complex-3.2.3_3.2.3~20201013~234009~git~OM~maint~3.2.3-1_all.deb
omlib-modelica-3.2.3_3.2.3~20201013~234009~git~OM~maint~3.2.3-1_all.deb
omlib-modelicaservices-3.2.3_3.2.3~20201013~234009~git~OM~maint~3.2.3-1_all.deb
omshell-terminal_1.16.0-1_amd64.deb
follow-up: 11 comment:10 by , 5 years ago
@casella You are right. We are missing the not initial() part in the C code.
I created a new ticket for this because this is not the root problem for this ticket (I guess at least): #6186
comment:11 by , 5 years ago
Replying to AnHeuermann:
@casella You are right. We are missing the
not initial()part in the C code.
I created a new ticket for this because this is not the root problem for this ticket (I guess at least): #6186
Excellent, thanks!
comment:12 by , 5 years ago
| Milestone: | 1.17.0 → 1.18.0 |
|---|
Retargeted to 1.18.0 because of 1.17.0 timed release.

The model get's flattened out to:
class DebugInitialValue parameter Real ratio_start = 0.0; Real _ratio; parameter Real cycle.earth_day_period = 24.0; Real cycle.daylight_ratio = _ratio; Real cycle.daylight.width(start = 0.5) = cycle.daylight_ratio; Boolean cycle.daylight.y; equation cycle.daylight.y = time < cycle.daylight.width; algorithm _ratio := ratio_start; if not initial() then assert(cycle.daylight.y == false, "oops", AssertionLevel.warning); end if; end DebugInitialValue;and here we can see the dilemma. If we evaluate the algorithm section first
cycle.daylight.widthis set to the start value and the assert muss trigger.If we evaluate the equations section first
_ratiois not set to_ratio_start.From the backend we will get this DAE-system:
So we first try to evaluate the algorithm section.
But I'm not sure if this behavior is wrong. Not sure why older omc versions behave different here though.
I could imagine to get the correct code one would need to use an
initial algorithmsection to set a start value for_ratio.