Validation & Veriﬁcation

in CFD with OpenFOAM
Manel Soria - ETSEIAT
We will learn:

•The difference between validation and veriﬁcation
•What is the MMS
•How to implement a new solver in openFOAM (can be useful!)
•How to run a set of simulations efﬁciently using Linux tools:
•sed
•for
•grep
•How to sample our openFOAM results and transfer them to Matlab
•What can we do in real life to (try to) ensure that our CFD results are
corect
Let’s begin !
By default, everything is wrong
… until you can prove it is correct

(or ﬁx it)
Technische Universität München
Motivation: Verification and Validation (V&V)
Verification
Process of assessing
software correctness and
numerical accuracy of the
solution to a given
mathematical model [1]
„Verification is solving the
equations right“ [2]
Highly accurate solutions are
necessary
Validation
Process of assessing the physical
accuracy of the mathematical model
based on comparison between
computational results and
experimental data [1]
„Validation is solving the right
equations“ [2]
High-quality results from experiments
are necessary
NUMERICAL
MODEL
REALITY
PHYSICAL
MODEL
Qualification
Verification Validation
3
V&V provides:
• evidence for code and results correctness
• concept of a quantitative accuracy assessment
1: Write a set of
equations (usually
ODE/PDE) that
implement physical
laws
2: Two steps
-Write a computer code to solve the
equations
-Choose a mesh, time step, residuals..
and solve numerically the equations
0: The reality
(inﬁntely subtle)
Technische Universität München
Motivation: Verification and Validation (V&V)
Verification
Process of assessing
software correctness and
numerical accuracy of the
solution to a given
mathematical model [1]
„Verification is solving the
equations right“ [2]
Highly accurate solutions are
necessary
Validation
Process of assessing the physical
accuracy of the mathematical model
based on comparison between
computational results and
experimental data [1]
„Validation is solving the right
equations“ [2]
High-quality results from experiments
are necessary
NUMERICAL
MODEL
REALITY
PHYSICAL
MODEL
Qualification
Verification Validation
3
V&V provides:
• evidence for code and results correctness
• concept of a quantitative accuracy assessment
Qualify the physical
and numerical
models for their use
in PREDICTIONS
Check that the
numerical solution
of the equations is
correct
Check that the
physical model is
accurate enough
Technische Universität München
Motivation: Verification and Validation (V&V)
Verification
Process of assessing
software correctness and
numerical accuracy of the
solution to a given
mathematical model [1]
„Verification is solving the
equations right“ [2]
Highly accurate solutions are
necessary
Validation
Process of assessing the physical
accuracy of the mathematical model
based on comparison between
computational results and
experimental data [1]
„Validation is solving the right
equations“ [2]
High-quality results from experiments
are necessary
NUMERICAL
MODEL
REALITY
PHYSICAL
MODEL
Qualification
Verification Validation
3
V&V provides:
• evidence for code and results correctness
• concept of a quantitative accuracy assessment
Holy Grial of
computational
enginering !!
SOLVE THE
EQUATIONS RIGHT
SOLVE THE
RIGHT EQUATIONS
Technische Universität München
Motivation: Verification and Validation (V&V)
Verification
Process of assessing
software correctness and
numerical accuracy of the
solution to a given
mathematical model [1]
„Verification is solving the
equations right“ [2]
Highly accurate solutions are
necessary
Validation
Process of assessing the physical
accuracy of the mathematical model
based on comparison between
computational results and
experimental data [1]
„Validation is solving the right
equations“ [2]
High-quality results from experiments
are necessary
NUMERICAL
MODEL
REALITY
PHYSICAL
MODEL
Qualification
Verification Validation
3
V&V provides:
• evidence for code and results correctness
• concept of a quantitative accuracy assessment
MATHEMATICAL
process
EXPERIMENTAL
process
Reality
Ideal world
Imperfect,
cheap copy
Mathematical reasoning
Validation and Veriﬁcation in Plato’s mind
Discovering (actually,
remembering) the ideal world
Never ! Are you joking ??
If you want to understand the stars, don’t observe them,
MMS: Method of Manufactured Solutions
D
PDE(u) = b
d
D:
Problem to be solved with OpenFoam:
d:
u = u
bc
∂u
∂n
=
∂u
∂n

bc
Only a few trivial cases have known analytic solution
Then, how can we check our solutions ?
.. what could be wrong?
-the code itself (not to be expected in OpenFoam)
-the mesh and/or the time step (most likely)
-the model used (e.g, turbulence model)
Given b and the b.c., ﬁnd u
MMS inverts the process to generate arbitrarily complex
solutions of our problem:
Generate u and then obtain (by derivation) b
Exemple: Conduction heat transfer equation
fvm::ddt(T) - fvm::laplacian(D, T) == B
∂T
∂t
−D

2
T
∂x
2
+

2
T
∂y
2
+

2
T
∂z
2

= B
∂T
∂t
−D∇
2
T = B
D: thermal diffusivity
OpenFoam representation:
We choose our domain to be [0:1]^3

To keep things simple, we choose T to be
only a function of x, and thermal diffusivity
to be 1. Example:

T=-4*x*(x-1)*(x-3/4)*(x-1/4)

… but in general, it can be (has to be) function of x,y,z

Then, by analitic derivation:

B=8*(x - 1)*(x - 1/4) + 8*(x - 1)*(x - 3/4) +
8*(x - 1/4)*(x - 3/4) + 8*x*(x - 1) + 8*x*(x - 1/4) +
8*x*(x - 3/4)

For lazy people.. use Matlab : (generaB)
clear all
close all
syms x y z t T B

T=-4*x*(x-1)*(x-3/4)*(x-1/4)

% ecuacion que vamos a resolver en OpenFOAM:
% fvm::ddt(T) - fvm::laplacian(DT, T) == B

% por tanto, este debe ser el termino fuente ..
B = diff(T,t) - DT*(diff(T,x,2)+diff(T,y,2)+diff(T,z,2) )

% Si queremos examinar los valores numericos de T o B, podemos hacerlo
% creando funciones a partir de los resultados simbolicos

fB=@(x,y,z,t) eval(char(B));
fT=@(x,y,z,t) eval(char(T));

fB(0,0.5,0.5,0.5)
fT(0,0.5,0.5,0.5)
Another example, again with thermal diffusivity equal to 1
T=-4*x*(x-1)*(x-3/4)*(x-1/4)*(x-7/10)*(x-8/10)*x^2

B = diff(T,t) - DT*(diff(T,x,2)+diff(T,y,2)+diff(T,z,2) )

B=simplify(B)

this yields:

B=
(x*(11200*x^5 - 29400*x^4 + 28485*x^3 - 12355*x^2 + 2271*x - 126))/50
B=
(x*(11200*x^5 - 29400*x^4 + 28485*x^3 - 12355*x^2 + 2271*x - 126))/50
T=-4*x*(x-1)*(x-3/4)*(x-1/4)*(x-7/10)*(x-8/10)*x^2
Now, we will use openFOAM to solve the problem:
∂T
∂t
−D

2
T
∂x
2
+

2
T
∂y
2
+

2
T
∂z
2

= B
where
B= (x*(11200*x^5 - 29400*x^4 + 28485*x^3 - 12355*x^2 + 2271*x - 126))/50

the domain is a 1x1x1 cube and:
T=0 in the x boundaries
dT/dn=0 in the y,z boundaries (to make it 1d)
Laplace equation,
can be solved with the available laplacianFoam, but to
introduce a RHS, we need to write a new solver

2
T = 0
A new solver in this case is surprisingly easy, it will only be
about 50 lines of C++ code !

… very easy (with the help of a friend) :)

Copy laplacianFoam source code in a separate folder

Info<< "Reading field B\n" << endl;
volScalarField B
(
IOobject
(
"B",
runTime.timeName(),
mesh,
IOobject::AUTO_WRITE
),
mesh
);
In laplacianFoam.C change the following:

1-Assign a value for B to each domain cell, as a function
of x,yz, and t
2-Change the PDE equation to be solved

in the original laplacianFoam, the equation is:

solve
(
fvm::ddt(T) - fvm::laplacian(DT, T)
);

This is C++ !
while (simple.loop())
{
Info<< "Time = " << runTime.timeName() << " peace & love " << runTime.value() << nl << endl;

forAll(B,celli) {
vector posicio=mesh.C()[celli];
double x,y,z,t; // get time & coordinates of our cell
x=posicio[0];
y=posicio[1];
z=posicio[2];
t=runTime.value();
// assign B value to our cell
B[celli]=(x*(11200.*x*x*x*x*x - 29400.*x*x*x*x + 28485.*x*x*x - 12355.*x*x + 2271.*x - 126.))/50.;
}

while (simple.correctNonOrthogonal())
{
solve
(
fvm::ddt(T) - fvm::laplacian(DT, T) == B // new equation to be solved
);
}

#include "write.H"

Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Before each time step, we calculate get the coordinates of our cell and
compute B(x,y,z,t)
Then, we include the scalar ﬁeld B at the RHS of the equation to be solved,
note the elegance of the notation !
In the Make folder, we change the name of the executable:

laplacianFoam.C

EXE = newlaplacianFoam

The new solver is compiled typing wmake, and then it has to
be copied to a folder in our path. The easier way to do so is:

wmake
cp newlaplacianFoam /folder/with/our/case

Then, once in the case folder, we will launch it as
./newlaplacianFoam
ﬁle to be compiled
name of the executable
We also need to create a deﬁnition for B ﬁeld in 0 folder
This is a bit nonsense as B will be assigned later, but it is the easier
solution
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 -1 1 0 0 0];
internalField uniform 0;
boundaryField
{
{
}
cold
{
type ﬁxedValue;
value uniform 0;
}
}
K/s
∂T
∂t
−D

2
T
∂x
2
+

2
T
∂y
2
+

2
T
∂z
2

= B
K/s K/m^2 K/s m^2/s
In constant/transportProperties, we specify thermal diffusivity=1

DT DT [ 0 2 -1 0 0 0 0 ] 1.0;

m^2/s
In constant/polyMesh/blockMeshDict, we specify:

blocks
(
hex (0 1 2 3 4 5 6 7) (10 10 10) simpleGrading (1 1 1)
);

In system/controlDict, we specify:

application laplacianFoam;

startFrom startTime;

startTime 0;

stopAt endTime;

endTime 1e6;

deltaT 1e6;

Steps to run a simulation (once the solver is ready):

1-With paper&pencil (or Matlab if you are as lazy as me)
-Generate T
-Obtain B
2-Insert B in OpenFoam and solve for T
-Edit solver to change B (take care with integers!!)
-Compile (wmake) and copy (cp) the executable
-Change constant/polyMesh/blockMeshDict (to test
different meshes)
-Change system/controlDict (if needed)
-Change system/sampleDict (if needed)
-Generate the new mesh: blockMesh
-Run the solver: ./newlaplacianFoam
We can see the results in paraview, but it will be better to use
the openFoam “sample” utility
speciﬁcations for sample are in system/sampleDict

// Fields to sample:
ﬁelds
(
T B
);

sets
(
lineX1
{
type uniform;
axis x;

start (0.0 0.5 0.5);
end (1.0 0.5 0.5);
nPoints 100;
}
);

100 points in line parallel to x axis,
from (0, 1/2, 1/2) to (1,1/2,1/2)
in /postProcessing/sets/1e+06, the ﬁle with our sample is created:

manel@ubuntu:~/Dropbox/CFD/cubeBpar/postProcessing/sets/1e
0 0 0
0.010101 0.000825318 1.97071e-05
0.020202 0.00165064 3.94142e-05
0.030303 0.00247595 5.91213e-05
0.040404 0.00330127 7.88284e-05
0.0505051 0.00412659 9.85355e-05
0.0606061 0.00495191 0.000118243
0.0707071 0.00577723 0.00013795
0.0808081 0.00660255 0.000157657
0.0909091 0.00742786 0.000177364

x B
T
We use Matlab to plot it and compare with the exact solution:
clear

ﬁleID = fopen('../cubeBpar/postProcessing/sets/1e+06/lineX1_B_T.xy','r');
formatSpec = '%f %f %f';
sizeA = [3 Inf];
DAT = fscanf(ﬁleID,formatSpec,sizeA);
% DAT contains: row 1: x positions; row 2: B; row 3: T
% Calculamos solucion analitica
y=0.5; % irrelevante, es unidimensional
z=0.5; % idem
t=0.5; % No se usa
for i=1:size(DAT,2) % numero de puntos
xv(i)=DAT(1,i);
x=xv(i);
Ta(i)=-4*x*(x-1)*(x-3/4)*(x-1/4)*(x-7/10)*(x-8/10)*x^2;
end
plot(xv,Ta,'b');
hold on
plot(DAT(1,:),DAT(3,:),'r');
x
T
openFoam (10)
exact
Steps to compare with the imposed analytical solution
(once the numerical solution has been computed):

1-Obtain a 1d cut of the T ﬁeld
-sample
we choose a 1d cut just because our problem is 1d, in
general, all the domain has to be sampled

2-Read it, and compute the exact solution in the same
positions, you can do it with Matlab or octave, gnuplot, …

T
Not too bad, but is it correct ?
How many control volumes do we need for an accurate solution?
We need to repeat the simulation with increasingly ﬁne meshes !
Can we do it automatically ?
Yes, we can !
x
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1.0;

vertices
(
(0 0 0)
(1 0 0)
(1 1 0)
(0 1 0)
(0 0 1)
(1 0 1)
(1 1 1)
(0 1 1)
);

blocks
(
hex (0 1 2 3 4 5 6 7) (#NX# 10 10) simpleGrading (1 1 1)
);

constant/polyMesh/blockMeshDict.NX (arbitrary name)
We will use the command sed to replace the string #NX#
with the number of control volumes that we want, for instance 123:

cat blockMeshDict.NX | sed "s/#NX#/123/" > blockMeshDict
Type the ﬁle
blockMeshDict.NX, but
direct the output to the
next command (symbol
“|”)
Substitute #NX# by
123
Direct the output
to the ﬁle
blockMeshDict
We create a ﬁle called (for instance) doit_once, with :

cd constant/polyMesh/
cat blockMeshDict.NX | sed "s/#NX#/\$1/" > blockMeshDict
cd ../..
blockMesh
./newlaplacianFoam
sample
cp -r postProcessing postProcessing_\$1

Then, we type:
chmod +x doit_once
./doit_once 20

First parameter
Make it executable
Run with 20
Copy the
results to another
folder
for x in 5 10 20 40 80 160 320 640 1280
do
echo \$x
./doit_once \$x
done
We create doit_all, with :
x
T
!x
error
!x
2
Max (T
!x
-Ta)
The meaning of it all
82CHAPTER 11. FINITE DIFFERENCE APPROXIMATIONOF DERIVATIVES
Second the truncation error is T.E. ∼ O(∆x
i−1
∆x
i
) and is second order, that is
if the grid spacing is decreased by 1/2, the T.E. error decreases by factor of 2
2
.
Thirdly, the previous point can be made clearer by focussing on the important case
where the grid spacing is constant: ∆x
i−1
= ∆x
i
= ∆x, the expression simpliﬁes
to:
u
i+1
−u
i−1
2∆x

∂u
∂x
Ø
Ø
Ø
Ø
Ø
x
i
=
∆x
2
3!

3
u
∂x
3
Ø
Ø
Ø
Ø
Ø
x
i
+. . . (11.22)
Hence, for an equally spaced grid the centered diﬀerence approximation converges
∂u
∂x
Ø
Ø
Ø
Ø
Ø
x
i
=
u
i+1
−u
i−1
2∆x
+O(∆x
2
) (11.23)
Note that like the forward and backward Euler diﬀerence formula, the centered dif-
ference uses information at only two points but delivers twice the order of the other
two methods. This property will hold in general whenever the grid spacing is con-
stant and the computational stencil, i.e. the set of points used in approximating
the derivative, is symmetric.
11.3.2 Higher order approximation
The Taylor expansion provides a very useful tool for the derivation of higher or-
der approximation to derivatives of any order. There are several approaches to
achieve this. We will ﬁrst look at an expendient one before elaborating on the
more systematic one. In most of the following we will assume the grid spacing to
be constant as is usually the case in most applications.
Equation (11.22) provides us with the simplest way to derive a fourth order ap-
proximation. An important property of this centered formula is that its truncation
error contains only odd derivative terms:
u
i+1
−u
i−1
2∆x
=
∂u
∂x
+
∆x
2
3!

3
u
∂x
3
+
∆x
4
5!

5
u
∂x
5
+
∆x
6
7!

7
u
∂x
7
+. . . +
∆x
2m
(2m+ 1)!

(2m+1)
u
∂x
(2m+1)
+. . .
(11.24)
The above formula can be applied with ∆x replace by 2∆x, and 3∆x respectively
to get:
u
i+2
−u
i−2
4∆x
=
∂u
∂x
+
(2∆x)
2
3!

3
u
∂x
3
+
(2∆x)
4
5!

5
u
∂x
5
+
(2∆x)
6
7!

7
u
∂x
7
+O(∆x
8
) (11.25)
u
i+3
−u
i−3
6∆x
=
∂u
∂x
+
(3∆x)
2
3!

3
u
∂x
3
+
(3∆x)
4
5!

5
u
∂x
5
+
(3∆x)
6
7!

7
u
∂x
7
+O(∆x
8
) (11.26)
It is now clear how to combine the diﬀerent estimates to obtain a fourth order
approximation to the ﬁrst derivative. Multiplying equation (11.24) by 2
2
and
78CHAPTER 11. FINITE DIFFERENCE APPROXIMATIONOF DERIVATIVES
x
i−1
x
i
x
i+1
Figure 11.1: Computational grid and example of backward, forward, and central
approximation to the derivative at point x
i
. The dash-dot line shows the centered
parabolic interpolation, while the dashed line show the backward (blue), forward
(red) and centered (magenta) linear interpolation to the function.
Intuitively, the approximation will improve, i.e. the error will be smaller, as ∆x is
made smaller. The above is not the only approximation possible, two equally valid
approximations are:
backward Euler:
u
0
(x
i
) ≈
u(x
i
) −u(x
i
−∆x)
∆x
=
u
i
−u
i−1
∆x
(11.3)
Centered Diﬀerence
u
0
(x
i
) ≈
u(x
i
+∆x) −u(x
i
−∆x)
2∆x
=
u
i+1
−u
i−1
2∆x
(11.4)
All these deﬁnitions are equivalent in the continuum but lead to diﬀerent approx-
imations in the discrete case. The question becomes which one is better, and is
80CHAPTER 11. FINITE DIFFERENCE APPROXIMATIONOF DERIVATIVES
If the (n+1)-th derivative of the function u has minimum m and maximum M
over the interval [x
i
x] then we can write:
Z
x
x
i
· · ·
Z
x
x
i
m( ds)
n+1
≤ R
n+1

Z
x
x
i
· · ·
Z
x
x
i
M( ds)
n+1
(11.12)
m
(x −x
i
)
n+1
(n + 1)!
≤ R
n+1
≤ M
(x −x
i
)
n+1
(n + 1)!
(11.13)
which shows that the remainder is bounded by the values of the derivative and the
distance of the point x to the expansion point x
i
raised to the power (n + 1). If
we further assume that u
(n+1)
is continuous then it must take all values between
m and M that is
R
n+1
= u
(n+1)
(ξ)
(x −x
i
)
n+1
(n + 1)!
(11.14)
for some ξ in the interval [x
i
x].
11.3.1 Taylor series and ﬁnite diﬀerences
Taylor series have been widely used to study the behavior of numerical approxi-
mation to diﬀerential equations. Let us investigate the forward Euler with Taylor
series. To do so, we expand the function u at x
i+1
i
:
u(x
i
+∆x
i
) = u(x
i
) +∆x
i
∂u
∂x
Ø
Ø
Ø
Ø
Ø
x
i
+
∆x
2
i
2!

2
u
∂x
2
Ø
Ø
Ø
Ø
Ø
x
i
+
∆x
3
i
3!

3
u
∂x
3
Ø
Ø
Ø
Ø
Ø
x
i
+. . . (11.15)
The Taylor series can be rearranged to read as follows:
u(x
i
+∆x
i
) −u(x
i
)
∆x
i

∂u
∂x
Ø
Ø
Ø
Ø
Ø
x
i
=
∆x
i
2!

2
u
∂x
2
Ø
Ø
Ø
Ø
Ø
x
i
+
∆x
2
i
3!

3
u
∂x
3
Ø
Ø
Ø
Ø
Ø
x
i
+. . .
| {z }
Truncation Error
(11.16)
where it is now clear that the forward Euler formula (11.2) corresponds to truncat-
ing the Taylor series after the second term. The right hand side of equation (11.16)
is the error committed in terminating the series and is referred to as the trun-
cation error. The tuncation error can be deﬁned as the diﬀerence between the
partial derivative and its ﬁnite diﬀerence representation. For suﬃciently smooth
functions, i.e. ones that possess continuous higher order derivatives, and suﬃ-
ciently small ∆x
i
, the ﬁrst term in the series can be used to characterize the order
of magnitude of the error. The ﬁrst term in the truncation error is the product
of the second derivative evaluated at x
i
and the grid spacing ∆x
i
: the former is a
property of the function itself while the latter is a numerical parameter which can
be changed. Thus, for ﬁnite

2
u
∂x
2
, the numerical approximation depends lineraly on
the parameter ∆x
i
. If we were to half ∆x
i
we ought to expect a linear decrease
First order
approximation
Second order
approximation
http://www.rsmas.miami.edu/personal/miskandarani/Courses/MSC321/lectﬁniteDifference.pdf
82CHAPTER 11. FINITE DIFFERENCE APPROXIMATIONOF DERIVATIVES
Second the truncation error is T.E. ∼ O(∆x
i−1
∆x
i
) and is second order, that is
if the grid spacing is decreased by 1/2, the T.E. error decreases by factor of 2
2
.
Thirdly, the previous point can be made clearer by focussing on the important case
where the grid spacing is constant: ∆x
i−1
= ∆x
i
= ∆x, the expression simpliﬁes
to:
u
i+1
−u
i−1
2∆x

∂u
∂x
Ø
Ø
Ø
Ø
Ø
x
i
=
∆x
2
3!

3
u
∂x
3
Ø
Ø
Ø
Ø
Ø
x
i
+. . . (11.22)
Hence, for an equally spaced grid the centered diﬀerence approximation converges
∂u
∂x
Ø
Ø
Ø
Ø
Ø
x
i
=
u
i+1
−u
i−1
2∆x
+O(∆x
2
) (11.23)
Note that like the forward and backward Euler diﬀerence formula, the centered dif-
ference uses information at only two points but delivers twice the order of the other
two methods. This property will hold in general whenever the grid spacing is con-
stant and the computational stencil, i.e. the set of points used in approximating
the derivative, is symmetric.
11.3.2 Higher order approximation
The Taylor expansion provides a very useful tool for the derivation of higher or-
der approximation to derivatives of any order. There are several approaches to
achieve this. We will ﬁrst look at an expendient one before elaborating on the
more systematic one. In most of the following we will assume the grid spacing to
be constant as is usually the case in most applications.
Equation (11.22) provides us with the simplest way to derive a fourth order ap-
proximation. An important property of this centered formula is that its truncation
error contains only odd derivative terms:
u
i+1
−u
i−1
2∆x
=
∂u
∂x
+
∆x
2
3!

3
u
∂x
3
+
∆x
4
5!

5
u
∂x
5
+
∆x
6
7!

7
u
∂x
7
+. . . +
∆x
2m
(2m+ 1)!

(2m+1)
u
∂x
(2m+1)
+. . .
(11.24)
The above formula can be applied with ∆x replace by 2∆x, and 3∆x respectively
to get:
u
i+2
−u
i−2
4∆x
=
∂u
∂x
+
(2∆x)
2
3!

3
u
∂x
3
+
(2∆x)
4
5!

5
u
∂x
5
+
(2∆x)
6
7!

7
u
∂x
7
+O(∆x
8
) (11.25)
u
i+3
−u
i−3
6∆x
=
∂u
∂x
+
(3∆x)
2
3!

3
u
∂x
3
+
(3∆x)
4
5!

5
u
∂x
5
+
(3∆x)
6
7!

7
u
∂x
7
+O(∆x
8
) (11.26)
It is now clear how to combine the diﬀerent estimates to obtain a fourth order
approximation to the ﬁrst derivative. Multiplying equation (11.24) by 2
2
and
Second order approximation: error decreases with !x
2
IF is
-Small enough so that the factor !x
2
can vanish the other terms
-But no too small, as the ﬁrst derivative is evaluated as !u/!x and in the
limit this becomes 0/0

Some models (eg, LES) have an explicit dependande on the mesh size:

Lim LES = DNS
!x !0
V&V in the real world ?
Full veriﬁcation of CFD results, not no mention validation,
is too expensive to be carried out in all outine simulations.

However, USE AT LEAST A COUPLE OF MESHES and compare the
results

In CFD it is almost compulsory to compare at least one simulation and
one experiment; if the results agree reasonably well, simulations can be
applied to similar situations.

Sometimes, even if there is a signiﬁcant disagreement (say, a 20% error
in the drag coefﬁcient), the results can show correctly the trends (e.g,
the increse/decrease in drag when some parameter is increased/
decreased)
To conclude…

DO
•Begin with a similar problem that has a known solution, look in
literature for experimental results; reproduce it and understand the
resuts
•Use AT LEAST two or (better) three different meshes of different
densities to evaluate how close to the mesh independent solution are
you
•Be specially careful with turbulence models !!

NEVER DO
•Never launch a simulation with a model (ie, multiphase, compressible,
LES..) if you don’t understand the equations and the physics behind .
•Never be satisﬁed with a single solution. If you can reﬁne the mesh,
generate a coarser mesh.
•Be impressed by the beauty of possibly wrong solutions

REMEMBER:
One day CFD will be reliable and wind tunnels will be closed; until then,
take care !