LPT For Erosion Modelling in OpenFOAM

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 17

LPT for erosion

modelling in
OpenFOAM
Differences between solidParticle and KinematicParcel
and how to add erosion modelling
Alejandro López
PhD Student
University of Strathclyde
Glasgow, UK
Theoretical background
 Lagrangian Particle Tracking

- Eulerian-Eulerian models

Particles treated as a continuous phase

Conservation equations are solved for the particulate phase

-Euler-Lagrange approach

Eulerian continuum equations solved for the fluid phase

Newton´s equations for motion solved for the particulate phase

Fp=mp*ap

 Erosion

Finnie´s equation
Implementation of LPT in
OpenFOAM
 solidParticle Class

cd $WM_PROJECT_DIR/src/lagrangian/solidParticle

solidParticle.C -> Foam::solidParticle::move


Carrier phase properties: rhoc, nuc and Uc

solidParticleCloud.C –> definition of particle properties -> rhop, e & mu

 The intermediate library


 CollidingParcel
 ReactingParcel
 ReactingMultiphaseParcel
 ThermoParcel
 KinematicParcel

cd $WM_PROJECT_DIR/src/lagrangian/intermediate
The intermediate library
particleForces injectionModel
 cellZoneInjection
 Drag
 coneInjection
 Lift  coneNozzleInjection
 Gravity  fieldActivatedInjection
 Paramagnetic  inflationInjection
 injectionModel
 PressureGradient  kinematicLookupTableInjection
 VirtualMass  manualInjection
 NonInertialFrame  noInjection
 patchInjection
 SRF
 patchFlowRateInjection

distributionModels
 exponential
 fixedValue
 general
 multiNormal
 normal
 RosinRammler
 uniform
The intermediate library
- ClounFunctionObjects
- facePostProcessing: Records particle face quantities on user-specified face
zone

- particleCollector: Collects the parcel-mass and mass flow rate over a set of
polygons, defined as a list of points

- particleTracks: Records all particle variables one each call to postFace

- particleTrap: Traps the particles within a given phase fraction for multiphase
cases

- patchPostProcessing: Standard post-processing. It outputs the desired


information a the user-specified patches.

- voidFraction: Creates the particle void fraction on the carrier phase

- particleErosion: This function creates the particle erosion field on the user-
specified patches
particleErosion
CloudFunctionObject
new volScalarField //Calculate magnitude of the particle
velocity at impingement
( const scalar magU = mag(U);
IOobject //Udir is the velocity unitary
( vector, i.e, the direction of the
this->owner().name() + "Q", particle at impingement.
mesh.time().timeName(), const vector Udir = U/magU;
// determine impact angle, alpha
mesh, const scalar alpha =
IOobject::READ_IF_PRESENT, mathematical::pi/2.0 - acos(nw &
IOobject::NO_WRITE Udir);
), const scalar coeff = p.nParticle()
*p.mass()*sqr(magU)/(p_*psi_*K_);
mesh, const label patchFaceI = pp.whichFace
dimensionedScalar("zero", dimVolume, (p.face());
0.0) scalar& Q = QPtr_->boundaryField()
) [patchI][patchFaceI];
if (tan(alpha) < K_/6.0)
{
Q += coeff*(sin(2.0*alpha) - 6.0/
K_*sqr(sin(alpha)));
}
else
{
Q += coeff*(K_*sqr(cos(alpha))/6.0);
}
Templating in OpenFOAM
Templates are functions or classes that are written for one or more types not yet specied.

Function templates template<class ParcelType>


template<class CloudType>
template <typename T> inline const
Foam::interpolation<Foam::scala
inline T const& max (T const& a, T const& r>&
b) Foam::KinematicParcel<ParcelTyp
e>::TrackingData<CloudType>::rh
{ oInterp() const
{
return a<b?b:a; return rhoInterp_();
}
}
template<class ParcelType>
The template parameters have to be announced with a template<class CloudType>
syntax like: inline const
Foam::interpolation<Foam::ve
template<parameters separated by commas> ctor>&
Foam::KinematicParcel<Parcel
Type>::TrackingData<CloudTyp
e>::UInterp() const
{
return UInterp_();
}
Templating in OpenFOAM
 Class templates :

template<class T>

class Item

The firrst one defines the template type specification, and the second

one is the C++ class declaration

The implementation of a template class function must be in the same file as its declaration

 Template specialization

template <> class myclass <char> { ... };

This allows the definition of a specific implementation when the argument is of type char.
Coupling of the kinematicCloud
Class and an incompressiblesolver
 Uncoupled LPT

Copy and recompile the intermediate library:

cd $WM_PROJECT_USER_DIR

mkdir -p src/lagrangian/

cp -r $FOAM_SRC/lagrangian/intermediate $WM_PROJECT_USER_DIR/
src/lagrangian

- In case a faster compilation is desired modify Make/files & Make/options by deleting the
entries relative to other types of parcels and clouds

- LIB = $(FOAM_USER_LIBBIN)/libkinematiclagrangianIntermediate
- wclean lib
- wmake libso
Coupling of the kinematicCloud
Class and an incompressible solver
 pimpleKinematicFoam LIB_USER_SRC = $(WM_PROJECT_USER_DIR)/src

EXE_INC = \
-I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \
-I$(LIB_SRC)/transportModels \
 Create the solver directory -I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/finiteVolume/lnInclude\
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
cd $WM_PROJECT_USER_DIR/ applications/solvers/ -I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_USER_SRC)/lagrangian/intermediate/lnInclude \ # -I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
mkdir pimpleKinematicFoam -I$(LIB_SRC)/lagrangian/distributionModels/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/liquidProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/liquidMixtureProperties/lnInclude \
Copy pimpleFoam into user´s directory -I$(LIB_SRC)/thermophysicalModels/properties/solidProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/properties/solidMixtureProperties/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/SLGThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
cd pimpleKinematicFoam -I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude

cp -r $WM_PROJECT_DIR/ applications/solvers/ EXE_LIBS = \


incompressible/pimpleFoam/* . -lincompressibleTurbulenceModel \
-lincompressibleRASModels \
-lincompressibleLESModels \
-lincompressibleTransportModels \
-lfiniteVolume \
Change name of pimpleFoam into desired one -lmeshTools\
-lfvOptions \
-llagrangian\
-lkinematiclagrangianIntermediate \ # -llagrangianintermediate \
-lthermophysicalFunctions \
mv pimpleFoam.C pimpleKinematicFoam.C -lsurfaceFilmModels \
-ldistributionModels \
-lregionModels \
-lspecie \
-lfluidThermophysicalModels \
-lliquidProperties \
-lliquidMixtureProperties \
-lsolidProperties \
-lsolidMixtureProperties \
 Modify Make/files & Make/options -lreactionThermophysicalModels \
-lSLGThermo \
-lradiationModels \
 Files -lLESdeltas \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels \
pimpleKinematicFoam.C -lregionModels \
-lsurfaceFilmModels \
-ldynamicFvMesh \
-lsampling

EXE = $(FOAM_USER_APPBIN)/
pimpleKinematicFoam
Coupling of the kinematicCloud
Class and an incompressible solver
createFields.H: At the beginning of the file add: Add density and dynamic viscosity fields Add the constructor for the
volScalarField rhoInf
kinematicParcel class
(
IOobject
(
Info<< "\nReading transportProperties "rho", word kinematicCloudName
\n" << endl; runTime.timeName(), ("kinematicCloud");
IOdictionary transportProperties mesh, args.optionReadIfPresent
( IOobject::NO_READ,
IOobject::AUTO_WRITE ("cloudName",
IOobject ), kinematicCloudName);
( mesh, Info<< "Constructing
"transportProperties", rhoInfValue kinematicCloud " <<
runTime.constant(), );
kinematicCloudName << endl;
mesh, And just after: basicKinematicCloud
IOobject::MUST_READ_IF_MODIFIED, kinematicCloud
IOobject::NO_WRITE autoPtr<incompressible::turbulenceModel>
turbulence (
) ( incompressible::turbulenceModel::New kinematicCloudName,
); (U, phi, laminarTransport)); add: rhoInf,
dimensionedScalar rhoInfValue U,
( volScalarField mu
( mu,
transportProperties.lookup("rhoInf") IOobject g
); ( );
"mu",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
laminarTransport.nu()*rhoInfValue
);
Coupling of the kinematicCloud
Class and an incompressible solver
pimpleKinematicFoam.C : Then, after #include "createMesh.H”:

After #include "IOMRFZoneList.H” copy #include "readGravitationalAcceleration.H"

#include "basicKinematicCloud.H" Finally, just before runTime.write();

Include after int main(int argc, char *argv[]) Info<< "Evolving kinematicCloud.name() <<
the following lines: endl;

argList::addOption kinematicCloud.evolve();

"cloudName", And compile with:

"name", wclean

"specify alternative cloud name. default is wmake


'kinematicCloud'"

);
Coupling of the kinematicCloud
Class and an incompressible solver
 Coupled Lagrangian Particle Tracking (
TrackData& td,
const scalar dt, // timestep
const label cellI, // owner cell
 Term responsible for the coupling is Su() : const scalar Re, // Reynolds number
const scalar mu, // local carrier
viscosity
const scalar mass, // mass
//- Calculate new particle const vector& Su, // explicit particle
velocity momentum source
vector& dUTrans, // momentum transfer
to carrier
template<class TrackData> scalar& Spu // linearised drag
coefficient
const vector calcVelocity ) const;
Coupling of the kinematicCloud
Class and an incompressible
solver
Inside createFields.H the following line is added after the density is read And recompile with:
from the particleProperties dictionary:
wclean

dimensionedScalar invrhoInf("invrhoInf",(1.0/rhoInfValue)); wmake

If the solution is properly coupled, the solver will write out two fields:
Then, in order to create the coupled version of the solver is to include this nameoftheCloud:Ucoeff It is of type
momentum transfer into the UEqn.H, so the file will look now like: volscalarField::DimensionedInternalField
// Solve the Momentum equation
tmp<fvVectorMatrix> UEqn It is a nonuniform List<vector>
( nameoftheCloud:Utrans It is of type
fvm::ddt(U)
+ fvm::div(phi, U) volVectorField::DimensionedInternalField
+ turbulence->divDevReff(U)
== It is a nonuniform List<scalar>
fvOptions(U)
+invrhoInf*kinematicCloud.SU(U)
);
UEqn().relax();
fvOptions.constrain(UEqn());
volScalarField rAU(1.0/UEqn().A());
if (pimple.momentumPredictor())
{
solve
(
UEqn()
==
-fvc::grad(p)
);
fvOptions.correct(U);
}
Preprocessing
 Geometry
 Simple Geometry
created with
blockMesh
 9000 hex cells
 Cuadrangular pipe
with a 90º bend

kinematicCloudProperties dictionary
run
find tutorials/ -name kinematicCloudProperties
Postprocessing
 LPT in Paraview

– foamToVTK and – Postprocess


then open the VTK cloud directly in
file with paraview paraview
Erosion in Paraview
 Display erosion: kinematicCloudQ field

You might also like