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
Posted 6 years ago
POSTED BY: Updating Name

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?

Yes.

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).

That would be my suggestion and preference, some of the advantages are:

  • You avoid one source for misstakes.
  • Your library has a higher chance of being interoperable with other libraries (since everything is modeled in the same units).

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): ...

I don't really know how you use that, but doesn't it gets confusing since the simulation time unit in Modelica is always in seconds so when plotting results they will be presented in seconds?

To me it would make more sense to do all modelling in a standard unit and then making things like the model time base simply a display issue, does that fit your use case or am I missing something?

So what functionality are you missing to achieve that, a user selectable displayUnit for time (probably per model) is one thing I guess. What else do you need?

Otto

POSTED BY: Otto Tronarp
POSTED BY: Otto Tronarp
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

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).

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
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard