Skip to content
Snippets Groups Projects
Commit fc6b44ee authored by Henry's avatar Henry
Browse files

twoPhaseEulerFoam: Added experimental face-based momentum equation formulation

This formulation provides C-grid like pressure-flux staggering on an
unstructured mesh which is hugely beneficial for Euler-Euler multiphase
equations as it allows for all forces to be treated in a consistent
manner on the cell-faces which provides better balance, stability and
accuracy.  However, to achieve face-force consistency the momentum
transport terms must be interpolated to the faces reducing accuracy of
this part of the system but this is offset by the increase in accuracy
of the force-balance.

Currently it is not clear if this face-based momentum equation
formulation is preferable for all Euler-Euler simulations so I have
included it on a switch to allow evaluation and comparison with the
previous cell-based formulation.  To try the new algorithm simply switch
it on, e.g.:

PIMPLE
{
    nOuterCorrectors 3;
    nCorrectors      1;
    nNonOrthogonalCorrectors 0;
    faceMomentum     yes;
}

It is proving particularly good for bubbly flows, eliminating the
staggering patterns often seen in the air velocity field with the
previous algorithm, removing other spurious numerical artifacts in the
velocity fields and improving stability and allowing larger time-steps
For particle-gas flows the advantage is noticeable but not nearly as
pronounced as in the bubbly flow cases.

Please test the new algorithm on your cases and provide feedback.

Henry G. Weller
CFD Direct
parent 69d46a7e
Branches
Tags
No related merge requests found
Showing
with 283 additions and 123 deletions
......@@ -5,7 +5,7 @@
volScalarField Cpv1("Cpv1", thermo1.Cpv());
volScalarField Cpv2("Cpv2", thermo2.Cpv());
volScalarField heatTransferCoeff(fluid.heatTransferCoeff());
volScalarField Kh(fluid.Kh());
fvScalarMatrix he1Eqn
(
......@@ -32,9 +32,9 @@
he1Eqn -=
(
heatTransferCoeff*(thermo2.T() - thermo1.T())
+ heatTransferCoeff*he1/Cpv1
- fvm::Sp(heatTransferCoeff/Cpv1, he1)
Kh*(thermo2.T() - thermo1.T())
+ Kh*he1/Cpv1
- fvm::Sp(Kh/Cpv1, he1)
+ fvOptions(alpha1, rho1, he1)
);
......@@ -63,9 +63,9 @@
he2Eqn -=
(
heatTransferCoeff*(thermo1.T() - thermo2.T())
+ heatTransferCoeff*he2/Cpv2
- fvm::Sp(heatTransferCoeff/Cpv2, he2)
Kh*(thermo1.T() - thermo2.T())
+ Kh*he2/Cpv2
- fvm::Sp(Kh/Cpv2, he2)
+ fvOptions(alpha2, rho2, he2)
);
......
......@@ -70,24 +70,36 @@
fluid.U()
);
Info<< "Calculating field DDtU1 and DDtU2\n" << endl;
volVectorField DDtU1
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell
(
"DDtU1",
fvc::ddt(U1)
+ fvc::div(phi1, U1)
- fvc::div(phi1)*U1
p,
p_rgh,
pimple.dict(),
pRefCell,
pRefValue
);
volVectorField DDtU2
Info<< "Creating field dpdt\n" << endl;
volScalarField dpdt
(
"DDtU2",
fvc::ddt(U2)
+ fvc::div(phi2, U2)
- fvc::div(phi2)*U2
IOobject
(
"dpdt",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar("dpdt", p.dimensions()/dimTime, 0)
);
Info<< "Creating field kinetic energy K\n" << endl;
volScalarField K1(IOobject::groupName("K", phase1.name()), 0.5*magSqr(U1));
volScalarField K2(IOobject::groupName("K", phase2.name()), 0.5*magSqr(U2));
volScalarField rAU1
(
IOobject
......@@ -99,7 +111,7 @@
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("zero", dimensionSet(-1, 3, 1, 0, 0), 0.0)
dimensionedScalar("zero", dimensionSet(-1, 3, 1, 0, 0), 0)
);
volScalarField rAU2
......@@ -113,34 +125,33 @@
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("zero", dimensionSet(-1, 3, 1, 0, 0), 0.0)
dimensionedScalar("zero", dimensionSet(-1, 3, 1, 0, 0), 0)
);
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell
surfaceScalarField rAU1f
(
p,
p_rgh,
pimple.dict(),
pRefCell,
pRefValue
IOobject
(
IOobject::groupName("rAUf", phase1.name()),
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("zero", dimensionSet(-1, 3, 1, 0, 0), 0)
);
Info<< "Creating field dpdt\n" << endl;
volScalarField dpdt
surfaceScalarField rAU2f
(
IOobject
(
"dpdt",
IOobject::groupName("rAUf", phase2.name()),
runTime.timeName(),
mesh
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("dpdt", p.dimensions()/dimTime, 0)
dimensionedScalar("zero", dimensionSet(-1, 3, 1, 0, 0), 0)
);
Info<< "Creating field kinetic energy K\n" << endl;
volScalarField K1(IOobject::groupName("K", phase1.name()), 0.5*magSqr(U1));
volScalarField K2(IOobject::groupName("K", phase2.name()), 0.5*magSqr(U2));
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -26,6 +26,7 @@ License
#include "dragModel.H"
#include "phasePair.H"
#include "swarmCorrection.H"
#include "surfaceInterpolate.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -102,12 +103,11 @@ Foam::dragModel::~dragModel()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::dragModel::K() const
Foam::tmp<Foam::volScalarField> Foam::dragModel::Ki() const
{
return
0.75
*CdRe()
*max(pair_.dispersed(), residualAlpha_)
*swarmCorrection_->Cs()
*pair_.continuous().rho()
*pair_.continuous().nu()
......@@ -115,6 +115,20 @@ Foam::tmp<Foam::volScalarField> Foam::dragModel::K() const
}
Foam::tmp<Foam::volScalarField> Foam::dragModel::K() const
{
return max(pair_.dispersed(), residualAlpha_)*Ki();
}
Foam::tmp<Foam::surfaceScalarField> Foam::dragModel::Kf() const
{
return
max(fvc::interpolate(pair_.dispersed()), residualAlpha_)
*fvc::interpolate(Ki());
}
bool Foam::dragModel::writeData(Ostream& os) const
{
return os.good();
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -130,14 +130,32 @@ public:
// Member Functions
//- Return the residual phase-fraction
// used to stabilize the phase momentum as the phase-fraction -> 0
const dimensionedScalar& residualAlpha() const
{
return residualAlpha_;
}
//- Drag coefficient
virtual tmp<volScalarField> CdRe() const = 0;
//- The drag function K used in the momentum equation
//- Return the phase-intensive drag coefficient Ki
// used in the momentum equations
// ddt(alpha1*rho1*U1) + ... = ... alphad*K*(U1-U2)
// ddt(alpha2*rho2*U2) + ... = ... alphad*K*(U2-U1)
virtual tmp<volScalarField> Ki() const;
//- Return the drag coefficient K
// used in the momentum equations
// ddt(alpha1*rho1*U1) + ... = ... K*(U1-U2)
// ddt(alpha2*rho2*U2) + ... = ... K*(U2-U1)
virtual tmp<volScalarField> K() const;
//- Return the drag coefficient Kf
// used in the face-momentum equations
virtual tmp<surfaceScalarField> Kf() const;
//- Dummy write for regIOobject
bool writeData(Ostream& os) const;
};
......
......@@ -26,6 +26,7 @@ License
#include "segregated.H"
#include "phasePair.H"
#include "fvcGrad.H"
#include "surfaceInterpolate.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -147,4 +148,10 @@ Foam::tmp<Foam::volScalarField> Foam::dragModels::segregated::K() const
}
Foam::tmp<Foam::surfaceScalarField> Foam::dragModels::segregated::Kf() const
{
return fvc::interpolate(K());
}
// ************************************************************************* //
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -99,6 +99,9 @@ public:
//- The drag function used in the momentum equation
virtual tmp<volScalarField> K() const;
//- The drag function Kf used in the face-momentum equations
virtual tmp<surfaceScalarField> Kf() const;
};
......
......@@ -26,7 +26,7 @@ License
#include "liftModel.H"
#include "phasePair.H"
#include "fvcCurl.H"
#include "addToRunTimeSelectionTable.H"
#include "surfaceInterpolate.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -59,11 +59,10 @@ Foam::liftModel::~liftModel()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volVectorField> Foam::liftModel::F() const
Foam::tmp<Foam::volVectorField> Foam::liftModel::Fi() const
{
return
Cl()
*pair_.dispersed()
*pair_.continuous().rho()
*(
pair_.Ur() ^ fvc::curl(pair_.continuous().U())
......@@ -71,4 +70,20 @@ Foam::tmp<Foam::volVectorField> Foam::liftModel::F() const
}
Foam::tmp<Foam::volVectorField> Foam::liftModel::F() const
{
return pair_.dispersed()*Fi();
}
Foam::tmp<Foam::surfaceScalarField> Foam::liftModel::Ff() const
{
const fvMesh& mesh(this->pair_.phase1().mesh());
return
fvc::interpolate(pair_.dispersed())
*(fvc::interpolate(Fi()) & mesh.Sf());
}
// ************************************************************************* //
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -112,11 +112,17 @@ public:
// Member Functions
//- Lift coefficient
//- Return lift coefficient
virtual tmp<volScalarField> Cl() const = 0;
//- Lift force
//- Return phase-intensive lift force
virtual tmp<volVectorField> Fi() const;
//- Return lift force
virtual tmp<volVectorField> F() const;
//- Return face lift force
virtual tmp<surfaceScalarField> Ff() const;
};
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -63,34 +63,71 @@ Foam::tmp<Foam::volScalarField> Foam::liftModels::noLift::Cl() const
{
const fvMesh& mesh(this->pair_.phase1().mesh());
return
tmp<volScalarField>
return tmp<volScalarField>
(
new volScalarField
(
new volScalarField
IOobject
(
IOobject
(
"Cl",
mesh.time().timeName(),
mesh
),
"Cl",
mesh.time().timeName(),
mesh,
dimensionedScalar("Cl", dimless, 0)
)
);
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimensionedScalar("Cl", dimless, 0)
)
);
}
Foam::tmp<Foam::volVectorField> Foam::liftModels::noLift::F() const
{
return
Cl()
*dimensionedVector
const fvMesh& mesh(this->pair_.phase1().mesh());
return tmp<volVectorField>
(
new volVectorField
(
"zero",
dimensionSet(1, -2, -2, 0, 0),
vector::zero
);
IOobject
(
"noLift:F",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimensionedVector("zero", dimF, vector::zero)
)
);
}
Foam::tmp<Foam::surfaceScalarField> Foam::liftModels::noLift::Ff() const
{
const fvMesh& mesh(this->pair_.phase1().mesh());
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
IOobject
(
"noLift:Ff",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimensionedScalar("zero", dimF*dimArea, 0)
)
);
}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -81,6 +81,9 @@ public:
//- Lift force
virtual tmp<volVectorField> F() const;
//- Lift force on faces
virtual tmp<surfaceScalarField> Ff() const;
};
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -73,21 +73,23 @@ Foam::virtualMassModels::constantVirtualMassCoefficient::Cvm() const
{
const fvMesh& mesh(this->pair_.phase1().mesh());
return
tmp<volScalarField>
return tmp<volScalarField>
(
new volScalarField
(
new volScalarField
IOobject
(
IOobject
(
"zero",
mesh.time().timeName(),
mesh
),
"Cvm",
mesh.time().timeName(),
mesh,
Cvm_
)
);
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
Cvm_
)
);
}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -25,6 +25,7 @@ License
#include "virtualMassModel.H"
#include "phasePair.H"
#include "surfaceInterpolate.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -70,9 +71,22 @@ Foam::virtualMassModel::~virtualMassModel()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::virtualMassModel::Ki() const
{
return Cvm()*pair_.continuous().rho();
}
Foam::tmp<Foam::volScalarField> Foam::virtualMassModel::K() const
{
return Cvm()*pair_.dispersed()*pair_.continuous().rho();
return pair_.dispersed()*Ki();
}
Foam::tmp<Foam::surfaceScalarField> Foam::virtualMassModel::Kf() const
{
return
fvc::interpolate(pair_.dispersed())*fvc::interpolate(Ki());
}
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -116,14 +116,25 @@ public:
// Member Functions
//- Virtual mass coefficient
//- Return the virtual mass coefficient
virtual tmp<volScalarField> Cvm() const = 0;
//- The virtual mass function K used in the momentum equation
//- Return the phase-intensive virtual mass coefficient Ki
// used in the momentum equation
// ddt(alpha1*rho1*U1) + ... = ... alphad*K*(DU1_Dt - DU2_Dt)
// ddt(alpha2*rho2*U2) + ... = ... alphad*K*(DU1_Dt - DU2_Dt)
virtual tmp<volScalarField> Ki() const;
//- Return the virtual mass coefficient K
// used in the momentum equation
// ddt(alpha1*rho1*U1) + ... = ... K*(DU1_Dt - DU2_Dt)
// ddt(alpha2*rho2*U2) + ... = ... K*(DU1_Dt - DU2_Dt)
virtual tmp<volScalarField> K() const;
//- Return the virtual mass coefficient Kf
// used in the face-momentum equations
virtual tmp<surfaceScalarField> Kf() const;
// Dummy write for regIOobject
bool writeData(Ostream& os) const;
};
......
......@@ -66,7 +66,7 @@ Foam::wallLubricationModels::Antal::~Antal()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volVectorField> Foam::wallLubricationModels::Antal::F() const
Foam::tmp<Foam::volVectorField> Foam::wallLubricationModels::Antal::Fi() const
{
volVectorField Ur(pair_.Ur());
......@@ -78,7 +78,6 @@ Foam::tmp<Foam::volVectorField> Foam::wallLubricationModels::Antal::F() const
dimensionedScalar("zero", dimless/dimLength, 0),
Cw1_/pair_.dispersed().d() + Cw2_/yWall()
)
*pair_.dispersed()
*pair_.continuous().rho()
*magSqr(Ur - (Ur & n)*n)
*n;
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -95,8 +95,8 @@ public:
// Member Functions
//- Wall lubrication force
tmp<volVectorField> F() const;
//- Return phase-intensive wall lubrication force
tmp<volVectorField> Fi() const;
};
......
......@@ -67,7 +67,7 @@ Foam::wallLubricationModels::Frank::~Frank()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volVectorField> Foam::wallLubricationModels::Frank::F() const
Foam::tmp<Foam::volVectorField> Foam::wallLubricationModels::Frank::Fi() const
{
volVectorField Ur(pair_.Ur());
......@@ -88,7 +88,6 @@ Foam::tmp<Foam::volVectorField> Foam::wallLubricationModels::Frank::F() const
dimensionedScalar("zero", dimless/dimLength, 0.0),
(1.0 - yTilde)/(Cwd_*y*pow(yTilde, p_ - 1.0))
)
*pair_.dispersed()
*pair_.continuous().rho()
*magSqr(Ur - (Ur & n)*n)
*n;
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -105,8 +105,8 @@ public:
// Member Functions
//- Wall lubrication force
tmp<volVectorField> F() const;
//- Return phase-intensive wall lubrication force
tmp<volVectorField> Fi() const;
};
......
......@@ -66,7 +66,7 @@ Foam::wallLubricationModels::TomiyamaWallLubrication::~TomiyamaWallLubrication()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volVectorField>
Foam::wallLubricationModels::TomiyamaWallLubrication::F() const
Foam::wallLubricationModels::TomiyamaWallLubrication::Fi() const
{
volVectorField Ur(pair_.Ur());
......@@ -87,7 +87,6 @@ Foam::wallLubricationModels::TomiyamaWallLubrication::F() const
1/sqr(y)
- 1/sqr(D_ - y)
)
*pair_.dispersed()
*pair_.continuous().rho()
*magSqr(Ur - (Ur & n)*n)
*n;
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -98,8 +98,8 @@ public:
// Member Functions
//- Wall lubrication force
tmp<volVectorField> F() const;
//- Return phase-intensive wall lubrication force
tmp<volVectorField> Fi() const;
};
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2014 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2014-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -64,31 +64,53 @@ Foam::wallLubricationModels::noWallLubrication::~noWallLubrication()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volVectorField>
Foam::wallLubricationModels::noWallLubrication::Fi() const
{
const fvMesh& mesh(this->pair_.phase1().mesh());
return tmp<volVectorField>
(
new volVectorField
(
IOobject
(
"noWallLubrication:Fi",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimensionedVector("zero", dimF, vector::zero)
)
);
}
Foam::tmp<Foam::volVectorField>
Foam::wallLubricationModels::noWallLubrication::F() const
{
const fvMesh& mesh(this->pair_.phase1().mesh());
return
tmp<volVectorField>
return tmp<volVectorField>
(
new volVectorField
(
new volVectorField
IOobject
(
IOobject
(
"zero",
mesh.time().timeName(),
mesh
),
"noWallLubrication:F",
mesh.time().timeName(),
mesh,
dimensionedVector
(
"zero",
dimensionSet(1, -2, -2, 0, 0),
vector::zero
)
)
);
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimensionedVector("zero", dimF, vector::zero)
)
);
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment