Dynamic Mesh
in OpenFOAM
Fumiya Nozaki
Last updated: 31 December 2015
114 PAGES
1
Disclaimer
“This offering is not approved or
endorsed by OpenCFD Limited,
the producer of the OpenFOAM
software and owner of the
OPENFOAM® and OpenCFD®
trade marks.”
2
Dynamic Mesh in OpenFOAM
In OpenFOAM, the mesh motions and the topology
changes are handled by Dynamic Mesh functionality.
Settings for Dynamic Mesh are described in
dynamicMeshDict file located in the constant directory.
Solvers that can handle these mesh changes have the
letters “DyM”, an abbreviation for Dynamic Mesh, in its
name.
e.g. pimpleDyMFoam, interDyMFoam
3
Dynamic Mesh in OpenFOAM
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMesh solidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solidBodyMotionFvMeshCoeffs
{
cellZone rotor;
solidBodyMotionFunction rotatingMotion;
rotatingMotionCoeffs
{
origin (0 0 0);
axis (0 0 1);
omega 6.2832; // rad/s
}
}
// ************************************************************************* //
constant/dynamicMeshDict
Selection of dynamicFvMesh
type from available options
Settings for the selected
dynamicFvMesh
4
Dynamic Mesh in OpenFOAM
In OpenFOAM, the mesh motions and the topology
changes are handled by Dynamic Mesh functionality.
Settings for Dynamic Mesh are described in
dynamicMeshDict file located in the constant directory.
Solvers that can handle these mesh changes have the
letters “DyM”, an abbreviation for Dynamic Mesh, in its
name.
e.g. pimpleDyMFoam, interDyMFoam
5
while (runTime.run())
{
#include "readControls.H"
#include "CourantNo.H"
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
mesh.update();
// Calculate absolute flux from the mapped surface velocity
phi = mesh.Sf() & Uf;
if (mesh.changing() && correctPhi)
{
#include "correctPhi.H"
}
// Make the flux relative to the mesh motion
fvc::makeRelative(phi, U);
if (mesh.changing() && checkMeshCourantNo)
{
#include "meshCourantNo.H"
}
applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/pimpleDyMFoam.C
It calls the mesh motion library
to calculate the new position of
points and update the mesh.
Dynamic Mesh in OpenFOAM 6
Available types of dynamicFvMesh without topological changes
• staticFvMesh
Disable dynamic mesh
• solidBodyMotionFvMesh
Perform the rigid-body motions such as translational and rotational
movements
• multiSolidBodyMotionFvMesh
Perform the rigid-body motions in multiple regions
• dynamicMotionSolverFvMesh
Solve a Laplace’s equation for the motion displacement or motion
velocity to calculate the updated position of points
• dynamicInkJetFvMesh
Move mesh points sinusoidally in the x direction by explicitly calculating
the new positions
• dynamicRefineFvMesh
Refine the mesh depending on the user specified field values
7
Available types of dynamicFvMesh with topological changes
• rawTopoChangerFvMesh
• movingConeTopoFvMesh
• mixerFvMesh
• linearValveFvMesh
• linearValveLayersFvMesh
Under survey
8
Inheritance diagram for dynamicFvMesh models
dynamicFvMesh
staticFvMesh
dynamicInkJetFvMeshsolidBodyMotionFvMesh
multiSolidBodyMotionFvMesh
dynamicMotionSolverFvMesh
dynamicRefineFvMesh
Abstract base class for geometry
and/or topology changing fvMesh
9
Inheritance diagram for dynamicFvMesh models
dynamicFvMesh
rawTopoChangerFvMesh
movingConeTopoFvMesh
mixerFvMesh
linearValveFvMesh
linearValveLayersFvMesh
topoChangerFvMesh Abstract base class for
a topology changing fvMesh
10
solidBodyMotionFvMesh
Available types of solid motions
 Translational motions
• linearMotion : Uniform linear motion with constant velocity
• oscillatingLinearMotion : Oscillating linear motion
 Rotational motions
• rotatingMotion : Uniform circular motion
• axisRotationMotion : Uniform circular motion
• oscillatingRotatingMotion : Oscillating rotation motion
 Ship Design Analysis [1]
• SDA
 Tabulated data
• tabulated6DoFMotion
 Combination of above types
• multiMotion
12
linearMotion
dynamicFvMesh solidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solidBodyMotionFvMeshCoeffs
{
solidBodyMotionFunction linearMotion;
linearMotionCoeffs
{
velocity (1 0 0);
}
}
constant/dynamicMeshDict
13
oscillatingLinearMotion
dynamicFvMesh solidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solidBodyMotionFvMeshCoeffs
{
cellZone inletChannel;
solidBodyMotionFunction oscillatingLinearMotion;
oscillatingLinearMotionCoeffs
{
amplitude (0 0.5 0);
omega 3.14;
}
}
tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/
dynamicMeshDict
14
rotatingMotion
dynamicFvMesh solidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solidBodyMotionFvMeshCoeffs
{
cellZone rotor;
solidBodyMotionFunction rotatingMotion;
rotatingMotionCoeffs
{
origin (0 0 0);
axis (0 0 1);
omega 6.2832;
}
}
tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/dynamicMeshDict
15
axisRotationMotion
dynamicFvMesh solidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solidBodyMotionFvMeshCoeffs
{
cellZone rotor;
solidBodyMotionFunction axisRotationMotion;
axisRotationMotionCoeffs
{
origin (0 0 0);
radialVelocity (0 0 360);
}
}
tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/dynamicMeshDict
16
oscillatingRotatingMotion
dynamicFvMesh solidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solidBodyMotionFvMeshCoeffs
{
cellZone rotor;
solidBodyMotionFunction oscillatingRotatingMotion;
oscillatingRotatingMotionCoeffs
{
origin (0 0 0);
omega 6.28;
amplitude (0 0 45);
}
}
tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/dynamicMeshDict
17
oscillatingRotatingMotion
rotor
18
oscillatingRotatingMotion
rotor
19
oscillatingRotatingMotion
rotor
20
oscillatingRotatingMotion
rotor
21
oscillatingRotatingMotion
rotor
22
oscillatingRotatingMotion
rotor
23
oscillatingRotatingMotion
rotor
24
oscillatingRotatingMotion
rotor
25
oscillatingRotatingMotion
rotor
26
oscillatingRotatingMotion
rotor
27
oscillatingRotatingMotion
rotor
28
oscillatingRotatingMotion
rotor
29
oscillatingRotatingMotion
rotor
30
oscillatingRotatingMotion
rotor
31
oscillatingRotatingMotion
rotor
32
oscillatingRotatingMotion
rotor
33
oscillatingRotatingMotion
rotor
34
oscillatingRotatingMotion
rotor
35
oscillatingRotatingMotion
rotor
36
oscillatingRotatingMotion
rotor
37
oscillatingRotatingMotion
rotor
38
tabulated6DoFMotion
dynamicFvMesh solidBodyMotionFvMesh;
solidBodyMotionFvMeshCoeffs
{
solidBodyMotionFunction tabulated6DoFMotion;
tabulated6DoFMotionCoeffs
{
CofG (0 0 0);
timeDataFileName "$FOAM_CASE/constant/6DoF.dat";
}
}
tutorials/multiphase/interDyMFoam/ras/sloshingTank3D6DoF/constant/dynamicMeshDict
39
100
(
(0 ((0 0 0) (0 0 0)))
(0.40404 ((0.401298 0.952899 0.321827) (4.82741 2.79073 2.00649)))
(0.808081 ((0.786273 1.8071 0.635266) (9.52899 5.3597 3.93137)))
(1.21212 ((1.13927 2.47414 0.932149) (13.9822 7.5028 5.69634)))
(1.61616 ((1.44593 2.88493 1.20474) (18.071 9.04972 7.22963)))
(2.0202 ((1.69377 2.99691 1.44593) (21.6889 9.87755 8.46886)))
(2.42424 ((1.87273 2.7985 1.64943) (24.7414 9.92051 9.36363)))
(2.82828 ((1.97551 2.31024 1.80994) (27.1492 9.17518 9.87755)))
. . .
(40 ((1.82589 1.65428 -0.575807) (-8.6371 2.70906 9.12945)))
)
tutorials/multiphase/interDyMFoam/ras/sloshingTank3D6DoF/constant/6DoF.dat
tabulated6DoFMotion 40
multiMotion
dynamicFvMesh solidBodyMotionFvMesh;
solidBodyMotionFvMeshCoeffs
{
solidBodyMotionFunction multiMotion;
multiMotionCoeffs
{
// Table rotating in z axis
rotatingTable
{
solidBodyMotionFunction rotatingMotion;
rotatingMotionCoeffs
{
origin (0 0.1 0);
axis (0 0 1);
omega 6.2832; // rad/s
}
}
// Tube rocking on rotating table
rotatingBox
{
solidBodyMotionFunction oscillatingRotatingMotion;
oscillatingRotatingMotionCoeffs
{
origin (0 0 0);
omega 40;
amplitude (45 0 0);
}
}
}
}
tutorials/multiphase/interDyMFoam/ras/testTubeMixer/constant/dynamicMeshDict
// Table rotating in z axis
rotatingTable
{
solidBodyMotionFunction rotatingMotion;
rotatingMotionCoeffs
{
origin (0 0.1 0);
axis (0 0 1);
omega 6.2832;
}
}
// Tube rocking on rotating table
rotatingBox
{
solidBodyMotionFunction oscillatingRotatingMotion;
oscillatingRotatingMotionCoeffs
{
origin (0 0 0);
omega 40;
amplitude (45 0 0);
}
}
41
multiSolidBodyMotionFvMesh
dynamicMeshDict
dynamicFvMesh multiSolidBodyMotionFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
multiSolidBodyMotionFvMeshCoeffs
{
rotor1
{
solidBodyMotionFunction rotatingMotion;
rotatingMotionCoeffs
{
origin (0 0 0);
axis (0 0 1);
omega 3.1416;
}
}
rotor2
{
solidBodyMotionFunction rotatingMotion;
rotatingMotionCoeffs
{
origin (4 0 0);
axis (0 0 1);
omega -3.1416;
}
}
}
// ************************************************************************* //
constant/dynamicMeshDict
Different settings of rigid body
motions in multiple cellZones
43
An example usage
rotor2
rotor1
44
dynamicMotionSolverFvMesh
Brief description of dynamicMotionSolverFvMesh
 Solve a Laplace’s equation for the motion displacement 𝑑 𝑚 [𝑚] or motion
velocity 𝑢 𝑚 [ 𝑚 𝑠]:
𝛻 ∙ 𝛾𝛻𝑑 𝑚 = 0
or
𝛻 ∙ 𝛾𝛻𝑢 𝑚 = 0
 Users can select which equations to be solved.
 Users need to specify how to calculate the diffusion coefficient 𝛾 of the
equation.
46
dynamicMeshDict
dynamicFvMesh dynamicMotionSolverFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
solver velocityComponentLaplacian;
velocityComponentLaplacianCoeffs
{
component x;
diffusivity directional (1 200 0);
}
tutorials/incompressible/pimpleDyMFoam/movingCone/constant/dynamicMeshDict
 Users can select which equations to be solved by choosing the solver
from the available options.
 Users need to specify how to calculate the diffusion coefficient 𝛾 of
the equation by selecting from the options.
1
2
1
2
47
Available types of solver
 Solving for cellDisplacement (unit: [𝑚])
• displacementLaplacian
• displacementComponentLaplacian
• displacementInterpolation
• displacementLayeredMotion
• displacementSBRStress
 Solving for cellMotionU (unit: [ 𝑚 𝑠])
• velocityLaplacian
• velocityComponentLaplacian
48
Available types of solver | displacementLaplacian
void Foam::displacementLaplacianFvMotionSolver::solve()
{
// The points have moved so before interpolation update
// the motionSolver accordingly
movePoints(fvMesh_.points());
diffusivity().correct();
pointDisplacement_.boundaryField().updateCoeffs();
Foam::solve
(
fvm::laplacian
(
diffusivity().operator()(),
cellDisplacement_,
"laplacian(diffusivity,cellDisplacement)"
)
);
}
src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/
displacementLaplacianFvMotionSolver.C
Solving Laplace’s Eqn.
49
Available types of solver | velocityLaplacian
void Foam::velocityLaplacianFvMotionSolver::solve()
{
// The points have moved so before interpolation update
// the fvMotionSolver accordingly
movePoints(fvMesh_.points());
diffusivityPtr_->correct();
pointMotionU_.boundaryField().updateCoeffs();
Foam::solve
(
fvm::laplacian
(
diffusivityPtr_->operator()(),
cellMotionU_,
"laplacian(diffusivity,cellMotionU)"
)
);
}
src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/
velocityLaplacianFvMotionSolver.C
Solving Laplace’s Eqn.
50
Available types of diffusivity models
• uniform
• directional
• motionDirectional
• inverseVolume
• inverseDistance
• inverseFaceDistance
• inversePointDistance
• quadratic
• exponential
• file
51
Class diagram of diffusivity models
motionDiffusivity
uniformDiffusivity quadraticDiffusivity exponentialDiffusivity fileDiffusivity
directionalDiffusivity
motionDirectionalDiffusivity
inverseVolumeDiffusivity
inverseDistanceDiffusivity
inverseFaceDistanceDiffusivity
inversePointDistanceDiffusivity
 Source Code: src/fvMotionSolver/motionDiffusivity/
52
Class diagram of diffusivity models
motionDiffusivity class
//- Return diffusivity field
virtual tmp<surfaceScalarField> operator()() const = 0;
// Protected data
surfaceScalarField faceDiffusivity_;
correct()
//- Correct the motion diffusivity
virtual void correct() = 0;
uniformDiffusivity class
virtual tmp<surfaceScalarField> operator()() const
{
return faceDiffusivity_;
}
directionalDiffusivity class
motionDirectionalDiffusivity class
inverseVolumeDiffusivity class
inverseDistanceDiffusivity class
inverseFaceDistanceDiffusivity class
inversePointDistanceDiffusivity class
override
override
53
Class diagram of diffusivity models
motionDiffusivity class
//- Return diffusivity field
virtual tmp<surfaceScalarField> operator()() const = 0;
Foam::tmp<Foam::surfaceScalarField>
Foam::quadraticDiffusivity::operator()() const
{
return sqr(basicDiffusivityPtr_->operator()());
}
//- Correct the motion diffusivity
virtual void correct() = 0;
quadraticDiffusivity class
override
void Foam::quadraticDiffusivity::correct()
{
basicDiffusivityPtr_->correct();
}
54
Class diagram of diffusivity models
motionDiffusivity class
//- Return diffusivity field
virtual tmp<surfaceScalarField> operator()() const = 0;
Foam::tmp<Foam::surfaceScalarField>
Foam::exponentialDiffusivity::operator()() const
{
return exp(-alpha_/basicDiffusivityPtr_->operator()());
}
//- Correct the motion diffusivity
virtual void correct() = 0;
exponentialDiffusivity class
override
void Foam::exponentialDiffusivity::correct()
{
basicDiffusivityPtr_->correct();
}
55
Calculation of diffusion coefficient
void Foam::inverseVolumeDiffusivity::correct()
{
volScalarField V
(
IOobject
(
"V",
mesh().time().timeName(),
mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh(),
dimless,
zeroGradientFvPatchScalarField::typeName
);
V.internalField() = mesh().V();
V.correctBoundaryConditions();
faceDiffusivity_ = 1.0/fvc::interpolate(V);
}
src/fvMotionSolver/motionDiffusivity/inverseVolume/inverseVolumeDiffusivity.C
In the case of inverseVolume type,
faceDiffusivity_ is calculated as the
inverse of the cell volumes as its
name indicates.
 correct() function calculates the diffusion coefficient field faceDiffusivity_
56
• cmptMultiply(a, b) where 𝑎 = 𝑎0, 𝑎1, 𝑎2 , 𝑏 = 𝑏0, 𝑏1, 𝑏2
𝑐𝑚𝑝𝑡𝑀𝑢𝑙𝑡𝑖𝑝𝑙𝑦 𝑎, 𝑏 = 𝑎0 𝑏0, 𝑎1 𝑏1, 𝑎2 𝑏2
Calculation of diffusion coefficient
void Foam::directionalDiffusivity::correct()
{
const surfaceVectorField n(mesh().Sf()/mesh().magSf());
faceDiffusivity_ == (n & cmptMultiply(diffusivityVector_, n));
}
src/fvMotionSolver/motionDiffusivity/directional/directionalDiffusivity.C
In the case of directional type,
faceDiffusivity_ is calculated using
the user specified diffusivityVector_
and unit normal vectors of each face.
57
Mesh update process
bool Foam::dynamicMotionSolverFvMesh::update()
{
fvMesh::movePoints(motionPtr_->newPoints());
if (foundObject<volVectorField>("U"))
{
volVectorField& U =
const_cast<volVectorField&>(lookupObject<volVectorField>("U"));
U.correctBoundaryConditions();
}
return true;
}
src/dynamicFvMesh/dynamicMotionSolverFvMesh/dynamicMotionSolverFvMesh.C
Foam::tmp<Foam::pointField> Foam::motionSolver::newPoints()
{
solve();
return curPoints();
}
src/dynamicMesh/motionSolver/motionSolver/motionSolver.C
 mesh.update() calls update() function of dynamicMotionSolverFvMesh class.
58
void Foam::velocityComponentLaplacianFvMotionSolver::solve()
{
// The points have moved so before interpolation update
// the fvMotionSolver accordingly
movePoints(fvMesh_.points());
diffusivityPtr_->correct();
pointMotionU_.boundaryField().updateCoeffs();
Foam::solve
(
fvm::laplacian
(
diffusivityPtr_->operator()(),
cellMotionU_,
"laplacian(diffusivity,cellMotionU)"
)
);
}
src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/
velocityComponentLaplacianFvMotionSolver.C
Foam::tmp<Foam::pointField> Foam::motionSolver::newPoints()
{
solve();
return curPoints();
}
src/dynamicMesh/motionSolver/motionSolver/motionSolver.C
Solve Laplace’s Eqn.
Update the diffusion
coefficient field
Mesh update process 59
Foam::tmp<Foam::pointField> Foam::motionSolver::newPoints()
{
solve();
return curPoints();
}
src/dynamicMesh/motionSolver/motionSolver/motionSolver.C
Foam::tmp<Foam::pointField>
Foam::velocityComponentLaplacianFvMotionSolver::curPoints() const
{
volPointInterpolation::New(fvMesh_).interpolate
(
cellMotionU_,
pointMotionU_
);
tmp<pointField> tcurPoints(new pointField(fvMesh_.points()));
tcurPoints().replace
(
cmpt_,
tcurPoints().component(cmpt_)
+ fvMesh_.time().deltaTValue()*pointMotionU_.internalField()
);
twoDCorrectPoints(tcurPoints());
return tcurPoints;
}
src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/
velocityComponentLaplacianFvMotionSolver.C
Calculate the new
position of points
Interpolate the motion velocity
from cell centres to points
Mesh update process 60
movingWall
{
type uniformFixedValue;
uniformValue constant 1;
}
Moving at constant
velocity of 1m/s
“farField.*”
{
type slip;
}
movingCone tutorial 61
movingCone tutorial 62
movingCone tutorial 63
movingCone tutorial 64
movingCone tutorial 65
movingCone tutorial 66
movingCone tutorial 67
movingCone tutorial 68
movingCone tutorial 69
movingCone tutorial 70
movingCone tutorial 71
movingCone tutorial 72
movingCone tutorial 73
movingCone tutorial 74
movingCone tutorial 75
movingCone tutorial 76
dynamicInkJetFvMesh
Brief description of dynamicInkJetFvMesh
 From the description in the header file
 Mesh motion specifically for the "pumping" system of an ink-jet injector.

The set of points in the "pumping" region are compressed and expanded
sinusoidally to impose a sinusoidal variation of the flow at the nozzle exit.
Points can move only in the X direction
78
Brief description of dynamicInkJetFvMesh
Points can move only in the X direction
 From the description in the header file
 Mesh motion specifically for the "pumping" system of an ink-jet injector.

The set of points in the "pumping" region are compressed and expanded
sinusoidally to impose a sinusoidal variation of the flow at the nozzle exit.
79
An example usage
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMesh dynamicInkJetFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
dynamicInkJetFvMeshCoeffs
{
amplitude 0.5;
frequency 1;
refPlaneX 0.0;
}
// ************************************************************************* //
constant/dynamicMeshDict
Three input parameters
control the mesh motions
80
An example usage
refPlaneX
-1.0 -0.5 0.0 0.5 1.0
81
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
82
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
83
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
84
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
85
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
86
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
87
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
88
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
89
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
90
An example usage
-1.0 -0.5 0.0 0.5 1.0
refPlaneX
91
Calculation of the new position of points
bool Foam::dynamicInkJetFvMesh::update()
{
scalar scalingFunction =
0.5*
(
::cos(constant::mathematical::twoPi*frequency_*time().value())
- 1.0
);
Info<< "Mesh scaling. Time = " << time().value() << " scaling: "
<< scalingFunction << endl;
pointField newPoints = stationaryPoints_;
newPoints.replace
(
vector::X,
stationaryPoints_.component(vector::X)*
(
1.0
+ pos
(
- (stationaryPoints_.component(vector::X))
- refPlaneX_
)*amplitude_*scalingFunction
)
);
src/dynamicFvMesh/dynamicInkJetFvMesh/dynamicInkJetFvMesh.C
Explicitly calculate
the new position of points
Modify only the x-coordinate
92
Calculation of the new position of points
fvMesh::movePoints(newPoints);
volVectorField& U =
const_cast<volVectorField&>(lookupObject<volVectorField>("U"));
U.correctBoundaryConditions();
return true;
}
src/dynamicFvMesh/dynamicInkJetFvMesh/dynamicInkJetFvMesh.C
93
dynamicRefineFvMesh
Under survey
movingConeTopoFvMesh
Brief description of movingConeTopoFvMesh
 From the description in the header file
 Sample topoChangerFvMesh that moves an object in x direction
 and introduces/removes layers.
 It is designed exclusively for use with the movingCone tutorial.
96
An example usage
dynamicFvMesh movingConeTopoFvMesh;
motionSolverLibs ( "libfvMotionSolvers.so" );
movingConeTopoFvMeshCoeffs
{
motionVelAmplitude (1.5 0.0 0.0);
motionVelPeriod 0.003;
leftEdge 0.0;
leftObstacleEdge 0.0;
rightObstacleEdge 0.0;
right
{
minThickness 3e-5;
maxThickness 6e-5;
}
left
{
minThickness 3e-5;
maxThickness 5e-5;
}
}
constant/dynamicMeshDict
These parameters are required
but not used.
97
 Read dynamicMeshDict and set the values of private data
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::movingConeTopoFvMesh::movingConeTopoFvMesh(const IOobject& io)
:
topoChangerFvMesh(io),
motionDict_
(
IOdictionary
(
IOobject
(
"dynamicMeshDict",
time().constant(),
*this,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
).subDict(typeName + "Coeffs")
),
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
Constructors 98
motionVelAmplitude_(motionDict_.lookup("motionVelAmplitude")),
motionVelPeriod_(readScalar(motionDict_.lookup("motionVelPeriod"))),
curMotionVel_
(
motionVelAmplitude_*
Foam::sin(time().value()*M_PI/motionVelPeriod_)
),
leftEdge_(readScalar(motionDict_.lookup("leftEdge"))),
curLeft_(readScalar(motionDict_.lookup("leftObstacleEdge"))),
curRight_(readScalar(motionDict_.lookup("rightObstacleEdge")))
{
Pout<< "Initial time:" << time().value()
<< " Initial curMotionVel_:" << curMotionVel_
<< endl;
addZonesAndModifiers();
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
Constructors (cont’d)
Read the parameters
from dynamicMeshDict
• motionVelAmplitude
• motionVelPeriod
• leftEdge
• leftObstacleEdge
• rightObstacleEdge
Create two faceZones
• rightExtrusionFaces
• leftExtrusionFaces
and modifiers for motion action
99
curLeft_ = average
(
faceZones()
[
faceZones().findZoneID("leftExtrusionFaces")
]().localPoints()
).x() - SMALL;
curRight_ = average
(
faceZones()
[
faceZones().findZoneID("rightExtrusionFaces")
]().localPoints()
).x() + SMALL;
motionMask_ = vertexMarkup
(
points(),
curLeft_,
curRight_
);
}
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
Constructors (cont’d) 100
The initial x-coordinates of left and
right sides of the moving obstacle
(curLeft_ and curRight_) are calculated
using the faceZones.
addZonesAndModifiers
void Foam::movingConeTopoFvMesh::addZonesAndModifiers()
{
// Add zones and modifiers for motion action
if
(
pointZones().size()
|| faceZones().size()
|| cellZones().size()
|| topoChanger_.size()
)
{
Info<< "void movingConeTopoFvMesh::addZonesAndModifiers() : "
<< "Zones and modifiers already present. Skipping."
<< endl;
return;
}
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
101
 Create two faceZones and modifiers for motion action
addZonesAndModifiers
Info<< "Time = " << time().timeName() << endl
<< "Adding zones and modifiers to the mesh" << endl;
const vectorField& fc = faceCentres();
const vectorField& fa = faceAreas();
labelList zone1(fc.size());
boolList flipZone1(fc.size(), false);
label nZoneFaces1 = 0;
labelList zone2(fc.size());
boolList flipZone2(fc.size(), false);
label nZoneFaces2 = 0;
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
102
addZonesAndModifiers
forAll(fc, faceI)
{
if
(
fc[faceI].x() > -0.003501
&& fc[faceI].x() < -0.003499
)
{
if ((fa[faceI] & vector(1, 0, 0)) < 0)
{
flipZone1[nZoneFaces1] = true;
}
zone1[nZoneFaces1] = faceI;
Info<< "face " << faceI << " for zone 1. Flip: "
<< flipZone1[nZoneFaces1] << endl;
nZoneFaces1++;
}
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
103
The faces whose center x-coordinates are
greater than -0.003501 and less than -0.003499
are added to the labelList zone1.
These hard-coded values are designed for movingCone tutorial.
For
movingCone
tutorial
addZonesAndModifiers
else if
(
fc[faceI].x() > -0.00701
&& fc[faceI].x() < -0.00699
)
{
if ((fa[faceI] & vector(1, 0, 0)) > 0)
{
flipZone2[nZoneFaces2] = true;
}
zone2[nZoneFaces2] = faceI;
Info<< "face " << faceI << " for zone 2. Flip: "
<< flipZone2[nZoneFaces2] << endl;
nZoneFaces2++;
}
}
zone1.setSize(nZoneFaces1);
flipZone1.setSize(nZoneFaces1);
zone2.setSize(nZoneFaces2);
flipZone2.setSize(nZoneFaces2);
Info<< "zone: " << zone1 << endl;
Info<< "zone: " << zone2 << endl;
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
104
The faces whose center x-coordinates are
greater than -0.00701 and less than -0.00699
are added to the labelList zone2.
Reset the size of four lists.
For
movingCone
tutorial
addZonesAndModifiers
List<pointZone*> pz(0);
List<faceZone*> fz(2);
List<cellZone*> cz(0);
label nFz = 0;
fz[nFz] =
new faceZone
(
"rightExtrusionFaces",
zone1,
flipZone1,
nFz,
faceZones()
);
nFz++;
fz[nFz] =
new faceZone
(
"leftExtrusionFaces",
zone2,
flipZone2,
nFz,
faceZones()
);
nFz++;
fz.setSize(nFz);
Info<< "Adding mesh zones." << endl;
addZones(pz, fz, cz);
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
105
Create two faceZones
• rightExtrusionFaces
from zone1 and flipZone1
• leftExtrusionFaces
from zone2 and flipZone2
addZonesAndModifiers
// Add layer addition/removal interfaces
List<polyMeshModifier*> tm(2);
label nMods = 0;
tm[nMods] =
new layerAdditionRemoval
(
"right",
nMods,
topoChanger_,
"rightExtrusionFaces",
readScalar
(
motionDict_.subDict("right").lookup("minThickness")
),
readScalar
(
motionDict_.subDict("right").lookup("maxThickness")
)
);
nMods++;
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
106
addZonesAndModifiers
tm[nMods] = new layerAdditionRemoval
(
"left",
nMods,
topoChanger_,
"leftExtrusionFaces",
readScalar
(
motionDict_.subDict("left").lookup("minThickness")
),
readScalar
(
motionDict_.subDict("left").lookup("maxThickness")
)
);
nMods++;
tm.setSize(nMods);
Info<< "Adding " << nMods << " mesh modifiers" << endl;
topoChanger_.addTopologyModifiers(tm);
write();
}
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
107
vertexMarkup
Foam::tmp<Foam::scalarField> Foam::movingConeTopoFvMesh::vertexMarkup
(
const pointField& p,
const scalar curLeft,
const scalar curRight
) const
{
Info<< "Updating vertex markup. curLeft: "
<< curLeft << " curRight: " << curRight << endl;
tmp<scalarField> tvertexMarkup(new scalarField(p.size()));
scalarField& vertexMarkup = tvertexMarkup();
forAll(p, pI)
{
if (p[pI].x() < curLeft - SMALL)
{
vertexMarkup[pI] = -1;
}
else if (p[pI].x() > curRight + SMALL)
{
vertexMarkup[pI] = 1;
}
else
{
vertexMarkup[pI] = 0;
}
}
return tvertexMarkup;
}
src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C
108
 Classify the points by their positions
vertexMarkup 109
curLeft curRight
-1 1
0
References
[1] Roll Motion of a Box and Interaction with Free-Surface
http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2009/ArashEslamdoost/RollMotionofaBoxandInteracti
onwithFreeSurface.pdf
[2] A tutorial on how to use Dynamic Mesh solver IcoDyMFOAM
http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2007/PiroozMoradnia/OpenFOAM-rapport.pdf
[3] Mesh motion alternatives
http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2009/AndreuOliverGonzalez/PresentationFINAL_Mesh
MotionAlternatives.pdf
[4] OpenFOAM project: A modification of the movingConeTopoFvMesh library
http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2008/ErikBjerklund/OpenFoamBjerklundE3.pdf
[5] Dynamic mesh in OpenFOAM
https://ilyasivkov.wordpress.com/2015/04/23/dynamic-mesh-in-openfoam/
110
This work is licensed under a Creative Commons
Attribution-ShareAlike 4.0 International License.
You should have received a copy of the license
along with this work. If not, see
<http://creativecommons.org/licenses/by-sa/4.0/>.
111

Dynamic Mesh in OpenFOAM

  • 1.
    Dynamic Mesh in OpenFOAM FumiyaNozaki Last updated: 31 December 2015 114 PAGES 1
  • 2.
    Disclaimer “This offering isnot approved or endorsed by OpenCFD Limited, the producer of the OpenFOAM software and owner of the OPENFOAM® and OpenCFD® trade marks.” 2
  • 3.
    Dynamic Mesh inOpenFOAM In OpenFOAM, the mesh motions and the topology changes are handled by Dynamic Mesh functionality. Settings for Dynamic Mesh are described in dynamicMeshDict file located in the constant directory. Solvers that can handle these mesh changes have the letters “DyM”, an abbreviation for Dynamic Mesh, in its name. e.g. pimpleDyMFoam, interDyMFoam 3
  • 4.
    Dynamic Mesh inOpenFOAM FoamFile { version 2.0; format ascii; class dictionary; location "constant"; object dynamicMeshDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dynamicFvMesh solidBodyMotionFvMesh; motionSolverLibs ( "libfvMotionSolvers.so" ); solidBodyMotionFvMeshCoeffs { cellZone rotor; solidBodyMotionFunction rotatingMotion; rotatingMotionCoeffs { origin (0 0 0); axis (0 0 1); omega 6.2832; // rad/s } } // ************************************************************************* // constant/dynamicMeshDict Selection of dynamicFvMesh type from available options Settings for the selected dynamicFvMesh 4
  • 5.
    Dynamic Mesh inOpenFOAM In OpenFOAM, the mesh motions and the topology changes are handled by Dynamic Mesh functionality. Settings for Dynamic Mesh are described in dynamicMeshDict file located in the constant directory. Solvers that can handle these mesh changes have the letters “DyM”, an abbreviation for Dynamic Mesh, in its name. e.g. pimpleDyMFoam, interDyMFoam 5
  • 6.
    while (runTime.run()) { #include "readControls.H" #include"CourantNo.H" #include "setDeltaT.H" runTime++; Info<< "Time = " << runTime.timeName() << nl << endl; mesh.update(); // Calculate absolute flux from the mapped surface velocity phi = mesh.Sf() & Uf; if (mesh.changing() && correctPhi) { #include "correctPhi.H" } // Make the flux relative to the mesh motion fvc::makeRelative(phi, U); if (mesh.changing() && checkMeshCourantNo) { #include "meshCourantNo.H" } applications/solvers/incompressible/pimpleFoam/pimpleDyMFoam/pimpleDyMFoam.C It calls the mesh motion library to calculate the new position of points and update the mesh. Dynamic Mesh in OpenFOAM 6
  • 7.
    Available types ofdynamicFvMesh without topological changes • staticFvMesh Disable dynamic mesh • solidBodyMotionFvMesh Perform the rigid-body motions such as translational and rotational movements • multiSolidBodyMotionFvMesh Perform the rigid-body motions in multiple regions • dynamicMotionSolverFvMesh Solve a Laplace’s equation for the motion displacement or motion velocity to calculate the updated position of points • dynamicInkJetFvMesh Move mesh points sinusoidally in the x direction by explicitly calculating the new positions • dynamicRefineFvMesh Refine the mesh depending on the user specified field values 7
  • 8.
    Available types ofdynamicFvMesh with topological changes • rawTopoChangerFvMesh • movingConeTopoFvMesh • mixerFvMesh • linearValveFvMesh • linearValveLayersFvMesh Under survey 8
  • 9.
    Inheritance diagram fordynamicFvMesh models dynamicFvMesh staticFvMesh dynamicInkJetFvMeshsolidBodyMotionFvMesh multiSolidBodyMotionFvMesh dynamicMotionSolverFvMesh dynamicRefineFvMesh Abstract base class for geometry and/or topology changing fvMesh 9
  • 10.
    Inheritance diagram fordynamicFvMesh models dynamicFvMesh rawTopoChangerFvMesh movingConeTopoFvMesh mixerFvMesh linearValveFvMesh linearValveLayersFvMesh topoChangerFvMesh Abstract base class for a topology changing fvMesh 10
  • 11.
  • 12.
    Available types ofsolid motions  Translational motions • linearMotion : Uniform linear motion with constant velocity • oscillatingLinearMotion : Oscillating linear motion  Rotational motions • rotatingMotion : Uniform circular motion • axisRotationMotion : Uniform circular motion • oscillatingRotatingMotion : Oscillating rotation motion  Ship Design Analysis [1] • SDA  Tabulated data • tabulated6DoFMotion  Combination of above types • multiMotion 12
  • 13.
    linearMotion dynamicFvMesh solidBodyMotionFvMesh; motionSolverLibs ("libfvMotionSolvers.so" ); solidBodyMotionFvMeshCoeffs { solidBodyMotionFunction linearMotion; linearMotionCoeffs { velocity (1 0 0); } } constant/dynamicMeshDict 13
  • 14.
    oscillatingLinearMotion dynamicFvMesh solidBodyMotionFvMesh; motionSolverLibs ("libfvMotionSolvers.so" ); solidBodyMotionFvMeshCoeffs { cellZone inletChannel; solidBodyMotionFunction oscillatingLinearMotion; oscillatingLinearMotionCoeffs { amplitude (0 0.5 0); omega 3.14; } } tutorials/incompressible/pimpleDyMFoam/oscillatingInletACMI2D/constant/ dynamicMeshDict 14
  • 15.
    rotatingMotion dynamicFvMesh solidBodyMotionFvMesh; motionSolverLibs ("libfvMotionSolvers.so" ); solidBodyMotionFvMeshCoeffs { cellZone rotor; solidBodyMotionFunction rotatingMotion; rotatingMotionCoeffs { origin (0 0 0); axis (0 0 1); omega 6.2832; } } tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/dynamicMeshDict 15
  • 16.
    axisRotationMotion dynamicFvMesh solidBodyMotionFvMesh; motionSolverLibs ("libfvMotionSolvers.so" ); solidBodyMotionFvMeshCoeffs { cellZone rotor; solidBodyMotionFunction axisRotationMotion; axisRotationMotionCoeffs { origin (0 0 0); radialVelocity (0 0 360); } } tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/dynamicMeshDict 16
  • 17.
    oscillatingRotatingMotion dynamicFvMesh solidBodyMotionFvMesh; motionSolverLibs ("libfvMotionSolvers.so" ); solidBodyMotionFvMeshCoeffs { cellZone rotor; solidBodyMotionFunction oscillatingRotatingMotion; oscillatingRotatingMotionCoeffs { origin (0 0 0); omega 6.28; amplitude (0 0 45); } } tutorials/incompressible/pimpleDyMFoam/mixerVesselAMI2D/constant/dynamicMeshDict 17
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
    tabulated6DoFMotion dynamicFvMesh solidBodyMotionFvMesh; solidBodyMotionFvMeshCoeffs { solidBodyMotionFunction tabulated6DoFMotion; tabulated6DoFMotionCoeffs { CofG(0 0 0); timeDataFileName "$FOAM_CASE/constant/6DoF.dat"; } } tutorials/multiphase/interDyMFoam/ras/sloshingTank3D6DoF/constant/dynamicMeshDict 39
  • 40.
    100 ( (0 ((0 00) (0 0 0))) (0.40404 ((0.401298 0.952899 0.321827) (4.82741 2.79073 2.00649))) (0.808081 ((0.786273 1.8071 0.635266) (9.52899 5.3597 3.93137))) (1.21212 ((1.13927 2.47414 0.932149) (13.9822 7.5028 5.69634))) (1.61616 ((1.44593 2.88493 1.20474) (18.071 9.04972 7.22963))) (2.0202 ((1.69377 2.99691 1.44593) (21.6889 9.87755 8.46886))) (2.42424 ((1.87273 2.7985 1.64943) (24.7414 9.92051 9.36363))) (2.82828 ((1.97551 2.31024 1.80994) (27.1492 9.17518 9.87755))) . . . (40 ((1.82589 1.65428 -0.575807) (-8.6371 2.70906 9.12945))) ) tutorials/multiphase/interDyMFoam/ras/sloshingTank3D6DoF/constant/6DoF.dat tabulated6DoFMotion 40
  • 41.
    multiMotion dynamicFvMesh solidBodyMotionFvMesh; solidBodyMotionFvMeshCoeffs { solidBodyMotionFunction multiMotion; multiMotionCoeffs { //Table rotating in z axis rotatingTable { solidBodyMotionFunction rotatingMotion; rotatingMotionCoeffs { origin (0 0.1 0); axis (0 0 1); omega 6.2832; // rad/s } } // Tube rocking on rotating table rotatingBox { solidBodyMotionFunction oscillatingRotatingMotion; oscillatingRotatingMotionCoeffs { origin (0 0 0); omega 40; amplitude (45 0 0); } } } } tutorials/multiphase/interDyMFoam/ras/testTubeMixer/constant/dynamicMeshDict // Table rotating in z axis rotatingTable { solidBodyMotionFunction rotatingMotion; rotatingMotionCoeffs { origin (0 0.1 0); axis (0 0 1); omega 6.2832; } } // Tube rocking on rotating table rotatingBox { solidBodyMotionFunction oscillatingRotatingMotion; oscillatingRotatingMotionCoeffs { origin (0 0 0); omega 40; amplitude (45 0 0); } } 41
  • 42.
  • 43.
    dynamicMeshDict dynamicFvMesh multiSolidBodyMotionFvMesh; motionSolverLibs ("libfvMotionSolvers.so" ); multiSolidBodyMotionFvMeshCoeffs { rotor1 { solidBodyMotionFunction rotatingMotion; rotatingMotionCoeffs { origin (0 0 0); axis (0 0 1); omega 3.1416; } } rotor2 { solidBodyMotionFunction rotatingMotion; rotatingMotionCoeffs { origin (4 0 0); axis (0 0 1); omega -3.1416; } } } // ************************************************************************* // constant/dynamicMeshDict Different settings of rigid body motions in multiple cellZones 43
  • 44.
  • 45.
  • 46.
    Brief description ofdynamicMotionSolverFvMesh  Solve a Laplace’s equation for the motion displacement 𝑑 𝑚 [𝑚] or motion velocity 𝑢 𝑚 [ 𝑚 𝑠]: 𝛻 ∙ 𝛾𝛻𝑑 𝑚 = 0 or 𝛻 ∙ 𝛾𝛻𝑢 𝑚 = 0  Users can select which equations to be solved.  Users need to specify how to calculate the diffusion coefficient 𝛾 of the equation. 46
  • 47.
    dynamicMeshDict dynamicFvMesh dynamicMotionSolverFvMesh; motionSolverLibs ("libfvMotionSolvers.so" ); solver velocityComponentLaplacian; velocityComponentLaplacianCoeffs { component x; diffusivity directional (1 200 0); } tutorials/incompressible/pimpleDyMFoam/movingCone/constant/dynamicMeshDict  Users can select which equations to be solved by choosing the solver from the available options.  Users need to specify how to calculate the diffusion coefficient 𝛾 of the equation by selecting from the options. 1 2 1 2 47
  • 48.
    Available types ofsolver  Solving for cellDisplacement (unit: [𝑚]) • displacementLaplacian • displacementComponentLaplacian • displacementInterpolation • displacementLayeredMotion • displacementSBRStress  Solving for cellMotionU (unit: [ 𝑚 𝑠]) • velocityLaplacian • velocityComponentLaplacian 48
  • 49.
    Available types ofsolver | displacementLaplacian void Foam::displacementLaplacianFvMotionSolver::solve() { // The points have moved so before interpolation update // the motionSolver accordingly movePoints(fvMesh_.points()); diffusivity().correct(); pointDisplacement_.boundaryField().updateCoeffs(); Foam::solve ( fvm::laplacian ( diffusivity().operator()(), cellDisplacement_, "laplacian(diffusivity,cellDisplacement)" ) ); } src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/ displacementLaplacianFvMotionSolver.C Solving Laplace’s Eqn. 49
  • 50.
    Available types ofsolver | velocityLaplacian void Foam::velocityLaplacianFvMotionSolver::solve() { // The points have moved so before interpolation update // the fvMotionSolver accordingly movePoints(fvMesh_.points()); diffusivityPtr_->correct(); pointMotionU_.boundaryField().updateCoeffs(); Foam::solve ( fvm::laplacian ( diffusivityPtr_->operator()(), cellMotionU_, "laplacian(diffusivity,cellMotionU)" ) ); } src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/ velocityLaplacianFvMotionSolver.C Solving Laplace’s Eqn. 50
  • 51.
    Available types ofdiffusivity models • uniform • directional • motionDirectional • inverseVolume • inverseDistance • inverseFaceDistance • inversePointDistance • quadratic • exponential • file 51
  • 52.
    Class diagram ofdiffusivity models motionDiffusivity uniformDiffusivity quadraticDiffusivity exponentialDiffusivity fileDiffusivity directionalDiffusivity motionDirectionalDiffusivity inverseVolumeDiffusivity inverseDistanceDiffusivity inverseFaceDistanceDiffusivity inversePointDistanceDiffusivity  Source Code: src/fvMotionSolver/motionDiffusivity/ 52
  • 53.
    Class diagram ofdiffusivity models motionDiffusivity class //- Return diffusivity field virtual tmp<surfaceScalarField> operator()() const = 0; // Protected data surfaceScalarField faceDiffusivity_; correct() //- Correct the motion diffusivity virtual void correct() = 0; uniformDiffusivity class virtual tmp<surfaceScalarField> operator()() const { return faceDiffusivity_; } directionalDiffusivity class motionDirectionalDiffusivity class inverseVolumeDiffusivity class inverseDistanceDiffusivity class inverseFaceDistanceDiffusivity class inversePointDistanceDiffusivity class override override 53
  • 54.
    Class diagram ofdiffusivity models motionDiffusivity class //- Return diffusivity field virtual tmp<surfaceScalarField> operator()() const = 0; Foam::tmp<Foam::surfaceScalarField> Foam::quadraticDiffusivity::operator()() const { return sqr(basicDiffusivityPtr_->operator()()); } //- Correct the motion diffusivity virtual void correct() = 0; quadraticDiffusivity class override void Foam::quadraticDiffusivity::correct() { basicDiffusivityPtr_->correct(); } 54
  • 55.
    Class diagram ofdiffusivity models motionDiffusivity class //- Return diffusivity field virtual tmp<surfaceScalarField> operator()() const = 0; Foam::tmp<Foam::surfaceScalarField> Foam::exponentialDiffusivity::operator()() const { return exp(-alpha_/basicDiffusivityPtr_->operator()()); } //- Correct the motion diffusivity virtual void correct() = 0; exponentialDiffusivity class override void Foam::exponentialDiffusivity::correct() { basicDiffusivityPtr_->correct(); } 55
  • 56.
    Calculation of diffusioncoefficient void Foam::inverseVolumeDiffusivity::correct() { volScalarField V ( IOobject ( "V", mesh().time().timeName(), mesh(), IOobject::NO_READ, IOobject::NO_WRITE, false ), mesh(), dimless, zeroGradientFvPatchScalarField::typeName ); V.internalField() = mesh().V(); V.correctBoundaryConditions(); faceDiffusivity_ = 1.0/fvc::interpolate(V); } src/fvMotionSolver/motionDiffusivity/inverseVolume/inverseVolumeDiffusivity.C In the case of inverseVolume type, faceDiffusivity_ is calculated as the inverse of the cell volumes as its name indicates.  correct() function calculates the diffusion coefficient field faceDiffusivity_ 56
  • 57.
    • cmptMultiply(a, b)where 𝑎 = 𝑎0, 𝑎1, 𝑎2 , 𝑏 = 𝑏0, 𝑏1, 𝑏2 𝑐𝑚𝑝𝑡𝑀𝑢𝑙𝑡𝑖𝑝𝑙𝑦 𝑎, 𝑏 = 𝑎0 𝑏0, 𝑎1 𝑏1, 𝑎2 𝑏2 Calculation of diffusion coefficient void Foam::directionalDiffusivity::correct() { const surfaceVectorField n(mesh().Sf()/mesh().magSf()); faceDiffusivity_ == (n & cmptMultiply(diffusivityVector_, n)); } src/fvMotionSolver/motionDiffusivity/directional/directionalDiffusivity.C In the case of directional type, faceDiffusivity_ is calculated using the user specified diffusivityVector_ and unit normal vectors of each face. 57
  • 58.
    Mesh update process boolFoam::dynamicMotionSolverFvMesh::update() { fvMesh::movePoints(motionPtr_->newPoints()); if (foundObject<volVectorField>("U")) { volVectorField& U = const_cast<volVectorField&>(lookupObject<volVectorField>("U")); U.correctBoundaryConditions(); } return true; } src/dynamicFvMesh/dynamicMotionSolverFvMesh/dynamicMotionSolverFvMesh.C Foam::tmp<Foam::pointField> Foam::motionSolver::newPoints() { solve(); return curPoints(); } src/dynamicMesh/motionSolver/motionSolver/motionSolver.C  mesh.update() calls update() function of dynamicMotionSolverFvMesh class. 58
  • 59.
    void Foam::velocityComponentLaplacianFvMotionSolver::solve() { // Thepoints have moved so before interpolation update // the fvMotionSolver accordingly movePoints(fvMesh_.points()); diffusivityPtr_->correct(); pointMotionU_.boundaryField().updateCoeffs(); Foam::solve ( fvm::laplacian ( diffusivityPtr_->operator()(), cellMotionU_, "laplacian(diffusivity,cellMotionU)" ) ); } src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/ velocityComponentLaplacianFvMotionSolver.C Foam::tmp<Foam::pointField> Foam::motionSolver::newPoints() { solve(); return curPoints(); } src/dynamicMesh/motionSolver/motionSolver/motionSolver.C Solve Laplace’s Eqn. Update the diffusion coefficient field Mesh update process 59
  • 60.
    Foam::tmp<Foam::pointField> Foam::motionSolver::newPoints() { solve(); return curPoints(); } src/dynamicMesh/motionSolver/motionSolver/motionSolver.C Foam::tmp<Foam::pointField> Foam::velocityComponentLaplacianFvMotionSolver::curPoints()const { volPointInterpolation::New(fvMesh_).interpolate ( cellMotionU_, pointMotionU_ ); tmp<pointField> tcurPoints(new pointField(fvMesh_.points())); tcurPoints().replace ( cmpt_, tcurPoints().component(cmpt_) + fvMesh_.time().deltaTValue()*pointMotionU_.internalField() ); twoDCorrectPoints(tcurPoints()); return tcurPoints; } src/fvMotionSolver/fvMotionSolvers/componentVelocity/componentLaplacian/ velocityComponentLaplacianFvMotionSolver.C Calculate the new position of points Interpolate the motion velocity from cell centres to points Mesh update process 60
  • 61.
    movingWall { type uniformFixedValue; uniformValue constant1; } Moving at constant velocity of 1m/s “farField.*” { type slip; } movingCone tutorial 61
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
    Brief description ofdynamicInkJetFvMesh  From the description in the header file  Mesh motion specifically for the "pumping" system of an ink-jet injector.  The set of points in the "pumping" region are compressed and expanded sinusoidally to impose a sinusoidal variation of the flow at the nozzle exit. Points can move only in the X direction 78
  • 79.
    Brief description ofdynamicInkJetFvMesh Points can move only in the X direction  From the description in the header file  Mesh motion specifically for the "pumping" system of an ink-jet injector.  The set of points in the "pumping" region are compressed and expanded sinusoidally to impose a sinusoidal variation of the flow at the nozzle exit. 79
  • 80.
    An example usage FoamFile { version2.0; format ascii; class dictionary; location "constant"; object dynamicMeshDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // dynamicFvMesh dynamicInkJetFvMesh; motionSolverLibs ( "libfvMotionSolvers.so" ); dynamicInkJetFvMeshCoeffs { amplitude 0.5; frequency 1; refPlaneX 0.0; } // ************************************************************************* // constant/dynamicMeshDict Three input parameters control the mesh motions 80
  • 81.
  • 82.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 82
  • 83.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 83
  • 84.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 84
  • 85.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 85
  • 86.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 86
  • 87.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 87
  • 88.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 88
  • 89.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 89
  • 90.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 90
  • 91.
    An example usage -1.0-0.5 0.0 0.5 1.0 refPlaneX 91
  • 92.
    Calculation of thenew position of points bool Foam::dynamicInkJetFvMesh::update() { scalar scalingFunction = 0.5* ( ::cos(constant::mathematical::twoPi*frequency_*time().value()) - 1.0 ); Info<< "Mesh scaling. Time = " << time().value() << " scaling: " << scalingFunction << endl; pointField newPoints = stationaryPoints_; newPoints.replace ( vector::X, stationaryPoints_.component(vector::X)* ( 1.0 + pos ( - (stationaryPoints_.component(vector::X)) - refPlaneX_ )*amplitude_*scalingFunction ) ); src/dynamicFvMesh/dynamicInkJetFvMesh/dynamicInkJetFvMesh.C Explicitly calculate the new position of points Modify only the x-coordinate 92
  • 93.
    Calculation of thenew position of points fvMesh::movePoints(newPoints); volVectorField& U = const_cast<volVectorField&>(lookupObject<volVectorField>("U")); U.correctBoundaryConditions(); return true; } src/dynamicFvMesh/dynamicInkJetFvMesh/dynamicInkJetFvMesh.C 93
  • 94.
  • 95.
  • 96.
    Brief description ofmovingConeTopoFvMesh  From the description in the header file  Sample topoChangerFvMesh that moves an object in x direction  and introduces/removes layers.  It is designed exclusively for use with the movingCone tutorial. 96
  • 97.
    An example usage dynamicFvMeshmovingConeTopoFvMesh; motionSolverLibs ( "libfvMotionSolvers.so" ); movingConeTopoFvMeshCoeffs { motionVelAmplitude (1.5 0.0 0.0); motionVelPeriod 0.003; leftEdge 0.0; leftObstacleEdge 0.0; rightObstacleEdge 0.0; right { minThickness 3e-5; maxThickness 6e-5; } left { minThickness 3e-5; maxThickness 5e-5; } } constant/dynamicMeshDict These parameters are required but not used. 97
  • 98.
     Read dynamicMeshDictand set the values of private data // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // Construct from components Foam::movingConeTopoFvMesh::movingConeTopoFvMesh(const IOobject& io) : topoChangerFvMesh(io), motionDict_ ( IOdictionary ( IOobject ( "dynamicMeshDict", time().constant(), *this, IOobject::MUST_READ_IF_MODIFIED, IOobject::NO_WRITE, false ) ).subDict(typeName + "Coeffs") ), src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C Constructors 98
  • 99.
    motionVelAmplitude_(motionDict_.lookup("motionVelAmplitude")), motionVelPeriod_(readScalar(motionDict_.lookup("motionVelPeriod"))), curMotionVel_ ( motionVelAmplitude_* Foam::sin(time().value()*M_PI/motionVelPeriod_) ), leftEdge_(readScalar(motionDict_.lookup("leftEdge"))), curLeft_(readScalar(motionDict_.lookup("leftObstacleEdge"))), curRight_(readScalar(motionDict_.lookup("rightObstacleEdge"))) { Pout<< "Initial time:"<< time().value() << " Initial curMotionVel_:" << curMotionVel_ << endl; addZonesAndModifiers(); src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C Constructors (cont’d) Read the parameters from dynamicMeshDict • motionVelAmplitude • motionVelPeriod • leftEdge • leftObstacleEdge • rightObstacleEdge Create two faceZones • rightExtrusionFaces • leftExtrusionFaces and modifiers for motion action 99
  • 100.
    curLeft_ = average ( faceZones() [ faceZones().findZoneID("leftExtrusionFaces") ]().localPoints() ).x()- SMALL; curRight_ = average ( faceZones() [ faceZones().findZoneID("rightExtrusionFaces") ]().localPoints() ).x() + SMALL; motionMask_ = vertexMarkup ( points(), curLeft_, curRight_ ); } src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C Constructors (cont’d) 100 The initial x-coordinates of left and right sides of the moving obstacle (curLeft_ and curRight_) are calculated using the faceZones.
  • 101.
    addZonesAndModifiers void Foam::movingConeTopoFvMesh::addZonesAndModifiers() { // Addzones and modifiers for motion action if ( pointZones().size() || faceZones().size() || cellZones().size() || topoChanger_.size() ) { Info<< "void movingConeTopoFvMesh::addZonesAndModifiers() : " << "Zones and modifiers already present. Skipping." << endl; return; } src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 101  Create two faceZones and modifiers for motion action
  • 102.
    addZonesAndModifiers Info<< "Time =" << time().timeName() << endl << "Adding zones and modifiers to the mesh" << endl; const vectorField& fc = faceCentres(); const vectorField& fa = faceAreas(); labelList zone1(fc.size()); boolList flipZone1(fc.size(), false); label nZoneFaces1 = 0; labelList zone2(fc.size()); boolList flipZone2(fc.size(), false); label nZoneFaces2 = 0; src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 102
  • 103.
    addZonesAndModifiers forAll(fc, faceI) { if ( fc[faceI].x() >-0.003501 && fc[faceI].x() < -0.003499 ) { if ((fa[faceI] & vector(1, 0, 0)) < 0) { flipZone1[nZoneFaces1] = true; } zone1[nZoneFaces1] = faceI; Info<< "face " << faceI << " for zone 1. Flip: " << flipZone1[nZoneFaces1] << endl; nZoneFaces1++; } src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 103 The faces whose center x-coordinates are greater than -0.003501 and less than -0.003499 are added to the labelList zone1. These hard-coded values are designed for movingCone tutorial. For movingCone tutorial
  • 104.
    addZonesAndModifiers else if ( fc[faceI].x() >-0.00701 && fc[faceI].x() < -0.00699 ) { if ((fa[faceI] & vector(1, 0, 0)) > 0) { flipZone2[nZoneFaces2] = true; } zone2[nZoneFaces2] = faceI; Info<< "face " << faceI << " for zone 2. Flip: " << flipZone2[nZoneFaces2] << endl; nZoneFaces2++; } } zone1.setSize(nZoneFaces1); flipZone1.setSize(nZoneFaces1); zone2.setSize(nZoneFaces2); flipZone2.setSize(nZoneFaces2); Info<< "zone: " << zone1 << endl; Info<< "zone: " << zone2 << endl; src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 104 The faces whose center x-coordinates are greater than -0.00701 and less than -0.00699 are added to the labelList zone2. Reset the size of four lists. For movingCone tutorial
  • 105.
    addZonesAndModifiers List<pointZone*> pz(0); List<faceZone*> fz(2); List<cellZone*>cz(0); label nFz = 0; fz[nFz] = new faceZone ( "rightExtrusionFaces", zone1, flipZone1, nFz, faceZones() ); nFz++; fz[nFz] = new faceZone ( "leftExtrusionFaces", zone2, flipZone2, nFz, faceZones() ); nFz++; fz.setSize(nFz); Info<< "Adding mesh zones." << endl; addZones(pz, fz, cz); src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 105 Create two faceZones • rightExtrusionFaces from zone1 and flipZone1 • leftExtrusionFaces from zone2 and flipZone2
  • 106.
    addZonesAndModifiers // Add layeraddition/removal interfaces List<polyMeshModifier*> tm(2); label nMods = 0; tm[nMods] = new layerAdditionRemoval ( "right", nMods, topoChanger_, "rightExtrusionFaces", readScalar ( motionDict_.subDict("right").lookup("minThickness") ), readScalar ( motionDict_.subDict("right").lookup("maxThickness") ) ); nMods++; src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 106
  • 107.
    addZonesAndModifiers tm[nMods] = newlayerAdditionRemoval ( "left", nMods, topoChanger_, "leftExtrusionFaces", readScalar ( motionDict_.subDict("left").lookup("minThickness") ), readScalar ( motionDict_.subDict("left").lookup("maxThickness") ) ); nMods++; tm.setSize(nMods); Info<< "Adding " << nMods << " mesh modifiers" << endl; topoChanger_.addTopologyModifiers(tm); write(); } src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 107
  • 108.
    vertexMarkup Foam::tmp<Foam::scalarField> Foam::movingConeTopoFvMesh::vertexMarkup ( const pointField&p, const scalar curLeft, const scalar curRight ) const { Info<< "Updating vertex markup. curLeft: " << curLeft << " curRight: " << curRight << endl; tmp<scalarField> tvertexMarkup(new scalarField(p.size())); scalarField& vertexMarkup = tvertexMarkup(); forAll(p, pI) { if (p[pI].x() < curLeft - SMALL) { vertexMarkup[pI] = -1; } else if (p[pI].x() > curRight + SMALL) { vertexMarkup[pI] = 1; } else { vertexMarkup[pI] = 0; } } return tvertexMarkup; } src/topoChangerFvMesh/movingConeTopoFvMesh/movingConeTopoFvMesh.C 108  Classify the points by their positions
  • 109.
  • 110.
    References [1] Roll Motionof a Box and Interaction with Free-Surface http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2009/ArashEslamdoost/RollMotionofaBoxandInteracti onwithFreeSurface.pdf [2] A tutorial on how to use Dynamic Mesh solver IcoDyMFOAM http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2007/PiroozMoradnia/OpenFOAM-rapport.pdf [3] Mesh motion alternatives http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2009/AndreuOliverGonzalez/PresentationFINAL_Mesh MotionAlternatives.pdf [4] OpenFOAM project: A modification of the movingConeTopoFvMesh library http://www.tfd.chalmers.se/~hani/kurser/OS_CFD_2008/ErikBjerklund/OpenFoamBjerklundE3.pdf [5] Dynamic mesh in OpenFOAM https://ilyasivkov.wordpress.com/2015/04/23/dynamic-mesh-in-openfoam/ 110
  • 111.
    This work islicensed under a Creative Commons Attribution-ShareAlike 4.0 International License. You should have received a copy of the license along with this work. If not, see <http://creativecommons.org/licenses/by-sa/4.0/>. 111