-
Transient simulation of opening and closing guide vanes of a hydraulic turbine
Abhishek SarafDepartment of Applied MechanicsChalmers University of Technology
8th December 2015
-
Objective
• Investigate and capability findings of OpenFOAM-2.4x inhandling transient flows when there is some mesh deformationin the computational domain.
• Determine forces and moments acting on each guide vaneduring the simulation time.
-
Introduction
• In hydraulic turbines the inflow to the rotor is controlled by openingor closing of the guide vanes in order to achieve the optimalefficiency of the turbine.
• Also in case of emergency conditions the guide vanes are closed inorder to prevent any damage to the rotor.
• In this case an investigation will be carried out on the guide vanes ofa Francis turbine where the guide vanes rotate alternatively, and theforces and moment acting on each guide vane are calculated.
-
Methodology
• Meshing
• Implementing rotation of each guide vane
• Boundary conditions and assumptions
• Case set up
• Results
• Alternate Finding - Building a new dynamic mesh class
-
Meshing
2D Schematic diagram
-
Reference dimensions:
Name Units Dimension
Inlet Diameter m 0.475
Outlet Diameter m 0.335
Guide Vane Height m 0.104
Pitch Circle Diameter m 0.400
No. of guide vanes - 16
-
Meshing Strategy
• Create the mesh of the reference case
• Copy the reference case 16 times
• Change the names of the patches of the new meshes
• Rotate the meshes using meshUtility – “transformPoints –rotate”
• Merge the meshes
• Stitch the meshes into one mesh region.
-
Create reference mesh
• Initialize OpenFoam 2.4.x
• Copy the case folder “TME205_asaraf” to the $FOAM_RUN directory.
cd $FOAM_RUN/TME205_asaraf/Guidevanerotation
blockMesh –case GuideVane1
• View the mesh in paraview/paraFoam
touch –case GuideVane1/GuideVane1.foam
paraview
• Load the “.foam” file and view the mesh
-
Reference mesh
-
• The mesh generation process which is mentioned in the section meshing strategy will take time if done manually. Hence a text file is supplied which has instructions to perform the necessary tasks.
gedit files/meshgenerationsteps.dat
• Follow the instructions given in the data file and just copy them into the terminal window
• The mesh is generated and you can use checkMesh option to see that you have one region.
checkMesh –case merged
• View the newly created mesh in paraview or parafoam
touch –case merged/merged.foam
-
Final stitched mesh
-
Examine the boundary file
gedit merged/constant/polyMesh/boundary
• It is observed that the common faces now have no “nfaces”. All those patches can be deleted
• But patches LHS1 and RHS16 still have faces in them.
• Here we modify the boundary file manually for these two patches.
• The modifications should be done according to this reference boundary file
gedit files/boundary.dat
-
Implementing rotation cd $FOAM_RUN/Guidevanerotation/rotationVelocity
gedit rotationVelocityPointPatchVectorField.C
gedit rotationVelocityPointPatchVectorField.H
• Now we will have a look at how the rotation of each guide vane is implemented. The reference library
that is modified is the angular oscillating velocity located at
$FOAM_SRC/fvMotionSolver/pointPatchFields/derived/angularOscillatingVelo
\city/
gedit $FOAM_SRC/fvMotionSolver/pointPatchFields/derived \
angularOscillatingVelocity/angularOscillatingVelocityPointPatchVectorF \
ield.C
gedit $FOAM_SRC/fvMotionSolver/pointPatchFields/derived \
angularOscillatingVelocityPointPatchVectorField.H
• If we look into the rotationVelocityPointPatchVectorField.C ,the function of rotation is taken care by the
lines 155 to 168 of the .C file.
-
• Have a look at Make/files and Make/options
Make/files
Make/options
• compile the code to make it useable using
wmake libso
EXE_INC = \
-I$FOAM_SRC/triSurface/lnInclude \
-I$FOAM_SRC/meshTools/lnInclude \
-I$FOAM_SRC/dynamicMesh/lnInclude \
-I$FOAM_SRC/finiteVolume/lnInclude \
-I$FOAM_SRC/fvMotionSolver/lnInclude
LIB_LIBS = \
-ltriSurface \
-lmeshTools \
-ldynamicMesh \
-lfiniteVolume
rotationVelocityPointPatchVectorField.C
LIB = $(FOAM_USER_LIBBIN)/rotationVelocity
-
Boundary Conditions
For the guide vane, in the 0/pointMotionU file
GV1
{
type rotationVelocity;//New library
axis (0 0 1);
origin (0.0780350 .3923143 0);// Center of Rotation
angle -4;// Degrees per second
value uniform (0 0 0);
}
and in the 0/U file
GV1
{
type movingWallVelocity;
value uniform (0 0 0);
}
-
Inlet Boundary condition
inlet
{
type cylindricalInletVelocity;
axis (0 0 1);
centre (0 0 0);
axialVelocity 0;
radialVelocity -3.92; //ms-1
rpm 60;//rpm
value uniform (0 0 0);
}
-
A look inside dynamicMeshDict
gedit constant/dynamicMeshDict
dynamicFvMesh dynamicMotionSolverFvMesh;
motionSolverLibs ("libfvMotionSolvers.so");
solver velocityLaplacian;
velocityLaplacianCoeffs
{
diffusivity uniform;
}
-
Results
-
Velocity surface contours at time=1second and
total rotation of 3 degrees
-
Pressure surface contours at time=1second and
total rotation of 3 degrees
-
Lift Force(N) versus Simulation Time(s)
-
Moment(N-m) versus simulation time(s)
-
Alternate findings- building a new dynamic mesh class
cd FOAM_RUN/TME205_asaraf \
newdynamicMeshclass/
• This is a new dynamic mesh class which combines both solid body motion and adaptive grid
refinement.
• The dynamicRefineFvMesh is used a base class and the SolidBodyMotionFvMesh is called inside that
class.
-
Class hierarchy of dynamicFvMesh
-
Class hierarchy of “mydynamicFvMesh”
-
Observations
• Upon investigation into the source codes of solidBodyMotionFvMeshand dynamicRefineFvMesh, it is observed that it is easier to rebuild the solidBodyMotionFvMesh than to rebuild the dynamicRefineFvMesh which is very complex.
• Therefore, the new class “mydynamicFvMesh” will inherit from dynamicRefineFvMesh and is chosen as the base class and some elements from solidBodyMotionFvMesh are reused.
-
cd $FOAM_RUN
mkdir mydynamicFvMesh
cd mydynamicFvMesh
We will now generate the class files as follows:
foamNew source C mydyanmicFvMesh
foamNew source H mydyanmicFvMesh
In addition, in order to compile this new library, Make/files and Make/options need to be created.
mkdir Make
cd Make
touch files options
gedit files
gedit options
The “files” must contain
mydynamicFvMesh.C
LIB = $(FOAM_USER_LIBBIN)/mydynamicFvMesh
The “options” must contain
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-ldynamicMesh \
-ldynamicFvMesh
The newly created .C and .H need to be cleaned up and should look like this
mydynamicFvMesh.C
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
\*---------------------------------------------------------------------------*/
#include "mydynamicFvMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mydynamicFvMesh::mydynamicFvMesh()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::mydynamicFvMesh::~mydynamicFvMesh()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
mydynamicFvMesh.H
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
Class
Foam::mydynamicFvMesh
Description
SourceFiles
mydynamicFvMeshI.H
mydynamicFvMesh.C
mydynamicFvMeshIO.C
\*---------------------------------------------------------------------------*/
#ifndef mydynamicFvMesh_H
#define mydynamicFvMesh_H
#include ".H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
namespace Foam
{
class mydynamicFvMesh
:
{
public:
// Static data members
// Constructors
//- Construct null
mydynamicFvMesh();
//- Destructor
~mydynamicFvMesh();
// Member Functions
};
} // End namespace Foam
#endif
Now, the .C and .H files
We will start by inheriting the the dynamicRefineFvMesh into our code. This is added to the
mydynamicFvMesh.H file as shown in a snippet of the header file below.
#ifndef mydynamicFvMesh_H
#define mydynamicFvMesh_H
#include "dynamicRefineFvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class mydynamicFvMesh
A per figure 7 the new dynamic mesh class is to be derived using virtual inheritance, hence in the
header file the following changes need to be made to the destructor
//- Destructor
virtual ~mydynamicFvMesh();
Proceeding with this, global static variable is declared in the headed file.
public:
// Static data members
TypeName ("mydynamicFvMesh");
After declaring the type name, one needs to add the header file which will allow the code to use
TypeName. Add the header file in the .H file
#include "dynamicRefineFvMesh.H"
#include "typeInfo.H"
-
Now in the .C file , the static type name variable and debug switches are defined as follows
namespace Foam {
defineTypeNameAndDebug(mydynamicFvMesh, 0);
The class is made usable by declaring the update member function. We add the following lines to
the .H and .C codes resprectively.
mydynamicFvMesh.H
// Member Functions
virtual bool update();
mydynamicFvMesh.C
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * *
* * * //
bool Foam::mydynamicFvMesh::update()
{
dynamicRefineFvMesh::update();
return true ;
}
The following step will create an interface of the new class and will ask the code to follow the
dynamicFvRefineMesh
mydynamicFvMesh.H
// Constructors
explicit mydynamicFvMesh(const IOobject& io);
mydynamicFvMesh.C
Foam::mydynamicFvMesh::mydynamicFvMesh(const IOobject& io)
:
dynamicRefineFvMesh(io)
{}
At this stage, the mydynamicFvMesh class will behave exactly like the parent class that is the
dynamicFvRefineMesh. Now to use the new dynamic mesh class, it has to be added to the run time
selectable table. Appropriate header file is also to be added to the .C file. Therefore in the
mydynamicFvMesh.C file we add the following
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam {
defineTypeNameAndDebug(mydynamicFvMesh, 0);
addToRunTimeSelectionTable(dynamicFvMesh, mydynamicFvMesh, IOobject);
}
-
The mydyanmicFvMesh class now needs to be given solid body motion. First we will have a look at
the constructor of solidBodyMotionFvMesh.C as it will be reused.
Constructor of solidBpdyMotionFvMesh
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * *
* * * //
Foam::solidBodyMotionFvMesh::solidBodyMotionFvMesh(const IOobject& io)
:
dynamicFvMesh(io),
dynamicMeshCoeffs_
(
IOdictionary
(
IOobject
(
"dynamicMeshDict",
io.time().constant(),
*this,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
).subDict(typeName + "Coeffs")
),
SBMFPtr_(solidBodyMotionFunction::New(dynamicMeshCoeffs_,
io.time())),
undisplacedPoints_
(
IOobject
(
"points",
io.time().constant(),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
),
pointIDs_(),
moveAllCells_(false),
UName_(dynamicMeshCoeffs_.lookupOrDefault("UName", "U"))
{
if (undisplacedPoints_.size() != nPoints())
{
FatalIOErrorIn
(
"solidBodyMotionFvMesh::solidBodyMotionFvMesh(const
IOobject&)",
dynamicMeshCoeffs_
)
-
word cellZoneName =
dynamicMeshCoeffs_.lookupOrDefault("cellZone", "none");
word cellSetName =
dynamicMeshCoeffs_.lookupOrDefault("cellSet", "none");
if ((cellZoneName != "none") && (cellSetName != "none"))
{
FatalIOErrorIn
(
"solidBodyMotionFvMesh::solidBodyMotionFvMesh(const
IOobject&)",
dynamicMeshCoeffs_
)
-
moveAllCells_ = nCells == 0;
if (moveAllCells_)
{
Info
-
class mydynamicFvMesh
:
public dynamicRefineFvMesh
{
//- Dictionary of solid body motion control parameters
const dictionary motionCoeffs_;
//- The motion control function
autoPtr SBMFPtr_;
//- The reference points which are transformed
pointIOField undisplacedPoints_;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * *
* * * //
Foam::mydynamicFvMesh::mydynamicFvMesh(const IOobject& io)
:
dynamicRefineFvMesh(io),
motionCoeffs_
(
IOdictionary
(
IOobject
(
"dynamicMeshDict",
io.time().constant(),
*this,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
).subDict(typeName + "Coeffs")
),
SBMFPtr_(solidBodyMotionFunction::New(motionCoeffs_, io.time())),
undisplacedPoints_
(
IOobject
(
"points",
io.time().constant(),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
)
{}
After defining the constructors of the new class, the parameters for the solid mesh motion function
namely mydynamicFvMeshCoeffs are defined in the the constant/dynamicMeshDict file. An example
of this is shown below.
FoamFile
{
version 2.0;
-
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* * * * //
dynamicFvMesh mydynamicFvMesh;
mydynamicFvMeshCoeffs
{
solidBodyMotionFunction linearMotion;
linearMotionCoeffs
{
velocity (0 0 -0.1);
}
}
Now the update member function of the solidBodyMotionFvMesh is reused in the new class so that
the points of the mesh can be moved and also ensure that the motion points are synchronized with
the new mesh points generated after mesh refinement.
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * *
* * * //
bool Foam::mydynamicFvMesh::update()
{
dynamicRefineFvMesh::update();
undisplacedPoints_ = this->points();
static bool hasWarned = false;
fvMesh::movePoints
(
transform
(
SBMFPtr_().transformation(),
undisplacedPoints_
)
);
if (foundObject("U"))
{
const_cast(lookupObject("U"))
.correctBoundaryConditions();
}
else if (!hasWarned)
{
hasWarned = true;
WarningIn("solidBodyPointMotionSolver::update()")
-
Test Case
• The test case can be accessed at
cd $FOAM_RUN/TME205_asaraf/newdynamicMeshclass/readytorun
• Let us have a look at how the test case has been defined
-
Results
-
Initial mesh at t=0 seconds
-
Initial mesh at t=0.15 seconds
-
Refined mesh at t=0.25
seconds