Group Abstract Group Abstract

Message Boards Message Boards

0
|
11.5K Views
|
11 Replies
|
5 Total Likes
View groups...
Share
Share this post:

Why can't a parameter be used to set the unit-attribute?

Hi everybody,

The following minimal example does compile without any problems in WSM 4.3 and 5.1. But it will cause an error in WSM 12.0 all of a sudden:

model UnitErrorModel
  MyComponent c( hasUnit = "myUnit" );

  block MyComponent
    parameter String hasUnit = "1";
    output Real y( unit = hasUnit );
  equation
    y = 10;
  end MyComponent;

end UnitErrorModel;

So the global model will have a component c that modifies a parameter hasUnit which is used by the component to set the unit-attribute of its output y.

In Mathematica [12.0.0 for Microsoft Windows (64-bit) (April 6, 2019)] I observe this:

model = Import[ "UnitErrorModel.mo" ];
SystemModelSimulate[ model, { 0, 10 } ]

SystemModelSimulate::bldl

Internal error: Codegen.getValueString: Non-constant expression:c.hasUnit

What has changed in WSM that this is causing an error? Why can't a parameter (note, that making the modification final will not resolve the issue) be used to set the unit-attribute - after all it is known at runtime when compiling the model?

Best regards, Guido

Note: I cross-posted an extended question on StackOverflow.

Background: I am developing a library for (acausal) System Dynamics modeling. Since SD is very low level (e.g. stocks and flows) working with “hard-wired” SI-units is not helpful for modeling managerial or economical problems. Yet, unit checking is very useful and widely embraced in the SD community. Thus, having a flexible way to use parameters to assign units to output (and input) connectors wouldmbe very helpful; this is also how most dedicated SD tools go about it.

11 Replies

Hi Otto,

I completely agree with what you are saying.

What I meant is the use of conversions for a different choice of basic unit. So you cannot have:

Real myTime( quantity = "Time", unit = "yr", displayUnit = "mo")

... if you have defined a cumstom conversion for mo ? yr somewhere. But once you allow to go into a non-SI-Unit as base unit, you imo need to be able to define the full matrix? (Coming from Mathematica with arbitrary precision arithmetic I, of course, would rather define a conversion from the larger unit to the smaller so that I may use integers or rational numbers and then make use of these exact fractions automatically for the reverse conversion. But it will probably not matter here.)

I am fine with seconds as base unit if you come up with the support for displayUnit as you have indicated.

Guido

PS: What about rates?

PPS: Regarding the final attribute. I have come to avoid it a bit. For example, if I redeclare the type for the output of a component (e.g. maybe to control unit, displayUnit or simply to switch from a Real to Boolean to build a different model using a generic class), then that output will be hidden in the default settings of the Simulation Center which filters these vars).

Posted 6 years ago
POSTED BY: Updating Name

Hi Otto,

to make this post complete, I will try to answer what I have found out til now and wrap this discussion up:

  1. Custom conversions can be found under Tools>Options>Global>Unit Conversions (the documentation could be optimized in this regard since you will not easily find a hint there looking for "conversion").

    A slight glitch with adding conversions for Non-SI-units: If you want to enter a conversion from "weeks" to "seconds", System Modeler will automatically discover the conversion from "seconds" to "weeks" and only allow updating the existing conversion. Unfortunately, the software will not make use of that conversion though, so that if you have entered a conversion from "seconds" to "weeks" this will preclude a way to have "weeks" as the standard unit of default and then go to "seconds" using displayUnit. (For unit conversions we should only have to define a diagonal in the conversion matrix and then have the matrix filled automatically using reciprocal factors).

    Another thing, not so easily solved, is the fact that for rates we would need (?) a different conversion factor for each possible rate if we allow Non-SI-units for stocks in economic models: e.g. have adifferent conversion factor for apples/s and oranges/s to apples/yr and oranges/yr?

  2. Numerical issues - still waiting for some advice how far a modeler has to think about such things...

  3. displayUnit is usually changed in drop down menus (e.g. in the Simulation Center while choosing vars for display, in the Parameter-Windows within the Modeling Center). This is quite often fine and all one needs. I would still be interested in a way to programmatically override drow-down choices: Will using final achieve this?

In the end, everything would maybe be fine using seconds if System Modeler would allow what OpenModelica allows: Changing the displayUnit for Simulation Time. Unfortunately, I am not aware of any convenience in this regard. There is to my knowledge no way to nicely adjust display of time in the diagrams from "seconds" to say "years", is there?

So, without that convenience we may still try to use Non-SI-Units using type and replaceable somehow. But that is another question I posted here. UPDATE: Note, that I just now expaned that post demonstrating, that it appears that we cannot use a constant expression with the inner prefix (e.g. inner constant String GlobalUnitOfTime = "yr" ) as this also will give errors during compilation.

Guido

POSTED BY: Otto Tronarp

Otto,

There is something to your arguments and I am a bit unused (still) to thinking about before and after compilation - not being a software engineer myself... ;-)

To reframe what your are saying, let us simply assume, that I have an exectuable instance of a model and the user can enter a value that is used when the simulation is actually started. On the screen I would have to tell the user an "instance before his entry", that he is supposed to give say a rate in days, weeks, or months - because this is how the model is set up to calculate in the formulas. So, in Modelica lingo the time base of the model (i.e. the unit of time) would have to be of constant variability (e.g. set before the model is made an executable) and the entry of the user would be of parametric variability. Right?

Note: The other option (@Jan Brugard - as with time zones ;-) ) would be to have everything converted to some standard e.g. SI-units like seconds in the case of time. This being very unusual for SD ... I have not done it (yet).

Now, I am still confused about the following code (which is used at the top level of every model I set up with my library):

inner parameter TimeBases modelTimeBase = TimeBases.years "The model's time base";
inner constant String modelTimeBaseUnit = BusinessSimulation.Constants.timeBaseUnits[modelTimeBase];
inner parameter Time dt(unit = modelTimeBaseUnit) = 1 / 16 "Smallest possible interval of time for compatibility with conventional fixed-step System Dynamics models";

I am having an enumeration TimeBases (seconds, minutes, hours, ... ) which is used to choose the unit of time for the model (which then nicely works as a drop down menu). Even though the String modelTimeBaseUnit above is stated to be a constant, it seems to "inherit" the parametric variability of modelTimeBase.

In short: The above use of modelTimeBaseUnit to set the unit attribute inside the lower level components of models does cause an error also.

So, change the above variables to be constants? (or better stick to SI-units with scaling?)

Guido

PS:

Constants and parameters are very similar, but also have some differences (Section 3.11.2, page 99). Parameters are typically much more common in application models. When in doubt whether to use constant or parameter, use parameter, except when declaring a constant in a package/ library where constant is allowed but not parameter.

Fritzson, Peter. Principles of Object-Oriented Modeling and Simulation with Modelica 3.3: A Cyber-Physical Approach (Kindle-Positionen1795-1799). Wiley. Kindle-Version.

When in doubt ... After thinking about what you have written, I still believe that the user may well choose time and the unit of time as a parameter given a compiled model.

Most Modelica tools support resimulating a model without recompilation after changing a parameter, which usually makes the time waiting for results much shorter.

Fritzson, Peter. Principles of Object-Oriented Modeling and Simulation with Modelica 3.3: A Cyber-Physical Approach (Kindle-Positionen1785-1786). Wiley. Kindle-Version.

Everything in that model could be made to act upon that parametric choice (as with all other parameters also). Chosing the unit of time for giving rates could (and maybe should) well be a parameter of a model (the choice of time scale could be passed onto other components as an inner parameter). While I cannot simply "rescale" apples to be oranges, I can well do so for any unit of time. Where is the fault in my thinking?

A constant is a parameter that cannot be changed after translation. That is exactly the behaviour in your unit scenario and "parametric structure" scenario. In my opinion it would be better to actually use the constant construct in those scenarios to better communicate what is expected to happen instead of having the compiler force evaluation of the parameter (and there by effectively transform it to a constant).

Otto

POSTED BY: Otto Tronarp
POSTED BY: Otto Tronarp

You are correct in that it's not in violation with the specification, although making it a constant makes more sense since you would invalidate all your static unit checking if you are allowed to change the unit after building the simulation. We filed an issue on the specification regarding this (https://github.com/modelica/ModelicaSpecification/issues/2362).

Otto

POSTED BY: Otto Tronarp

While I still cannot find a parameter to be in violation with Modelica specifications (it would be the natural thing to handle this and it has worked so far in WSM and still works in Dymola), changing the declaration for hasUnit from parameter to constant solves the issue!

That at least means, that my library can be rescued with minimal effort ... ;)

Guido

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard