modelica / ModelicaSpecification

Specification of the Modelica Language
https://specification.modelica.org
Creative Commons Attribution Share Alike 4.0 International
96 stars 41 forks source link

Proper way to deal with simulation over long time spans #2937

Open casella opened 3 years ago

casella commented 3 years ago

With @GianniFerretti, we are considering models that have typical time constants of days, such as epidemiological models or weeks, such as bioreactor models.

When developing hand-made code for these modes, people normally use days or weeks as unit of time, and also as a base unit for all coefficients involving time (e.g. time constants, decay constants, kinetics constants, etc.).

The standard approach in Modelica is to use SI units throughout. In fact, Section 3.6.7 of the specification implicitly defines time with final unit = "s", so this cannot be changed even if one wanted to, contrary to other process variables, were the units could (in principle) also be declared to be non-SI.

The question is: what is the proper way to write libraries that have time constants of days or weeks?

Are users expected to rely on tools to perform the necessary unit conversion for parameter input and for output display? If so, how to set the default display unit for time, say, time(displayUnit = "d"), since time is an implicitly defined, built-in variable?

henrikt-ma commented 3 years ago

Users are welcome to use System Modeler, where they are given the choice of time display unit. :)

model ExponentialDecayInHours
  Real x(start = 1.0, fixed = true);
  parameter Real k(unit = "1/s", displayUnit = "1/h") = 0.000138888888888889; /* In displayUnit: 0.5 1/h */
equation
  der(x) = -k * x;
  annotation(
    experiment(StopTime = 7200, __Wolfram_DisplayTimeUnit = "h"),
    Documentation(figures = {Figure(title = "Hour time scale", identifier = "0e216", preferred = true, plots = {Plot(curves = {Curve(y = x)})}, caption = "Exponential decay with rate %{k}.  Note that time axis is in hours, not seconds.")})
  );
end ExponentialDecayInHours;
ExpDecayFigure

Interest in standardization, anyone?

Regarding changing unit to a non-SI unit (or unit with prefix), doing this in a reliable way requires proper unit checking, or you are doomed to mix units in incorrect ways, causing incorrect results. I believe your, @casella, efforts are needed here to make progress! When should we make a new attempt at units of literals?

gkurzbach commented 3 years ago

In SimulationX you can do the same thing. There, the values of the unit and displayUnit attribute and their factors are bound to a certain quantity attribute value using a database. The value of the displayUnit attribute is used as default for the unit of the diagram axes. You can choose between the different units belonging to the quantity. It doesn't matter whether they are SI-units or not.

HansOlsson commented 3 years ago

With @GianniFerretti, we are considering models that have typical time constants of days, such as epidemiological models or weeks, such as bioreactor models.

When developing hand-made code for these modes, people normally use days or weeks as unit of time, and also as a base unit for all coefficients involving time (e.g. time constants, decay constants, kinetics constants, etc.).

The standard approach in Modelica is to use SI units throughout. In fact, Section 3.6.7 of the specification implicitly defines time with final unit = "s", so this cannot be changed even if one wanted to, contrary to other process variables, were the units could (in principle) also be declared to be non-SI.

The question is: what is the proper way to write libraries that have time constants of days or weeks?

Use displayUnit for that; 'd' for days is acceptable non-SI unit in the SI-standard (and not to be confused with the prefix d). Note that 'w' for weeks isn't recognized, but the Modelica standard might add that (not to be confused with W for Watt).

For longer times than a week there are so many slightly different variants that it becomes messy; and it makes more sense to align the time-axis with an actual calendar which is a different topic; specifically that is #2245

Are users expected to rely on tools to perform the necessary unit conversion for parameter input and for output display?

That's the entire point about displayUnit, since it implies that there are no conversions in the actual formulas written by users - which reduces the risk of severe errors.

If so, how to set the default display unit for time, say, time(displayUnit = "d"), since time is an implicitly defined, built-in variable?

Currently that is done for each tool (and, yes, you can of course do it in Dymola as well). We might standarize something for it for the next release.

The figure-annotations added in 3.5 should support setting unit for the axis in plots, but it seems that is currently not as automatic as desired in some tools.