We are happy to incorporate content from volunteers!!
Coding Patterns
Precision
OpenFOAM supports compile-time selection of its usual integer elements
(label
) and its usual floating-point elements (scalar
).
This choice is defined by the environment variables:
-
WM_LABEL_SIZE
: Label size in bits (32 | 64) -
WM_PRECISION_OPTION
: Floating-point precision (DP | SP | SPDP)
When writing code, some additional care must be taken to ensure that
the resulting code will compile properly for different values of
label
and scalar
. A simple, but counter-intuitive example:
scalar foo = ...;
if (equal(foo, 0.0))
{
}
The code looks good, the programmer even clearly documented that it is
a floating-point comparison by using 0.0
. Unfortunately, when
compiled with single precision, this is how the comparison actually
appears:
if (equal(<float>, <double>))
{
}
The default compiled type for 0.0
will be double
.
For zero, the easiest way is to write it as an integer and let the
compiler promote to the correct type:
if (equal(foo, 0))
{
}
For non-zero values, use a functional cast instead:
if (equal(foo, scalar(1.5)))
{
}
Setup for testing
To ensure that developed code compiles properly across all ranges of precision, the following combination is recommended:
export WM_LABEL_SIZE=64
export WM_PRECISION_OPTION=SPDP
If your code compiles flawlessly with this, you have done a good job!
Dictionary input
When handling dictionary input, type deduction may need additional assistance. This can written different ways:
xyz = dict.lookupOrDefault<scalar>("name", 1.5); // Preferred form
xyz = dict.lookupOrDefault("name", scalar(1.5)); // ... not quite so nice
The first form is preferrable since the templated type is more evident and the value itself is easier to find.
Anti-pattern: Over-specifying bool
input.
A reasonable amount of legacy code will still have code like the
following:
dict.lookupOrDefault<bool>("name", true);
dict.lookupOrDefault<Switch>("name", true);
Most code does not actually require use of Switch
instead of bool
.
The sole remaining purpose for Switch
is to retain the named values
(yes
, no
, on
, off
...) for output purposes. For input
purposes, both Switch
and bool
accept exactly the same input.
Unless the code actually requires Switch
, simply write
dict.lookupOrDefault("name", true);
there is no type ambiguity for the compiler.
Copyright (C) 2019-2020 OpenCFD Ltd.