# Unit Checking in System Modeler and making use of unit attributes

Posted 5 months ago
861 Views
|
7 Replies
|
6 Total Likes
|
 Unit checking (or dimensional analysis) is an important means of model verification:Units of Measurement in a Modelica CompilerQuestion 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 =  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 = ) 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)
7 Replies
Sort By:
Posted 5 months ago
 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.
Posted 5 months ago
 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: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.yto get 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 5 months ago
Posted 5 months ago
 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)?
Posted 5 months ago
 1) No there isn't any support for unit checking in system modeler, I suppose you could roll your own using Wolfram Language since you can extract the equations and the unit information.2) If this was allowed (changing the unit dynamically) how would you do the important static unit checking?SystemModeler has displayUnit support in plots since version 4.3, try for example model DisplayUnitTest extends IntroductoryExamples.MultiDomain.DCMotor(EMF1.i.displayUnit = "mA"); end DisplayUnitTest; If you plot EMF1.i it will be in mA instead of A. And in the upcoming version you will be able to add your own unit conversions to the list of known units.But I guess what you want/need in addition to that is "displayUnit" support for the builtin time variable. That is unfortunately not available yet, but as you point out really handy if not a requirement for certain fields.SystemModeler does support the nominal attribute, but that is used for scaling calculations to improve numeric robustness and not something you see directly as a user.
 You can apply units on a reusable unitless library in different waysModify 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.