Challenge

Project 1- Creating your own OpenFOAM solver

Creating your own OpenFOAM solver

Development of this case setup is for a scalar transport simulation in a lid-driven cavity flow using your custom solver "myScalarFoam".

The simulation is set up as a quasi-2D case (one cell thick in the z-direction) with a moving top wall. A scalar quantity is initialized with a "hot spot" in a spherical region, and the simulation will track how this scalar is transported by the flow field over time.ScalarFoam: A Scalar Transport Solver Based on OpenFOAM

Abstract

This report presents the development of a new OpenFOAM solver called scalarFoam for simulating scalar transport in fluid flows. The solver was created by modifying the existing icoFoam solver to solve the scalar transport equation: ∂s/∂t + ∇·(us) = 0, where s is the scalar quantity transported by velocity u. The implementation process involved modifying the source code of icoFoam, compiling the new solver, and testing it on a modified cavity case. This report documents the development process, code modifications, case setup, and results, providing insights into the numerical implementation of scalar transport in OpenFOAM.

1. Introduction

OpenFOAM (Open Field Operation and Manipulation) is an open-source C++ library for computational fluid dynamics (CFD). It provides a flexible framework for developing custom solvers for various fluid flow problems. In this project, a new solver was developed to simulate scalar transport in incompressible flows.

The scalar transport equation describes how a passive scalar quantity (such as temperature, concentration, or salinity) is transported by a fluid flow without affecting the flow itself. The governing equation is:

∂t/∂s​+∇⋅(us)=0

Where:

  • s is the scalar quantity being transported

  • u is the velocity field of the fluid

  • t is time

This project involved:

  1. Modifying the existing icoFoam solver to create scalarFoam

  2. Setting up and running a test case based on the cavity tutorial

  3. Analyzing the results of scalar transport simulation


2. Solver Development

The development of scalarFoam involved modifying several files from the icoFoam solver. The key modifications are described below.

2.1 Main Solver File (myScalarFoam.C)

The main solver file was modified to solve the scalar transport equation instead of the momentum equation. The major changes included:

#include "fvCFD.H"

#include "pisoControl.H"


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


int main(int argc, char *argv[])

{

argList::addNote

(

"Transient solver for incompressible, laminar flow"

" of Newtonian fluids."

);


#include "postProcess.H"


#include "addCheckCaseOptions.H"

#include "setRootCaseLists.H"

#include "createTime.H"

#include "createMesh.H"


pisoControl piso(mesh);


#include "createFields.H"

#include "initContinuityErrs.H"


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


Info<< "\nStarting time loop\n" << endl;


while (runTime.loop())

{

Info<< "Time = " << runTime.timeName() << nl << endl;


#include "CourantNo.H"


// Momentum predictor


fvVectorMatrix UEqn

(

fvm::ddt(U)

+ fvm::div(phi, U)

- fvm::laplacian(nu, U)

);


if (piso.momentumPredictor())

{

solve(UEqn == -fvc::grad(p));

}


// --- PISO loop

while (piso.correct())

{

volScalarField rAU(1.0/UEqn.A());

volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p));

surfaceScalarField phiHbyA

(

"phiHbyA",

fvc::flux(HbyA)

+ fvc::interpolate(rAU)*fvc::ddtCorr(U, phi)

);


adjustPhi(phiHbyA, U, p);


// Update the pressure BCs to ensure flux consistency

constrainPressure(p, U, phiHbyA, rAU);


// Non-orthogonal pressure corrector loop

while (piso.correctNonOrthogonal())

{

// Pressure corrector


fvScalarMatrix pEqn

(

fvm::laplacian(rAU, p) == fvc::div(phiHbyA)

);


pEqn.setReference(pRefCell, pRefValue);


pEqn.solve(p.select(piso.finalInnerIter()));


if (piso.finalNonOrthogonalIter())

{

phi = phiHbyA - pEqn.flux();

}

}


#include "continuityErrs.H"


U = HbyA - rAU*fvc::grad(p);

U.correctBoundaryConditions();

}

fvScalarMatrix sEqn

(

fvm::ddt(s)

+fvm::div(phi,s)

);

sEqn.solve();

s.correctBoundaryConditions();


runTime.write();


runTime.printExecutionTime(Info);

}


Info<< "End\n" << endl;


return 0;

}


The main change was the inclusion of "sEqn.H" instead of the PISO algorithm files used in icoFoam.

2.2 Create Fields File (createFields.H)

The createFields.H file was modified to include the definition of the scalar field s:

Info<< "Reading transportProperties\n" << endl;


IOdictionary transportProperties

(

IOobject

(

"transportProperties",

runTime.constant(),

mesh,

IOobject::MUST_READ_IF_MODIFIED,

IOobject::NO_WRITE

)

);


dimensionedScalar nu

(

"nu",

dimViscosity,

transportProperties

);


Info<< "Reading field p\n" << endl;

volScalarField p

(

IOobject

(

"p",

runTime.timeName(),

mesh,

IOobject::MUST_READ,

IOobject::AUTO_WRITE

),

mesh

);



Info<< "Reading field U\n" << endl;

volVectorField U

(

IOobject

(

"U",

runTime.timeName(),

mesh,

IOobject::MUST_READ,

IOobject::AUTO_WRITE

),

mesh

);


Info<< "Reading field s\n" << endl;


volScalarField s

(

IOobject

(

"s",

runTime.timeName(),

mesh,

IOobject::MUST_READ,

IOobject::AUTO_WRITE

),

mesh

);




#include "createPhi.H"



label pRefCell = 0;

scalar pRefValue = 0.0;

setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue);

mesh.setFluxRequired(p.name());



The key addition is the definition of the scalar field s, which replaced the pressure field p from the original icoFoam solver.

2.3 Scalar Equation File (sEqn.H)

A new file called sEqn.H was created to implement the scalar transport equation:

// Solve the scalar transport equation

fvScalarMatrix sEqn

(

fvm::ddt(s)

+ fvm::div(phi, s)

);


sEqn.solve();


This replaces the momentum and pressure correction equations from icoFoam with a simple scalar transport equation.

2.4 Make Files

The Make/files file was modified to compile the new solver:

scalarFoam.C


EXE = $(FOAM_USER_APPBIN)/scalarFoam


This specifies that the compiled executable should be named scalarFoam and placed in the user's applications bin directory.

The Make/options file remained largely unchanged from icoFoam:

EXE_INC = \

-I$(LIB_SRC)/finiteVolume/lnInclude \

-I$(LIB_SRC)/meshTools/lnInclude


EXE_LIBS = \

-lfiniteVolume \

-lmeshTools








3. Test Case Setup

To validate the scalarFoam solver, a test case was set up based on the standard cavity tutorial case for icoFoam.

3.1 Case Directory Structure

The directory structure for the test case was created as follows:

scalarCavity/

├── 0/

│ ├── s

│ └── U

│ └── P

├── constant/

│ ├── transportProperties

│ └── polyMesh/

├── system/

│ ├── controlDict

│ ├── fvSchemes

│ └── fvSolution

3.2 Initial Conditions

The initial conditions for the scalar field s were specified in the 0/s file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2106 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class volScalarField;

location "0";

object s;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


dimensions [0 0 0 0 0 0 0];


internalField uniform 300;


boundaryField

{

movingWall

{

type zeroGradient;

}


fixedWalls

{

type zeroGradient;

}


frontAndBack

{

type empty;

}

}


The initial conditions for the scalar field s were specified in the 0/P file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class volScalarField;

location "0";

object p;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions [0 2 -2 0 0 0 0];

internalField uniform 0;

boundaryField

{

movingWall

{

type zeroGradient;

}

fixedWalls

{

type zeroGradient;

}

frontAndBack

{

type empty;

}

}

// ************************************************************************* //


The initial conditions for the scalar field s were specified in the 0/U file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class volVectorField;

object U;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions [0 1 -1 0 0 0 0];

internalField uniform (0 0 0);

boundaryField

{

movingWall

{

type fixedValue;

value uniform (1 0 0);

}

fixedWalls

{

type noSlip;

}

frontAndBack

{

type empty;

}

}

// ************************************************************************* //


3.3 Constant Directory

The transportProperties:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

//location "constant"

object transportProperties;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


nu 0.001;



// ************************************************************************* //


3.4 Numerical Schemes (system)


The numerical schemes were specified in the system/blockMeshDict file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

object blockMeshDict;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


scale 0.1;


vertices

(

(0 0 0)

(1 0 0)

(1 1 0)

(0 1 0)

(0 0 0.5)

(1 0 0.5)

(1 1 0.5)

(0 1 0.5)

);


blocks

(

hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1)

);


edges

(

);


boundary

(

movingWall

{

type wall;

faces

(

(3 7 6 2)

);

}

fixedWalls

{

type wall;

faces

(

(0 4 7 3)

(2 6 5 1)

(1 5 4 0)

);

}

frontAndBack

{

type empty;

faces

(

(0 3 2 1)

(4 5 6 7)

);

}

);

mergePatchPairs

(

);


// ************************************************************************* //

This OpenFOAM configuration file (blockMeshDict) defines the mesh geometry for a simplified 3D cavity flow simulation. Key components include:

  1. Scale Factor:

    • All dimensions are scaled by a factor of 0.1


  1. Vertex Definitions:

    • Eight vertices define a rectangular box with:

      • Base dimensions: 1×1 units in the x-y plane

      • Height: 0.5 units in the z-direction

    • After scaling, the actual dimensions will be 0.1×0.1×0.05 units

  2. Block Definition:

    • A single hexahedral block using all eight vertices

    • Mesh resolution: 20×20×1 cells (effectively a 2D simulation with one cell in z-direction)

    • Simple grading (1 1 1) for uniform cell spacing in all directions

  3. Edges:

    • No special edge definitions (empty section)

  4. Boundary Conditions:

    • movingWall: The top face (y=1) is defined as a wall boundary

    • fixedWalls: The left, right, and bottom faces are defined as wall boundaries

    • frontAndBack: The front (z=0) and back (z=0.5) faces are defined as empty boundaries (indicating 2D flow)

  5. Patch Merging:

    • No patches to be merged (empty section)

This configuration creates a 2D cavity mesh with a moving top wall, which is a classic test case for fluid flow solvers. The mesh consists of 20×20 cells in a 0.1×0.1 meter domain, with the z-direction treated as 2D using the empty boundary condition.


The numerical schemes were specified in the system/controlDict file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

object controlDict;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

application myScalarFoam;

startFrom startTime;

startTime 0;

stopAt endTime;

endTime 10;

deltaT 0.005;

writeControl timeStep;

writeInterval 20;

purgeWrite 0;

writeFormat ascii;

writePrecision 6;

writeCompression off;

timeFormat general;

timePrecision 6;

runTimeModifiable true;

// ************************************************************************* //

This OpenFOAM configuration file (controlDict) controls the simulation execution parameters and output settings. Key components include:

  1. Application:

    • Uses myScalarFoam as the solver application (your custom scalar transport solver)

  2. Simulation Time Control:

    • Starts the simulation from startTime (0)

    • Runs until endTime (10 time units)

    • Uses a fixed time step size of deltaT (0.005 time units)

  3. Output Control:

    • writeControl: Results are written based on time steps

    • writeInterval: Output is saved every 20 time steps

    • purgeWrite: 0 (keeps all time directories)

    • writeFormat: Results are saved in ASCII format

    • writePrecision: 6 decimal places for numerical output

    • writeCompression: No compression for output files

  4. Time Formatting:

    • timeFormat: Uses general format for time directory names

    • timePrecision: 6 decimal places for time values

  5. Runtime Modification:

    • runTimeModifiable: true (allows changing parameters during runtime)

This configuration sets up a simulation that runs from t=0 to t=10 with a time step of 0.005, saving results every 20 steps. The solver used is myScalarFoam, your custom scalar transport solver. The simulation allows for runtime parameter modifications, which is useful for adjusting settings without restarting the simulation.






The numerical schemes were specified in the system/decomposeParDict file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

object decomposeParDict;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

numberOfSubdomains 9;

method hierarchical;

coeffs

{

n (3 3 1);

}

// ************************************************************************* //

This OpenFOAM configuration file (decomposeParDict) defines the domain decomposition settings for parallel processing of a simulation. Key components include:

  1. Number of Subdomains:

    • The computational domain will be divided into 9 subdomains for parallel execution

  2. Decomposition Method:

    • Uses the hierarchical method, which splits the domain in a hierarchical manner along each coordinate direction

  3. Decomposition Coefficients:

    • n (3 3 1): Specifies how the domain is split in each direction:

      • 3 partitions in the x-direction

      • 3 partitions in the y-direction

      • 1 partition in the z-direction (no division in z)

This configuration would be used with the decomposePar utility to prepare the case for parallel execution on 9 processors. The hierarchical decomposition creates a 3×3 grid of subdomains in the xy-plane, with no division in the z-direction, which is appropriate for a quasi-2D simulation (such as the cavity case with only one cell in the z-direction).





The numerical schemes were specified in the system/fvSchemes file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

object fvSchemes;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

ddtSchemes

{

default Euler;

}

gradSchemes

{

default Gauss linear;

grad(p) Gauss linear;

//grad(s) Gauss linear;

}

divSchemes

{

default none;

div(phi,U) Gauss linear;

div(phi,s) Gauss upwind;

}

laplacianSchemes

{

default Gauss linear orthogonal;

}

interpolationSchemes

{

default linear;

}

snGradSchemes

{

default orthogonal;

}

// ************************************************************************* //

This OpenFOAM configuration file (fvSchemes) defines the numerical discretization schemes for different terms in the governing equations. Key components include:

  1. Time Derivative Schemes (ddtSchemes):

    • default: Uses first-order Euler implicit scheme for time advancement

  2. Gradient Calculation Schemes (gradSchemes):

    • default: Uses Gaussian integration with linear interpolation

    • grad(p): Specifically uses Gaussian integration with linear interpolation for pressure gradients

    • A commented-out entry for scalar gradient calculation is present (//grad(s))

  3. Divergence Schemes (divSchemes):

    • default: No default scheme specified (must be explicitly defined for each divergence term)

    • div(phi,U): Uses Gaussian integration with linear interpolation for velocity convection

    • div(phi,s): Uses Gaussian integration with upwind differencing for scalar convection (important for stability in scalar transport)

  4. Laplacian Schemes (laplacianSchemes):

    • default: Uses Gaussian integration with linear interpolation and orthogonal correction

  5. Interpolation Schemes (interpolationSchemes):

    • default: Uses linear interpolation for face values from cell centers

  6. Surface Normal Gradient Schemes (snGradSchemes):

    • default: Uses orthogonal approach (assumes orthogonal mesh)

This configuration provides appropriate numerical schemes for an incompressible flow solver with scalar transport. The upwind scheme for scalar convection is particularly important for stability, as it accounts for the direction of flow when calculating scalar transport.



The numerical schemes were specified in the system/fvSolution file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

object fvSolution;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


solvers

{

p

{

solver PCG;

preconditioner DIC;

tolerance 1e-06;

relTol 0.05;

}

pFinal

{

$p;

relTol 0;

}

U

{

solver smoothSolver;

smoother symGaussSeidel;

tolerance 1e-05;

relTol 0;

}

s

{

solver PBiCG;

preconditioner DILU;

tolerance 1e-05;

relTol 0;

}

}

PISO

{

nCorrectors 2;

nNonOrthogonalCorrectors 0;

pRefCell 0;

pRefValue 0;

}

// ************************************************************************* //

This OpenFOAM configuration file (fvSolution) defines the numerical solution methods and control parameters for a CFD simulation. It contains:

  1. Solver Settings for Different Variables:

    • Pressure (p): Uses PCG (Preconditioned Conjugate Gradient) solver with DIC (Diagonal Incomplete Cholesky) preconditioner. Convergence criteria set at absolute tolerance of 1e-06 and relative tolerance of 0.05.

    • Final Pressure (pFinal): Inherits settings from p solver but with zero relative tolerance for tighter convergence at the final step.

    • Velocity (U): Uses smoothSolver with symmetric Gauss-Seidel smoothing. Convergence criteria set at absolute tolerance of 1e-05 with zero relative tolerance.

    • Scalar Field (s): Uses PBiCG (Preconditioned Bi-Conjugate Gradient) solver with DILU (Diagonal Incomplete LU) preconditioner. Convergence criteria set at absolute tolerance of 1e-05 with zero relative tolerance.

  2. PISO Algorithm Settings:

    • nCorrectors: 2 pressure correction iterations per time step

    • nNonOrthogonalCorrectors: 0 (no additional corrections for non-orthogonal meshes)

    • pRefCell: Cell 0 is used as reference for pressure

    • pRefValue: Reference pressure value is set to 0

This configuration is set up for a solver that handles incompressible flow with a scalar transport equation, likely your scalarFoam solver. It defines appropriate linear solvers for each variable and the PISO algorithm parameters for pressure-velocity coupling.



The numerical schemes were specified in the system/PDRblockMesh file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/



FoamFile

{

version 2.0;

format ascii;

class dictionary;

object PDRblockMeshDict;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

scale 0.1;

x

{

points (0 1);

nCells (20);

ratios (1);

}

y

{

points (0 1);

nCells (20);

ratios (1);

}

z

{

points (0 0.1);

nCells (1);

ratios (1);

}

boundary

(

movingWall

{

type wall;

faces (3);

}

fixedWalls

{

type wall;

faces (0 1 2);

}

frontAndBack

{

type empty;

faces (4 5);

}

);

// ************************************************************************* //

This file is an OpenFOAM dictionary called PDRblockMeshDict that defines a simplified block mesh generation configuration for a CFD simulation. The key components are:

  1. Scale Factor: Sets a scaling factor of 0.1 for the entire mesh.

  2. Domain Dimensions:

    • X-direction: Domain spans from 0 to 1 units, divided into 20 cells with uniform spacing (ratio 1)

    • Y-direction: Domain spans from 0 to 1 units, divided into 20 cells with uniform spacing (ratio 1)

    • Z-direction: Very thin domain from 0 to 0.1 units, with only 1 cell in this direction (essentially a 2D simulation)

  3. Boundary Conditions:

    • movingWall: Wall boundary assigned to face 3 (likely the top face)

    • fixedWalls: Wall boundary assigned to faces 0, 1, and 2 (likely the sides and bottom)

    • frontAndBack: Empty boundary type assigned to faces 4 and 5 (the front and back faces in the thin z-direction)

This configuration describes a simplified 2D lid-driven cavity case with a 20×20 cell mesh, where the top boundary is a moving wall and the remaining boundaries are fixed walls or empty (for the quasi-2D approach).


The numerical schemes were specified in the system/setFieldsDict file:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2406 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

location system;

object setFieldsDict;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


defaultFieldValues

(

volScalarFieldValue s 300

);

regions

(

sphereToCell

{

centre (0.05 0.05 0.05);

radius 0.03;

fieldValues

(

volScalarFieldValue s 500

);

}

);


// ************************************************************************* //

This dictionary would be used with the setFields utility in OpenFOAM to initialize the scalar field s in your simulation. It specifically:

  1. Sets the scalar field s to 300 throughout the entire domain as a default value

  2. Creates a "hot spot" or concentrated region where s = 500 in a small sphere centered at (0.05, 0.05, 0.05) with radius 0.03

This kind of initialization is useful for transport problems where you want to observe how a locally concentrated scalar (like temperature, concentration, etc.) is transported by the flow field over time. For your scalarFoam solver, this would create an initial condition with a spherical region of higher scalar value embedded in a uniform background.

To use this file, you would:

  1. Place it in the system directory of your case

  2. Run the command setFields before running your solver

  3. This would modify the initial s field according to the specifications

This allows you to study how the scalar is transported from the concentrated region throughout the domain under the influence of the velocity field.


The key modification was the addition of the div(phi,s) scheme, which specifies how to discretize the convective term in the scalar transport equation. The upwind scheme was chosen for numerical stability.

3.5 Solution Control

The system/fvSolution file was modified to include a solver for the scalar field s:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2106 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

object fvSolution;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


solvers

{

s

{

solver PBiCGStab;

preconditioner DILU;

tolerance 1e-06;

relTol 0.1;

}

}


PISO

{

nCorrectors 2;

nNonOrthogonalCorrectors 0;

pRefCell 0;

pRefValue 0;

}


A PBiCGStab solver was specified for the scalar field s, with DILU preconditioning. The PISO settings were kept from the original case, although they are not used by scalarFoam.

3.6 Run Control

The system/controlDict file was modified to use the new scalarFoam solver:

/*--------------------------------*- C++ -*----------------------------------*\

| ========= | |

| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |

| \\ / O peration | Version: v2106 |

| \\ / A nd | Website: www.openfoam.com |

| \\/ M anipulation | |

\*---------------------------------------------------------------------------*/

FoamFile

{

version 2.0;

format ascii;

class dictionary;

object controlDict;

}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //


application scalarFoam;


startFrom startTime;


startTime 0;


stopAt endTime;


endTime 10;


deltaT 0.005;


writeControl timeStep;


writeInterval 20;


purgeWrite 0;


writeFormat ascii;


writePrecision 6;


writeCompression off;


timeFormat general;


timePrecision 6;


runTimeModifiable true;


The main change was setting the application to scalarFoam.

4. Results and Discussion


4.1 Compilation Results

The scalarFoam solver was successfully compiled using the wmake utility:

$ wmake



This created the executable in the $FOAM_USER_APPBIN directory.

4.2 Simulation Results

The scalarCavity case was run using the scalarFoam solver:

blockMesh:

setFields:

myScalarFoam:


The simulation results showed the transport of the scalar quantity s from the moving wall (top boundary) into the cavity over time.

4.3 Scalar Field Visualization

The scalar field s was visualized at different time steps using ParaView. The images below show the evolution of the scalar field over time: 0.1, 0.2, 0.5, 1, 10.


The results demonstrate how the scalar quantity is transported by the velocity field from the top moving wall into the cavity. The scalar contours show the expected behavior of advection, with higher values propagating from the moving wall into the domain over time.

4.4 Physical Interpretation

The transport of the scalar quantity s in this case can be interpreted as the transport of a passive scalar property, such as a dye or temperature, by the lid-driven cavity flow. The results show that:

  1. The scalar is initially concentrated at the moving lid boundary (value = 1)

  2. As the simulation progresses, the scalar is transported into the cavity by the flow

  3. The transport follows the main vortex pattern of the cavity flow

  4. Gradients of the scalar field are steeper in regions of higher velocity

This behavior is consistent with the physics of scalar transport in fluid flows, validating the implementation of the scalarFoam solver.

5. Conclusion

This project successfully developed a scalar transport solver (scalarFoam) by modifying the existing icoFoam solver in OpenFOAM. This case setup is for a scalar transport simulation in a lid-driven cavity flow using your custom solver "myScalarFoam". The simulation is set up as a quasi-2D case (one cell thick in the z-direction) with a moving top wall. A scalar quantity is initialized with a "hot spot" in a spherical region, and the simulation will track how this scalar is transported by the flow field over time.The key achievements were:

  1. Implementation of the scalar transport equation in the OpenFOAM framework

  2. Development of a functional solver for scalar transport

  3. Successful testing of the solver on a modified cavity case

  4. Visualization and analysis of scalar transport results

The scalarFoam solver provides a foundation for simulating various passive scalar transport phenomena in incompressible flows, such as temperature distribution, concentration of species, or other non-reactive scalars.

6. Future Work

Several extensions and improvements could be considered for future work:

  1. Addition of diffusion terms to model scalar diffusion: ∂s/∂t + ∇·(us) = ∇·(D∇s)

  2. Implementation of source terms for scalar generation or consumption

  3. Coupling with other physical models such as temperature-dependent density

  4. Extension to multiple scalar quantities

  5. Performance optimization for large-scale simulations





























































































































































Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.