-
Notifications
You must be signed in to change notification settings - Fork 0
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 Buildings.UsersGuide.Conventions.
- Partial classes and base classes that are not of interest to the user should be stored in a subdirectory called
BaseClasses. - Do not copy sections of code. Use object inheritance.
- Implement components of fluid flow systems by extending the partial classes in
Buildings.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
finalkeyword. - For parameters and variables, provide values for the
minandmaxattribute where applicable. - For any variable or parameter that may need to be solved numerically, provide a value for the
startandnominalattribute. - Use types from
Modelica.SIunitswhere possible.
- Avoid events where possible.
- Only divide by quantities that cannot take on zero. For example, if
xmay 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
assertfunction to check for invalid values of parameters or variables. For example, use
assert(phi>=0, "Relative humidity must not be negative.")
1. Use either graphical modeling or textual code. Avoid using both within one class.
1. For computational efficiency, equations shall were possible be differentiable and have a continuous first derivative.
1. 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, and ```x = f(y)```, avoid ```y = 0``` for ```x<0``` and ```y=x^2``` otherwise. The reason is that if a simulator tries to solve ```0=f(x)```, then any value of ```x <= 0``` is a solution, which can cause instability in the solver.
1. 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 rate ```V_flow``` is zero, one may be inclined to use a construct of the form
dp = smooth(1, if V_flow == 0 then 0 else f(V_flow));
The problem with this formulation is that for ```V_flow=0```, the derivative is ```dp/dV_flow = 0```. However, the limit ```dp/dV_flow```, as ```|V_flow|``` tends to zero, may be non-zero. Hence, the first derivative has a discontinuity at ```V_flow=0```, which can cause a solver to fail to solve the equation because the ```smooth``` statement declared that the first derivative exists and is continuous.
1. 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 form ```Buildings.Utilities.Math``` for this approximation.
1. 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](Function-Derivatives).
## Functions
1. Use the ```smoothOrder``` annotation if a function is differentiable.
1. If a function is invertible, also implement its inverse function and use the ```inverse``` attribute. See ```Buildings.Fluid.BaseClasses.FlowModels``` for an example.
1. If a model allows a linearized implementation of an equation, then implement the linearized equation in an ```equation``` section and not in the ```algorithm``` section of a ```function```. Otherwise, a symbolic processor cannot invert the linear equation, which can lead to coupled systems of equations. See ```Buildings.Fluid.BaseClasses.FlowModels``` for an example.
## Documentation
1. Add a one-line comment to all parameters and variables, including protected ones.
1. Group similar variables using the ```group``` and ```tab``` annotation. For example, use
parameter 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"));
1. Add model documentation to the ```info``` section. To document equations, use the format
```html
<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 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 Buildings/Resources/Images/ that has the same name as the full package. For example, use
...
</p>
<p align="center">
<img alt="Image of ..." src="modelica://Buildings/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 the png file. svg files can be created with http://inkscape.org/, which works on any operating system. See for example the file in Resources/Images/Examples/Tutorial/SpaceCooling/schematics.svg.
- Add author information to the
revisionsection. - Run a spell check.
- Start headings with
<h4>. - Add hyperlinks to other models using their full name. For example, use
See Buildings.Fluid.Sensors.Density.
1. To refer to names of parameters or variables in the documentation and revision sections, use the syntax ```<code>...</code>```. Do not use ```<tt>...</tt>```.
1. Add a default component name, such as ```annotation(defaultComponentName="senDen", ...```
1. For complex packages, provide a User's Guide, and reference the User's Guide in ```Buildings.UsersGuide```.
1. 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.
## Unit Tests
1. Implement at least one unit test for each class and run the unit tests. See [unit test implementation](Unit-Tests).
1. Use ```Buildings.Utilities.Diagnostics.AssertEquality``` to cause a test to fail if the result is incorrect.
1. Ensure that no unit test requires a numerical Jacobian. If a numerical Jacobian is needed, improve the model.