Module 7
Module 7
Lecture 1
Module 7 - Lecture 1 1
Roadmap
1. Programming in OpenFOAM®.
Building blocks.
Module 7 - Lecture 1 2
Programming in OpenFOAM®. Building blocks
During this session we will:
• Then, we will take a look at how to generate tensor fields from tensors.
• Finally we will see how to discretize a model equation and solve the
linear system of equations using OpenFOAM® classes and templates.
Module 7 - Lecture 1 3
Programming in OpenFOAM®. Building blocks
During this session we will:
Module 7 - Lecture 1 4
Programming in OpenFOAM®. Building blocks
By the way and in case you did not know it,
Module 7 - Lecture 1 5
Programming in OpenFOAM®. Building blocks
Some preliminaries,
• The PDEs must be discretized in time and space before we solve them.
Module 7 - Lecture 1 6
Programming in OpenFOAM®. Building blocks
Basic tensor classes in OpenFOAM®
0 Scalar scalar
Module 7 - Lecture 1 7
Programming in OpenFOAM®. Building blocks
Basic tensor classes in OpenFOAM®
We can access the component T13 or Txz using the xz ( ) access function.
Module 7 - Lecture 1 8
Programming in OpenFOAM®. Building blocks
Basic tensor classes in OpenFOAM®
Txz = 3
Notice that in OpenFOAM® we use the function Info instead of the function cout.
Module 7 - Lecture 1 9
Programming in OpenFOAM®. Building blocks
Algebraic tensor operations in OpenFOAM®
• Tensor operations operate on the entire tensor entity instead of a series of operations
on its components.
• The OpenFOAM® syntax closely mimics the syntax used in written mathematics,
using descriptive functions or symbolic operators.
• Some of the algebraic tensor operations are listed in the following table.
Mathematical OpenFOAM®
Operation Remarks
description description
Addition a+b a + b
Scalar s * a
sa
multiplication
Module 7 - Lecture 1 11
Programming in OpenFOAM®. Building blocks
Examples of the use of some tensor classes
• $> cd $PTOFC/programming_playground/test_dir_OF/tensor
• $> wmake
(This will compile the source code and put the binary in the directory $FOAM_USER_APPBIN)
• $> Test-tensor
At this point look at the output and study the file Test-tensor.C, and try to
understand what we have done.
Module 7 - Lecture 1 12
Programming in OpenFOAM®. Building blocks
Dimensional units in OpenFOAM®
• OpenFOAM® encourages the user to attach dimensional units to any tensor and it
will perform dimension checking of any tensor operation.
Module 7 - Lecture 1 13
Programming in OpenFOAM®. Building blocks
Dimensional units in OpenFOAM®
• Units are defined using the dimensionSet class tensor, with its units defined using
the dimensioned<Type> template class, the <Type> being scalar, vector, tensor,
etc. The dimensioned<Type> stores the variable name, the dimensions and the
tensor values.
• For example, a tensor with dimensions is declare in the following way:
dimensionedTensor sigma
(
0 6
1
“sigma”,
10 0 0
dimensionSet(1, -1, -2, 0, 0, 0, 0), ⌘ =@ 0 106 0 A
tensor(10e6,0,0,0,10e6,0,0,0,10e6) 0 0 106
);
Module 7 - Lecture 1 14
Programming in OpenFOAM®. Building blocks
Units correspondence in dimensionSet
1 Mass kilogram kg
2 Length meters m
3 Time second s
4 Temperature Kelvin K
6 Current ampere A
Luminuous cd
7 candela
intensity
dimensionedTensor sigma
( 0 6
1
“sigma”, 10 0 0
dimensionSet(1, -1, -2, 0, 0, 0, 0), ⌘ =@ 0 106 0 A
tensor(1e6,0,0,0,1e6,0,0,0,1e6)
); 0 0 106
#include “dimensionedTensor.H”
• Before return(0):
dimensionedTensor sigma
(
"sigma",
dimensionSet(1, -1, -2, 0, 0, 0, 0),
tensor(1e6,0,0,0,1e6,0,0,0,1e6)
);
Info<< "Sigma: " << sigma << endl;
By the end of this exercise, your output should looks like this:
Notice that the object sigma, which belongs to the dimensionedTensor class, contains
the name, the dimensions and values.
Module 7 - Lecture 1 18
Programming in OpenFOAM®. Building blocks
Dimensional units examples
Try to add the following member functions of the dimensionedTensor class in Test-
tensor.C (in the directory $PTOFC/programming_playground/my_tensor you
will find the modified files):
Also, extract some of the values of the tensor by adding the following line:
Note that the value() member function first converts the expression to a tensor, which
has a yy() member function. The dimensionedTensor class does not have a yy()
member function, so it is not possible to directly get its value by using sigma.yy().
Module 7 - Lecture 1 19
Programming in OpenFOAM®. Building blocks
OpenFOAM® lists and fields
• Lists of the tensor classes are defined in OpenFOAM® by the template class
Field<Type>. For better code legibility, all instances of Field<Type>, e.g.
Field<vector>, are renamed using typedef declarations as scalarField, vectorField,
tensorField, symmTensorField, tensorThirdField and symmTensorThirdField.
Module 7 - Lecture 1 20
Programming in OpenFOAM®. Building blocks
OpenFOAM® lists and fields
• You can check $FOAM_SRC/OpenFOAM/fields/Fields for the field classes.
• OpenFOAM® also supports operations between a field and a zero rank tensor, e.g.
all values of a Field U can be multiplied by the scalar 2 by simple coding the
following line, U = 2.0 * U.
Module 7 - Lecture 1 21
Programming in OpenFOAM®. Building blocks
Construction of a tensor field in OpenFOAM®
Add the following to Test-tensor.C (in the directory
$PTOFC/programming_playground/my_tensor you will find the modified files):
• Before main():
#include "tensorField.H"
• Before return(0):
Module 7 - Lecture 1 23
Programming in OpenFOAM®. Building blocks
Discretization of a tensor field in OpenFOAM®
• The cells are contiguous, i.e., they do not overlap and completely fill the domain.
• Dependent variables and other properties are stored at the cell centroid.
Module 7 - Lecture 1 24
Programming in OpenFOAM®. Building blocks
Discretization of a tensor field in OpenFOAM®
• The mesh class polyMesh is used to construct the polyhedral mesh using the
minimum information required.
• The fvMesh class extends the polyMesh class to include additional data needed for
the FVM discretization.
Module 7 - Lecture 1 25
Programming in OpenFOAM®. Building blocks
Discretization of a tensor field in OpenFOAM®
• The template class geometricField relates a tensor field to a fvMesh. Using typedef
declarations geometricField is renamed to volField (cell center), surfaceField (cell
faces), and pointField (cell vertices).
• The template class geometricField stores internal fields, boundary fields, mesh
information, dimensions, old values and previous iteration values.
• A geometricField inherits all the tensor algebra of its corresponding field, has
dimension checking, and can be subjected to specific discretization procedures.
Module 7 - Lecture 1 26
Programming in OpenFOAM®. Building blocks
Data stored in the fvMesh class
Access
Class Description Symbol
function
volScalarField Cell volumes V V()
Module 7 - Lecture 1 27
Programming in OpenFOAM®. Building blocks
Examine a fvMesh
• Let us study a fvMesh example. First let us compile the Test-mesh application.
From the terminal
• $> cd $PTOFC/programming_playground/test_dir_OF/mesh
• $> wmake
• $> cd $PTOFC/programming_playground/my_mesh/cavity
• $> blockMesh
Module 7 - Lecture 1 28
Programming in OpenFOAM®. Building blocks
Examine a fvMesh
Module 7 - Lecture 1 29
Programming in OpenFOAM®. Building blocks
Examine a fvMesh
Now, try to add in Test-mesh.C the following lines (in the directory
$PTOFC/programming_playground/my_mesh you will find the modified files):
• before return(0):
Module 7 - Lecture 1 30
Programming in OpenFOAM®. Building blocks
Examine a volScalarField
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< p << endl;
Info<< p.boundaryField()[0] << endl;
• In this phase, OpenFOAM® converts the PDEs into a set of linear algebraic
equations, A x = b, where x and b are volFields (geometricField). A is a fvMatrix,
which is created by a discretization of a geometricField and inherits the algebra of its
corresponding field, and it supports many of the standard algebraic matrix operations.
Module 7 - Lecture 1 32
Programming in OpenFOAM®. Building blocks
Discretization of the basic PDE terms in OpenFOAM®
The list is not complete
Mathematical fvm::
Term description fvc::
expression
laplacian(phi)
Laplacian r2 , · laplacian(Gamma, phi)
⇥ , ⇤ ⇥ ddt(phi)
Time derivative ddt(rho,phi)
⇥t ⇤t
div(psi,scheme)
Convection ·( ) , ·( ) div(psi,phi)
Sp(rho,phi)
Source ⇢ SuSp(rho,phi)
$PTOFC/programming_playground/my_convection_diffusion
Module 7 - Lecture 1 34
Programming in OpenFOAM®. Building blocks
• In the directory
$PTOFC/programming_playground/my_convection_dif
fusion you will find this tutorial.
• From this point on, please follow me.
• We are all going to work at the same pace.
Module 7 - Lecture 1 35
Programming in OpenFOAM®. Building blocks
Solution of the convection-diffusion equation
⇥T
+ ⇥ · ( T) ⇥ · ( ⇥T ) = 0
⇥t
solve
(
fvm::ddt(T)
+ fvm::div(phi,T)
- fvm::laplacian(DT,T)
);
Module 7 - Lecture 1 36
Programming in OpenFOAM®. Building blocks
Solution of the convection-diffusion equation
• cd $PTOFC/programming_playground/my_convection_diffusion
• wmake
• Now go to the
$PTOFC/programming_playground/my_convection_diffusion/case
directory and run the new solver. In the terminal:
• cd $PTOFC/programming_playground/my_convection_diffusion/case
• blockMesh
• my_Test_convection_difusion
• paraFoam
Module 7 - Lecture 1 37
Programming in OpenFOAM®. Building blocks
Solution of the convection-diffusion equation
By the end of this exercise, your output should looks like this:
Module 7 - Lecture 1 38
Programming in OpenFOAM®. Building blocks
Solution of the convection-diffusion equation
By the end of this exercise, your output should looks like this:
Module 7 - Lecture 2 1
Roadmap
1. Before we start
2. How to implement a new boundary condition
in OpenFOAM® - Parabolic velocity profile
3. Model case for parabolic velocity profile
4. How to implement a new boundary condition
in OpenFOAM® - Paraboloid velocity profile
5. Model case for paraboloid velocity profile
module 7 - Lecture 2 2
Roadmap
1. Before we start
2. How to implement a new boundary condition
in OpenFOAM® - Parabolic velocity profile
3. Model case for parabolic velocity profile
4. How to implement a new boundary condition
in OpenFOAM® - Paraboloid velocity profile
5. Model case for paraboloid velocity profile
module 7 - Lecture 2 3
Before we start
In order to implement a new boundary condition, we should follow these basic steps:
• In order to implement your own boundary condition you need to either find an
already defined boundary condition and copy it to your user directory and start
modification from there, or use the new utility of OpenFOAM version 3.0.x,
foamNewBC.
• foamNewBC creates directory of source and compilation files for a new boundary
condition.
module 7 - Lecture 2 4
Roadmap
1. Before we start
2. How to implement a new boundary condition
in OpenFOAM® - Parabolic velocity profile
3. Model case for parabolic velocity profile
4. How to implement a new boundary condition
in OpenFOAM® - Paraboloid velocity profile
5. Model case for paraboloid velocity profile
module 7 - Lecture 2 5
How to implement a new boundary condition in OpenFOAM®
module 7 - Lecture 2 6
How to implement a new boundary condition in OpenFOAM®
module 7 - Lecture 2 7
How to implement a new boundary condition in OpenFOAM®
module 7 - Lecture 2 8
How to implement a new boundary condition in OpenFOAM®
module 7 - Lecture 2 9
How to implement a new boundary condition in OpenFOAM®
1. $> cd $WM_PROJECT_USER_DIR/run
2. $> foamNewBC –help
• As you can see foamNewBC comes with different conditions and options. For our
case, since the velocity boundary condition that we have is fixed, we use -f
condition and since for our boundary, we work only with vectors, we use -v option.
We name our boundary condition ParabolicVelocity . For all these, we type the
following in the terminal:
module 7 - Lecture 2 10
How to implement a new boundary condition in OpenFOAM®
foamNewBC –f –v ParabolicVelocity
files
ParabolicVelocity ParabolicVelocity
Make
! Options
FvPatchVectorField.H FvPatchVectorField.C
module 7 - Lecture 2 11
How to implement a new boundary condition in OpenFOAM®
• H file (Header file) inside the ParabolicVelocity refers to the class declaration
that includes the name of class and functions will be used in the main C code.
• C file contains the constructors, private functions and member functions which will be
discussed in detail.
module 7 - Lecture 2 12
How to implement a new boundary condition in OpenFOAM®
Header file
• Open the header file:
100 //- Single valued scalar quantity, e.g. a coefficient
101 scalar scalarData_;
102 • In lines (100-127) different kind of
103 //- Single valued Type quantity, e.g. reference pressure pRefValue_ private data are declared. Since in
104 // Other options include vector, tensor
105 vector data_;
our boundary condition we just
106 need vector and scalar, we keep
107 //- Field of Types, typically defined across patch faces the line (101) and (105) and we
108 // e.g. total pressure p0_. Other options include vectorField
109 vectorField fieldData_;
delete the rest of the private data
110 and private function.( line (107-
111 //- Type specified as a function of time for time-varying BCs 127))
112 autoPtr<DataEntry<vector> > timeVsData_;
113
114 //- Word entry, e.g. pName_ for name of the pressure field on database
115 word wordData_; • Since in our boundary condition
116 we need two vector, copy line(105)
117 //- Label, e.g. patch index, current time index
118 label labelData_; and past it in the next line of it.
119
120 //- Boolean for true/false, e.g. specify if flow rate is volumetric_
121 bool boolData_;
122
• There is no need to modify the rest
123 of the header file which is related
124 // Private Member Functions to the constructors and member
125
functions declaration.
126 //- Return current time
127 scalar t() const;
module 7 - Lecture 2 13
How to implement a new boundary condition in OpenFOAM®
• Use ctrl-H in gedit and search for scalarData and replace it with maxValue. Do
the same for the two data vectors. Name one of the n and the another y.
• After all these modifications save and close the header file.
module 7 - Lecture 2 14
How to implement a new boundary condition in OpenFOAM®
• Type name in the header file will be used when specifying the boundary
condition in our simulations.
• maxValue is a scalar which refers to the peak velocity magnitude and two
vectors, n_ and y_ refer to the flow direction and the direction of the y-
coordinate, respectively.
• Remember the needs of your boundary condition. If it need a vector field, then you
need to use vectorField fieldData_ in the declaration process. So always
when you want to code your boundary condition, first see what you really need.
• The rest of the header file refers to the declaration of member functions and
constructors which we will not modify.
module 7 - Lecture 2 15
How to implement a new boundary condition in OpenFOAM®
The C file
• Open the C file with gedit:
• Line (34-37) refers to the private function definition. This function allows you to access
to the time in your simulation. Since we don’t use any private function, we remove
these lines.
• Use ctrl-H in gedit and search for scalarData and replace it with maxValue.
module 7 - Lecture 2 16
How to implement a new boundary condition in OpenFOAM®
The C file
• Since we defined two vectors, we need to duplicate every line containing data_ and
rename to data1_. For example
39 Foam::parabolicVelocityFvPatchVectorField::
40 parabolicVelocityFvPatchVectorField
41 (
42 const fvPatch& p,
43 const DimensionedField<vector, volMesh>& iF
44 )
45 :
46 fixedValueFvPatchVectorField(p, iF),
47 maxValue_(0.0),
48 data_(pTraits<vector>::zero),
48 data1_(pTraits<vector>::zero)
49 {
50 }
• Use ctrl-H in gedit and search for data and replace it with n. Do the same for
data1 and replace it with y.
module 7 - Lecture 2 17
How to implement a new boundary condition in OpenFOAM®
What is in C file?
module 7 - Lecture 2 18
How to implement a new boundary condition in OpenFOAM®
What is in C file?
module 7 - Lecture 2 19
How to implement a new boundary condition in OpenFOAM®
What is in C file?
64 n_(pTraits<vector>(dict.lookup("n"))),
65 y_(pTraits<vector>(dict.lookup("y")))
66 {
67
68
69 if (mag(n_) < SMALL || mag(y_) < SMALL)
70 {
71 FatalErrorIn("parabolicVelocityFvPatchVectorField(dict)")
72 << "n or y given with zero size not correct"
73 << abort(FatalError);
74 }
75
76 n_ /= mag(n_);
77 y_ /= mag(y_);
78
79
80
81 fixedValueFvPatchVectorField::evaluate();
82
83 /*
84 //Initialise with the value entry if evaluation is not possible
85 fvPatchVectorField::operator=
86 (
87 vectorField("value", dict, p.size())
88 );
89 */
90 }
module 7 - Lecture 2 20
How to implement a new boundary condition in OpenFOAM®
What is in C file?
• We now look at the member function updatecoeffs(). This is the place that we define our
boundary condition.
module 7 - Lecture 2 21
How to implement a new boundary condition in OpenFOAM®
What is in updatecoeffs?
• In line (172) we define constant vector field c which returns the face
centers of the patch.
• After all these modifications save the C file and in terminal execute
wmake.
module 7 - Lecture 2 22
Roadmap
1. Before we start
2. How to implement a new boundary condition
in OpenFOAM® - Parabolic velocity profile
3. Model case for parabolic velocity profile
4. How to implement a new boundary condition
in OpenFOAM® - Paraboloid velocity profile
5. Model case for paraboloid velocity profile
module 7 - Lecture 2 23
Case setup
2D elbow pipe
1. $> cd $PTOFC/101programming/cases/elbow2d
• Open the U file in the 0 directory and use the parabolic boundary condition as follow:
29 velocity-inlet-5
30 {
31
32 type parabolicVelocity;
33
34 maxValue 2.0;
35 n (1 0 0);
36 y (0 1 0);
37
38 /*if you use paraFoam -builtin you can safely comment this line,
39 if not you will need to add it,
40 this line needs to be added in order to parafoam to work
41 it is a dummy value
42 */
43 value (0 0 0);
44 }
module 7 - Lecture 2 24
Case setup
2D elbow pipe
• Navigate to system directory and open controlDict and add the following line at
the end of the file:
• This will let you to use the parabolic boundary condition you defined.
libs ("libparabolicVelocity.so")
module 7 - Lecture 2 25
Case setup
Running the case
1. $> cd $PTOFC/101programming/cases/elbow2d
2. $> foamCleanPolyMesh
3. $> foamCleanTutorials
4. $> fluentMeshToFoam ../../../meshes_and_geometries/elbow2d_1/ascii.msh
5. $> checkMesh
6. $> icoFoam
7. $> paraFoam
module 7 - Lecture 2 26
Roadmap
1. Before we start
2. How to implement a new boundary condition
in OpenFOAM® - Parabolic velocity profile
3. Model case for parabolic velocity profile
4. How to implement a new boundary condition
in OpenFOAM® - Paraboloid velocity profile
5. Model case for parabolic velocity profile
module 7 - Lecture 2 27
How to implement a new boundary condition in OpenFOAM®
module 7 - Lecture 2 28
How to implement a new boundary condition in OpenFOAM®
module 7 - Lecture 2 29
How to implement a new boundary condition in OpenFOAM®
module 7 - Lecture 2 30
How to implement a new boundary condition in OpenFOAM®
• Since the paraboloid boundary condition is similar to the parabolic case, we can modify
the already defined parabolic boundary condition and modifying it. For this reason copy
the parabolicVelocity directory in the run directory and rename it to paraboloid.
• Navigate to the make directory and open the files file. Change it like this:
1 paraboloidFvPatchVectorField.C
2
3 LIB = $(FOAM_USER_LIBBIN)/paraboloid
module 7 - Lecture 2 31
How to implement a new boundary condition in OpenFOAM®
94 class paraboloidFvPatchVectorField
95 :
96 public fixedValueFvPatchVectorField
97 {
98 // Private data
99
100 //- Single valued scalar quantity, e.g. a coefficient
101 scalar radius_;
102 scalar maxValue_;
103
104
105 //- Single valued Type quantity, e.g. reference pressure pRefValue_
106 // Other options include vector, tensor
107
108 vector y1_;
109 vector n_;
110 vector y_;
module 7 - Lecture 2 32
How to implement a new boundary condition in OpenFOAM®
• Open the C file and same as the parabolic boundary condition define y1 and radius
for each constructor. For example for the first constructor you should have something
like this:
38 paraboloidFvPatchVectorField
39 (
40 const fvPatch& p,
41 const DimensionedField<vector, volMesh>& iF
42 )
43 :
44 fixedValueFvPatchVectorField(p, iF),
45 radius_(0.0),
46 maxValue_(0.0),
47 y1_(1, 0, 0),
48 n_(1, 0, 0),
49 y_(0, 1, 0)
50
51 {
52 }
module 7 - Lecture 2 33
How to implement a new boundary condition in OpenFOAM®
• Similar to the parabolic boundary condition for the second constructor we have:
56 paraboloidFvPatchVectorField
57 (
58 const fvPatch& p,
59 const DimensionedField<vector, volMesh>& iF,
60 const dictionary& dict
61 )
62 :
63 fixedValueFvPatchVectorField(p, iF),
64 radius_(readScalar(dict.lookup("radius"))),
65 maxValue_(readScalar(dict.lookup("maxValue"))),
66 y1_(pTraits<vector>(dict.lookup("y1"))),
67 n_(pTraits<vector>(dict.lookup("n"))),
68 y_(pTraits<vector>(dict.lookup("y")))
69 {
70
71
72 if (mag(n_) < SMALL || mag(y_) < SMALL || mag(y1_) < SMALL)
73 {
74 FatalErrorIn("paraboloidFvPatchVectorField(dict)")
75 << "n or y given with zero size not correct"
76 << abort(FatalError);
77 }
78
79 n_ /= mag(n_);
80 y_ /= mag(y_);
81 y1_ /= mag(y1_);
module 7 - Lecture 2 34
How to implement a new boundary condition in OpenFOAM®
190 scalarField coord2 = ((c - ctr) & y_)*((c - ctr) & y_) + ((c - ctr) & y1_)
191 *((c - ctr) & y1_) - radius_;
192 vectorField::operation=(n_*maxValue*-4*(coord2));
module 7 - Lecture 2 35
Roadmap
1. Before we start
2. How to implement a new boundary condition
in OpenFOAM® - Parabolic velocity profile
3. Model case for parabolic velocity profile
4. How to implement a new boundary condition
in OpenFOAM® - Paraboloid velocity profile
5. Model case for paraboloid velocity profile
module 7 - Lecture 2 36
Case setup
3D elbow pipe
1. $> cd $PTOFC/101programming/cases/elbow3d
• Open the U file in the 0 directory and use the paraboloid boundary condition as
follow:
38 auto3
39 {
40 // type fixedValue;
41 // value uniform (0.1 0 0);
42
43 type paraboloid;
44 maxValue 0.4;
45 n (1 0 0);
46 y (0 1 0);
47 y1 (0 0 1);
48 radius 0.25;
49 value uniform (0 0 0);
50 }
module 7 - Lecture 2 37
Case setup
3D elbow pipe
• Navigate system directory and open controlDict and add the following line at
the end of the file:
libs ("paraboloid.so")
• This will let you to use the paraboloid boundary condition you defined.
module 7 - Lecture 2 38
Case setup
Running the case
1. $> cd $PTOFC/101programming/cases/elbow3d
Remember, $PTOFC is pointing to the path where you unpack the tutorials.
2. $> foamCleanPolyMesh
3. $> foamCleanTutorials
4. $> blockMesh
5. $> surfaceFeatureExtract –noFunctionObjects
6. $> snappyHexMesh –overwrite
7. $> createPatch –overwrite
8. $> renumberMesh –overwrite
9. $> icoFoam
10. $> paraFoam
module 7 - Lecture 2 39
Additional activities
Exercises
module 7 - Lecture 2 40
Additional activities
Exercises
• Add a parabolic boundary condition for the another inlet of the pipe and compare the
result with the uniform boundary condition.
• Add a time varying boundary condition to the parabolic boundary condition. Sin(t) is
a good option.
module 7 - Lecture 2 41
Module 7
Lecture 3
Module 7- Lecture 3 1
Roadmap
1. Before we start
2. How to modify an existing application in
OpenFOAM®
3. Case setup
Module 7 - Lecture 3 2
Roadmap
1. Before we start
2. How to modify an existing application in
OpenFOAM®
3. Case setup
Module 7 - Lecture 3 3
Before we start
• In order to implement your own application you need to either find the already
defined application and copy it to your user directory and start modification from
there, or use the new utility of OpenFOAM version 3.0.x, foamNewApp.
Module 7 - Lecture 3 4
Roadmap
1. Before we start
2. How to modify an existing application in
OpenFOAM®
3. Case setup
Module 7 - Lecture 3 5
How to modify an existing application in OpenFOAM®
Module 7 - Lecture 3 6
How to modify an existing application in OpenFOAM®
Module 7 - Lecture 3 7
How to modify an existing application in OpenFOAM®
1. $> cd $FOAM_SOLVERS/incompressible/
2. $> cp –r icoFoam $WM_PROJECT_USER_DIR/run
3. $> cd $WM_PROJECT_USER_DIR/run
4. $> mv icoFoam my_icoFoam
• In this way we copy the icoFoam solver to your run directory in the project
directory and we navigate to the run directory. Then we change the name of it to
my_icoFoam.
• Navigate my_icoFoam and rename icoFoam.C to my_icoFoam.C.
Module 7 - Lecture 3 8
How to modify an existing application in OpenFOAM®
1 my_icoFoam.C
2
3 EXE = $(FOAM_USER_APPBIN)/my_icoFoam
• Line (3) will let you to create your executable application in the user define
solver directory.
• There is no need to change the options file.
Module 7 - Lecture 3 9
How to modify an existing application in OpenFOAM®
files
Make ! createFields.H my_icoFoam.C
Options
Module 7 - Lecture 3 10
How to modify an existing application in OpenFOAM®
• H file (Header file) inside the my_icoFoam directory refers to the reading the
transport properties defined in the constant directory and the fields defined in the 0
directory of your case study.
• C file contains the main solver.
Module 7 - Lecture 3 11
How to modify an existing application in OpenFOAM®
Header file
• Open the header file:
Module 7 - Lecture 3 12
How to modify an existing application in OpenFOAM®
Header file
• Open the header file:
23 dimensionedScalar DS
24 ( • We add lines (23-42) in order to
25 "DS", define our scalar field S and the
26 dimensionSet(0,2,-1,0,0),
27 transportProperties.lookup("DS") diffusion coefficient DS.
28 );
29 • In lines (23-28) diffusion coefficient
30 Info<< "Reading field S\n" << endl;
31 volScalarField S
with the name DS is created which
32 ( has the same dimension of
33 IOobject
34 ( viscosity and the value is read
35 "S", from the transportProperties
36 runTime.timeName(),
37 mesh, in the constant directory of case
38 IOobject::MUST_READ, study, using lookup command.
39 IOobject::AUTO_WRITE
40 ),
41 mesh
• In lines (31-42) volume scalar field
42 ); S with the name S and the values
will be read from the 0 directory
and automatically will be written
after the calculation.
Module 7 - Lecture 3 13
How to modify an existing application in OpenFOAM®
The C file
• Open the C file with gedit:
• The while loop in the C file refers to the algorithm in order to find the velocity field U.
We will not modify this part. Before runTime.write() add our convection –
diffusion equation.
• After these modifications, save the C file and in the terminal execute wmake.
Module 7 - Lecture 3 14
Roadmap
1. Before we start
2. How to modify an existing application in
OpenFOAM®
3. Case setup
Module 7 - Lecture 3 15
Case setup
2D elbow pipe
1. $> cd $PTOFC/101programming/cases/advectionDiffusion
• In the S file in the 0 directory we defined the uniform values of 1 and 2 "# /% # for
velocity-inlet-5 and 6, respectively.
• In the transportProperties in the constant directory we add the diffusion
coeffcient:
19 DS DS[0 2 -1 0 0 0 0] 2e-3;
Module 7 - Lecture 3 16
Case setup
2D elbow pipe
28 divSchemes
29 {
30 default none;
31 div(phi,U) Gauss limitedLinearV 1;
32 div(phi,S) Gauss upwind; //new variable
33 }
34
35 laplacianSchemes
36 {
37 default none;
38 laplacian(nu,U) Gauss linear corrected;
39 laplacian((1|A(U)),p) Gauss linear corrected;
40 laplacian(DS,S) Gauss linear corrected; //new
41 }
• We add lines (32) and (40) in order to define an appropriate divergence and
laplacian method for S.
Module 7 - Lecture 3 17
Case setup
2D elbow pipe
22 S
23 {
24 solver PBiCG;
25 preconditioner DILU;
26 tolerance 1e-05;
27 relTol 0;
28 }
Module 7 - Lecture 3 18
Case setup
Running the case
• Navigate to the case directory in the run directory and run the following commands:
1. $> cd $PTOFC/101programming/cases/advectionDiffusion
2. $> foamCleanPolyMesh
3. $> foamCleanTutorials
4. $> fluentMeshToFoam ../../../meshes_and_geometries/elbow2d_1/ascii.msh
5. $> checkMesh
6. $> my_icoFoam
7. $> paraFoam
Module 7 - Lecture 3 19
Additional activities
Exercises
Module 7 - Lecture 3 20
Additional activities
Exercises
• Add another concentration equation for &# in the way that is depending to &.
• Add a piece of code that calculates the vorticity of the flow in each time step.
Module 7 - Lecture 3 21
Module 7
Lecture 4
Module 7- Lecture 4 1
Roadmap
1. Before we start
2. How to implement a new boundary condition
with groovyBC
3. How to implement a new boundary condition
with codeStream
Module 7 - Lecture 4 2
Roadmap
1. Before we start
2. How to implement a new boundary condition
with groovyBC
3. How to implement a new boundary condition
with codeStream
Module 7 - Lecture 4 3
Before we start
• For a more complete tutorial regarding groovyBC refer to the following links:
• https://openfoamwiki.net/index.php/Contrib/groovyBC
Module 7 - Lecture 4 4
Roadmap
1. Before we start
2. How to implement a new boundary condition
with groovyBC
3. How to implement a new boundary condition
with codeStream
Module 7 - Lecture 4 5
How to implement new boundary condition with groovyBC
Module 7 - Lecture 4 6
How to implement new boundary condition with groovyBC
( − (%&' ( − (%*+
! = 4 !%&'
(%&' − (%*+ ,
(%&'
(%*+
Module 7 - Lecture 4 7
How to implement new boundary condition with groovyBC
• Navigate to the case directory and open the U file in the 0 directory:
1. $> cd $PTOFC/101programming/cases/2dElbowGroovyBC
2. $> gedit 0/U
29 velocity-inlet-5
30 {
31
32 type groovyBC;
33 variables "maxValue=2.0;yp=pts().y;minY=min(yp);maxY=max(yp);len=0.25*pow(maxY-minY,2);";
34 valueExpression "-maxValue*(pos().y-minY)*(maxY-pos().y)*normal()/len";
35 value (0 0 0);
36
37 }
Module 7 - Lecture 4 8
How to implement new boundary condition with groovyBC
• Line (33) refers to the variable definition. In this line we define the peak velocity as
maxValue. Here pts().y allows us to access to the mesh vertices of y and with
min and max functions we can calculate the minimum and maximum of the patch.
• Line (34) refers to the value expression. Here we define our fix value boundary
condition. Here pos().y allows us to access to the face center of mesh and
normal() gives us the normal vector to the patch face.
• Remember there are lots of already defined functions and utilities you can use with
groovyBC. For more examples visit the website mentioned at the beginning of tutorial.
Module 7 - Lecture 4 9
How to implement new boundary condition with groovyBC
2D elbow pipe
• Navigate to system directory and open controlDict and add the following line at
the end of the file:
libs ("libgroovyBC.so")
• This will let you to use the groovyBc boundary condition you defined.
Module 7 - Lecture 4 10
How to implement new boundary condition with groovyBC
• Navigate to the case directory in the run directory and run the following commands:
1. $> cd $PTOFC/101programming/cases/2dElbowGroovyBC
2. $> foamCleanPolyMesh
3. $> foamCleanTutorials
4. $> fluentMeshToFoam ../../../meshes_and_geometries/elbow2d_1/ascii.msh
5. $> checkMesh
6. $> icoFoam
7. $> paraFoam
Module 7 - Lecture 4 11
Roadmap
1. Before we start
2. How to implement a new boundary condition
with groovyBC
3. How to implement a new boundary condition
with codeStream
Module 7 - Lecture 4 12
How to implement new boundary condition with codeStream
Module 7 - Lecture 4 13
How to implement new boundary condition with codeStream
What is codeStream?
• codeStream directly takes C++ code which is compiled and executed to deliver
the dictionary entry. This is another method in order to implement you new
boundary condition which needs more knowledge about coding.
• code: Specifies the code. You can specify your variables and functions
and the main result here.
• Navigate to the case directory and open the U file in the 0 directory:
1. $> cd $PTOFC/101programming/cases/2dElbowCodeStream
2. $> gedit 0/U
Module 7 - Lecture 4 15
How to implement new boundary condition with codeStream
29 velocity-inlet-5
30 {
31 type codedFixedValue;
32 value uniform (0 0 0);
• Line (31) refers to the type of
33 redirectType parabolicProfile; boundary condition. Line (33)
34 create a directory with the name of
35 code
36 #{ parabolicProfile with the
37 scalar U_0 = 2, r = 8;
38 const fvPatch& boundaryPatch = patch();
make directory, C and H files in
39 const vectorField& Cf = boundaryPatch.Cf(); dynamicCode directory.
40 vectorField& field = *this;
41 • patch() command lets us to
42 forAll(Cf, faceI)
43 { access to the boundary mesh and
44 field[faceI] = vector(U_0*(Cf[faceI].y()/4 - pow(Cf[faceI].y(),2)/pow(r,2)),0,0); with Cf() we access to the face
45 // field[faceI] = vector(2,0,0);
46 } centers of that patch (line 38 and
47 39).
48 #};
49 • *this lets us to access to the
50 codeOptions
51 #{ velocity field.
52
53 -I$(LIB_SRC)/finiteVolume/lnInclude \ • forAll is a typedef loop in
54 -I$(LIB_SRC)/meshTools/lnInclude
55 OpenFOAM. With this command
56 #}; we loop over all face centers and
57
58 codeInclude calculate of new boundary
59 #{ condition for each face center.
60 #include "fvCFD.H"
61 #include <cmath>
62 #include <iostream>
63 #};
64 }
Module 7 - Lecture 4 16
How to implement new boundary condition with codeStream
• Navigate to the case directory in the run directory and run the following commands:
1. $> cd $PTOFC/101programming/cases/2dElbowCodeStream
2. $> foamCleanPolyMesh
3. $> foamCleanTutorials
4. $> fluentMeshToFoam ../../../meshes_and_geometries/elbow2d_1/ascii.msh
5. $> checkMesh
6. $> icoFoam
7. $> paraFoam
Module 7 - Lecture 4 17
How to implement new boundary condition with codeStream
Module 7 - Lecture 4 18
Additional activities
Exercises
Module 7 - Lecture 4 19
Additional activities
Exercises
• Define the paraboloid boundary condition with groovyBC and CodeStream and
compare the results.
• Add a time varying boundary condition with groovyBC. For this you need to refer to
the website of groovyBC.
• With groovyBC and CodeStream implement the following boundary condition for the
concentration of convection diffusion equation, implemented in the previous module:
Module 7 - Lecture 4 20
Module 7
Wrap up
Module 7 - Wrap up 1
Main takeaways
• After finishing this module, you should be able to do the following:
• Basic understanding of high level programming in OpenFOAM®.
• Implement the convection-diffusion equation from scratch.
• Program your own boundary conditions using high level programming.
• Leverage groovyBC to implement boundary conditions.
• Use codeStream to implement boundary conditions.
• Modify existing solvers.
• Understand the main structure of solvers and utilities.
• Explore the source code.
• Find information in the source code and the doxygen documentation.
Module 7 - Wrap up 2
Additional tutorials
• In the course’s directory ($PTOFC) you will find many tutorials (which are different from those
that come with the OpenFOAM® installation). We highly encourage you to go through each
one to understand and get functional using OpenFOAM®.
• Remember, in each case directory you will find a README.FIRST file with general instructions
of how to run the case.
• If you have a case of your own, let us know and we will try to do our best to help you to setup
your case. But remember, the physics is yours.
Module 7 - Wrap up 3