-
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 IBPSA.UsersGuide.Conventions. (This link will be replaced with a link to the IBPSA library when the first html version is posted.)
- Classes declared as
partial
and base classes that are not of interest to the user should be stored in a subdirectory calledBaseClasses
. Each other class, except for constants, must have an icon. - 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
classes in
IBPSA.Fluid.Interfaces
. - Use the full package names when instantiating a class.
- Models, functions and blocks must be implemented as
one model, function or block per file. An exception are the
IBPSA.Media
packages.
-
Declare all public parameters before protected ones.
-
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 but need to be verified by the user, provide a default value by using its start attribute. For example, for a heat exchanger, use
parameter Real eps(start=0.8, min=0, max=1, unit="1") "Heat exchanger effectiveness";
Do not use
parameter Real eps=0.8
as this can lead to errors that are difficult to detect if a modeller forgets to overwrite the default value of0.8
with the actual value. The model will simulate, but gives wrong results due to unsuited parameter values and there will be no warning. On the other hand, usingparameter Real eps(start=0.8)
will give a warning and hence users can assign better values. -
If a parameter value can be precomputed based on other parameters, set its value to this equation. For example,
parameter Medium.MassFlowRate m_flow_small(min=0) = 1E-4*m_flow_nominal ...
-
If a parameter assignment should not be changed by a user, use the
final
keyword.
-
-
For parameters and variables, provide values for the
min
andmax
attribute where applicable. Be aware, that these bounds are not enforced by the simulator. If themin
andmax
attribute are set, each violation of these bounds during the simulation may raise a warning.Simulators may allow to supress these warnings. In Dymola, violation of bounds can be checked using
Advanced.AssertAllInsideMinMax=true;
-
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 the
assert
function together with"In " + getInstanceName() + ":...
to check for invalid values of parameters or variables. For example, useassert(phi>=0, "In " + getInstanceName() + ": Relative humidity must not be negative.");
Note the use of
getInstanceName()
, which will write the instance name as part of the error message. Otherwise, JModelica will not write the instance name. -
Use either graphical modeling or textual code. When using graphical schematic modeling, do not add textual equations. For example, avoid the following, as on the graphical editor, the model looks appears to be singular:
model Avoid Modelica.Blocks.Continuous.Integrator integrator "Integrator" annotation (Placement(transformation(extent={{-10,-10},{10,10}}))); equation integrator.u = 1; end Avoid;
-
For computational efficiency, equations shall where possible be differentiable and have a continuous first derivative.
-
Avoid equations where the first derivative with respect to another variable is zero. 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. Note that this problem do not exist for functions that assign a value to a constant as these will be evaluated during the model translation. -
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 formIBPSA.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
Advanced.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
annotation. SeeIBPSA.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. SeeIBPSA.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 description string 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
IBPSA/Resources/Images/
that has the same name as the full package. For example, use</p> <p align="center"> <img alt="Image of ..." src="modelica://IBPSA/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://IBPSA.Fluid.Sensors.Density"> IBPSA.Fluid.Sensors.Density</a>.
-
Add a default component name, such as
annotation(defaultComponentName="senDen", ...
to objects that will be used as drag and drop elements, as this automatically assigns them this name.
-
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
IBPSA.UsersGuide
. -
Use the string
fixme
within development branches to mark passages that still need to be revised (e.g., to improve code or to fix bugs). Before merging a branch into the master, allfixme
strings must be removed. Within the master branch, nofixme
are allowed. -
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>Dynamics</h4> <p> Describe which states and dynamics are present in the model and which parameters may be used to influence them. This need not be added in partial classes. </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>
-
Always use lower case html tags.
- Implement at least one unit test for each model, block and function,
and run the unit tests.
Unit tests should cover all branches of
if-then
constructs. See unit test implementation. - Use
IBPSA.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.