Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
openfoam
openfoam
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 331
    • Issues 331
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 6
    • Merge Requests 6
  • Operations
    • Operations
    • Incidents
  • Analytics
    • Analytics
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
  • Development
  • openfoamopenfoam
  • Wiki
    • Coding
    • Patterns
  • precision

Last edited by Mark Olesen Jul 09, 2020
Page history

precision

home code

We are happy to incorporate content from volunteers!!

Coding Patterns

  • Coding Patterns
  • Precision
    • Setup for testing
    • Dictionary input

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.

Clone repository
  • Repository migration
  • Submitting issues
  • building
  • building
    • cross compile mingw
  • coding
    • git workflow
    • patterns
      • HashTable
      • dictionary
      • memory
      • patterns
      • precision
      • selectors
      • strings
    • style
      • style
  • Home
  • icons
    • info
View All Pages