Group Abstract Group Abstract

Message Boards Message Boards

0
|
11.7K Views
|
8 Replies
|
6 Total Likes
View groups...
Share
Share this post:

Unit Checking in System Modeler and making use of unit attributes

Unit checking (or dimensional analysis) is an important means of model verification:

Units of Measurement in a Modelica Compiler

Question 1: Is unit checking implemented in the current version of Wolfram System Modeler? (If not, what options are there to achieve it by other means?)

In Modelica units are stored as attributes to variables (e.g. Real( unit = "m/s" ) ) and are usually enabled by modifications of existing basic types with default values for these attributes (e.g. the default unit for the type Real is " ").

Question 2: How to make use of this "meta information" within the model itself:

  • How can I access the unit of some variable?

    parameter String referencedUnit = <function of another variable to access its unit>
    
  • How can I assign such a referenced unit to another variable within the runtime of a model? (e.g. I have written a converter function to convert units of time, say from minutes to months, as this is frequently needed in economic or business simulation models where SIunits are rather an exception).

    output convertedTime =Real( quantity = "Time", unit = <to be assigned in func-body> )
    

    or

    input String timeUnitA; // unit of time to convert from
    input String timeUnitB; //unit of time to convert to
    output convertedTime = Real( quantity = "Time", unit = timeUnitB )
    

(All the above will not work for me as different degrees of variability prohibit this: a modification of the unit attribute must be a constant...).

EDIT: I have cross-posted the second part of my question on stack overflow (5363743)

8 Replies

You can apply units on a reusable unitless library in different ways

Modify your instances:

model ApplyUnit
  Modelica.Blocks.Sources.Sine sine1(y(unit="m", displayUnit="ft")) annotation(Placement(visible = true, transformation(origin = {-120, 32.607}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
  annotation(Diagram(coordinateSystem(extent = {{-150, -90}, {150, 90}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5})), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10}), graphics = {Rectangle(visible = true, lineColor = {0, 114, 195}, fillColor = {255, 255, 255}, extent = {{-100, -100}, {100, 100}}, radius = 25), Text(visible = true, textColor = {64, 64, 64}, extent = {{-150, 110}, {150, 150}}, textString = "%name")}));
end ApplyUnit;

Make specialized classes with units

model DistanceSine
extends Modelica.Blocks.Sources.Sine(y(unit="m", displayUnit="ft"));
end DistanceSine;

However, there isn't any GUI support for setting the initial unit in this way so you have to do it in text mode.

If you are making your own library from ground up you could also make something relying on replaceable/redeclare.

POSTED BY: Otto Tronarp
POSTED BY: Otto Tronarp

Taking the "absence of evidence as evidence of absence" it seems that at the moment System Modeler does not support unit checking (e.g. my first question)?

Neil,

Thank you for your answer, which is helpful albeit to be honest I am not yet sure whether it resolves akwardness in System Dynamics modeling with Modelica. ;-)

The Block (e.g. continuous time conversion) allows to have some model var to represent time in a time base different from seconds. But I would still have to set up my experiment in seconds, wouldn't I? (e.g. I could not ,say, go from 2018 to 2030 to represent years directly, could I?)

I am not sure about the use of displayUnits as I would need something like conversion factors for units like years and month which I have not seen so far in Version 4.3 which I am trying out here?

So far, my (quick and dirty) solution is to treat my model's time base (years, quarters, months - as rates are usually given in these bases) as if it were seconds and doing numerical conversions for other times bases to my model's time base (using just the dimensionless function output). Then I will just adjust the unit for time in plots manually (or using a simple block as you did) to show the time base.

Guido

PS: Indeed operator records are not really helpful here, albeit the example given on stack overflow is an elegant solution for conversions. So far, I am not aware that you can define your own operator records in WSM though?

Guido,

While all the units of time are done in seconds internally, you can work around this in SystemModeler.

In this model I have a filter that has a one year time constant (talk about moving slowly!). I want to plot it in years, not seconds:

enter image description here

Note that the step starts after one year (which I entered in days in the dialog (display units) but it shows up as seconds on the built-in block. I made my own seconds to year converter block:

model ToYear
  extends Modelica.Blocks.Interfaces.SISO;
equation
  y = u / (3600 * 24 * 365);
  annotation(Diagram(coordinateSystem(extent = {{-150, -90}, {150, 90}}, preserveAspectRatio = true, initialScale = 0.1, grid = {5, 5}), graphics = {Text(visible = true, origin = {-135.776, 24.908}, extent = {{-30.776, -3.301}, {30.776, 3.301}}, textString = "Seconds"), Text(visible = true, origin = {118.717, 25}, extent = {{-11.283, -5}, {11.283, 5}}, textString = "Years")}), Icon(coordinateSystem(extent = {{-100, -100}, {100, 100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {10, 10}), graphics = {Rectangle(visible = true, lineColor = {0, 114, 195}, fillColor = {255, 255, 255}, extent = {{-100, -100}, {100, 100}}, radius = 25), Text(visible = true, textColor = {64, 64, 64}, extent = {{-150, 110}, {150, 150}}, textString = "%name"), Text(visible = true, origin = {-147.2, 47.902}, extent = {{-45.346, -12.098}, {45.346, 12.098}}, textString = "Seconds"), Text(visible = true, origin = {140, 45}, extent = {{-33.849, -15}, {33.849, 15}}, textString = "Years")}));
end ToYear;

Now in the Simulation Center do an X-Y plot of toYear1.y vs filter.y

to get

enter image description here

All other units (other than the time base) can be dealt with by using displayunits and doing conversion to your desired unit in Simulation Center. I know you posted about using operator records but I do not see how that will help you in this case (unless I am missing something)

Is this what you were looking for?

Regards,

Neil

POSTED BY: Neil Singer

This answer given on stack overflow suggests that while all time values in Modelica are calculated using "seconds", one may make use of displayUnit (show a derived unit in plots) and nominal (scale values) attributes.

Can a user define his own displayUnit conversions as is possible in Dymola? (displayUnit.mos)

UPDATE:

I checked with WSM 4.3 and there displayUnit will have no effect upon plot outputs, as it seems. I also could not see that using nominal for scaling will work in that version of System Modeler.

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