Skip to content

Instantly share code, notes, and snippets.

@Beramos
Last active June 1, 2018 09:49
Show Gist options
  • Select an option

  • Save Beramos/56a584569c3ff820fe0890c359b435db to your computer and use it in GitHub Desktop.

Select an option

Save Beramos/56a584569c3ff820fe0890c359b435db to your computer and use it in GitHub Desktop.
OpenFOAM_programming_tricksNtips (OF4)

OpenFOAM tricks and Tips

This file documents what I'm learning in OpenFOAM.

Lists

When programming in vanilla c++ one would use std::list for lists. However OpenFOAM has it's own implementation of the List class

Syntax:

List<type> varName (size);

IOobjects

Example of initiating fields without reading in a dictionary

// Scalars //
volScalarField normalStress
(
    IOobject
    (
        "normalStress",
        mesh.time().timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::AUTO_WRITE
    ),
    mesh,
    dimensionedScalar
    (
        "normalStress",
        sqr(dimLength)/sqr(dimTime),
        0
    )
);

// Vectors //
volVectorField tractionVector
(
  IOobject
  (
      "tractionVector",
      mesh.time().timeName(),
      mesh,
      IOobject::NO_READ,
      IOobject::AUTO_WRITE
  ),
  mesh,
  dimensionedVector
  (
      "tractionVector",
      dimensionSet(0, 0, 0, 0, 0, 0 ,0),
      vector::zero
  )
);

Boundary fields

Often access is needed to the boundaries of the domain. If you want access to the boundary conditions you can use which are imposed on the cell faces at the boundary,

const fvPatchField<Type>& bf = fieldName.boundaryField()[patchID];

However, the boundaryField is directly coupled to the boundary conditions and is overwritten every time the boundary conditions are evaluated. Another type of boundary access are the internalFields at the specified boundary. These are the actual values stored in the cell centers of the mesh and are not part of the boundary conditions. These fields can be accessed as such,

const Field<Type>& ifB = fieldName.boundaryField()[patchID].patchInternalField()

Boundary conditions

How to Access dictionaries from boundary condition Source

Access uniformDimensionedFields uniformDimensionedFields are dimensionedfields with one value which can be written out. In the current fvPatchField class template this type is not declared. So in the header file of your boundary condition add

    #include "uniformDimensionedFields.H"

and in the private data declaration add

    uniformDimensionedVectorField nameObject_;

Next, one should include the following in the member initialiser list(1) of the fvPatchField constructor

nameObject_ 
    (
        IOobject
        (
            "filename",
            this->db().time().constant(),
            this->db(),
            IOobject::MUST_READ,
            IOobject::NO_WRITE,
            true
        )
    ),

Get the dictionary from the database

const dictionary& transportProperties = db().lookupObject<IOdictionary>
(
 "transportProperties"
);

Get subdictionary

dictionary mySubDict
(
 transportProperties.subDict("mySubDict")
);

Miscellaneous

Access scalar value

dimensionedScalar myScalar(mySubDict.lookup("myScalar"));

Access to surface normals

const vectorField& Sf = p.boundaryMesh().mesh().Sf();

Basic c++ understanding

Pointers and references

One of the first things to learn when new to c++ is in my opinion, pointers and references. When programming in OpenFOAM pointers and references are encountered on a regular basis. This website provides a concise summary of pointers and references in c++

Including code

In c++ #include "filename" is used to insert pieces of code. It is a copy-paste action and works like import in python

Templating

Often you will want your classes to be more generic and applicable for different types. E.g. when implementing a new boundary condition, you could need it to work on both scalarFields and vectorFields. For this you will use templating.

Some notes on templating: When calling a member function of a class template. You need to use .template to indicate that this is a templated function. Example of class member function call,

const dictionary& transportProperties = this->db().lookupObject<IOdictionary> // Reading transportProperties
    (
     "transportProperties"
    );

Example of class template member function call,

const dictionary& transportProperties = this->db().template lookupObject<IOdictionary> // Reading transportProperties
    (
     "transportProperties"
    );

If you wouldn't written '''.template''' the following compiler error would have been raised,

error: expected primary-expression before ‘>’ token

Working with gdb

The gdb debugger can be really useful when trying to debug your OpenFOAM application. It is a good way to sandbox around in the OpenFOAM application.

Some tips:

Printing objects in gdb often results in recursion which makes it very hard to read what you actually want to print. This can be disabled by using the following command:

set print static-members off

(1) In the definition of a constructor of a class, member initializer list specifies the initializers for direct and virtual base subobjects and non-static data members

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment