Opened 6 years ago

Closed 6 years ago

#5383 closed defect (wontfix)

Instruction y[i] = if ud2[i] > 0.0 then true else false; not correctly executed in a loop

Reported by: Jean-Philippe Tavella <jean-philippe.tavella@…> Owned by: Karim Adbdelhak
Priority: high Milestone: 1.14.0
Component: Run-time Version: v1.13.0
Keywords: Cc: audrey.jardin@…

Description

Dear All,

Please open the attached file BooleanIssue.mo under OM and run the model TestBooleanTransmission in Basic.Tests for 6 s.

Now,visualize the variables: u[2], ud1[2], ud2(2] and y[2].

All results are correct except for the last variable y[2] that is unexpectedly constant with value 1(true).

This appears as a rough mistake.Best

Attachments (1)

BooleanIssue.mo (20.0 KB ) - added by Jean-Philippe Tavella <jean-philippe.tavella@…> 6 years ago.

Download all attachments as: .zip

Change History (6)

by Jean-Philippe Tavella <jean-philippe.tavella@…>, 6 years ago

Attachment: BooleanIssue.mo added

comment:1 by Adeel Asghar, 6 years ago

Component: OMEditRun-time
Owner: changed from Adeel Asghar to Willi Braun
Status: newassigned

comment:2 by Adeel Asghar, 6 years ago

Owner: changed from Willi Braun to Karim Adbdelhak

comment:3 by Karim Adbdelhak, 6 years ago

If i understand the problem correctly we have the functions

y[i] = if ud2[i] > 0.0 then true else false;

To determine if y[i] is true or false. Because equality check on float variables is not supported the operator > is equal to >= which might be confusing. Since ud2[i] is either 1.0 or 0.0 due to

ud2[i] = if u_UL.latency == 0 then if ud1[i] then 1.0 else 0.0 else delay(if ud1[i] then 1.0 else 0.0, u_UL.latency / 1000, maxDelay);

The actual condition ud2[i] >= 0.0 never gets crossed. As this is expected behaviour for float variables you can use two different approaches to catch equality:

  1. Use an epsilon as crossing condition:

parameter Real eps=10^(-6);
And change the condition to
y[i] = if ud2[i] > eps then true else false;

  1. Since equality on Real vars is only supported in functions use Modelica.Math.isEqual:

y[i] = if ud2[i] > 0.0 and not Modelica.Math.isEqual(ud2[i],0.0) then true else false;
Simply using ud2[i]==0.0 will not work.

I would recommend the second version, since it works both ways. The first one only works if approaching from positive numbers.

If this resolves the problem feel free to close the ticket!

EDIT:
Just to clarify this: In most cases the check for equality on > or >= operators for float variables would be unnecessary, therefore it is not automatically done. If really need it could be added, but i would rather avoid that to keep simulation and compilation time down. Just catch equality with Modelica.Math.isEqual when needed.

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

comment:4 by J-Ph Tavella <jean-philippe.tavella@…>, 6 years ago

The proposed solution perfectly works on OM but doesn't with Dymola.

So I have a Modelica code for OM and ANOTHER Modelica code for Dymola: quite a pity !

Is there any possibility to determine whether a code is running under OM or not in order to select one equation rather than another one?

If you cannot answer the question the case can be seen as solved.

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

Resolution: wontfix
Status: assignedclosed

Replying to J-Ph Tavella <jean-philippe.tavella@…>:

The proposed solution perfectly works on OM but doesn't with Dymola.

So I have a Modelica code for OM and ANOTHER Modelica code for Dymola: quite a pity !

Indeed...

Is there any possibility to determine whether a code is running under OM or not in order to select one equation rather than another one?

The Modelica language has no such option, and rightfully so, because we're striving to have a standard language, not N mutually incompatible dialects. Adding that feature would probably be tantamount to opening the gates of hell :)

As I understood from Karim's comments, your original code was numerically ill-conditioned, so it may or may not work in a give tool (or even in a specific version of a certain tool) depending on factors beyond your control, so I would avoid using it if you want to have a library that runs on multiple tools.

I'm not sure why the second alternative doesn't work in Dymola, you should probably ask their customer support, and get this fixed in the medium-long term.

In the short term, you may define a top-level package constants in your library such as

package MyLibrary
  constant useDymola = false;
  
  model MyModel
   ...
  equation
    if useDymola then
      <equations that work with Dymola here>
    else
      <equations that work with OMC here>
  end MyModel;
  ...
end MyPackage;

Then, you need to keep two variants of your library MyLibrary, which only differ by the package constant. If you organize the library with one file for each sub-package, then it's just a small difference in the top-level package.mo file, you can easily manage this using branches in GIT or SVN.

It's a bit ugly, but as an interim solution it works well. In the long term, you need to interact with the tool developers until you get both tools to work on a well-posed version of the code.

Note: See TracTickets for help on using tickets.