-
Notifications
You must be signed in to change notification settings - Fork 84
Style Guide
This page provides a check list that should be used when contributing a new class (model, block, function etc.) to the library.
- Follow the conventions in Annex60.UsersGuide.Conventions. (This link will be replaced with a link to the Annex library when the first html version is posted.)
- Partial classes and base classes that are not of interest to the user
should be stored in a subdirectory called
BaseClasses
. - Examples and validation models should be in directories such as
Valves.Examples
andValves.Validations
. A script for the regression tests must be added as described below. - Do not copy sections of code. Use object inheritance.
- Implement components of fluid flow systems by extending the partial
classes in
Annex60.Fluid.Interfaces
. - Use the full package names when instantiating a class.
-
Declare variables and final parameters that are not of interest to users as protected.
-
Set default parameter values as follows:
-
If a parameter value can range over a large region, do not provide a default value. Examples are nominal mass flow rates.
-
If a parameter value does not vary significantly, provide a default by using its start attribute. For example, use
parameter Real eps(start=0.8, min=0, max=1, unit="1") "Heat exchanger effectiveness";
-
If a parameter value can be precomputed based on other parameters, set its default value to this equation. For example,
parameter Medium.MassFlowRate m_flow_small(min=0) = 1E-4*m_flow_nominal ...
-
If a parameter value should not be changed by a user, use the
final
keyword.
-
-
For parameters and variables, provide values for the
min
andmax
attribute where applicable. -
For any variable or parameter that may need to be solved numerically, provide a value for the
start
andnominal
attribute. -
Use types from
Modelica.SIunits
where possible.
-
Avoid events where possible.
-
Only divide by quantities that cannot take on zero. For example, if
x
may take on zero, usey=x
, not1=y/x
, as the second version indicates to a simulator that it is save to divide byx
. -
Use SI units in all equations.
-
Use the
assert
function to check for invalid values of parameters or variables. For example, useassert(phi>=0, "Relative humidity must not be negative.")
-
Use either graphical modeling or textual code. Avoid using both within one class.
-
For computational efficiency, equations shall were possible be differentiable and have a continuous first derivative.
-
Avoid equations where the first derivative with respect to another variable is zero, except at a single point. For example, if
x, y
are variables, andx = f(y)
, avoidy = 0
forx<0
andy=x^2
otherwise. The reason is that if a simulator tries to solve0=f(x)
, then any value ofx <= 0
is a solution, which can cause instability in the solver. -
Do not replace an equation by a constant for a single value, unless the derivative of the original equation is zero for this value. For example, if computing a pressure drop
dp
may involve computing a long equation, but one knows that the result is always zero if the volume flow rateV_flow
is zero, one may be inclined to use a construct of the formdp = smooth(1, if V_flow == 0 then 0 else f(V_flow));
The problem with this formulation is that forV_flow=0
, the derivative isdp/dV_flow = 0
. However, the limitdp/dV_flow
, as|V_flow|
tends to zero, may be non-zero. Hence, the first derivative has a discontinuity atV_flow=0
, which can cause a solver to fail to solve the equation because thesmooth
statement declared that the first derivative exists and is continuous. -
Make sure that the derivatives of equations are bounded on compact sets. For example, instead of using
y=sign(x) * sqrt(abs(x))
, approximate the equation with a differentiable function that has a finite derivative near zero. Use functions formAnnex60.Utilities.Math
for this approximation. -
Whenever possible, a Modelica tool should not have to do numerical differentiation. For example, in Dymola, if your model translation log shows
Number of numerical Jacobians: 1
(or any number other than zero), then enter on the command line
Hidden.PrintFailureToDifferentiate = true;
Next, translate the model again to see what functions cannot be differentiated symbolically. Then, implement symbolic derivatives for this function. See implementation of function derivatives.
- Use the
smoothOrder
annotation if a function is differentiable. - If a function is invertible, also implement its inverse function and
use the
inverse
attribute. SeeAnnex60.Fluid.BaseClasses.FlowModels
for an example. - If a model allows a linearized implementation of an equation, then
implement the linearized equation in an
equation
section and not in thealgorithm
section of afunction
. Otherwise, a symbolic processor cannot invert the linear equation, which can lead to coupled systems of equations. SeeAnnex60.Fluid.BaseClasses.FlowModels
for an example.
-
Packages are first sorted alphabetically by the function
_sort_package_order
. That function is part of BuildingsPy and is called byimport buildingspy.development.refactor as r r.write_package_order(".", True)
-
After alphabetical sorting, the following packages, if they exist, are moved to the front:
Tutorial UsersGuide
and the following packages, if they exist, are moved to the end:
Data Types Examples Validation Benchmarks Experimental Interfaces BaseClasses Internal Obsolete
The remaining classes are ordered as follows and inserted between the above list: First, models, blocks and records are listed, then functions, and then packages.
-
Add a one-line comment to all parameters and variables, including protected ones.
-
Group similar variables using the
group
andtab
annotation. For example, useparameter Modelica.SIunits.Time tau = 60 "Time constant at nominal flow" annotation (Dialog(group="Nominal condition"));
or use
parameter Types.Dynamics substanceDynamics=energyDynamics "Formulation of substance balance" annotation(Evaluate=true, Dialog(tab = "Assumptions", group="Dynamics"));
-
Add model documentation to the
info
section. To document equations, use the format<p> The polynomial has the form </p> <p align="center" style="font-style:italic;"> y = a<sub>1</sub> + a<sub>2</sub> x + a<sub>3</sub> x<sup>2</sup> + ..., </p> <p> where <i>a<sub>1</sub></i> is ...
To denote time derivatives, such as for mass flow rate, use <code>ṁ</code>.
To refer to parameters of the model, use the format
To linearize the equation, set <code>linearize=true</code>.
To format tables, use
<p> <table summary="summary" border="1" cellspacing="0" cellpadding="2" style="border-collapse:collapse;"> <tr><th>Header 1</th> <th>Header 2</th> </tr> <tr><td>Data 1</td> <td>Data 2</td> </tr> </table> </p>
To include figures, place the figure into a directory in
Annex60/Resources/Images/
that has the same name as the full package. For example, use</p> <p align="center"> <img alt="Image of ..." src="modelica://Annex60/Resources/Images/Fluid/FixedResistances/FixedResistanceDpM.png"/> </p> <p>
To create new figures, put the source file for the figure, preferably in
svg
format, in the same directory as thepng
file.svg
files can be created with http://inkscape.org/, which works on any operating system. See for example the file inResources/Images/Examples/Tutorial/SpaceCooling/schematics.svg
. -
Add author information to the
revision
section. -
Run a spell check.
-
Start headings with
<h4>
. -
Add hyperlinks to other models using their full name. For example, use
See <a href="modelica://Annex60.Fluid.Sensors.Density"> Annex60.Fluid.Sensors.Density</a>.
-
To refer to names of parameters or variables in the documentation and revision sections, use the syntax
<code>...</code>
. Do not use<tt>...</tt>
. -
Add a default component name, such as
annotation(defaultComponentName="senDen", ...
-
Keep the line length to no more than around 80 characters.
-
For complex packages, provide a User's Guide, and reference the User's Guide in
Annex60.UsersGuide
. -
If anything still needs to be revised, add the string
fixme
with a descriptive comment. Prior to a library release, the library will be searched for this string to avoid releasing unfinished code. -
A suggested template for the documentation of classes is below. Except for the short introduction, the sections are optional.
<p> A short introduction. </p> <h4>Main equations</h4> <p> xxx </p> <h4>Assumption and limitations</h4> <p> xxx </p> <h4>Typical use and important parameters</h4> <p> xxx </p> <h4>Options</h4> <p> xxx </p> <h4>Validation</h4> <p> Describe whether the validation was done using analytical validation, comparative model validation or empirical validation. </p> <h4>Implementation</h4> <p> xxx </p> <h4>References</h4> <p> xxx </p>
- Implement at least one unit test for each class and run the unit tests. See unit test implementation.
- Use
Annex60.Utilities.Diagnostics.AssertEquality
to cause a test to fail if the result is incorrect. - Ensure that no unit test requires a numerical Jacobian. If a numerical Jacobian is needed, improve the model.