Skip to content

OpenFOAM setup (fluid)

Gerasimos Chourdakis edited this page Jul 15, 2020 · 18 revisions

OpenFOAM reads several configuration files, which are included in a case directory. In our tutorial, for the Fluid participant, we see the following files:

  • 0/: State of the domain at time=0. In other words: the initial and boundary conditions.
    • T: Temperature field
    • U: Velocity
    • alphat: Turbulent thermal diffusivity
    • epsilon, k: Parameters of the k-epsilon turbulence model (disabled by default)
    • nut: Turbulent viscosity
    • p and p_rgh: Pressure
  • constant/: Model properties
    • g: Gravity
    • thermophysicalProperties: Properties of the thermophysical model (thermodynamics, transport, etc.)
    • turbulenceProperties: Properties of the turbulence model. By default it is set to laminar flow.
  • system/: Solver properties
    • blockMeshDict: Mesh properties. The mesh is produced with the command blockMesh.
    • controlDict: Time step length, end time, output settings etc
    • fvSchemes: Finite Volume Schemes - the numerical schemes
    • fvSolution: Finite Volume Solution - the numerical solvers' parameters
    • preciceDict: Our adapter's configuration file
  • Fluid.foam: An empty file that serves as a reference to ParaView

Let's see the most relevant files in more details.

Mesh generation

The mesh for this case is defined in the system/blockMeshDict file. This is one of the ways to define a mesh in OpenFOAM, which does not require a geometry file.

In this file, the section vertices( ... ) specifies geometry points in the form (x y z), where the values are in meters (unless the ration convertToMeters is different than 1). In the blocks( ... ) sections, the vertices are used to create blocks:

blocks
(
    hex (12 0 3 13 15 4 7 14) (81 41 1) simpleGrading (.2 15 1)
    hex (0 1 2 3 4 5 6 7) (161 41 1) simpleGrading (5 15 1)
    hex (1 8 9 2 5 10 11 6) (51 41 1) simpleGrading (1 15 1)
);
  • Each line corresponds to a block.
  • The hex means hexahedral cells.
  • The first set of numbers defines the vertices used for the block and the numbers correspond to the order they were defined in the vertices. When defining blocks, the order of the nodes in each block needs to follow the "right-hand rule".
  • The second set of numbers is the cells per (x y z) direction. Here, we only use one cell in the z (depth) direction.
  • The rest of the line defines the cell grading or mesh stretching. Here, the method simpleGrading is used. The set of numbers define the ratio of the size of the last cell in each direction to the first one.

In this file we also define the boundaries of the geometry in the boundary( ... ) section. For example:

interface
{
    type wall;
    faces
    (
        (4 0 1 5)
    );
}

defines a wall boundary, named interface, that consists of one face. These numbers refer again to the geometry points and need to follow the "right-hand rule". We are going to use this boundary as the coupling interface.

In order to generate the mesh, we run blockMesh. This is done in the run scripts. You may also check the quality of the mesh using checkMesh. The result mesh looks like this:

Mesh overview

Boundary conditions

The boundary conditions are defined in the 0/ directory, in a different file for each field. Note that, if you started the simulation from a later time (e.g. t=500), then you would define them in the 500/ directory.

Let's see what is defined in the 0/T for the temperature, which participates in the coupling:

dimensions      [ 0 0 0 1 0 0 0 ];

internalField   uniform 300;

boundaryField
{
    interface
    {
        type            fixedGradient;
        gradient        uniform 0;
    }
    inlet
    {
        type            fixedValue;
        value           $internalField;
    }
    outlet
    {
        type            zeroGradient;
    }
...
    defaultFaces
    {
        type            empty;
    }
}

The dimensions defines the dimensions of the field (their exponents), in the form [kg m s K mol A cd] for the SI unit system. OpenFOAM also supports other unit systems. Note that most of the fields that OpenFOAM uses are dimensioned and their conformity is checked during computations.

The internalField specifies the values at the cell centers. In this case, we assign the same (uniform) value to all the cells (300 K).

The section boundaryField{ ... } specifies the boundary conditions. Here we list the following types:

  • The interface is set to type fixedGradient. This is done because we are going to read heat fluxes on this boundary. See the adapter's configuration page for more. The gradient value is overwritten by the adapter.
  • The inlet (defined as the left boundary in the blockMeshDict) is set to a Dirichlet boundary condition. The temperature is set to be the same as the value set in the internalField.
  • In the outlet we specify that the temperature does not change anymore. This is equivalent to writing fixedGradient with gradient uniform 0.
  • The defaultFaces covers any faces that have not been defined here. In this case, this matches the front and back boundaries. We are assuming a 2D problem, so we assign the z-boundaries to empty.

Model properties

It is important to remember that OpenFOAM is not one solver, but rather a collection of solvers, which vary in what models they support. In this tutorial, we use the solver buoyantPimpleFoam for the fluid, which supports the full spectrum of thermophysical and turbulence models.

In the constant/thermophysicalProperties file, we are mainly interested in the values of Cp (specific heat), mu (dynamic viscosity) and Pr (Prandtl number). You may recall for the conductivity, the Prandtl number and the dynamic viscosity:

Equations for k, Pr, mu

From these, we see that we only need these three properties to calculate the conductivity:

Equation for k, using only Pr, mu, and cp

In the constant/turbulenceProperties, we see that turbulence is disabled. We can enable it by setting simulationType to RAS. The respective parameters are set in the RAS dictionary. Other turbulence models are also supported.

Control of the simulation

In the system/controlDict file, we can configure the start, the end, the time step and the write times of the simulation, along with other parameters.

startFrom       startTime;

startTime       0;

stopAt          endTime;

endTime         1;

deltaT          0.01;

Here we configure that the simulation should start from time=0 (another option would be startFrom latestTime) and end at time=1. Since this is a transient solver, this means that the simulated time is 1 second. The deltaT is the time step. In this case, the time step length is fixed. If you want a dynamic timestep, look for the keyword "adjustTimeStep".

writeControl    runTime;

writeInterval   0.2;

purgeWrite      0;

writeFormat     ascii;

writePrecision  6;

writeCompression off;

Here we define the write parameters:

  • We ask the solver to output every 0.2 seconds of simulated time.
  • If purgeWrite was other than 0, it would only keep the specified number of the latest time directories.
  • The output should be in ascii (not binary) files, with 6 digits of precision. The result files should not be compressed.
functions
{
    preCICE_Adapter
    {
        type preciceAdapterFunctionObject;
        libs ("libpreciceAdapterFunctionObject.so");
    }
}

Here we specify that the solver should load the adapter.

Please refer to the OpenFOAM User Guide for more information.

The adapter's configuration file

The preciceDict file needs to be in the system/ directory. In this case, it contains the following:

FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "system";
    object      preciceDict;
}

preciceConfig "precice-config.xml";

participant Fluid;

modules (CHT);

interfaces
{
  Interface1
  {
    mesh              Fluid-Mesh;
    patches           (interface);
    
    readData
    (
      Heat-Flux
    );
    
    writeData
    (
      Temperature
    );
  };
};

The preCICE configuration file is named precice-config.xml (see precice-config.xml) and is located in the parent directory, where both simulations are started from. The contents of the adapter's configuration file need to be consistent with those of the preCICE configuration file. This file is described in the preCICE wiki.

In this case, we only have one interface. In this, we use the mesh Fluid-Mesh (defined in the precice-config.xml). The only OpenFOAM boundary patch that takes part in this interface is named interface (defined in the system/blockMeshDict).

We want to perform a Dirichlet-Neumann coupling. We specify that the Fluid participant should write temperatures and it should read heat fluxes. Therefore:

  • We set writeData(Temperature); and readData(Heat-Flux); for the Fluid.
  • We set type fixedGradient for the temperature at the interface for the Fluid.
  • We set writeData(Heat-Flux); and readData(Temperature); for the Solid.
  • We set type fixedValue for the temperature at the interface for the Solid.

Read more at the adapter's configuration page.