included real gas thermo in extend 3.1

This commit is contained in:
Christian Lucas 2015-08-23 16:26:27 +02:00
parent 1dd681f6e9
commit 4ce8687b97
122 changed files with 14746 additions and 0 deletions

View file

@ -0,0 +1,3 @@
realFluidPisoFoam.C
EXE = $(FOAM_APPBIN)/realFluidPisoFoam

View file

@ -0,0 +1,14 @@
EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
-I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-lbasicThermophysicalModels \
-lspecie \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels

View file

@ -0,0 +1,11 @@
fvVectorMatrix UEqn
(
fvm::ddt(rho, U)
+ fvm::div(phi, U)
+ turbulence->divDevRhoReff(U)
);
if (momentumPredictor)
{
solve(UEqn == -fvc::grad(p));
}

View file

@ -0,0 +1,57 @@
Info<< "Reading thermophysical properties\n" << endl;
autoPtr<basicPsiThermo> pThermo
(
basicPsiThermo::New(mesh)
);
basicPsiThermo& thermo = pThermo();
volScalarField& p = thermo.p();
volScalarField& h = thermo.h();
const volScalarField& psi = thermo.psi();
const volScalarField& drhodh = thermo.drhodh();
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
thermo.rho()
);
Info<< "\nReading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "compressibleCreatePhi.H"
Info<< "Creating turbulence model\n" << endl;
autoPtr<compressible::turbulenceModel> turbulence
(
compressible::turbulenceModel::New
(
rho,
U,
phi,
thermo
)
);
Info<< "Creating field DpDt\n" << endl;
volScalarField DpDt =
fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);

View file

@ -0,0 +1,12 @@
{
solve
(
fvm::ddt(rho, h)
+ fvm::div(phi, h)
- fvm::laplacian(turbulence->alphaEff(), h)
==
DpDt
);
thermo.correct();
}

View file

@ -0,0 +1,37 @@
rho = thermo.rho();
volScalarField rUA = 1.0/UEqn.A();
U = rUA*UEqn.H();
phi =
fvc::interpolate(rho)*
(
(fvc::interpolate(U) & mesh.Sf())
+ fvc::ddtPhiCorr(rUA, rho, U, phi)
);
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix pEqn
(
psi*fvm::ddt(p)
+ drhodh*fvc::ddt(h)
+ fvc::div(phi)
- fvm::laplacian(rho*rUA, p)
);
pEqn.solve();
if (nonOrth == nNonOrthCorr)
{
phi += pEqn.flux();
}
}
#include "rhoEqn.H"
#include "compressibleContinuityErrs.H"
U -= rUA*fvc::grad(p);
U.correctBoundaryConditions();
DpDt = fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);

View file

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright held by original author
\\/ 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 2 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, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
realFluidPisoFoam
Description
Transient PISO solver for compressible, laminar or turbulent flow o
of real fluids e.g. real gases (cubic equations of state)
Solver cannot be used with perfect gas library
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "basicPsiThermo.H"
#include "turbulenceModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"
#include "initContinuityErrs.H"
#include "readTimeControls.H"
#include "compressibleCourantNo.H"
#include "setInitialDeltaT.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readTimeControls.H"
#include "readPISOControls.H"
#include "compressibleCourantNo.H"
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
#include "rhoEqn.H"
#include "UEqn.H"
// --- PISO loop
for (int corr=1; corr<=nCorr; corr++)
{
#include "hEqn.H"
#include "pEqn.H"
}
turbulence->correct();
rho = thermo.rho();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View file

@ -8,6 +8,8 @@ psiThermo/basicPsiThermo/newBasicPsiThermo.C
psiThermo/hPsiThermo/hPsiThermos.C
psiThermo/hsPsiThermo/hsPsiThermos.C
psiThermo/ePsiThermo/ePsiThermos.C
psiThermo/realGasHThermo/realGasHThermos.C
psiThermo/realGasEThermo/realGasEThermos.C
rhoThermo/basicRhoThermo/basicRhoThermo.C
rhoThermo/basicRhoThermo/newBasicRhoThermo.C

View file

@ -32,15 +32,24 @@ Description
#include "makeBasicMixture.H"
#include "perfectGas.H"
#include "redlichKwong.H"
#include "pengRobinson.H"
#include "aungierRedlichKwong.H"
#include "soaveRedlichKwong.H"
#include "eConstThermo.H"
#include "hConstThermo.H"
#include "janafThermo.H"
#include "nasaHeatCapacityPolynomial.H"
#include "constantHeatCapacity.H"
#include "specieThermo.H"
#include "realGasSpecieThermo.H"
#include "constTransport.H"
#include "sutherlandTransport.H"
#include "constRealGasTransport.H"
#include "sutherlandRealGasTransport.H"
#include "pureMixture.H"
@ -93,6 +102,151 @@ makeBasicMixture
perfectGas
);
//CL: Real Gas Mixtures
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
redlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
pengRobinson
);
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
aungierRedlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
soaveRedlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
redlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
pengRobinson
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
aungierRedlichKwong
);
makeBasicRealFluidMixture
(
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
soaveRedlichKwong
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View file

@ -46,6 +46,17 @@ defineTemplateTypeNameAndDebugWithName \
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define makeBasicRealFluidMixture(Mixture,Transport,SpecieThermo,Thermo,EqnOfState) \
\
typedef Mixture<Transport<SpecieThermo<Thermo<EqnOfState> > > > \
Mixture##Transport##SpecieThermo##Thermo##EqnOfState; \
\
defineTemplateTypeNameAndDebugWithName \
(Mixture##Transport##SpecieThermo##Thermo##EqnOfState, \
#Mixture"<"#Transport"<"#SpecieThermo"<"#Thermo"<"#EqnOfState">>>>", 0)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -48,4 +48,19 @@ Foam::basicPsiThermo::~basicPsiThermo()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::volScalarField& Foam::basicPsiThermo::drhodh() const
{
notImplemented("basicPsiThermo::drhodh()");
return const_cast<volScalarField&>(volScalarField::null());
}
const Foam::volScalarField& Foam::basicPsiThermo::drhode() const
{
notImplemented("basicPsiThermo::drhode()");
return const_cast<volScalarField&>(volScalarField::null());
}
// ************************************************************************* //

View file

@ -108,6 +108,12 @@ public:
{
return p_*psi();
}
//CL: drhodh needed for pressure equation of the real gas solver
virtual const volScalarField& drhodh() const;
//CL: drhode needed for pressure equation of the real gas solver
virtual const volScalarField& drhode() const;
};

View file

@ -60,6 +60,28 @@ addToRunTimeSelectionTable \
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define makeBasicRealGasThermo(Cthermo,Mixture,Transport,SpecieThermo,Thermo,EqnOfState)\
\
typedef Cthermo<Mixture<Transport<SpecieThermo<Thermo<EqnOfState> > > > > \
Cthermo##Mixture##Transport##SpecieThermo##Thermo##EqnOfState; \
\
defineTemplateTypeNameAndDebugWithName \
( \
Cthermo##Mixture##Transport##SpecieThermo##Thermo##EqnOfState, \
#Cthermo \
"<"#Mixture"<"#Transport"<"#SpecieThermo"<"#Thermo"<"#EqnOfState">>>>>", \
0 \
); \
\
addToRunTimeSelectionTable \
( \
basicPsiThermo, \
Cthermo##Mixture##Transport##SpecieThermo##Thermo##EqnOfState, \
fvMesh \
)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,516 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "realGasEThermo.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class MixtureType>
void Foam::realGasEThermo<MixtureType>::calculate()
{
const scalarField& eCells = e_.internalField();
const scalarField& pCells = this->p_.internalField();
scalarField& TCells = this->T_.internalField();
scalarField& rhoCells= this->rho_.internalField();
scalarField& psiCells = this->psi_.internalField();
scalarField& drhodeCells = this->drhode_.internalField();
scalarField& muCells = this->mu_.internalField();
scalarField& alphaCells = this->alpha_.internalField();
forAll(TCells, celli)
{
const typename MixtureType::thermoType& mixture_ =
this->cellMixture(celli);
mixture_.TE(eCells[celli], TCells[celli], pCells[celli], rhoCells[celli]);
psiCells[celli]=mixture_.psiE(rhoCells[celli], TCells[celli]);
drhodeCells[celli]=mixture_.drhodE(rhoCells[celli], TCells[celli]);
muCells[celli] = mixture_.mu(TCells[celli]);
alphaCells[celli] = mixture_.alpha(rhoCells[celli], TCells[celli]);
}
forAll(T_.boundaryField(), patchi)
{
fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
fvPatchScalarField& pT = this->T_.boundaryField()[patchi];
fvPatchScalarField& ppsi = this->psi_.boundaryField()[patchi];
fvPatchScalarField& pdrhode = this->drhode_.boundaryField()[patchi];
fvPatchScalarField& prho = this->rho_.boundaryField()[patchi];
fvPatchScalarField& pe = e_.boundaryField()[patchi];
fvPatchScalarField& pmu = this->mu_.boundaryField()[patchi];
fvPatchScalarField& palpha = this->alpha_.boundaryField()[patchi];
if (pT.fixesValue())
{
forAll(pT, facei)
{
const typename MixtureType::thermoType& mixture_ =
this->patchFaceMixture(patchi, facei);
prho[facei] = mixture_.rho(pp[facei], pT[facei],prho[facei]);
ppsi[facei]=mixture_.psiE(prho[facei],pT[facei]);
pdrhode[facei]=mixture_.drhodE(prho[facei],pT[facei]);
pe[facei] = mixture_.E(prho[facei], pT[facei]);
pmu[facei] = mixture_.mu(pT[facei]);
palpha[facei] = mixture_.alpha(prho[facei],pT[facei]);
}
}
else
{
forAll(pT, facei)
{
const typename MixtureType::thermoType& mixture_ =
this->patchFaceMixture(patchi, facei);
mixture_.TE(pe[facei], pT[facei],pp[facei],prho[facei]);
pmu[facei] = mixture_.mu(pT[facei]);
ppsi[facei]=mixture_.psiE(prho[facei],pT[facei]);
pdrhode[facei]=mixture_.drhodE(prho[facei],pT[facei]);
palpha[facei] = mixture_.alpha(prho[facei],pT[facei]);
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class MixtureType>
Foam::realGasEThermo<MixtureType>::realGasEThermo
(
const fvMesh& mesh,
const objectRegistry& obj
)
:
basicPsiThermo(mesh, obj),
MixtureType(*this, mesh, obj),
e_
(
IOobject
(
"e",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(0, 2, -2, 0, 0),
this->eBoundaryTypes()
),
rho_
(
IOobject
(
"rhoThermo",
mesh.time().timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
mesh,
dimDensity
),
drhode_
(
IOobject
(
"drhode",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(1, -5, 2, 0, 0)
)
{
scalarField& eCells = e_.internalField();
const scalarField& TCells = this->T_.internalField();
const scalarField& pCells =this->p_.internalField();
scalarField& rhoCells =this->rho_.internalField();
forAll(rhoCells, celli)
{
rhoCells[celli]=this->cellMixture(celli).rho(pCells[celli],TCells[celli]);
}
forAll(rho_.boundaryField(), patchi)
{
rho_.boundaryField()[patchi] ==
rho(this->T_.boundaryField()[patchi], patchi);
}
forAll(eCells, celli)
{
eCells[celli] = this->cellMixture(celli).E(rhoCells[celli],TCells[celli]);
}
forAll(e_.boundaryField(), patchi)
{
e_.boundaryField()[patchi] ==
e(this->T_.boundaryField()[patchi], patchi);
}
eBoundaryCorrection(e_);
calculate();
// Switch on saving old time
this->psi_.oldTime();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class MixtureType>
Foam::realGasEThermo<MixtureType>::~realGasEThermo()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class MixtureType>
void Foam::realGasEThermo<MixtureType>::correct()
{
if (debug)
{
Info<< "entering realGasEThermo<MixtureType>::correct()" << endl;
}
// force the saving of the old-time values
this->psi_.oldTime();
calculate();
if (debug)
{
Info<< "exiting realGasEThermo<MixtureType>::correct()" << endl;
}
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasEThermo<MixtureType>::e
(
const scalarField& T,
const labelList& cells
) const
{
//CL: need the pressure of the internal field to calculate the realGas internal energy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const scalarField& pCells = this->p_.internalField();
tmp<scalarField> te(new scalarField(T.size()));
scalarField& e = te();
forAll(T, celli)
{
e[celli] = this->cellMixture(cells[celli]).E(this->cellMixture(cells[celli]).rho(pCells[cells[celli]],T[celli]),T[celli]);
}
return te;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasEThermo<MixtureType>::e
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas internal energy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> te(new scalarField(T.size()));
scalarField& e = te();
forAll(T, facei)
{
e[facei] = this->patchFaceMixture(patchi, facei).E(this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]),T[facei]);
}
return te;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasEThermo<MixtureType>::rho
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas density
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> trho(new scalarField(T.size()));
scalarField& rho = trho();
forAll(T, facei)
{
rho[facei] = this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]);
}
return trho;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasEThermo<MixtureType>::Cp
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas cp
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> tCp(new scalarField(T.size()));
scalarField& cp = tCp();
forAll(T, facei)
{
cp[facei] = this->patchFaceMixture(patchi, facei).Cp(this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]),T[facei]);
}
return tCp;
}
template<class MixtureType>
Foam::tmp<Foam::volScalarField> Foam::realGasEThermo<MixtureType>::Cp() const
{
const fvMesh& mesh = this->T_.mesh();
tmp<volScalarField> tCp
(
new volScalarField
(
IOobject
(
"Cp",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionSet(0, 2, -2, -1, 0),
this->T_.boundaryField().types()
)
);
volScalarField& cp = tCp();
forAll(this->T_, celli)
{
cp[celli] = this->cellMixture(celli).Cp(this->rho_[celli], this->T_[celli]);
}
forAll(this->T_.boundaryField(), patchi)
{
const fvPatchScalarField& pT = this->T_.boundaryField()[patchi];
const fvPatchScalarField& prho = this->rho_.boundaryField()[patchi];
fvPatchScalarField& pCp = cp.boundaryField()[patchi];
forAll(pT, facei)
{
pCp[facei] = this->patchFaceMixture(patchi, facei).Cp(prho[facei], pT[facei]);
}
}
return tCp;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasEThermo<MixtureType>::Cv
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas internal energy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> tCv(new scalarField(T.size()));
scalarField& cv = tCv();
forAll(T, facei)
{
cv[facei] = this->patchFaceMixture(patchi, facei).Cv(this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]), T[facei]);
}
return tCv;
}
// CL: Maybe this function should be changed so that it is not "const" function anymore
template<class MixtureType>
Foam::tmp<Foam::volScalarField> Foam::realGasEThermo<MixtureType>::rho() const
{
const fvMesh& mesh = this->T_.mesh();
//CL: create an rho Field, which will be return
//CL: the problem is that this function is "const",
//CL: so a new variabel is needed
tmp<volScalarField> trho
(
new volScalarField
(
IOobject
(
"rhoFunctionThermo",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimDensity
)
);
//CL: copy "old" rho value onto the new rho field as start point
//CL: for the newton solver used in this->TE( ... )
trho()=rho_;
volScalarField& rho = trho();
const scalarField& eCells = e_.internalField();
const scalarField& pCells = this->p_.internalField();
scalarField TCells = this->T_.internalField();
forAll(pCells, celli)
{
const typename MixtureType::thermoType& mixture_ =
this->cellMixture(celli);
// getting the new rho Field
mixture_.TE(eCells[celli], TCells[celli], pCells[celli], rho[celli]);
}
forAll(p_.boundaryField(), patchi)
{
fvPatchScalarField pp = this->p_.boundaryField()[patchi];
fvPatchScalarField pe = e_.boundaryField()[patchi];
fvPatchScalarField pT = this->T_.boundaryField()[patchi];
fvPatchScalarField& prho_ = rho.boundaryField()[patchi];
forAll(pp, facei)
{
const typename MixtureType::thermoType& mixture_ =
this->patchFaceMixture(patchi, facei);
// getting the new rho patch Field
mixture_.TE(pe[facei], pT[facei],pp[facei],prho_[facei]);
}
}
return trho;
}
template<class MixtureType>
Foam::tmp<Foam::volScalarField> Foam::realGasEThermo<MixtureType>::Cv() const
{
const fvMesh& mesh = this->T_.mesh();
tmp<volScalarField> tCv
(
new volScalarField
(
IOobject
(
"Cv",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionSet(0, 2, -2, -1, 0)
)
);
volScalarField& cv = tCv();
forAll(this->T_, celli)
{
cv[celli] = this->cellMixture(celli).Cv(this->rho_[celli], this->T_[celli]);
}
forAll(this->T_.boundaryField(), patchi)
{
cv.boundaryField()[patchi] =
Cv(this->T_.boundaryField()[patchi], patchi);
}
return tCv;
}
template<class MixtureType>
bool Foam::realGasEThermo<MixtureType>::read()
{
if (basicPsiThermo::read())
{
MixtureType::read(*this);
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,203 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::realGasEThermo
Description
Internal energy for a real gas fluid libary
SourceFiles
realGasEThermo.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef realGasEThermo_H
#define realGasEThermo_H
#include "basicPsiThermo.H"
#include "basicMixture.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class realGasEThermo Declaration
\*---------------------------------------------------------------------------*/
template<class MixtureType>
class realGasEThermo
:
public basicPsiThermo,
public MixtureType
{
// Private data
//- Enthalpy field
volScalarField e_;
//- DensityField
volScalarField rho_;
//- drhode_Field
volScalarField drhode_;
// Private member functions
//- Calculate the thermo variables
void calculate();
//- Construct as copy (not implemented)
realGasEThermo(const realGasEThermo<MixtureType>&);
public:
//- Runtime type information
TypeName("realGasEThermo");
// Constructors
//- Construct from mesh
realGasEThermo(const fvMesh&, const objectRegistry& obj);
//- Destructor
virtual ~realGasEThermo();
// Member functions
//- Return the compostion of the mixture
virtual basicMixture& composition()
{
return *this;
}
//- Return the compostion of the mixture
virtual const basicMixture& composition() const
{
return *this;
}
//- Update properties
virtual void correct();
// Access to thermodynamic state variables
//- Enthalpy [J/kg]
// Non-const access allowed for transport equations
virtual volScalarField& e()
{
return e_;
}
//- Enthalpy [J/kg]
virtual const volScalarField& e() const
{
return e_;
}
//CL: drhode needed for pressure equation of the real gas solver
virtual const volScalarField& drhode() const
{
return drhode_;
}
// Fields derived from thermodynamic state variables
//- Enthalpy for cell-set [J/kg]
virtual tmp<scalarField> e
(
const scalarField& T,
const labelList& cells
) const;
//- Enthalpy for patch [J/kg]
virtual tmp<scalarField> e
(
const scalarField& T,
const label patchi
) const;
//- Density for patch [J/kg]
virtual tmp<scalarField> rho
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant pressure for patch [J/kg/K]
virtual tmp<scalarField> Cp
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant pressure [J/kg/K]
virtual tmp<volScalarField> Cp() const;
//- Heat capacity at constant volume for patch [J/kg/K]
virtual tmp<scalarField> Cv
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant volume [J/kg/K]
virtual tmp<volScalarField> Cv() const;
//- Density [kg/m^3] - uses current value of pressure
virtual tmp<volScalarField> rho() const;
//- Read thermophysicalProperties dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#ifdef NoRepository
# include "realGasEThermo.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,237 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "makeBasicPsiThermo.H"
#include "redlichKwong.H"
#include "pengRobinson.H"
#include "aungierRedlichKwong.H"
#include "soaveRedlichKwong.H"
#include "nasaHeatCapacityPolynomial.H"
#include "realGasSpecieThermo.H"
#include "constTransport.H"
#include "constRealGasTransport.H"
#include "sutherlandTransport.H"
#include "sutherlandRealGasTransport.H"
#include "constantHeatCapacity.H"
#include "pureMixture.H"
#include "realGasEThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/* * * * * * * * * * * * * * * private static data * * * * * * * * * * * * * */
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
pengRobinson
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
redlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
soaveRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
pengRobinson
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
redlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
soaveRedlichKwong
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,517 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "realGasHThermo.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class MixtureType>
void Foam::realGasHThermo<MixtureType>::calculate()
{
const scalarField& hCells = h_.internalField();
const scalarField& pCells = this->p_.internalField();
scalarField& TCells = this->T_.internalField();
scalarField& rhoCells= this->rho_.internalField();
scalarField& psiCells = this->psi_.internalField();
scalarField& drhodhCells = this->drhodh_.internalField();
scalarField& muCells = this->mu_.internalField();
scalarField& alphaCells = this->alpha_.internalField();
forAll(TCells, celli)
{
const typename MixtureType::thermoType& mixture_ =
this->cellMixture(celli);
mixture_.TH(hCells[celli], TCells[celli], pCells[celli], rhoCells[celli]);
psiCells[celli]=mixture_.psi(rhoCells[celli], TCells[celli]);
drhodhCells[celli]=mixture_.drhodH(rhoCells[celli], TCells[celli]);
muCells[celli] = mixture_.mu(TCells[celli]);
alphaCells[celli] = mixture_.alpha(rhoCells[celli], TCells[celli]);
}
forAll(T_.boundaryField(), patchi)
{
fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
fvPatchScalarField& pT = this->T_.boundaryField()[patchi];
fvPatchScalarField& ppsi = this->psi_.boundaryField()[patchi];
fvPatchScalarField& pdrhodh = this->drhodh_.boundaryField()[patchi];
fvPatchScalarField& prho = this->rho_.boundaryField()[patchi];
fvPatchScalarField& ph = h_.boundaryField()[patchi];
fvPatchScalarField& pmu = this->mu_.boundaryField()[patchi];
fvPatchScalarField& palpha = this->alpha_.boundaryField()[patchi];
if (pT.fixesValue())
{
forAll(pT, facei)
{
const typename MixtureType::thermoType& mixture_ =
this->patchFaceMixture(patchi, facei);
prho[facei] = mixture_.rho(pp[facei], pT[facei],prho[facei]);
ppsi[facei]=mixture_.psi(prho[facei],pT[facei]);
pdrhodh[facei]=mixture_.drhodH(prho[facei],pT[facei]);
ph[facei] = mixture_.H(prho[facei], pT[facei]);
pmu[facei] = mixture_.mu(pT[facei]);
palpha[facei] = mixture_.alpha(prho[facei],pT[facei]);
}
}
else
{
forAll(pT, facei)
{
const typename MixtureType::thermoType& mixture_ =
this->patchFaceMixture(patchi, facei);
mixture_.TH(ph[facei], pT[facei],pp[facei],prho[facei]);
pmu[facei] = mixture_.mu(pT[facei]);
ppsi[facei]=mixture_.psi(prho[facei],pT[facei]);
pdrhodh[facei]=mixture_.drhodH(prho[facei],pT[facei]);
palpha[facei] = mixture_.alpha(prho[facei],pT[facei]);
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class MixtureType>
Foam::realGasHThermo<MixtureType>::realGasHThermo
(
const fvMesh& mesh,
const objectRegistry& obj
)
:
basicPsiThermo(mesh, obj),
MixtureType(*this, mesh, obj),
h_
(
IOobject
(
"h",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(0, 2, -2, 0, 0),
this->hBoundaryTypes()
),
rho_
(
IOobject
(
"rhoThermo",
mesh.time().timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
mesh,
dimDensity
),
drhodh_
(
IOobject
(
"drhodh",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(1, -5, 2, 0, 0)
)
{
scalarField& hCells = h_.internalField();
const scalarField& TCells = this->T_.internalField();
const scalarField& pCells =this->p_.internalField();
scalarField& rhoCells =this->rho_.internalField();
forAll(rhoCells, celli)
{
rhoCells[celli]=this->cellMixture(celli).rho(pCells[celli],TCells[celli]);
}
forAll(rho_.boundaryField(), patchi)
{
rho_.boundaryField()[patchi] ==
rho(this->T_.boundaryField()[patchi], patchi);
}
forAll(hCells, celli)
{
hCells[celli] = this->cellMixture(celli).H(rhoCells[celli],TCells[celli]);
}
forAll(h_.boundaryField(), patchi)
{
h_.boundaryField()[patchi] ==
h(this->T_.boundaryField()[patchi], patchi);
}
hBoundaryCorrection(h_);
calculate();
// Switch on saving old time
this->psi_.oldTime();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class MixtureType>
Foam::realGasHThermo<MixtureType>::~realGasHThermo()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class MixtureType>
void Foam::realGasHThermo<MixtureType>::correct()
{
if (debug)
{
Info<< "entering realGasHThermo<MixtureType>::correct()" << endl;
}
// force the saving of the old-time values
this->psi_.oldTime();
calculate();
if (debug)
{
Info<< "exiting realGasHThermo<MixtureType>::correct()" << endl;
}
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasHThermo<MixtureType>::h
(
const scalarField& T,
const labelList& cells
) const
{
//CL: need the pressure of the internal field to calculate the realGas enthalpy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const scalarField& pCells = this->p_.internalField();
tmp<scalarField> th(new scalarField(T.size()));
scalarField& h = th();
forAll(T, celli)
{
h[celli] = this->cellMixture(cells[celli]).H(this->cellMixture(cells[celli]).rho(pCells[cells[celli]],T[celli]),T[celli]);
}
return th;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasHThermo<MixtureType>::h
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas enthalpy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> th(new scalarField(T.size()));
scalarField& h = th();
forAll(T, facei)
{
h[facei] = this->patchFaceMixture(patchi, facei).H(this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]),T[facei]);
}
return th;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasHThermo<MixtureType>::rho
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas enthalpy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> trho(new scalarField(T.size()));
scalarField& rho = trho();
forAll(T, facei)
{
rho[facei] = this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]);
}
return trho;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasHThermo<MixtureType>::Cp
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas enthalpy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> tCp(new scalarField(T.size()));
scalarField& cp = tCp();
forAll(T, facei)
{
cp[facei] = this->patchFaceMixture(patchi, facei).Cp(this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]),T[facei]);
}
return tCp;
}
template<class MixtureType>
Foam::tmp<Foam::volScalarField> Foam::realGasHThermo<MixtureType>::Cp() const
{
const fvMesh& mesh = this->T_.mesh();
tmp<volScalarField> tCp
(
new volScalarField
(
IOobject
(
"Cp",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionSet(0, 2, -2, -1, 0),
this->T_.boundaryField().types()
)
);
volScalarField& cp = tCp();
forAll(this->T_, celli)
{
cp[celli] = this->cellMixture(celli).Cp(this->rho_[celli], this->T_[celli]);
}
forAll(this->T_.boundaryField(), patchi)
{
const fvPatchScalarField& pT = this->T_.boundaryField()[patchi];
const fvPatchScalarField& prho = this->rho_.boundaryField()[patchi];
fvPatchScalarField& pCp = cp.boundaryField()[patchi];
forAll(pT, facei)
{
pCp[facei] = this->patchFaceMixture(patchi, facei).Cp(prho[facei], pT[facei]);
}
}
return tCp;
}
template<class MixtureType>
Foam::tmp<Foam::scalarField> Foam::realGasHThermo<MixtureType>::Cv
(
const scalarField& T,
const label patchi
) const
{
//CL: need the pressure at the patch to calculate the realGas enthalpy
//CL: this is done this way to assure compatibility to old OF Thermo-Versions
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> tCv(new scalarField(T.size()));
scalarField& cv = tCv();
forAll(T, facei)
{
cv[facei] = this->patchFaceMixture(patchi, facei).Cv(this->patchFaceMixture(patchi, facei).rho(pp[facei], T[facei]), T[facei]);
}
return tCv;
}
// CL: Maybe this function should be changed so that it is not "const" fucntion anymore
template<class MixtureType>
Foam::tmp<Foam::volScalarField> Foam::realGasHThermo<MixtureType>::rho() const
{
const fvMesh& mesh = this->T_.mesh();
//CL: create a rho Field, which will be return
//CL: the problem is that this function is "const",
//CL: so a new variabel is needed
tmp<volScalarField> trho
(
new volScalarField
(
IOobject
(
"rhoFunctionThermo",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimDensity
)
);
//CL: copy "old" rho value onto the new rho field as start point
//CL: for the newton solver used in this->TH( ... )
trho()=rho_;
volScalarField& rho = trho();
const scalarField& hCells = h_.internalField();
const scalarField& pCells = this->p_.internalField();
scalarField TCells = this->T_.internalField();
forAll(pCells, celli)
{
const typename MixtureType::thermoType& mixture_ =
this->cellMixture(celli);
// getting the new rho Field
mixture_.TH(hCells[celli], TCells[celli], pCells[celli], rho[celli]);
}
forAll(p_.boundaryField(), patchi)
{
fvPatchScalarField pp = this->p_.boundaryField()[patchi];
fvPatchScalarField ph = h_.boundaryField()[patchi];
fvPatchScalarField pT = this->T_.boundaryField()[patchi];
fvPatchScalarField& prho_ = rho.boundaryField()[patchi];
forAll(pp, facei)
{
const typename MixtureType::thermoType& mixture_ =
this->patchFaceMixture(patchi, facei);
// getting the new rho patch Field
mixture_.TH(ph[facei], pT[facei],pp[facei],prho_[facei]);
}
}
return trho;
}
template<class MixtureType>
Foam::tmp<Foam::volScalarField> Foam::realGasHThermo<MixtureType>::Cv() const
{
const fvMesh& mesh = this->T_.mesh();
tmp<volScalarField> tCv
(
new volScalarField
(
IOobject
(
"Cv",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
dimensionSet(0, 2, -2, -1, 0)
)
);
volScalarField& cv = tCv();
forAll(this->T_, celli)
{
cv[celli] = this->cellMixture(celli).Cv(this->rho_[celli], this->T_[celli]);
}
forAll(this->T_.boundaryField(), patchi)
{
cv.boundaryField()[patchi] =
Cv(this->T_.boundaryField()[patchi], patchi);
}
return tCv;
}
template<class MixtureType>
bool Foam::realGasHThermo<MixtureType>::read()
{
if (basicPsiThermo::read())
{
MixtureType::read(*this);
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,203 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::realGasHThermo
Description
Enthalpy for a real gas fluid libary
SourceFiles
realGasHThermo.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef realGasHThermo_H
#define realGasHThermo_H
#include "basicPsiThermo.H"
#include "basicMixture.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class realGasHThermo Declaration
\*---------------------------------------------------------------------------*/
template<class MixtureType>
class realGasHThermo
:
public basicPsiThermo,
public MixtureType
{
// Private data
//- Enthalpy field
volScalarField h_;
//- DensityField
volScalarField rho_;
//- drhodh_Field
volScalarField drhodh_;
// Private member functions
//- Calculate the thermo variables
void calculate();
//- Construct as copy (not implemented)
realGasHThermo(const realGasHThermo<MixtureType>&);
public:
//- Runtime type information
TypeName("realGasHThermo");
// Constructors
//- Construct from mesh
realGasHThermo(const fvMesh&, const objectRegistry& obj);
//- Destructor
virtual ~realGasHThermo();
// Member functions
//- Return the compostion of the mixture
virtual basicMixture& composition()
{
return *this;
}
//- Return the compostion of the mixture
virtual const basicMixture& composition() const
{
return *this;
}
//- Update properties
virtual void correct();
// Access to thermodynamic state variables
//- Enthalpy [J/kg]
// Non-const access allowed for transport equations
virtual volScalarField& h()
{
return h_;
}
//- Enthalpy [J/kg]
virtual const volScalarField& h() const
{
return h_;
}
//CL: drhodh needed for pressure equation of the real gas solver
virtual const volScalarField& drhodh() const
{
return drhodh_;
}
// Fields derived from thermodynamic state variables
//- Enthalpy for cell-set [J/kg]
virtual tmp<scalarField> h
(
const scalarField& T,
const labelList& cells
) const;
//- Enthalpy for patch [J/kg]
virtual tmp<scalarField> h
(
const scalarField& T,
const label patchi
) const;
//- Density for patch [J/kg]
virtual tmp<scalarField> rho
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant pressure for patch [J/kg/K]
virtual tmp<scalarField> Cp
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant pressure [J/kg/K]
virtual tmp<volScalarField> Cp() const;
//- Heat capacity at constant volume for patch [J/kg/K]
virtual tmp<scalarField> Cv
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant volume [J/kg/K]
virtual tmp<volScalarField> Cv() const;
//- Density [kg/m^3] - uses current value of pressure
virtual tmp<volScalarField> rho() const;
//- Read thermophysicalProperties dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#ifdef NoRepository
# include "realGasHThermo.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,235 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "makeBasicPsiThermo.H"
#include "redlichKwong.H"
#include "pengRobinson.H"
#include "aungierRedlichKwong.H"
#include "soaveRedlichKwong.H"
#include "nasaHeatCapacityPolynomial.H"
#include "realGasSpecieThermo.H"
#include "constTransport.H"
#include "constRealGasTransport.H"
#include "sutherlandTransport.H"
#include "sutherlandRealGasTransport.H"
#include "constantHeatCapacity.H"
#include "pureMixture.H"
#include "realGasHThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/* * * * * * * * * * * * * * * private static data * * * * * * * * * * * * * */
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
pengRobinson
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
redlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
sutherlandRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
soaveRedlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
pengRobinson
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
redlichKwong
);
makeBasicRealGasThermo
(
realGasHThermo,
pureMixture,
constRealGasTransport,
realGasSpecieThermo,
constantHeatCapacity,
soaveRedlichKwong
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,26 @@
#!/bin/bash
cd ${0%/*} || exit 1 # run from this directory
# Installing freeSteam 2.1
if [ ! -d "freesteam-2.1" ]; then
wget http://sourceforge.net/projects/freesteam/files/freesteam/2.1/freesteam-2.1.tar.bz2
tar xjvf freesteam-2.1.tar.bz2
rm freesteam-2.1.tar.bz2
fi
#installing required packages for freesteam
sudo apt-get install subversion scons libgsl0-dev python-dev swig ipython python-matplotlib
#compiling freesteam
cd freesteam-2.1
scons
cd -
#copy dynamic library to $WM_PROJECT_DIR/lib/
cp freesteam-2.1/libfreesteam.so $WM_PROJECT_DIR/lib/$WM_ARCH$WM_COMPILER$WM_PRECISION_OPTION$WM_COMPILE_OPTION
#compiling classes to connect freesteam to foam
wmake libso
# ----------------------------------------------------------------- end-of-file

View file

@ -0,0 +1,602 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "IAPWS-IF97.H"
#include <iostream>
#include <stdlib.h>
//CL: calculated all (minimal) needed properties for a given pressure and enthalpy
void Foam::calculateProperties_ph
(
scalar &p,
scalar &h,
scalar &T,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha
)
{
SteamState S;
// CL: vapor mass fraction is also calculated in calculateProperties_h
// CL: in this fuction, x is a dummy variable and x is not return to IAPWSThermo.C
scalar x;
S=freesteam_set_ph(p,h);
calculateProperties_h(S,p,h,T,rho,psi,drhodh,mu,alpha,x);
}
//CL: calculated all (minimal) needed properties + the vapor mass fraction for a given pressure and enthalpy
void Foam::calculateProperties_ph
(
scalar &p,
scalar &h,
scalar &T,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha,
scalar &x
)
{
SteamState S;
S=freesteam_set_ph(p,h);
calculateProperties_h(S,p,h,T,rho,psi,drhodh,mu,alpha,x);
}
//CL: calculated all (minimal) needed properties for a given pressure and temperature
void Foam::calculateProperties_pT
(
scalar &p,
scalar &T,
scalar &h,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha
)
{
SteamState S;
// CL: vapor mass fraction is also calculated in calculateProperties_h
// CL: in this fuction, x is a dummy variable and x is not return to IAPWSThermo.
scalar x;
S=freesteam_set_pT(p,T);
calculateProperties_h(S,p,h,T,rho,psi,drhodh,mu,alpha,x);
}
//CL: calculated all (minimal) needed properties + the vapor mass fraction for a given pressure and temperature
void Foam::calculateProperties_pT
(
scalar &p,
scalar &T,
scalar &h,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha,
scalar &x
)
{
SteamState S;
S=freesteam_set_pT(p,T);
calculateProperties_h(S,p,h,T,rho,psi,drhodh,mu,alpha,x);
}
//CL: calculated the properties --> this function is called by the functions above
//CL: does not calulated the internal energy, if this is needed e.g. for sonicFoam
//CL: the function has to be changed a little bit
void Foam::calculateProperties_h
(
SteamState S,
scalar &p,
scalar &h,
scalar &T,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha,
scalar &x
)
{
label region;
scalar kappa,lambda,cp,beta;
region=freesteam_region(S);
if (region==1)
{
p=S.R1.p;
T=S.R1.T;
rho=1/freesteam_region1_v_pT(S.R1.p,S.R1.T);
h=freesteam_region1_h_pT(S.R1.p,S.R1.T);
x=0;
//Cl: note: in FreeStream, beta=1/V*(dV/dP)_P=const is called alphaV (in this region)
//Cl: note: in FreeStream, kappa=1/V*(dV/dP)_T=const is called kappaT (in this region)
kappa=freesteam_region1_kappaT_pT(S.R1.p,S.R1.T);
beta=freesteam_region1_alphav_pT(S.R1.p,S.R1.T);
cp=freesteam_region1_cp_pT(S.R1.p,S.R1.T);
//CL: getting derivatives using Bridgmans table
//CL: psi=(drho/dp)_h=const
//CL: drhodh=(drho/dh)_p=const
psi=-((T*beta*beta-beta)/cp-kappa*rho);
drhodh=-rho*beta/cp;
//CL: getting transport properties
mu=freesteam_mu_rhoT(rho, T);
lambda=freesteam_k_rhoT(rho,T);
alpha=lambda/cp; //Cl: Important info -->alpha= thermal diffusivity time density
}
else if (region==2)
{
p=S.R2.p;
T=S.R2.T;
rho=1/freesteam_region2_v_pT(S.R2.p,S.R2.T);
h=freesteam_region2_h_pT(S.R2.p,S.R2.T);
x=1;
//Cl: note: in FreeStream, beta=1/V*(dV/dP)_P=const is called alphaV (in this region)
//Cl: note: in FreeStream, kappa=1/V*(dV/dP)_T=const is called kappaT (in this region)
kappa=freesteam_region2_kappaT_pT(S.R2.p,S.R2.T);
beta=freesteam_region2_alphav_pT(S.R2.p,S.R2.T);
cp=freesteam_region2_cp_pT(S.R2.p,S.R2.T);
//CL: getting derivatives using Bridgmans table
//CL: psi=(drho/dp)_h=const
//CL: drhodh=(drho/dh)_p=const
psi=-((T*beta*beta-beta)/cp-kappa*rho);
drhodh=-rho*beta/cp;
//CL: getting transport properties
mu=freesteam_mu_rhoT(rho, T);
lambda=freesteam_k_rhoT(rho,T);
alpha=lambda/cp; //Cl: Important info -->alpha= thermal diffusivity time density
}
else if (region==3)
{
scalar gamma,cv;
rho=S.R3.rho;
T=S.R3.T;
p=freesteam_region3_p_rhoT(S.R3.rho,S.R3.T);
h=freesteam_region3_h_rhoT(S.R3.rho,S.R3.T);
//CL= when h<h @ critical point -->x=0 else x=1
if (h<2084256.263)
{
x=0;
}
else
{
x=1;
}
//Cl: note: beta=1/V*(dV/dP)_P=const
//Cl: note: kappa=1/V*(dV/dP)_T=const
//Cl: note: in FreeStream, gamma=1/p*(dp/dT)_v=const is called alphap (in this region)
gamma=freesteam_region3_alphap_rhoT(S.R3.rho,S.R3.T);
cp=freesteam_region3_cp_rhoT(S.R3.rho,S.R3.T);
cv=freesteam_region3_cv_rhoT(S.R3.rho,S.R3.T);
beta=(cp-cv)/(S.R3.T/S.R3.rho*p*gamma);
kappa=(cp-cv)/(S.R3.T/S.R3.rho*p*p*gamma*gamma);
//CL: getting derivatives using Bridgmans table
//CL: psi=(drho/dp)_h=const
//CL: drhodh=(drho/dh)_p=const
psi=-((T*beta*beta-beta)/cp-kappa*rho);
drhodh=-rho*beta/cp;
//CL: getting transport properties
mu=freesteam_mu_rhoT(rho, T);
lambda=freesteam_k_rhoT(rho,T);
alpha=lambda/cp; //Cl: Important info -->alpha= thermal diffusivity time density
}
else if (region==4)
{
scalar rhov,rhol,betav,betal,kappav,kappal,vv,vl,cpl,cpv,hl,hv,cp;
scalar dvldp,dvvdp,dhldp,dhvdp;
scalar dpdT,dvdh,dvdp,dxdp;
SteamState Sl,Sv;
x=S.R4.x;
T=S.R4.T;
rho=1/freesteam_region4_v_Tx(S.R4.T,S.R4.x);
h=freesteam_region4_h_Tx(S.R4.T,S.R4.x);
p=freesteam_region4_psat_T(S.R4.T);
cp=freesteam_region4_cp_Tx(S.R4.T,S.R4.x);
//CL: Getting density on the vapour and liquid lines
rhov=freesteam_region4_rhog_T(S.R4.T);
rhol=freesteam_region4_rhof_T(S.R4.T);
vv=1/rhov;
vl=1/rhol;
//CL: getting derivatives --> this is a bit tricky inside the vapor dome
dpdT=freesteam_region4_dpsatdT_T(S.R4.T);
// getting the states outside the vapour dome
Sl=freesteam_set_pv(p,vl-0.0000001); //inside region 1
Sv=freesteam_set_pv(p,vv+0.0000001); //inside region 2
kappal=freesteam_region1_kappaT_pT(Sl.R1.p,Sl.R1.T);
kappav=freesteam_region2_kappaT_pT(Sv.R2.p,Sv.R2.T);
betal=freesteam_region1_alphav_pT(Sl.R1.p,Sl.R1.T);
betav=freesteam_region2_alphav_pT(Sv.R2.p,Sv.R2.T);
cpl=freesteam_region1_cp_pT(Sl.R1.p,Sl.R1.T);
cpv=freesteam_region2_cp_pT(Sv.R2.p,Sv.R2.T);
hl=freesteam_region1_h_pT(Sl.R1.p,Sl.R1.T);
hv=freesteam_region2_h_pT(Sv.R2.p,Sv.R2.T);
//calculation derviatives on liquid and vapour line
dvldp=betal*vl/dpdT-kappal*vl;
dvvdp=betav*vv/dpdT-kappav*vv;
dhldp=vl*(1-betal*Sl.R1.T)+cpl/dpdT;
dhvdp=vv*(1-betav*Sv.R2.T)+cpv/dpdT;
dxdp=-dhldp/(hv-hl)
+(h-hl)/((hv-hl)*(hv-hl))
*(dhvdp-dhldp);
//CL: psi=(drho/dp)_h=const
dvdp=dvldp+(dvvdp-dvldp)*x+(vv-vl)*dxdp;
psi=-rho*rho*dvdp;
//CL: drhodh=(drho/dh)_p=const
dvdh=(vv-vl)/(hv-hl);
drhodh=-rho*rho*dvdh;
//CL: getting transport properties
mu=freesteam_mu_rhoT(rho, T);
lambda=freesteam_k_rhoT(rho,T);
alpha=lambda/cp; //Cl: Important info -->alpha= thermal diffusivity time density
}
else
{
std::cout<<"IAPWS-IF97 error, outside the regions 1-4"<<std::endl;
}
}
//CL: returns density for given pressure and temperature
Foam::scalar Foam::rho_pT(scalar p,scalar T)
{
return 1/freesteam_v(freesteam_set_pT(p,T));
}
//CL: returns density for given pressure and enthalpy
Foam::scalar Foam::rho_ph(scalar p,scalar h)
{
return 1/freesteam_v(freesteam_set_ph(p,h));
}
//CL: returns Cp(heat capacity @ contant pressure) for given pressure and temperature
Foam::scalar Foam::cp_pT(scalar p,scalar T)
{
return freesteam_cp(freesteam_set_pT(p,T));
}
//CL: returns Cp(heat capacity @ contant pressure) for given pressure and enthalpy
Foam::scalar Foam::cp_ph(scalar p,scalar h)
{
return freesteam_cp(freesteam_set_ph(p,h));
}
//CL: returns Cv (heat capacity @ contant volume) for given pressure and temperature
Foam::scalar Foam::cv_pT(scalar p,scalar T)
{
return freesteam_cv(freesteam_set_pT(p,T));
}
//CL: returns Cv (heat capacity @ contant volume) for given pressure and enthalpy
Foam::scalar Foam::cv_ph(scalar p,scalar h)
{
return freesteam_cv(freesteam_set_ph(p,h));
}
//CL: returns enthalpy for given pressure and temperature
Foam::scalar Foam::h_pT(scalar p,scalar T)
{
return freesteam_h(freesteam_set_pT(p,T));
}
//CL: returns temperature for given pressure and enthalpy
Foam::scalar Foam::T_ph(scalar p,scalar h)
{
return freesteam_T(freesteam_set_ph(p,h));
}
//CL: psiH=(drho/dp)_h=const
Foam::scalar Foam::psiH_pT(scalar p,scalar T)
{
return psiH(freesteam_set_pT(p,T));
}
//CL: psiH=(drho/dp)_h=const
Foam::scalar Foam::psiH_ph(scalar p,scalar h)
{
return psiH(freesteam_set_ph(p,h));
}
//CL: psiH=(drho/dp)_h=const
Foam::scalar Foam::psiH(SteamState S)
{
label region;
scalar psiH=0;
scalar kappa,cp,beta,rho;
region=freesteam_region(S);
if (region==1)
{
//Cl: note: in FreeStream, beta=1/V*(dV/dP)_P=const is called alphaV (in this region)
//Cl: note: in FreeStream, kappa=1/V*(dV/dP)_T=const is called kappaT (in this region)
kappa=freesteam_region1_kappaT_pT(S.R1.p,S.R1.T);
beta=freesteam_region1_alphav_pT(S.R1.p,S.R1.T);
cp=freesteam_region1_cp_pT(S.R1.p,S.R1.T);
rho=1/freesteam_region1_v_pT(S.R1.p,S.R1.T);
//CL: getting derivatives using Bridgmans table
//CL: psiH=(drho/dp)_h=const
psiH=-((S.R1.T*beta*beta-beta)/cp-kappa*rho);
}
else if (region==2)
{
//Cl: note: in FreeStream, beta=1/V*(dV/dP)_P=const is called alphaV (in this region)
//Cl: note: in FreeStream, kappa=1/V*(dV/dP)_T=const is called kappaT (in this region)
kappa=freesteam_region2_kappaT_pT(S.R2.p,S.R2.T);
beta=freesteam_region2_alphav_pT(S.R2.p,S.R2.T);
cp=freesteam_region2_cp_pT(S.R2.p,S.R2.T);
rho=1/freesteam_region2_v_pT(S.R2.p,S.R2.T);
//CL: getting derivatives using Bridgmans table
//CL: psiH=(drho/dp)_h=const
psiH=-((S.R2.T*beta*beta-beta)/cp-kappa*rho);
}
else if (region==3)
{
scalar gamma,cv,p;
rho=S.R3.rho;
p=freesteam_region3_p_rhoT(S.R3.rho,S.R3.T);
//Cl: note: beta=1/V*(dV/dP)_P=const
//Cl: note: kappa=1/V*(dV/dP)_T=const
//Cl: note: in FreeStream, gamma=1/p*(dp/dT)_v=const is called alphap (in this region
gamma=freesteam_region3_alphap_rhoT(S.R3.rho,S.R3.T);
cp=freesteam_region3_cp_rhoT(S.R3.rho,S.R3.T);
cv=freesteam_region3_cv_rhoT(S.R3.rho,S.R3.T);
beta=(cp-cv)/(S.R3.T/S.R3.rho*p*gamma);
kappa=(cp-cv)/(S.R3.T/S.R3.rho*p*p*gamma*gamma);
//CL: getting derivatives using Bridgmans table
//CL: psiH=(drho/dp)_h=const
psiH=-((S.R3.T*beta*beta-beta)/cp-kappa*rho);
}
else if (region==4)
{
scalar rhov,rhol,betav,betal,kappav,kappal,vv,vl,cpl,cpv,hl,hv,h,p;
scalar dvldp,dvvdp,dhldp,dhvdp;
scalar dpdT,dvdp,dxdp;
SteamState Sl,Sv;
rho=1/freesteam_region4_v_Tx(S.R4.T,S.R4.x);
h=freesteam_region4_h_Tx(S.R4.T,S.R4.x);
p=freesteam_region4_psat_T(S.R4.T);
//CL: Getting density on the vapour and liquid lines
rhov=freesteam_region4_rhog_T(S.R4.T);
rhol=freesteam_region4_rhof_T(S.R4.T);
vv=1/rhov;
vl=1/rhol;
//CL: getting derivatives --> this is a bit tricky in the vapor dome
dpdT=freesteam_region4_dpsatdT_T(S.R4.T);
// getting the states outside the vapour dome
Sl=freesteam_set_pv(p,vl-0.0000001); //inside region 1
Sv=freesteam_set_pv(p,vv+0.0000001); //inside region 2
kappal=freesteam_region1_kappaT_pT(Sl.R1.p,Sl.R1.T);
kappav=freesteam_region2_kappaT_pT(Sv.R2.p,Sv.R2.T);
betal=freesteam_region1_alphav_pT(Sl.R1.p,Sl.R1.T);
betav=freesteam_region2_alphav_pT(Sv.R2.p,Sv.R2.T);
cpl=freesteam_region1_cp_pT(Sl.R1.p,Sl.R1.T);
cpv=freesteam_region2_cp_pT(Sv.R2.p,Sv.R2.T);
hl=freesteam_region1_h_pT(Sl.R1.p,Sl.R1.T);
hv=freesteam_region2_h_pT(Sv.R2.p,Sv.R2.T);
//calculation derviatives on liquid and vapour line
dvldp=betal*vl/dpdT-kappal*vl;
dvvdp=betav*vv/dpdT-kappav*vv;
dhldp=vl*(1-betal*Sl.R1.T)+cpl/dpdT;
dhvdp=vv*(1-betav*Sv.R2.T)+cpv/dpdT;
dxdp=-dhldp/(hv-hl)
+(h-hl)/((hv-hl)*(hv-hl))
*(dhvdp-dhldp);
//CL: psiH=(drho/dp)_h=const
dvdp=dvldp+(dvvdp-dvldp)*S.R4.x+(vv-vl)*dxdp;
psiH=-rho*rho*dvdp;
}
else
{
Info<<"IAPWS-IF97.C error, outside the regions 1-4"<<endl;
}
return psiH;
}
//CL: drhodh=(drho/dh)_p=const
Foam::scalar Foam::drhodh_pT(scalar p,scalar T)
{
return drhodh(freesteam_set_pT(p,T));
}
//CL: drhodh=(drho/dh)_p=const
Foam::scalar Foam::drhodh_ph(scalar p,scalar h)
{
return drhodh(freesteam_set_ph(p,h));
}
//CL: drhodh=(drho/dh)_p=const
Foam::scalar Foam::drhodh(SteamState S)
{
label region;
scalar drhodh=0;
scalar cp,beta,rho;
region=freesteam_region(S);
if (region==1)
{
rho=1/freesteam_region1_v_pT(S.R1.p,S.R1.T);
//Cl: note: in FreeStream, beta=1/V*(dV/dP)_P=const is called alphaV (in this region)
beta=freesteam_region1_alphav_pT(S.R1.p,S.R1.T);
cp=freesteam_region1_cp_pT(S.R1.p,S.R1.T);
//CL: getting derivatives using Bridgmans table
//CL: drhodh=(drho/dh)_p=const
drhodh=-rho*beta/cp;
}
else if (region==2)
{
rho=1/freesteam_region2_v_pT(S.R2.p,S.R2.T);
//Cl: note: in FreeStream, beta=1/V*(dV/dP)_P=const is called alphaV (in this region)
//Cl: note: in FreeStream, kappa=1/V*(dV/dP)_T=const is called kappaT (in this region)
beta=freesteam_region2_alphav_pT(S.R2.p,S.R2.T);
cp=freesteam_region2_cp_pT(S.R2.p,S.R2.T);
//CL: getting derivatives using Bridgmans table
//CL: drhodh=(drho/dh)_p=const
drhodh=-rho*beta/cp;
}
else if (region==3)
{
scalar gamma,cv,p;
p=freesteam_region3_p_rhoT(S.R3.rho,S.R3.T);
//Cl: note: beta=1/V*(dV/dP)_P=const
//Cl: note: in FreeStream, gamma=1/p*(dp/dT)_v=const is called alphap (in this region
gamma=freesteam_region3_alphap_rhoT(S.R3.rho,S.R3.T);
cp=freesteam_region3_cp_rhoT(S.R3.rho,S.R3.T);
cv=freesteam_region3_cv_rhoT(S.R3.rho,S.R3.T);
beta=(cp-cv)/(S.R3.T/S.R3.rho*p*gamma);
//CL: getting derivatives using Bridgmans table
//CL: drhodh=(drho/dh)_p=const
drhodh=-S.R3.rho*beta/cp;
}
else if (region==4)
{
scalar vv,vl,hl,hv,p;
SteamState Sl,Sv;
rho=1/freesteam_region4_v_Tx(S.R4.T,S.R4.x);
p=freesteam_region4_psat_T(S.R4.T);
//CL: Getting density on the vapour and liquid lines
vv=1/freesteam_region4_rhog_T(S.R4.T);
vl=1/freesteam_region4_rhof_T(S.R4.T);
// getting the states outside the vapour dome
Sl=freesteam_set_pv(p,vl-0.0000001); //inside region 1
Sv=freesteam_set_pv(p,vv+0.0000001); //inside region 2
hl=freesteam_region1_h_pT(Sl.R1.p,Sl.R1.T);
hv=freesteam_region2_h_pT(Sv.R2.p,Sv.R2.T);
//CL: drhodh=(drho/dh)_p=const
drhodh=-rho*rho*(vv-vl)/(hv-hl);
}
else
{
Info<<"IAPWS-IF97.C error, outside the regions 1-4"<<endl;
}
return drhodh;
}

View file

@ -0,0 +1,231 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
IAPWS-IF97 (water) based thermodynamic class. Water properties calculated by freeSteam.
This code connects OpenFoam with freeSteam and provides the basic functions needed in OpenFOAM
For more information about freeSteam and its authors have a look @ http://freesteam.sourceforge.net/example.php
SourceFiles
IAPWS-IF97.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef IAPWSIF97_H
#define IAPWSIF97_H
#include "basicPsiThermo.H"
#include "steam.H"
#ifdef __cplusplus
#define EXTERN extern "C"
#else
#define EXTERN extern
#endif
//CL:
EXTERN double freesteam_p(SteamState S);
EXTERN double freesteam_T(SteamState S);
EXTERN double freesteam_rho(SteamState S);
EXTERN double freesteam_v(SteamState S);
EXTERN double freesteam_u(SteamState S);
EXTERN double freesteam_h(SteamState S);
EXTERN double freesteam_s(SteamState S);
EXTERN double freesteam_cp(SteamState S);
EXTERN double freesteam_cv(SteamState S);
EXTERN double freesteam_w(SteamState S);
EXTERN double freesteam_x(SteamState S);
EXTERN double freesteam_mu(SteamState S);
EXTERN double freesteam_k(SteamState S);
//CL: getting SteamState for two given properties e.g. pressure and temperatur
EXTERN SteamState freesteam_set_pv(double,double);
EXTERN SteamState freesteam_set_pu(double,double);
EXTERN SteamState freesteam_set_pT(double,double);
EXTERN SteamState freesteam_set_ph(double,double);
//CL: getting region of the SteamState
EXTERN int freesteam_region(SteamState);
//CL: transport properties
EXTERN double freesteam_mu_rhoT(double,double);
EXTERN double freesteam_k_rhoT(double,double);
//CL: Region 1 --> see region1.h (freesteam)
EXTERN double freesteam_region1_v_pT(double,double);
EXTERN double freesteam_region1_h_pT(double,double);
EXTERN double freesteam_region1_kappaT_pT(double,double);
EXTERN double freesteam_region1_alphav_pT(double,double);
EXTERN double freesteam_region1_cp_pT(double,double);
EXTERN double freesteam_region1_u_pT(double,double);
EXTERN double freesteam_region1_s_pT(double,double);
EXTERN double freesteam_region1_cv_pT(double,double);
//CL: Region 2 --> see region2.h (freesteam)
EXTERN double freesteam_region2_v_pT(double,double);
EXTERN double freesteam_region2_u_pT(double,double);
EXTERN double freesteam_region2_s_pT(double,double);
EXTERN double freesteam_region2_h_pT(double,double);
EXTERN double freesteam_region2_cp_pT(double,double);
EXTERN double freesteam_region2_cv_pT(double,double);
EXTERN double freesteam_region2_alphav_pT(double,double);
EXTERN double freesteam_region2_kappaT_pT(double,double);
//CL: Region 3 --> see region3.h (freesteam)
EXTERN double freesteam_region3_p_rhoT(double,double);
EXTERN double freesteam_region3_u_rhoT(double,double);
EXTERN double freesteam_region3_s_rhoT(double,double);
EXTERN double freesteam_region3_h_rhoT(double,double);
EXTERN double freesteam_region3_cp_rhoT(double,double);
EXTERN double freesteam_region3_cv_rhoT(double,double);
EXTERN double freesteam_region3_alphap_rhoT(double,double);
EXTERN double freesteam_region3_betap_rhoT(double,double);
//CL: Region 4 --> see region4.h (freesteam)
EXTERN double freesteam_region4_psat_T(double);
EXTERN double freesteam_region4_Tsat_p(double);
EXTERN double freesteam_region4_rhof_T(double);
EXTERN double freesteam_region4_rhog_T(double);
EXTERN double freesteam_region4_v_Tx(double,double);
EXTERN double freesteam_region4_u_Tx(double,double);
EXTERN double freesteam_region4_h_Tx(double,double);
EXTERN double freesteam_region4_s_Tx(double,double);
EXTERN double freesteam_region4_cp_Tx(double,double);
EXTERN double freesteam_region4_cv_Tx(double,double);
EXTERN double freesteam_region4_dpsatdT_T(double);
namespace Foam
{
//CL: Functions to caluculate all fluid properties
void calculateProperties_h
(
SteamState S,
scalar &rho,
scalar &h,
scalar &T,
scalar &p,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha,
scalar &x
);
//CL: This functions returns all (minimal) needed propeties (p,T,h,rho,psi,drhodh,mu and alpha) for given p and T
void calculateProperties_pT
(
scalar &p,
scalar &T,
scalar &h,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha
);
//CL: This function returns the same values as the function above for given p and T
//CL: Additionally, the vapor mass fraction x is return
//CL: NOTE: This function is only included to have the possibility to update x at the fixedValue (Temperature) BC
//CL: can only return x=0 and x=1 because it is not possible to describe the vapour dome with p and T
void calculateProperties_pT
(
scalar &p,
scalar &T,
scalar &h,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha,
scalar &x
);
//CL: This functions returns all (minimal) needed properties (p,T,h,rho,psi,drhodh,mu and alpha) for given p and h
void calculateProperties_ph
(
scalar &p,
scalar &h,
scalar &T,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha
);
//CL: This function returns the same values as the function above for given p and h
//CL: Additionally, the vapor mass fraction x is return
void calculateProperties_ph
(
scalar &p,
scalar &h,
scalar &T,
scalar &rho,
scalar &psi,
scalar &drhodh,
scalar &mu,
scalar &alpha,
scalar &x
);
//CL: Return density for given pT or ph;
scalar rho_pT(scalar p,scalar T);
scalar rho_ph(scalar p,scalar h);
//CL: Return cp for given pT or ph;
scalar cp_pT(scalar p,scalar T);
scalar cp_ph(scalar p,scalar h);
//CL: Return cv for given pT or ph;
scalar cv_pT(scalar p,scalar T);
scalar cv_ph(scalar p,scalar h);
//CL: Return enthalpy for given pT;
scalar h_pT(scalar p,scalar T);
//CL: Return temperature for given ph;
scalar T_ph(scalar p,scalar T);
//CL: Return psiH=(drho/dp)_h=constant for given pT or ph;
scalar psiH_pT(scalar p,scalar T);
scalar psiH_ph(scalar p,scalar h);
scalar psiH(SteamState S);
//CL: Return drhodh=(drho/dh)_p=constant for given pT or ph;
scalar drhodh_pT(scalar p,scalar T);
scalar drhodh_ph(scalar p,scalar h);
scalar drhodh(SteamState S);
}
#endif //IAPWSIF97_C_

View file

@ -0,0 +1,476 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "IAPWSThermo.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::IAPWSThermo::calculate()
{
scalarField& hCells = h_.internalField();
scalarField& pCells = this->p_.internalField();
scalarField& TCells = this->T_.internalField();
scalarField& rhoCells= this->rho_.internalField();
scalarField& psiCells = this->psi_.internalField();
scalarField& drhodhCells = this->drhodh_.internalField();
scalarField& muCells = this->mu_.internalField();
scalarField& alphaCells = this->alpha_.internalField();
//CL: Updating all cell properties
//CL: loop through all cells
forAll(TCells, celli)
{
//CL: see IAPWAS-IF97.H
calculateProperties_ph
(
pCells[celli],
hCells[celli],
TCells[celli],
rhoCells[celli],
psiCells[celli],
drhodhCells[celli],
muCells[celli],
alphaCells[celli]
);
}
//CL: loop through all patches
forAll(T_.boundaryField(), patchi)
{
fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
fvPatchScalarField& pT = this->T_.boundaryField()[patchi];
fvPatchScalarField& ppsi = this->psi_.boundaryField()[patchi];
fvPatchScalarField& pdrhodh = this->drhodh_.boundaryField()[patchi];
fvPatchScalarField& prho = this->rho_.boundaryField()[patchi];
fvPatchScalarField& ph = this->h_.boundaryField()[patchi];
fvPatchScalarField& pmu = this->mu_.boundaryField()[patchi];
fvPatchScalarField& palpha = this->alpha_.boundaryField()[patchi];
//CL: Updating the patch properties for patches with fixed temperature BC's
if (pT.fixesValue())
{
forAll(pT, facei)
{
//CL: see IAPWAS-IF97.H
calculateProperties_pT
(
pp[facei],
pT[facei],
ph[facei],
prho[facei],
ppsi[facei],
pdrhodh[facei],
pmu[facei],
palpha[facei]
);
}
}
//CL: Updating the patch properties for patches without fixed temperature BC's
else
{
forAll(pT, facei)
{
//CL: see IAPWAS-IF97.H
calculateProperties_ph
(
pp[facei],
ph[facei],
pT[facei],
prho[facei],
ppsi[facei],
pdrhodh[facei],
pmu[facei],
palpha[facei]
);
}
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::IAPWSThermo::IAPWSThermo
(
const fvMesh& mesh,
const objectRegistry& obj
)
:
basicPsiThermo(mesh, obj),
h_
(
IOobject
(
"h",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(0, 2, -2, 0, 0),
this->hBoundaryTypes()
),
rho_
(
IOobject
(
"rhoThermo",
mesh.time().timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
),
mesh,
dimDensity
),
drhodh_
(
IOobject
(
"drhodh",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(1, -5, 2, 0, 0)
)
{
scalarField& hCells = h_.internalField();
scalarField& TCells = this->T_.internalField();
scalarField& pCells =this->p_.internalField();
scalarField& rhoCells =this->rho_.internalField();
forAll(hCells, celli)
{
hCells[celli] = h_pT(pCells[celli],TCells[celli]);
}
forAll(h_.boundaryField(), patchi)
{
h_.boundaryField()[patchi] ==
h(this->T_.boundaryField()[patchi], patchi);
}
forAll(rhoCells, celli)
{
rhoCells[celli] = rho_pT(pCells[celli],TCells[celli]);
}
forAll(rho_.boundaryField(), patchi)
{
rho_.boundaryField()[patchi] ==
rho(this->p_.boundaryField()[patchi] ,this->h_.boundaryField()[patchi], patchi);
}
hBoundaryCorrection(h_);
calculate();
// Switch on saving old time
this->psi_.oldTime();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::IAPWSThermo::~IAPWSThermo()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::IAPWSThermo::correct()
{
if (debug)
{
Info<< "entering IAPWSThermo::correct()" << endl;
}
// force the saving of the old-time values
this->psi_.oldTime();
calculate();
if (debug)
{
Info<< "exiting IAPWSThermo::correct()" << endl;
}
}
Foam::tmp<Foam::scalarField> Foam::IAPWSThermo::h
(
const scalarField& T,
const labelList& cells
) const
{
//getting pressure field
const scalarField& pCells = this->p_.internalField();
tmp<scalarField> th(new scalarField(T.size()));
scalarField& h = th();
forAll(T, celli)
{
h[celli] = h_pT(pCells[cells[celli]],T[celli]);
}
return th;
}
Foam::tmp<Foam::scalarField> Foam::IAPWSThermo::h
(
const scalarField& T,
const label patchi
) const
{
// getting pressure at the patch
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> th(new scalarField(T.size()));
scalarField& h = th();
forAll(T, facei)
{
h[facei] = h_pT(pp[facei], T[facei]);
}
return th;
}
//CL: Calculates rho at patch
Foam::tmp<Foam::scalarField> Foam::IAPWSThermo::rho
(
const scalarField& p,
const scalarField& h,
const label patchi
) const
{
tmp<scalarField> trho(new scalarField(h.size()));
scalarField& rho = trho();
forAll(h, facei)
{
rho[facei] = rho_ph(p[facei], h[facei]);
}
return trho;
}
Foam::tmp<Foam::scalarField> Foam::IAPWSThermo::Cp
(
const scalarField& T,
const label patchi
) const
{
// getting pressure at the patch
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> tCp(new scalarField(T.size()));
scalarField& cp = tCp();
forAll(T, facei)
{
cp[facei] = cp_ph(pp[facei],h_pT(pp[facei], T[facei]));
}
return tCp;
}
Foam::tmp<Foam::volScalarField> Foam::IAPWSThermo::Cp() const
{
const fvMesh& mesh = this->T_.mesh();
tmp<volScalarField> tCp
(
new volScalarField
(
IOobject
(
"Cp",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(0, 2, -2, -1, 0),
this->T_.boundaryField().types()
)
);
volScalarField& cp = tCp();
forAll(this->T_, celli)
{
cp[celli] = cp_ph(this->p_[celli], this->h_[celli]);
}
forAll(this->T_.boundaryField(), patchi)
{
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
const fvPatchScalarField& ph = this->h_.boundaryField()[patchi];
fvPatchScalarField& pCp = cp.boundaryField()[patchi];
forAll(ph, facei)
{
pCp[facei] = cp_ph(pp[facei], ph[facei]);
}
}
return tCp;
}
//CL: Returns an updated field for rho
Foam::tmp<Foam::volScalarField> Foam::IAPWSThermo::rho() const
{
const fvMesh& mesh = this->p_.mesh();
tmp<volScalarField> prho
(
new volScalarField
(
IOobject
(
"rhoThermo2",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimDensity
)
);
volScalarField& rho = prho();
forAll(this->p_, celli)
{
rho[celli] = rho_ph(this->p_[celli], this->h_[celli]);
}
forAll(this->T_.boundaryField(), patchi)
{
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
const fvPatchScalarField& ph = this->h_.boundaryField()[patchi];
fvPatchScalarField& prho = rho.boundaryField()[patchi];
forAll(ph, facei)
{
prho[facei] = rho_ph(pp[facei], ph[facei]);
}
}
return prho;
}
Foam::tmp<Foam::scalarField> Foam::IAPWSThermo::Cv
(
const scalarField& T,
const label patchi
) const
{
// getting pressure at the patch
const fvPatchScalarField& pp = this->p_.boundaryField()[patchi];
tmp<scalarField> tCv(new scalarField(T.size()));
scalarField& cv = tCv();
forAll(T, facei)
{
cv[facei] = cv_ph(pp[facei], h_pT(pp[facei], T[facei]));
}
return tCv;
}
Foam::tmp<Foam::volScalarField> Foam::IAPWSThermo::Cv() const
{
const fvMesh& mesh = this->T_.mesh();
tmp<volScalarField> tCv
(
new volScalarField
(
IOobject
(
"Cv",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionSet(0, 2, -2, -1, 0)
)
);
volScalarField& cv = tCv();
forAll(this->h_, celli)
{
cv[celli] = cv_ph(this->p_[celli], this->h_[celli]);
}
forAll(this->T_.boundaryField(), patchi)
{
cv.boundaryField()[patchi] =
Cv(this->T_.boundaryField()[patchi], patchi);
}
return tCv;
}
bool Foam::IAPWSThermo::read()
{
basicPsiThermo::read();
return true;
}
// ************************************************************************* //

View file

@ -0,0 +1,198 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::IAPWSThermo
Description:
Waterproperties based on the IAPWS 97 tables
The water properties are caluclated using freeSteam (http://freesteam.sourceforge.net/example.php)
General paper decribing the water tables:
"Revised Release on the IAPWS Industrial Formulation 1997 for the Thermodynamic Properties of Water and Steam"
SourceFiles
IAPWSThermo.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef IAPWSThermo_H
#define IAPWSThermo_H
#include "basicPsiThermo.H"
#include "IAPWS-IF97.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class IAPWSTHERMO Declaration
\*---------------------------------------------------------------------------*/
class IAPWSThermo
:
public basicPsiThermo
{
// Private data
//- Enthalpy field
volScalarField h_;
//- DensityField
volScalarField rho_;
// CL:drhodh Field
// CL:needed for pressure equation
volScalarField drhodh_;
// Private member functions
//- Calculate the thermo variables
void calculate();
public:
//- Runtime type information
TypeName("IAPWSThermo");
// Constructors
//- Construct from mesh
IAPWSThermo(const fvMesh&, const objectRegistry& obj);
//- Destructor
virtual ~IAPWSThermo();
// Member functions
//- Update properties
virtual void correct();
// Access to thermodynamic state variables
//- Enthalpy [J/kg]
// Non-const access allowed for transport equations
virtual volScalarField& h()
{
return h_;
}
//- Enthalpy [J/kg]
virtual const volScalarField& h() const
{
return h_;
}
// Fields derived from thermodynamic state variables
//- Enthalpy for cell-set [J/kg]
virtual tmp<scalarField> h
(
const scalarField& T,
const labelList& cells
) const;
//- Enthalpy for patch [J/kg]
virtual tmp<scalarField> h
(
const scalarField& T,
const label patchi
) const;
//- Density for patch [J/kg]
virtual tmp<scalarField> rho
(
const scalarField& p,
const scalarField& h,
const label patchi
) const;
//- Heat capacity at constant pressure for patch [J/kg/K]
// dummy function needed for BC
virtual tmp<scalarField> Cp
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant pressure [J/kg/K]
virtual tmp<volScalarField> Cp() const;
//- Heat capacity at constant volume for patch [J/kg/K]
virtual tmp<scalarField> Cv
(
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant volume [J/kg/K]
virtual tmp<volScalarField> Cv() const;
//- Gradient drhodh @ constant pressure
virtual const volScalarField& drhodh() const
{
return drhodh_;
}
//- Density [kg/m^3] - uses current value of pressure
virtual tmp<volScalarField> rho() const;
//- Read thermophysicalProperties dictionary
virtual bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "IAPWSThermo.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "makeBasicPsiThermo.H"
#include "IAPWSThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#define makeBasicExternalLibraryBasedThermo(Cthermo) \
\
typedef Cthermo \
Cthermo; \
\
defineTemplateTypeNameAndDebugWithName \
( \
Cthermo, \
#Cthermo, \
0 \
); \
\
addToRunTimeSelectionTable \
( \
basicPsiThermo, \
Cthermo, \
fvMesh \
)
/* * * * * * * * * * * * * * * private static data * * * * * * * * * * * * * */
makeBasicExternalLibraryBasedThermo
(
IAPWSThermo
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
Includes the definition of a struct from freestream
Code copied from freestream --> steam.h
\*---------------------------------------------------------------------------*/
typedef struct SteamState_R1_struct{
double p, T;
} SteamState_R1;
typedef struct SteamState_R2_struct{
double p, T;
} SteamState_R2;
typedef struct SteamState_R3_struct{
double rho, T;
} SteamState_R3;
typedef struct SteamState_R4_struct{
double T, x;
} SteamState_R4;
typedef struct SteamState_struct{
char region;
union{
SteamState_R1 R1;
SteamState_R2 R2;
SteamState_R3 R3;
SteamState_R4 R4;
};
} SteamState;

View file

@ -0,0 +1,4 @@
IAPWSThermo/IAPWS-IF97.C
IAPWSThermo/IAPWSThermos.C
LIB = $(FOAM_LIBBIN)/libIAPWSThermo

View file

@ -0,0 +1,8 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude
LIB_LIBS = \
-lfiniteVolume\
-lbasicThermophysicalModels

View file

@ -8,6 +8,10 @@ $(atomicWeights)/atomicWeights.C
$(specie)/specie.C
$(speciesTable)/speciesTable.C
$(equationOfState)/perfectGas/perfectGas.C
$(equationOfState)/cubicEquationOfState/redlichKwong/redlichKwong.C
$(equationOfState)/cubicEquationOfState/aungierRedlichKwong/aungierRedlichKwong.C
$(equationOfState)/cubicEquationOfState/pengRobinson/pengRobinson.C
$(equationOfState)/cubicEquationOfState/soaveRedlichKwong/soaveRedlichKwong.C
$(reactions)/makeChemkinReactions.C
$(reactions)/makeReactionThermoReactions.C
$(reactions)/makeLangmuirHinshelwoodReactions.C

View file

@ -0,0 +1,85 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
Aungier Redlich Kwong equation of state.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "aungierRedlichKwong.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::aungierRedlichKwong::aungierRedlichKwong(Istream& is)
:
specie(is),
pcrit_(readScalar(is)),
Tcrit_(readScalar(is)),
azentricFactor_(readScalar(is)),
rhocrit_(readScalar(is)),
a0_(0.42747*pow(this->RR,2)*pow(Tcrit_,2)/pcrit_),
b_(0.08664*this->RR*Tcrit_/pcrit_),
c_(this->RR*Tcrit_/(pcrit_+(a0_/(this->W()/rhocrit_*(this->W()/rhocrit_+b_))))+b_-this->W()/rhocrit_),
n_(0.4986+1.2735*azentricFactor_+0.4754*pow(azentricFactor_,2)),
b2_(pow(b_,2)),
b3_(pow(b_,3)),
b4_(pow(b_,4)),
b5_(pow(b_,5)),
c2_(pow(c_,2)),
// Starting GUESS for the density by ideal gas law
rhostd_(this->rho(Pstd,Tstd,Pstd/(Tstd*this->R()))),
//CL: Only uses the default values
rhoMax_(1500),
rhoMin_(1e-3),
aSave(0.0),
daSave(0.0),
d2aSave(0.0),
TSave(0.0)
{
is.check("aungierRedlichKwong::aungierRedlichKwong(Istream& is)");
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const aungierRedlichKwong& ark)
{
os << static_cast<const specie&>(ark)<< token::SPACE
<< ark.pcrit_ << tab<< ark.Tcrit_<< tab<<ark.azentricFactor_<< tab<<ark.rhocrit_;
os.check("Ostream& operator<<(Ostream& os, const aungierRedlichKwong& st)");
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* //

View file

@ -0,0 +1,308 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::aungierRedlichKwong
Description
Aungier Redlich Kwong equation of state.
Paper:
Title: A Fast, Accurate Real Gas Equation of State for Fluid Dynamic Analysis Applications
Authors: R. H. Aungier
Journal: Journal of Fluids Engineering, Vol.117, 1995
SourceFiles
aungierRedlichKwongI.H
aungierRedlichKwong.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef aungierRedlichKwong_H
#define aungierRedlichKwong_H
#include "specie.H"
#include "autoPtr.H"
#include "DynamicList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class aungierRedlichKwong Declaration
\*---------------------------------------------------------------------------*/
class aungierRedlichKwong
:
public specie
{
mutable scalar pcrit_;
mutable scalar Tcrit_;
mutable scalar azentricFactor_;
mutable scalar rhocrit_;
//Aungier Redlich Kwong factors
mutable scalar a0_;
mutable scalar b_;
mutable scalar c_;
mutable scalar n_;
//CL: pow of constants (b_, c_) used in the code e.g. b2_=b*b;
mutable scalar b2_;
mutable scalar b3_;
mutable scalar b4_;
mutable scalar b5_;
mutable scalar c2_;
//Density @STD, initialise after a, b!
mutable scalar rhostd_;
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
mutable scalar rhoMax_;
mutable scalar rhoMin_;
protected:
//CL: Variables to save the values of a, dadT and d2adT2 of the mixture
//CL: Variables must corrected for changing temperatures
mutable scalar aSave;
mutable scalar daSave;
mutable scalar d2aSave;
//CL: save the temperature for which the save coefficients (amix,dadTmix,d2adT2mix) are correct
mutable scalar TSave;
//Protected functions
//CL: function updates the coefficients (aSave, daSave, d2aSave)
inline void updateModelCoefficients(const scalar T) const;
public:
// Constructors
//- Construct from components
inline aungierRedlichKwong
(
const specie& sp
);
//- Construct from Istream
aungierRedlichKwong(Istream&);
//- Construct as named copy
inline aungierRedlichKwong(const word& name, const aungierRedlichKwong&);
//- Construct and return a clone
inline autoPtr<aungierRedlichKwong> clone() const;
// Selector from Istream
inline static autoPtr<aungierRedlichKwong> New(Istream& is);
// Member functions
inline scalar& rhostd();
inline scalar& rhostd() const;
inline scalar& rhoMin();
inline scalar& rhoMin() const;
inline scalar& rhoMax();
inline scalar& rhoMax() const;
inline scalar& Tcrit();
inline scalar& Tcrit() const;
inline scalar& pcrit();
inline scalar& pcrit() const;
inline scalar& rhocrit();
inline scalar& rhocrit() const;
inline scalar& azentricFactor();
inline scalar& azentricFactor() const;
//CL: Model coefficient a(T)
inline scalar a(const scalar T)const;
//CL: temperature deriviative of model coefficient a(T)
inline scalar dadT(const scalar T)const;
//CL: second order temperature deriviative of model coefficient a(T)
inline scalar d2adT2(const scalar T)const;
//Return Aungier Redlich Kwong factors
inline scalar& a0()const;
inline scalar& a0();
inline scalar& b()const;
inline scalar& b();
inline scalar& c()const;
inline scalar& c();
inline scalar& n()const;
inline scalar& n();
//CL: return power of constants (b_, c_)
inline scalar& b2()const;
inline scalar& b2();
inline scalar& b3()const;
inline scalar& b3();
inline scalar& b4()const;
inline scalar& b4();
inline scalar& b5()const;
inline scalar& b5();
inline scalar& c2()const;
inline scalar& c2();
//CL: Equation of state
inline scalar p(const scalar rho, const scalar T) const;
//CL: first order derivatives
inline scalar dpdv(const scalar rho, const scalar T) const;
inline scalar dpdT(const scalar rho, const scalar T) const;
inline scalar dvdT(const scalar rho, const scalar T) const;
inline scalar dvdp(const scalar rho, const scalar T) const;
inline scalar isobarExpCoef(const scalar rho, const scalar T) const;
inline scalar isothermalCompressiblity
(
const scalar rho,
const scalar T
) const;
//CL: Used for cv
inline scalar integral_d2pdT2_dv
(
const scalar rho,
const scalar T
) const ;
//CL: second order derivatives, not Used At The Moment
inline scalar d2pdv2(const scalar rho, const scalar T) const;
inline scalar d2pdT2(const scalar rho, scalar T) const;
inline scalar d2pdvdT(const scalar rho, const scalar T) const;
inline scalar d2vdT2(const scalar rho, const scalar T) const;
//CL: Used for internal Energy
inline scalar integral_p_dv(const scalar rho, const scalar T) const;
//CL: Used for Entropy
inline scalar integral_dpdT_dv(const scalar rho, const scalar T) const;
//- Return density [kg/m^3]
// rho0 is the starting point of the newton solver used to calculate rho
inline scalar rho
(
const scalar p,
const scalar T,
const scalar rho0
) const;
inline scalar rho(const scalar p, const scalar T) const;
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar psi(const scalar rho, const scalar T) const;
//- Return compression factor []
inline scalar Z
(
const scalar p,
const scalar T,
const scalar rho0
) const;
// Member operators
inline void operator+=(const aungierRedlichKwong&);
inline void operator*=(const scalar s);
// Friend operators
inline friend aungierRedlichKwong operator+
(
const aungierRedlichKwong&,
const aungierRedlichKwong&
);
inline friend aungierRedlichKwong operator*
(
const scalar s,
const aungierRedlichKwong&
);
// Ostream Operator
friend Ostream& operator<<(Ostream&, const aungierRedlichKwong&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "aungierRedlichKwongI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,674 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "aungierRedlichKwong.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
inline aungierRedlichKwong::aungierRedlichKwong
(
const specie& sp
)
:
specie(sp)
{}
// Construct as named copy
inline aungierRedlichKwong::aungierRedlichKwong(const word& name, const aungierRedlichKwong& pg)
:
specie(name, pg),
pcrit_(pg.pcrit_),
Tcrit_(pg.Tcrit_),
azentricFactor_(pg.azentricFactor_),
rhocrit_(pg.rhocrit_),
a0_(pg.a0_),
b_(pg.b_),
c_(pg.c_),
n_(pg.n_),
b2_(pg.b2_),
b3_(pg.b3_),
b4_(pg.b4_),
b5_(pg.b5_),
c2_(pg.c2_),
rhostd_(pg.rhostd_),
rhoMax_(pg.rhoMin_),
rhoMin_(pg.rhoMin_),
aSave(0.0),
daSave(0.0),
d2aSave(0.0),
TSave(0.0)
{}
// Construct and return a clone
inline autoPtr<aungierRedlichKwong> aungierRedlichKwong::clone() const
{
return autoPtr<aungierRedlichKwong>(new aungierRedlichKwong(*this));
}
// Selector from Istream
inline autoPtr<aungierRedlichKwong> aungierRedlichKwong::New(Istream& is)
{
return autoPtr<aungierRedlichKwong>(new aungierRedlichKwong(is));
}
// * * * * * * * * * * * * * Member Functions * * * * * * * * * * * //
inline scalar& aungierRedlichKwong::rhostd()
{
return rhostd_;
}
inline scalar& aungierRedlichKwong::rhostd()const
{
return rhostd_;
}
inline scalar& aungierRedlichKwong::rhoMin()
{
return rhoMin_;
}
inline scalar& aungierRedlichKwong::rhoMin()const
{
return rhoMin_;
}
inline scalar& aungierRedlichKwong::rhoMax()
{
return rhoMax_;
}
inline scalar& aungierRedlichKwong::rhoMax()const
{
return rhoMax_;
}
inline scalar& aungierRedlichKwong::Tcrit()
{
return Tcrit_;
}
inline scalar& aungierRedlichKwong::Tcrit()const
{
return Tcrit_;
}
inline scalar& aungierRedlichKwong::pcrit()
{
return pcrit_;
}
inline scalar& aungierRedlichKwong::pcrit()const
{
return pcrit_;
}
inline scalar& aungierRedlichKwong::rhocrit()
{
return rhocrit_;
}
inline scalar& aungierRedlichKwong::rhocrit()const
{
return rhocrit_;
}
inline scalar& aungierRedlichKwong::azentricFactor()
{
return azentricFactor_;
}
inline scalar& aungierRedlichKwong::azentricFactor()const
{
return azentricFactor_;
}
inline void aungierRedlichKwong::updateModelCoefficients(const scalar T)const
{
aSave=a0_*pow(T/Tcrit_,-n());
daSave=-a0_*n()*pow(T/Tcrit_,-n())/T;
d2aSave=a0_*(n() *n()+n())/(T*T)*pow(T/Tcrit_,-n());
//CL: saving the temperature at which the coefficients are valid
TSave=T;
}
//CL: Model coefficient a(T)
inline scalar aungierRedlichKwong::a(const scalar T)const
{
//CL: check if a has already been calculated for this temperature
if(TSave==T)
{
return aSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return aSave;
}
}
//CL: temperature deriviative of model coefficient a(T)
inline scalar aungierRedlichKwong::dadT(const scalar T)const
{
// check if a has already been calculated for this temperature
if(TSave==T)
{
return daSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return daSave;
}
}
//CL: second order temperature deriviative of model coefficient a(T)
inline scalar aungierRedlichKwong::d2adT2(const scalar T)const
{
// check if a has already been calculated for this temperature
if(TSave==T)
{
return d2aSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return d2aSave;
}
}
//Aungier Redlich Kwong factors
inline scalar& aungierRedlichKwong::a0()const
{
return a0_;
}
inline scalar& aungierRedlichKwong::a0()
{
return a0_;
}
inline scalar& aungierRedlichKwong::b()const
{
return b_;
}
inline scalar& aungierRedlichKwong::b()
{
return b_;
}
inline scalar& aungierRedlichKwong::c()const
{
return c_;
}
inline scalar& aungierRedlichKwong::c()
{
return c_;
}
inline scalar& aungierRedlichKwong::n()const
{
return n_;
}
inline scalar& aungierRedlichKwong::n()
{
return n_;
}
//CL: pow of constants (b(), c()) used in the code e.g. b2_=b*b;
inline scalar& aungierRedlichKwong::b2()const
{
return b2_;
}
inline scalar& aungierRedlichKwong::b2()
{
return b2_;
}
//CL: pow of constants (b(), c()) used in the code e.g. b3_=b2*b;
inline scalar& aungierRedlichKwong::b3()const
{
return b3_;
}
inline scalar& aungierRedlichKwong::b3()
{
return b3_;
}
//CL: pow of constants (b(), c()) used in the code e.g. b4_=b3*b;
inline scalar& aungierRedlichKwong::b4()const
{
return b4_;
}
inline scalar& aungierRedlichKwong::b4()
{
return b4_;
}
//CL: pow of constants (b(), c()) used in the code e.g. b5_=b4*b;
inline scalar& aungierRedlichKwong::b5()const
{
return b5_;
}
inline scalar& aungierRedlichKwong::b5()
{
return b5_;
}
//CL: pow of constants (b(), c()) used in the code e.g. b2_=b*b;
inline scalar& aungierRedlichKwong::c2()const
{
return c2_;
}
inline scalar& aungierRedlichKwong::c2()
{
return c2_;
}
//returns the pressure for a given density and temperature
inline scalar aungierRedlichKwong::p(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
return this->RR*T/(Vm-b()+c())
-a(T)/(Vm*(Vm+b()));
}
//Real deviative dp/dv at constant temperature
//(molar values)
inline scalar aungierRedlichKwong::dpdv(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
return (a(T)*(b3()-2*b2()*c()+b()*(c()+Vm)*(c()-3*Vm)+2*Vm*pow(c()+Vm,2))
-this->RR*T*Vm2*(b2()+2*b()*Vm+Vm2))
/(Vm2*pow(b()-c()-Vm,2)*pow(b()+Vm,2));
}
//Real deviative dp/dT at constant molar volume
//(molar values)
inline scalar aungierRedlichKwong::dpdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
return this->RR/(Vm-b()+c())-dadT(T)/(Vm*(Vm+b()));
}
//Real deviative dv/dT at constant pressure
//using implicit differentiation
//(molar values)
inline scalar aungierRedlichKwong::dvdT(const scalar rho,const scalar T) const
{
return (-1)*this->dpdT(rho,T)/this->dpdv(rho,T);
}
//Real deviative dv/dp at constant temperature
//(molar values)
inline scalar aungierRedlichKwong::dvdp(const scalar rho,const scalar T) const
{
return 1/this->dpdv(rho,T);
}
//needed to calculate the internal energy
//(molar values)
inline scalar aungierRedlichKwong::integral_p_dv
(
const scalar rho,
const scalar T
) const
{
scalar Vm = this->W()/rho;
return this->RR*T*log(-b()+c()+Vm)+a(T)*log(b()+Vm)/b()-a(T)*log(Vm)/b();
}
//needed to calculate the entropy
//(molar values)
inline scalar aungierRedlichKwong::integral_dpdT_dv
(
const scalar rho,
const scalar T
) const
{
scalar Vm = this->W()/rho;
return this->RR*log(-b()+c()+Vm)+dadT(T)*log(b()+Vm)/b()-dadT(T)*log(Vm)/b();
}
//(molar values)
inline scalar aungierRedlichKwong::d2pdT2(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
return -d2adT2(T)/(Vm*(Vm+b()));
}
//(molar values)
inline scalar aungierRedlichKwong::d2pdv2(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm*Vm*Vm;
return -2*(a(T)*(b5()-3*b4()*c()+3*b3()*(c2()-c()*Vm-Vm2)
-b2()*(c()+Vm)*(c2()-7*c()*Vm+Vm2)+3*b()*Vm*pow(c()+Vm,2)*(2*Vm-c())
-3*Vm2*pow(c()+Vm,3))+this->RR*T*Vm3*(b3()+3*b2()*Vm
+3*b()*Vm2+Vm3))
/(Vm3*pow(b()-c()-Vm,3)*pow(b()+Vm,3));
}
//(molar values)
//using second order implicit differentiation
inline scalar aungierRedlichKwong::d2vdT2(const scalar rho, const scalar T) const
{
scalar dpdT2=this->dpdT(rho,T)*this->dpdT(rho,T);
scalar dpdv2=this->dpdv(rho,T)*this->dpdv(rho,T);
scalar dpdv3=dpdv2*this->dpdv(rho,T);
return
-(
dpdT2*this->d2pdv2(rho,T)
+ dpdv2*this->d2pdT2(rho,T)
- 2*this->dpdv(rho,T)*this->dpdT(rho,T)*this->d2pdvdT(rho,T)
)
/(dpdv3);
}
//(molar values)
inline scalar aungierRedlichKwong::d2pdvdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
return (dadT(T)*(b3()-2*b2()*c()+b()*(c()+Vm)*(c()-3*Vm)+2*Vm*pow(c()+Vm,2))
-this->RR*Vm2*(b2()+2*b()*Vm+Vm2))
/(Vm2*pow(b()-c()-Vm,2)*pow(b()+Vm,2));
}
// the result of this intergal is needed for the nasa based cp polynomial
//(molar values)
inline scalar aungierRedlichKwong::integral_d2pdT2_dv
(
const scalar rho,
const scalar T
) const
{
scalar Vm = this->W()/rho;
return d2adT2(T)*log(b()+Vm)/b()-d2adT2(T)*log(Vm)/b();
}
//Isobar expansion Coefficent beta = 1/v (dv/dt) at constant p
//(molar values)
inline scalar aungierRedlichKwong::isobarExpCoef(const scalar rho,const scalar T) const
{
return this->dvdT(rho, T)*rho/this->W();
}
//isothemal compressiblity kappa (not Thermal conductivity)
//(molar values)
inline scalar aungierRedlichKwong::isothermalCompressiblity(const scalar rho,const scalar T) const
{
return this->isobarExpCoef(rho, T)/this->dpdT(rho, T);
//also possible : return -this->dvdp(rho,T)*rho/this->W();
}
//- Return density [kg/m^3]
inline scalar aungierRedlichKwong::rho(
const scalar p,
const scalar T,
const scalar rho0
) const
{
scalar molarVolumePrevIteration;
scalar molarVolume;
label iter=0;
label maxIter_=400;
scalar tol_=1e-8;
scalar rho1=rhoMax_;
scalar rho2=rhoMin_;
molarVolume=this->W()/rho0;
do
{
molarVolumePrevIteration= molarVolume;
label i=0;
do
{
molarVolume=molarVolumePrevIteration
-(
(this->p((this->W()/molarVolumePrevIteration),T) - p)
/(this->dpdv((this->W()/molarVolumePrevIteration),T))
)/pow(2,i);
i++;
if (i>8)
{
//CL: using bisection methode as backup,
//CL: solution must be between rho=0.001 to rho=1500;
//CL: if not, change rhoMax_ and rhoMin_
for(i=0; i<200; i++)
{
scalar f1 = this->p(rho1,T) - p;
scalar f2 = this->p(rho2,T) - p;
scalar rho3 = (rho1 + rho2)/2;
scalar f3 = this->p(rho3,T) - p;
if ((f2 < 0 && f3 > 0) || (f2 > 0 && f3 < 0))
{
rho1=rho3;
}
else if ((f1 < 0 && f3 > 0)||(f1 > 0 && f3 < 0))
{
rho2=rho3;
}
else
{
rho2=(rho2 + rho3)/2;
}
if(mag(f3) < p*tol_)
{
molarVolume=this->W()/rho3;
molarVolumePrevIteration=this->W()/rho3;
break;
}
else
{
molarVolumePrevIteration=this->W()/rho3;
}
}
}
}
while
(
mag(this->p((this->W()/molarVolume),T) - p)
> mag(this->p((this->W()/molarVolumePrevIteration),T) - p)
);
if (iter++ > maxIter_)
{
FatalErrorIn
(
"inline scalar aungierRedlichKwong::rho(const scalar p, const scalar T, const scalar rho0) const "
) << "Maximum number of iterations exceeded"
<< abort(FatalError);
}
}
while(mag(molarVolumePrevIteration-molarVolume) > tol_*(this->W()/rho0));
return this->W()/molarVolume;
}
//- Return density [kg/m^3]
inline scalar aungierRedlichKwong::rho(const scalar p,const scalar T) const
{
//using perfect gas equation as starting point
return rho(p,T,p/(this->R()*T));
}
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar aungierRedlichKwong::psi(const scalar rho, const scalar T) const
{
return -this->dvdp(rho,T)*rho*rho/this->W();
}
//- Return compression factor []
inline scalar aungierRedlichKwong::Z( const scalar p, const scalar T,const scalar rho0) const
{
return p/(this->R()*T*this->rho(p,T,rho0));
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void aungierRedlichKwong::operator+=(const aungierRedlichKwong& ark)
{
specie::operator+=(ark);
}
inline void aungierRedlichKwong::operator*=(const scalar s)
{
specie::operator*=(s);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
inline aungierRedlichKwong operator+
(
const aungierRedlichKwong& ark1,
const aungierRedlichKwong& ark2
)
{
return aungierRedlichKwong
(
static_cast<const specie&>(ark1)
+ static_cast<const specie&>(ark2)
);
}
inline aungierRedlichKwong operator*
(
const scalar s,
const aungierRedlichKwong& ark
)
{
return aungierRedlichKwong(s*static_cast<const specie&>(ark));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
Peng Robinson equation of state.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "pengRobinson.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::pengRobinson::pengRobinson(Istream& is)
:
specie(is),
pcrit_(readScalar(is)),
Tcrit_(readScalar(is)),
azentricFactor_(readScalar(is)),
a0_(0.457235*pow(this->RR,2)*pow(Tcrit_,2)/pcrit_),
b_(0.077796*this->RR*Tcrit_/pcrit_),
n_(0.37464+1.54226*azentricFactor_-0.26992*pow(azentricFactor_,2)),
b2_(b_*b_),
b3_(b2_*b_),
b4_(b3_*b_),
b5_(b4_*b_),
b6_(b5_*b_),
//CL: Only uses the default values
rhoMax_(1500),
rhoMin_(1e-3),
rhostd_(this->rho(Pstd,Tstd,Pstd/(Tstd*this->R()))),
aSave(0.0),
daSave(0.0),
d2aSave(0.0),
TSave(0.0)
{
is.check("pengRobinson::pengRobinson(Istream& is)");
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const pengRobinson& pr)
{
os << static_cast<const specie&>(pr)<< token::SPACE
<< pr.pcrit_ << tab<< pr.Tcrit_<< tab << pr.azentricFactor_;
os.check("Ostream& operator<<(Ostream& os, const pengRobinson& st)");
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -0,0 +1,296 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::pengRobinson
Description
Peng Robinson equation of state.
Paper:
Title: A New Two-Constant Equation of State
Authors: Ding-Yu Peng and Donald B. Robinson
Journal: Ind. Eng. Chem., Fundam., Vol. 15, No. 1, 1976
SourceFiles
pengRobinsonI.H
pengRobinson.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef pengRobinson_H
#define pengRobinson_H
#include "specie.H"
#include "autoPtr.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class perfectGas Declaration
\*---------------------------------------------------------------------------*/
class pengRobinson
:
public specie
{
// private data
scalar pcrit_;
mutable scalar Tcrit_;
scalar azentricFactor_;
//-Peng Robinson factors
mutable scalar a0_;
mutable scalar b_;
mutable scalar n_;
//CL: pow of constants b_ used in the code e.g. b2_=b*b;
mutable scalar b2_;
mutable scalar b3_;
mutable scalar b4_;
mutable scalar b5_;
mutable scalar b6_;
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
mutable scalar rhoMax_;
mutable scalar rhoMin_;
//- Density @STD, initialise after a0, b!
mutable scalar rhostd_;
protected:
//CL: Variables to save the values of a, dadT and d2adT2 of the mixture
//CL: Variables must corrected for changing temperatures
mutable scalar aSave;
mutable scalar daSave;
mutable scalar d2aSave;
//CL: save the temperature for which the save coefficients (amix,dadTmix,d2adT2mix) are correct
mutable scalar TSave;
//Protected functions
//CL: function updates the coefficients (aSave, daSave, d2aSave)
inline void updateModelCoefficients(const scalar T) const;
public:
// Constructors
//- Construct from components
inline pengRobinson
(
const specie& sp
);
//- Construct from Istream
pengRobinson(Istream&);
//- Construct as named copy
inline pengRobinson(const word& name,const pengRobinson&);
//- Construct and return a clone
inline autoPtr<pengRobinson> clone() const;
// Selector from Istream
inline static autoPtr<pengRobinson> New(Istream& is);
// Member functions
inline scalar& rhostd();
inline scalar& rhostd() const;
inline scalar& rhoMin();
inline scalar& rhoMin() const;
inline scalar& rhoMax();
inline scalar& rhoMax() const;
inline scalar& Tcrit();
inline scalar& Tcrit() const;
//CL: Model coefficient a(T)
inline scalar a(const scalar T)const;
//CL: temperature deriviative of model coefficient a(T)
inline scalar dadT(const scalar T)const;
//CL: second order temperature deriviative of model coefficient a(T)
inline scalar d2adT2(const scalar T)const;
//Return Peng Robinson factors
inline scalar& a0()const;
inline scalar& a0();
inline scalar& b()const;
inline scalar& b();
inline scalar& n()const;
inline scalar& n();
//CL: return power of constants b_
inline scalar& b2()const;
inline scalar& b2();
inline scalar& b3()const;
inline scalar& b3();
inline scalar& b4()const;
inline scalar& b4();
inline scalar& b5()const;
inline scalar& b5();
inline scalar& b6()const;
inline scalar& b6();
//CL: Equation of state
inline scalar p(const scalar rho, const scalar T) const;
//CL: first order derivatives
inline scalar dpdv(const scalar rho,const scalar T) const;
inline scalar dpdT(const scalar rho, const scalar T) const;
inline scalar dvdT(const scalar rho,const scalar T) const;
inline scalar dvdp(const scalar rho, const scalar T) const;
inline scalar isobarExpCoef
(
const scalar rho,
const scalar T
) const;
inline scalar isothermalCompressiblity
(
const scalar rho,
const scalar T
) const;
//CL: Used for cv
inline scalar integral_d2pdT2_dv
(
const scalar rho,
const scalar T
) const ;
//CL: second order derivatives, not Used At The Moment
inline scalar d2pdv2(const scalar rho,const scalar T) const;
inline scalar d2pdT2(const scalar rho,const scalar T) const;
inline scalar d2pdvdT(const scalar rho,const scalar T) const;
inline scalar d2vdT2(const scalar rho,const scalar T) const;
//CL: Used for internal Energy
inline scalar integral_p_dv(const scalar rho,const scalar T) const;
//CL: Used for Entropy
inline scalar integral_dpdT_dv(const scalar rho,const scalar T) const;
//- Return density [kg/m^3]
// rho0 is the starting point of the newton solver used to calculate rho
inline scalar rho
(
const scalar p,
const scalar T,
const scalar rho0
) const;
inline scalar rho(const scalar p,const scalar T) const;
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar psi(const scalar rho, const scalar T) const;
//- Return compression factor []
inline scalar Z
(
const scalar p,
const scalar T,
const scalar rho0
) const;
// Member operators
inline void operator+=(const pengRobinson&);
inline void operator*=(const scalar);
// Friend operators
inline friend pengRobinson operator+
(
const pengRobinson&,
const pengRobinson&
);
inline friend pengRobinson operator*
(
const scalar s,
const pengRobinson&
);
// Ostream Operator
friend Ostream& operator<<(Ostream&, const pengRobinson&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "pengRobinsonI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,646 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "pengRobinson.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
inline pengRobinson::pengRobinson
(
const specie& sp
)
:
specie(sp),
TSave(0)
{}
// Construct as named copy
inline pengRobinson::pengRobinson(const word& name, const pengRobinson& pr)
:
specie(name, pr),
pcrit_(pr.pcrit_),
Tcrit_(pr.Tcrit_),
azentricFactor_(pr.azentricFactor_),
a0_(pr.a0_),
b_(pr.b_),
n_(pr.n_),
b2_(pr.b2_),
b3_(pr.b3_),
b4_(pr.b4_),
b5_(pr.b5_),
b6_(pr.b6_),
rhoMax_(pr.rhoMax_),
rhoMin_(pr.rhoMin_),
rhostd_(pr.rhostd_),
aSave(0.0),
daSave(0.0),
d2aSave(0.0),
TSave(0.0)
{}
// Construct and return a clone
inline autoPtr<pengRobinson> pengRobinson::clone() const
{
return autoPtr<pengRobinson>(new pengRobinson(*this));
}
// Selector from Istream
inline autoPtr<pengRobinson> pengRobinson::New(Istream& is)
{
return autoPtr<pengRobinson>(new pengRobinson(is));
}
// * * * * * * * * * * * * * Member Functions * * * * * * * * * * * //
inline void pengRobinson::updateModelCoefficients(const scalar T)const
{
aSave=a0_*pow(1+n_*(1-pow(T/Tcrit_,0.5)),2);
daSave=a0_*n_*(n_*sqrt(T/Tcrit_)-n_-1)*sqrt(T/Tcrit_)/T;
d2aSave=a0_*n_*(n_+1)*sqrt(T/Tcrit_)/(2*T*T);
//CL: saving the temperature at which the coefficients are valid
TSave=T;
}
inline scalar& pengRobinson::rhostd()
{
return rhostd_;
}
inline scalar& pengRobinson::rhostd()const
{
return rhostd_;
}
inline scalar& pengRobinson::rhoMin()
{
return rhoMin_;
}
inline scalar& pengRobinson::rhoMin()const
{
return rhoMin_;
}
inline scalar& pengRobinson::rhoMax()
{
return rhoMax_;
}
inline scalar& pengRobinson::rhoMax()const
{
return rhoMax_;
}
inline scalar& pengRobinson::Tcrit()
{
return Tcrit_;
}
inline scalar& pengRobinson::Tcrit()const
{
return Tcrit_;
}
//CL: Model coefficient a(T)
inline scalar pengRobinson::a(const scalar T)const
{
//CL: check if a has already been calculated for this temperature
if(TSave==T)
{
return aSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return aSave;
}
}
//CL: temperature deriviative of model coefficient a(T)
inline scalar pengRobinson::dadT(const scalar T)const
{
// check if a has already been calculated for this temperature
if(TSave==T)
{
return daSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return daSave;
}
}
//CL: second order temperature deriviative of model coefficient a(T)
inline scalar pengRobinson::d2adT2(const scalar T)const
{
// check if a has already been calculated for this temperature
if(TSave==T)
{
return d2aSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return d2aSave;
}
}
inline scalar& pengRobinson::a0()const
{
return a0_;
}
inline scalar& pengRobinson::a0()
{
return a0_;
}
inline scalar& pengRobinson::b()const
{
return b_;
}
inline scalar& pengRobinson::b()
{
return b_;
}
inline scalar& pengRobinson::n()const
{
return n_;
}
inline scalar& pengRobinson::n()
{
return n_;
}
//CL: pow of constant b() used in the code e.g. b2_=b*b;
inline scalar& pengRobinson::b2()const
{
return b2_;
}
inline scalar& pengRobinson::b2()
{
return b2_;
}
inline scalar& pengRobinson::b3()const
{
return b3_;
}
inline scalar& pengRobinson::b3()
{
return b3_;
}
inline scalar& pengRobinson::b4()const
{
return b4_;
}
inline scalar& pengRobinson::b4()
{
return b4_;
}
inline scalar& pengRobinson::b5()const
{
return b5_;
}
inline scalar& pengRobinson::b5()
{
return b5_;
}
inline scalar& pengRobinson::b6()const
{
return b6_;
}
inline scalar& pengRobinson::b6()
{
return b6_;
}
//returns the pressure for a given density and temperature
inline scalar pengRobinson::p(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
return this->RR*T/(Vm-b())-a(T)/(Vm2+2*b()*Vm-b2());
}
//Real deviative dp/dv at constant temperature
//(molar values)
inline scalar pengRobinson::dpdv(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
scalar Vm4 = Vm3*Vm;
return(
2*a(T)*
(
b3()-b2()*Vm-b()*Vm2+Vm3
)
-this->RR*T*
(
b4()-4*b3()*Vm+2*b2()*Vm2
+4*b()*Vm3+Vm4
)
)
/(pow(b()-Vm,2)*pow(b2()-2*b()*Vm-Vm2,2));
}
//Real deviative dp/dT at constant molar volume
//(molar values)
inline scalar pengRobinson::dpdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
return this->RR/(Vm-b())-dadT(T)/(Vm2+2*b()*Vm-b2());
}
//Real deviative dv/dT at constant pressure
//by using implicit differentiation
//(molar values)
inline scalar pengRobinson::dvdT(const scalar rho,const scalar T) const
{
return (-1)*this->dpdT(rho,T)/this->dpdv(rho,T);
}
//(molar values)
inline scalar pengRobinson::dvdp(const scalar rho,const scalar T) const
{
return 1/this->dpdv(rho,T);
}
//(molar values)
//needed to calculate the internal energy
inline scalar pengRobinson::integral_p_dv(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar root2=pow(2,0.5);
return -root2*a(T)*log(b()*(1-root2)+Vm)/(4*b())+this->RR*T*log(Vm-b())
+root2*a(T)*log(b()*(root2+1)+Vm)/(4*b());
}
//(molar values)
//needed to calculate the entropy
inline scalar pengRobinson::integral_dpdT_dv(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar root2=pow(2,0.5);
return -root2*dadT(T)*log(b()*(1-root2)+Vm)/(4*b())
+this->RR*log(Vm-b())+root2*dadT(T)*log(b()*(root2+1)+Vm)/(4*b());
}
//(molar values)
inline scalar pengRobinson::d2pdT2(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
return -d2adT2(T)/(Vm2+2*b()*Vm-b2());
}
//(molar values)
inline scalar pengRobinson::d2pdv2(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
scalar Vm4 = Vm3*Vm;
scalar Vm5 = Vm4*Vm;
scalar Vm6 = Vm5*Vm;
return 2*
(
a(T)*
(
5*b5()-9*b4()*Vm+4*b2()*Vm3+3*b()*Vm4-3*Vm5
)
-this->RR*T*
(
b6()-6*b5()*Vm+9*b4()*Vm2+4*b3()*Vm3
-9*b2()*Vm4-6*b()*Vm5-Vm6
)
)
/(pow(b()-Vm,3)*pow(b2()-2*b()*Vm-Vm2,3));
}
//(molar values)
//using second order implicit differentiation
inline scalar pengRobinson::d2vdT2(const scalar rho, const scalar T) const
{
scalar dpdT2=this->dpdT(rho,T)*this->dpdT(rho,T);
scalar dpdv2=this->dpdv(rho,T)*this->dpdv(rho,T);
scalar dpdv3=dpdv2*this->dpdv(rho,T);
return
-(
dpdT2*this->d2pdv2(rho,T)
+ dpdv2*this->d2pdT2(rho,T)
- 2*this->dpdv(rho,T)*this->dpdT(rho,T)*this->d2pdvdT(rho,T)
)
/(dpdv3);
}
//(molar values)
inline scalar pengRobinson::d2pdvdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
scalar Vm4 = Vm3*Vm;
return(
2*dadT(T)*
(
b3()-b2()*Vm-b()*Vm2+Vm3
)
-this->RR*
(
b4()-4*b3()*Vm+2*b2()*Vm2
+4*b()*Vm3+Vm4
)
)
/(pow(b()-Vm,2)*pow(b2()-2*b()*Vm-Vm2,2));
}
// the result of this intergal is needed for the nasa based cp polynomial
//(molar values)
inline scalar pengRobinson::integral_d2pdT2_dv(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar root2=pow(2,0.5);
return root2*d2adT2(T)*log(b()*(root2+1)+Vm)/(4*b())-root2*d2adT2(T)*log(b()*(1-root2)+Vm)/(4*b());
}
//Isobar expansion Coefficent beta = 1/v (dv/dt) at constant p
//(molar values)
inline scalar pengRobinson::isobarExpCoef(const scalar rho,const scalar T) const
{
return this->dvdT(rho, T)*rho/this->W();
}
//isothemal compressiblity kappa (not Thermal conductivity)
//(molar values)
inline scalar pengRobinson::isothermalCompressiblity(const scalar rho,const scalar T) const
{
return this->isobarExpCoef(rho, T)/this->dpdT(rho, T);
//CL: also possible
//CL: return -this->dvdp(rho,T)*rho/this->W();
}
//- Return density [kg/m^3]
inline scalar pengRobinson::rho(
const scalar p,
const scalar T,
const scalar rho0
) const
{
scalar molarVolumePrevIteration;
scalar molarVolume;
label iter=0;
label maxIter_=400;
scalar tol_=1e-8;
scalar rho1=rhoMax_;
scalar rho2=rhoMin_;
molarVolume=this->W()/rho0;
do
{
molarVolumePrevIteration= molarVolume;
label i=0;
do
{
molarVolume=molarVolumePrevIteration
-(
(this->p((this->W()/molarVolumePrevIteration),T) - p)
/(this->dpdv((this->W()/molarVolumePrevIteration),T))
)/pow(2,i);
i++;
if (i>8)
{
//CL: using bisection methode as backup,
//CL: solution must be between rho=0.001 to rho=1500;
//CL: if not, change rhoMax_ and rhoMin_
for(i=0; i<200; i++)
{
scalar f1 = this->p(rho1,T) - p;
scalar f2 = this->p(rho2,T) - p;
scalar rho3 = (rho1 + rho2)/2;
scalar f3 = this->p(rho3,T) - p;
if ((f2 < 0 && f3 > 0) || (f2 > 0 && f3 < 0))
{
rho1=rho3;
}
else if ((f1 < 0 && f3 > 0)||(f1 > 0 && f3 < 0))
{
rho2=rho3;
}
else
{
rho2=(rho2 + rho3)/2;
}
if(mag(f3) < p*tol_)
{
molarVolume=this->W()/rho3;
molarVolumePrevIteration=this->W()/rho3;
break;
}
else
{
molarVolumePrevIteration=this->W()/rho3;
}
}
}
}
while
(
mag(this->p((this->W()/molarVolume),T) - p)
> mag(this->p((this->W()/molarVolumePrevIteration),T) - p)
);
if (iter++ > maxIter_)
{
FatalErrorIn
(
"inline scalar pengRobinson::rho(const scalar p, const scalar T, const scalar rho0) const "
) << "Maximum number of iterations exceeded"
<< abort(FatalError);
}
}
while(mag(molarVolumePrevIteration-molarVolume) > tol_*(this->W()/rho0));
return this->W()/molarVolume;
}
//- Return density [kg/m^3]on
inline scalar pengRobinson::rho(const scalar p,const scalar T) const
{
// using perfect gas equation as starting point
return rho(p,T,p/(this->R()*T));
}
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar pengRobinson::psi(const scalar rho, const scalar T) const
{
return -this->dvdp(rho,T)*rho*rho/this->W();
}
//- Return compression factor []
inline scalar pengRobinson::Z( const scalar p, const scalar T,const scalar rho0) const
{
return p/(this->R()*T*this->rho(p,T,rho0));
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void pengRobinson::operator+=(const pengRobinson& pr)
{
specie::operator+=(pr);
}
inline void pengRobinson::operator*=(const scalar s)
{
specie::operator*=(s);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
inline pengRobinson operator+
(
const pengRobinson& pr1,
const pengRobinson& pr2
)
{
return pengRobinson
(
static_cast<const specie&>(pr1)
+ static_cast<const specie&>(pr2)
);
}
inline pengRobinson operator*
(
const scalar s,
const pengRobinson& pr
)
{
return pengRobinson(s*static_cast<const specie&>(pr));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
Redlich Kwong equation of state.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "redlichKwong.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::redlichKwong::redlichKwong(Istream& is)
:
specie(is),
pcrit_(readScalar(is)),
Tcrit_(readScalar(is)),
a_(0.42748*pow(this->RR,2)*pow(Tcrit_,2.5)/pcrit_),
b_(0.08664*this->RR*Tcrit_/pcrit_),
//CL: Only uses the default values
rhoMax_(1500),
rhoMin_(1e-3),
b2_(pow(b_,2)),
b3_(pow(b_,3)),
b5_(pow(b_,5)),
// Starting GUESS for the density by ideal gas law
rhostd_(this->rho(Pstd, Tstd, Pstd/(Tstd*this->R())))
{
is.check("redlichKwong::redlichKwong(Istream& is)");
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const redlichKwong& rk)
{
os << static_cast<const specie&>(rk)<< token::SPACE
<< rk.pcrit_ << tab<< rk.Tcrit_;
os.check("Ostream& operator<<(Ostream& os, const redlichKwong& st)");
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -0,0 +1,240 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::redlichKwong
Description
Redlich Kwong equation of state.
SourceFiles
redlichKwongI.H
redlichKwong.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef redlichKwong_H
#define redlichKwong_H
#include "specie.H"
#include "autoPtr.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class redlichKwong Declaration
\*---------------------------------------------------------------------------*/
class redlichKwong
:
public specie
{
//CL: data at critical point
scalar pcrit_;
scalar Tcrit_;
//CL: Redlich Kwong factors
mutable scalar a_;
mutable scalar b_;
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
mutable scalar rhoMax_;
mutable scalar rhoMin_;
//CL: pow of constants b_ used in the code e.g. b2_=b*b;
mutable scalar b2_;
mutable scalar b3_;
mutable scalar b5_;
//- Density @STD, initialise after a, b!
mutable scalar rhostd_;
public:
// Constructors
//- Construct from components
inline redlichKwong
(
const specie& sp
);
//- Construct from Istream
redlichKwong(Istream&);
//- Construct as named copy
inline redlichKwong(const word& name, const redlichKwong&);
//- Construct and return a clone
inline autoPtr<redlichKwong> clone() const;
// Selector from Istream
inline static autoPtr<redlichKwong> New(Istream& is);
// Member functions
inline scalar& rhostd() const;
inline scalar& rhostd();
inline scalar& rhoMin() const;
inline scalar& rhoMin();
inline scalar& rhoMax() const;
inline scalar& rhoMax();
//Return Redlich Kwong factors
inline scalar& a() const;
inline scalar& a();
inline scalar& b() const;
inline scalar& b();
//CL: return power of constants b_
inline scalar& b2()const;
inline scalar& b2();
inline scalar& b3()const;
inline scalar& b3();
inline scalar& b5()const;
inline scalar& b5();
//CL: equation of state
inline scalar p(const scalar rho, const scalar T) const;
//CL: first order derivatives
inline scalar dpdv(const scalar rho, const scalar T) const;
inline scalar dpdT(const scalar rho, const scalar T) const;
inline scalar dvdT(const scalar rho, const scalar T) const;
inline scalar dvdp(const scalar rho, const scalar T) const;
inline scalar isobarExpCoef(const scalar rho, const scalar T) const;
inline scalar isothermalCompressiblity
(
const scalar rho,
const scalar T
) const;
//CL: Used for cv
inline scalar integral_d2pdT2_dv
(
const scalar rho,
const scalar T
) const;
//CL: Used for internal Energy
inline scalar integral_p_dv(const scalar rho, const scalar T) const;
//CL: Used for Entropy
inline scalar integral_dpdT_dv(const scalar rho, const scalar T) const;
//CL: second order derivatives, not Used At The Moment
inline scalar d2pdv2(const scalar rho, const scalar T) const;
inline scalar d2pdT2(const scalar rho, const scalar T) const;
inline scalar d2pdvdT(const scalar rho, const scalar T) const;
inline scalar d2vdT2(const scalar rho, const scalar T) const;
//- Return density [kg/m^3]
// rho0 is the starting point of the newton solver used to calculate rho
inline scalar rho
(
const scalar p,
const scalar T,
const scalar rho0
) const;
inline scalar rho(const scalar p, const scalar T) const;
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar psi(const scalar rho, const scalar T) const;
//- Return compression factor []
inline scalar Z
(
const scalar p,
const scalar T,
const scalar rho0
) const;
// Member operators
inline void operator+=(const redlichKwong&);
inline void operator*=(const scalar);
// Friend operators
inline friend redlichKwong operator+
(
const redlichKwong&,
const redlichKwong&
);
inline friend redlichKwong operator*
(
const scalar s,
const redlichKwong&
);
// Ostream Operator
friend Ostream& operator<<(Ostream&, const redlichKwong&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "redlichKwongI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,533 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "redlichKwong.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
inline redlichKwong::redlichKwong
(
const specie& sp
)
:
specie(sp)
{}
// Construct as named copy
inline redlichKwong::redlichKwong(const word& name, const redlichKwong& rk)
:
specie(name, rk),
pcrit_(rk.pcrit_),
Tcrit_(rk.Tcrit_),
a_(rk.a_),
b_(rk.b_),
rhoMax_(rk.rhoMax_),
rhoMin_(rk.rhoMin_),
b2_(rk.b2_),
b3_(rk.b3_),
b5_(rk.b5_),
rhostd_(rk.rhostd_)
{}
// Construct and return a clone
inline autoPtr<redlichKwong> redlichKwong::clone() const
{
return autoPtr<redlichKwong>(new redlichKwong(*this));
}
// Selector from Istream
inline autoPtr<redlichKwong> redlichKwong::New(Istream& is)
{
return autoPtr<redlichKwong>(new redlichKwong(is));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline scalar& redlichKwong::rhostd()const
{
return rhostd_;
}
inline scalar& redlichKwong::rhostd()
{
return rhostd_;
}
inline scalar& redlichKwong::rhoMin()const
{
return rhoMin_;
}
inline scalar& redlichKwong::rhoMin()
{
return rhoMin_;
}
inline scalar& redlichKwong::rhoMax()const
{
return rhoMax_;
}
inline scalar& redlichKwong::rhoMax()
{
return rhoMax_;
}
inline scalar& redlichKwong::a()const
{
return a_;
}
inline scalar& redlichKwong::a()
{
return a_;
}
inline scalar& redlichKwong::b()const
{
return b_;
}
inline scalar& redlichKwong::b()
{
return b_;
}
inline scalar& redlichKwong::b2()const
{
return b2_;
}
inline scalar& redlichKwong::b2()
{
return b2_;
}
inline scalar& redlichKwong::b3()const
{
return b3_;
}
inline scalar& redlichKwong::b3()
{
return b3_;
}
inline scalar& redlichKwong::b5()const
{
return b5_;
}
inline scalar& redlichKwong::b5()
{
return b5_;
}
//returns the pressure for a given density and temperature
inline scalar redlichKwong::p(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
return this->RR*T/(Vm - b_) - a_/(sqrt(T)*Vm*(Vm + b_));
}
//Real deviative dp/dv at constant temperature
//(molar values)
inline scalar redlichKwong::dpdv(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
return (a_*(b3() - 3*b_*Vm2 + 2*Vm3)
- this->RR*pow(T,1.5)*Vm2*(b2() + 2*b_*Vm + Vm2))
/(sqrt(T)*Vm2*pow((b_ + Vm),2)*pow( (b_ - Vm),2));
}
//Real deviative dp/dT at constant molar volume
//(molar values)
inline scalar redlichKwong::dpdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
return 0.5*a_/(pow(T,1.5)*Vm*(b_ + Vm))-this->RR/(b_ - Vm);
}
//Real deviative dv/dT at constant pressure
//using implicit differentiation
//(molar values)
inline scalar redlichKwong::dvdT(const scalar rho, const scalar T) const
{
return -this->dpdT(rho,T)/this->dpdv(rho,T);
}
//Real deviative dv/dp at constant temperature
//(molar values)
inline scalar redlichKwong::dvdp(const scalar rho, const scalar T) const
{
return 1/this->dpdv(rho,T);
}
//needed to calculate the internal energy
//(molar values)
inline scalar redlichKwong::integral_p_dv
(
const scalar rho,
const scalar T
) const
{
scalar Vm = this->W()/rho;
return this->RR*T*log(Vm - b_)
+ (a_*log(b_ + Vm))/(b_*sqrt(T))
- (a_*log(Vm))/(b_*sqrt(T));
}
//needed to calculate the entropy
//(molar values)
inline scalar redlichKwong::integral_dpdT_dv
(
const scalar rho,
const scalar T
) const
{
scalar T15_=pow(T,1.5);
scalar Vm = this->W()/rho;
return this->RR*log(Vm - b_)
-(a_*log(b_ + Vm))/(2*b_*T15_)
+(a_*log(Vm))/(2*b_*T15_);
}
//(molar values)
inline scalar redlichKwong::d2pdT2(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
return -0.75*a_/(pow(T,2.5)*Vm*(b_ + Vm));
}
//(molar values)
inline scalar redlichKwong::d2pdv2(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
scalar Vm4 = Vm3*Vm;
scalar Vm5 = Vm4*Vm;
return
(
2*(
a_*(
b5()-3*b3()*Vm2
- b2()*Vm3
+ 6*b_*Vm4-3*Vm5
)
+ this->RR*pow(T,1.5)*Vm3*(b3()
+ 3*b2()*Vm
+ 3*b_*Vm2+Vm3)
)
/(sqrt(T)*Vm3*pow((b_ + Vm),3)*pow(Vm-b_,3))
);
}
//(molar values)
//using second Order implicit differentiation
inline scalar redlichKwong::d2vdT2(const scalar rho, const scalar T) const
{
scalar dpdT2=this->dpdT(rho,T)*this->dpdT(rho,T);
scalar dpdv2=this->dpdv(rho,T)*this->dpdv(rho,T);
scalar dpdv3=dpdv2*this->dpdv(rho,T);
return
-(
dpdT2*this->d2pdv2(rho,T)
+ dpdv2*this->d2pdT2(rho,T)
- 2*this->dpdv(rho,T)*this->dpdT(rho,T)*this->d2pdvdT(rho,T)
)
/(dpdv3);
}
//(molar values)
inline scalar redlichKwong::d2pdvdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
scalar T15_ = pow(T,1.5);
return
-(0.5*(
a_*(b3() - 3*b_*Vm2 + 2*Vm3)
+ 2*this->RR*T15_*Vm2*(b2() + 2*b_*Vm + Vm2)
))
/(T15_*Vm2*pow(b_ + Vm,2)*pow(b_ - Vm,2));
}
// the result of this intergal is needed for the nasa based cp polynomial
//(molar values)
inline scalar redlichKwong::integral_d2pdT2_dv
(
const scalar rho,
const scalar T
) const
{
scalar T25_=pow(T,2.5);
scalar Vm = this->W()/rho;
return 0.75*a_*log(b_ + Vm)/(T25_*b_)
- 0.75*a_*log(Vm)/(T25_*b_);
}
//Isobar expansion Coefficent beta = 1/v (dv/dt) at constant p
//(molar values)
inline scalar redlichKwong::isobarExpCoef
(
const scalar rho,
const scalar T
) const
{
return this->dvdT(rho, T)*rho/this->W();
}
//isothemal compressiblity kappa (not Thermal conductivity)
//(molar values)
inline scalar redlichKwong::isothermalCompressiblity
(
const scalar rho,
const scalar T
) const
{
return this->isobarExpCoef(rho, T)/this->dpdT(rho, T);
//also possible : return -this->dvdp(rho,T)*rho/this->W();
}
//- Return density [kg/m^3]
inline scalar redlichKwong::rho
(
const scalar p,
const scalar T,
const scalar rho0
) const
{
scalar molarVolumePrevIteration;
scalar molarVolume;
label iter=0;
label maxIter_=400;
scalar tol_=1e-8;
scalar rho1=rhoMax();
scalar rho2=rhoMin();
molarVolume=this->W()/rho0;
do
{
molarVolumePrevIteration= molarVolume;
label i=0;
do
{
//CL: modified Newton solver
molarVolume=molarVolumePrevIteration
-(
(this->p((this->W()/molarVolumePrevIteration),T) - p)
/(this->dpdv((this->W()/molarVolumePrevIteration),T))
)/pow(2,i);
i++;
if (i>8)
{
//CL: using bisection methode as backup,
//CL: solution must be between rhoMin_ to rhoMax
for(i=0; i<200; i++)
{
scalar f1 = this->p(rho1,T) - p;
scalar f2 = this->p(rho2,T) - p;
scalar rho3 = (rho1 + rho2)/2;
scalar f3 = this->p(rho3,T) - p;
if ((f2 < 0 && f3 > 0) || (f2 > 0 && f3 < 0))
{
rho1=rho3;
}
else if ((f1 < 0 && f3 > 0)||(f1 > 0 && f3 < 0))
{
rho2=rho3;
}
else
{
rho2=(rho2 + rho3)/2;
}
if(mag(f3) < p*tol_)
{
molarVolume=this->W()/rho3;
molarVolumePrevIteration=this->W()/rho3;
break;
}
else
{
molarVolumePrevIteration=this->W()/rho3;
}
}
}
}
while
(
mag(this->p((this->W()/molarVolume),T) - p)
> mag(this->p((this->W()/molarVolumePrevIteration),T) - p)
);
if (iter++ > maxIter_)
{
FatalErrorIn
(
"inline scalar redlichKwong::rho(const scalar p, const scalar T, const scalar rho0) const "
) << "Maximum number of iterations exceeded"
<< abort(FatalError);
}
}
while(mag(molarVolumePrevIteration-molarVolume) > tol_*(this->W()/rho0));
return this->W()/molarVolume;
}
//- Return density [kg/m^3]on
inline scalar redlichKwong::rho(const scalar p, const scalar T) const
{
// using perfect gas equation as starting point
return rho(p,T,p/(this->R()*T));
}
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar redlichKwong::psi(const scalar rho, const scalar T) const
{
return -this->dvdp(rho,T)*rho*rho/this->W();
}
//- Return compression factor []
inline scalar redlichKwong::Z
(
const scalar p,
const scalar T,
const scalar rho0
) const
{
return p/(this->R()*T*this->rho(p,T,rho0));
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void redlichKwong::operator+=(const redlichKwong& rk)
{
specie::operator+=(rk);
}
inline void redlichKwong::operator*=(const scalar s)
{
specie::operator*=(s);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
inline redlichKwong operator+
(
const redlichKwong& rk1,
const redlichKwong& rk2
)
{
return redlichKwong
(
static_cast<const specie&>(rk1)
+ static_cast<const specie&>(rk2)
);
}
inline redlichKwong operator*
(
const scalar s,
const redlichKwong& rk
)
{
return redlichKwong(s*static_cast<const specie&>(rk));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,78 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
Soave Redlich Kwong equation of state.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "soaveRedlichKwong.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::soaveRedlichKwong::soaveRedlichKwong(Istream& is)
:
specie(is),
pcrit_(readScalar(is)),
Tcrit_(readScalar(is)),
azentricFactor_(readScalar(is)),
a0_(0.42747*pow(this->RR,2)*pow(Tcrit_,2)/(pcrit_)),
b_(0.08664*this->RR*Tcrit_/pcrit_),
n_(0.48508+1.55171*azentricFactor_-0.15613*pow(azentricFactor_,2)),
//CL: Only uses the default values
rhoMin_(1e-3),
rhoMax_(1500),
// Starting GUESS for the density by ideal gas law
rhostd_(this->rho(Pstd,Tstd,Pstd/(Tstd*this->R()))),
b2_(b_*b_),
b3_(b2_*b_),
b5_(b2_*b3_),
aSave(0.0),
daSave(0.0),
d2aSave(0.0),
TSave(0.0)
{
is.check("soaveRedlichKwong::soaveRedlichKwong(Istream& is)");
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const soaveRedlichKwong& srk)
{
os << static_cast<const specie&>(srk)<< token::SPACE
<< srk.pcrit_ << tab<< srk.Tcrit_<<tab<<srk.azentricFactor_;
os.check("Ostream& operator<<(Ostream& os, const soaveRedlichKwong& st)");
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -0,0 +1,281 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::soaveRedlichKwong
Description
Soave Redlich Kwong equation of state.
Paper:
Title: Equilibrium Constants from a Modified Redlich-Kwong Equation of State
Authors: G. Soave
Journal: Chemical Engineering Science, vol. 27(6), 1972, pp. 1197-1203
SourceFiles
soaveRedlichKwongI.H
soaveRedlichKwong.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef soaveRedlichKwong_H
#define soaveRedlichKwong_H
#include "specie.H"
#include "autoPtr.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class Soave Readlich Kwong Declaration
\*---------------------------------------------------------------------------*/
class soaveRedlichKwong
:
public specie
{
// private data
scalar pcrit_;
mutable scalar Tcrit_;
scalar azentricFactor_;
//-Soave Redlich Kwong
mutable scalar a0_;
mutable scalar b_;
mutable scalar n_;
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
mutable scalar rhoMin_;
mutable scalar rhoMax_;
//- Density @STD, initialise after a0, b!
mutable scalar rhostd_;
//CL: pow of constants b_ used in the code e.g. b2_=b*b;
mutable scalar b2_;
mutable scalar b3_;
mutable scalar b5_;
protected:
//CL: Variables to save the values of a, dadT and d2adT2 of the mixture
//CL: Variables must corrected for changing temperatures
mutable scalar aSave;
mutable scalar daSave;
mutable scalar d2aSave;
//CL: save the temperature for which the save coefficients (amix,dadTmix,d2adT2mix) are correct
mutable scalar TSave;
//Protected functions
//CL: function updates the coefficients (aSave, daSave, d2aSave)
inline void updateModelCoefficients(const scalar T) const;
public:
// Constructors
//- Construct from components
inline soaveRedlichKwong
(
const specie& s
);
//- Construct from Istream
soaveRedlichKwong(Istream&);
//- Construct as named copy
inline soaveRedlichKwong(const word& name,const soaveRedlichKwong&);
//- Construct and return a clone
inline autoPtr<soaveRedlichKwong> clone() const;
// Selector from Istream
inline static autoPtr<soaveRedlichKwong> New(Istream& is);
// Member functions
inline scalar& rhostd();
inline scalar& rhostd() const;
inline scalar& rhoMin();
inline scalar& rhoMin() const;
inline scalar& rhoMax();
inline scalar& rhoMax() const;
inline scalar& Tcrit();
inline scalar& Tcrit() const;
//CL: Model coefficient a(T)
inline scalar a(const scalar T)const;
//CL: temperature deriviative of model coefficient a(T)
inline scalar dadT(const scalar T)const;
//CL: second order temperature deriviative of model coefficient a(T)
inline scalar d2adT2(const scalar T)const;
//Return Soave Redlich Kwong factors
inline scalar& a0()const;
inline scalar& a0();
inline scalar& b()const;
inline scalar& b();
inline scalar& n()const;
inline scalar& n();
//CL: return power of constants b_
inline scalar& b2()const;
inline scalar& b2();
inline scalar& b3()const;
inline scalar& b3();
inline scalar& b5()const;
inline scalar& b5();
//CL: Equation of state
inline scalar p(const scalar rho, const scalar T) const;
//CL: first order derivatives
inline scalar dpdv(const scalar rho,const scalar T) const;
inline scalar dpdT(const scalar rho, const scalar T) const;
inline scalar dvdT(const scalar rho,const scalar T) const;
inline scalar dvdp(const scalar rho, const scalar T) const;
inline scalar isobarExpCoef
(
const scalar rho,
const scalar T
) const;
inline scalar isothermalCompressiblity
(
const scalar rho,
const scalar T
) const;
//CL: Used for cv
inline scalar integral_d2pdT2_dv(const scalar rho,const scalar T) const ;
//CL: second order derivatives, not Used At The Moment
inline scalar d2pdv2(const scalar rho,const scalar T) const;
inline scalar d2pdT2(const scalar rho,const scalar T) const;
inline scalar d2pdvdT(const scalar rho,const scalar T) const;
inline scalar d2vdT2(const scalar rho,const scalar T) const;
//CL: Used for internal Energy
inline scalar integral_p_dv(const scalar rho,const scalar T) const;
//Used for Entropy
inline scalar integral_dpdT_dv(const scalar rho,const scalar T) const;
//- Return density [kg/m^3]
// rho0 is the starting point of the newton solver used to calculate rho
inline scalar rho
(
const scalar p,
const scalar T,
const scalar rho0
) const;
inline scalar rho(const scalar p,const scalar T) const;
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar psi(const scalar rho, const scalar T) const;
//- Return compression factor []
inline scalar Z
(
const scalar p,
const scalar T,
const scalar rho0
) const;
// Member operators
inline void operator+=(const soaveRedlichKwong&);
inline void operator*=(const scalar);
// Friend operators
inline friend soaveRedlichKwong operator+
(
const soaveRedlichKwong&,
const soaveRedlichKwong&
);
inline friend soaveRedlichKwong operator*
(
const scalar s,
const soaveRedlichKwong&
);
// Ostream Operator
friend Ostream& operator<<(Ostream&, const soaveRedlichKwong&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "soaveRedlichKwongI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,606 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "soaveRedlichKwong.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
inline soaveRedlichKwong::soaveRedlichKwong
(
const specie& sp
)
:
specie(sp),
TSave(0)
{}
// Construct as named copy
inline soaveRedlichKwong::soaveRedlichKwong(const word& name,const soaveRedlichKwong& srk)
:
specie(name, srk),
pcrit_(srk.pcrit_),
Tcrit_(srk.Tcrit_),
azentricFactor_(srk.azentricFactor_),
a0_(srk.a0_),
b_(srk.b_),
n_(srk.n_),
rhoMin_(srk.rhoMin_),
rhoMax_(srk.rhoMax_),
rhostd_(srk.rhostd_),
b2_(srk.b2_),
b3_(srk.b3_),
b5_(srk.b5_),
aSave(0.0),
daSave(0.0),
d2aSave(0.0),
TSave(0.0)
{}
// Construct and return a clone
inline autoPtr<soaveRedlichKwong> soaveRedlichKwong::clone() const
{
return autoPtr<soaveRedlichKwong>(new soaveRedlichKwong(*this));
}
// Selector from Istream
inline autoPtr<soaveRedlichKwong> soaveRedlichKwong::New(Istream& is)
{
return autoPtr<soaveRedlichKwong>(new soaveRedlichKwong(is));
}
// * * * * * * * * * * * * * Member Functions * * * * * * * * * * * //
inline void soaveRedlichKwong::updateModelCoefficients(const scalar T)const
{
aSave=a0_*pow(1+n_*(1-pow(T/Tcrit_,0.5)),2);
daSave=a0_*n_*(n_*sqrt(T/Tcrit_)-n_-1)*sqrt(T/Tcrit_)/T;
d2aSave=a0_*n_*(n_+1)*sqrt(T/Tcrit_)/(2*T*T);
//CL: saving the temperature at which the coefficients are valid
TSave=T;
}
inline scalar& soaveRedlichKwong::rhostd()
{
return rhostd_;
}
inline scalar& soaveRedlichKwong::rhostd()const
{
return rhostd_;
}
inline scalar& soaveRedlichKwong::rhoMin()
{
return rhoMin_;
}
inline scalar& soaveRedlichKwong::rhoMin()const
{
return rhoMin_;
}
inline scalar& soaveRedlichKwong::rhoMax()
{
return rhoMax_;
}
inline scalar& soaveRedlichKwong::rhoMax()const
{
return rhoMax_;
}
inline scalar& soaveRedlichKwong::Tcrit()
{
return Tcrit_;
}
inline scalar& soaveRedlichKwong::Tcrit()const
{
return Tcrit_;
}
//CL: Model coefficient a(T)
inline scalar soaveRedlichKwong::a(const scalar T)const
{
//CL: check if a has already been calculated for this temperature
if(TSave==T)
{
return aSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return aSave;
}
}
//CL: temperature deriviative of model coefficient a(T)
inline scalar soaveRedlichKwong::dadT(const scalar T)const
{
// check if a has already been calculated for this temperature
if(TSave==T)
{
return daSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return daSave;
}
}
//CL: second order temperature deriviative of model coefficient a(T)
inline scalar soaveRedlichKwong::d2adT2(const scalar T)const
{
// check if a has already been calculated for this temperature
if(TSave==T)
{
return d2aSave;
}
//CL: If not, recalculate a(T), dadT(T) and d2adT2(T)
else
{
updateModelCoefficients(T);
return d2aSave;
}
}
inline scalar& soaveRedlichKwong::a0()const
{
return a0_;
}
inline scalar& soaveRedlichKwong::a0()
{
return a0_;
}
inline scalar& soaveRedlichKwong::b()const
{
return b_;
}
inline scalar& soaveRedlichKwong::b()
{
return b_;
}
inline scalar& soaveRedlichKwong::n()const
{
return n_;
}
inline scalar& soaveRedlichKwong::n()
{
return n_;
}
//CL: pow of constant b() used in the code e.g. b2_=b*b;
inline scalar& soaveRedlichKwong::b2()const
{
return b2_;
}
inline scalar& soaveRedlichKwong::b2()
{
return b2_;
}
inline scalar& soaveRedlichKwong::b3()const
{
return b3_;
}
inline scalar& soaveRedlichKwong::b3()
{
return b3_;
}
inline scalar& soaveRedlichKwong::b5()const
{
return b5_;
}
inline scalar& soaveRedlichKwong::b5()
{
return b5_;
}
//returns the pressure for a given density and temperature
inline scalar soaveRedlichKwong::p(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
return
(
this->RR*T/(Vm-b_)
-a(T)/(Vm*(Vm+b_))
);
}
//Real deviative dp/dv at constant temperature
//(molar values)
inline scalar soaveRedlichKwong::dpdv(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
return
(
a(T)*(b3()-3*b_*Vm2+2*Vm3)
-this->RR*T*Vm2*(b2()+2*b_*Vm+Vm2)
)
/(Vm2*pow(b_+Vm,2)*pow(b_-Vm,2));
}
//Real deviative dp/dT at constant molar volume
//(molar values)
inline scalar soaveRedlichKwong::dpdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
return
(
this->RR/(Vm-b_)
-dadT(T)/(Vm*(Vm+b_))
);
}
//Real deviative dv/dT at constant pressure
//using implicit differentiation
// (molar values)
inline scalar soaveRedlichKwong::dvdT(const scalar rho,const scalar T) const
{
return (-1)*this->dpdT(rho,T)/this->dpdv(rho,T);
}
//Real deviative dv/dp at constant temperature
//(molar values)
inline scalar soaveRedlichKwong::dvdp(const scalar rho,const scalar T) const
{
return 1/this->dpdv(rho,T);
}
//needed to calculate the internal energy
//(molar values)
inline scalar soaveRedlichKwong::integral_p_dv(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
return this->RR*T*log(Vm-b_)+a(T)*log(b_+Vm)/b_-a(T)*log(Vm)/b_;
}
//needed to calculate the entropy
//(molar values)
inline scalar soaveRedlichKwong::integral_dpdT_dv(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
return this->RR*log(Vm-b_)+dadT(T)*log(b_+Vm)/b_-dadT(T)*log(Vm)/b_;
}
//(molar values)
inline scalar soaveRedlichKwong::d2pdT2(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
return -d2adT2(T)/(Vm*(Vm+b_));
}
//(molar values)
inline scalar soaveRedlichKwong::d2pdv2(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
scalar Vm4 = Vm3*Vm;
scalar Vm5 = Vm4*Vm;
return
2*
(
a(T)*
(
b5()-3*b3()*Vm2-b2()*Vm3+6*b_*Vm4-3*Vm5
)
+this->RR*T*Vm3*
(
b3()+3*b2()*Vm+3*b_*Vm2+Vm3
)
)
/(Vm3*pow(b_+Vm,3)*pow(Vm-b_,3));
}
//(molar values)
// using second Order implicit differentiation
inline scalar soaveRedlichKwong::d2vdT2(const scalar rho, const scalar T) const
{
scalar dpdT2=this->dpdT(rho,T)*this->dpdT(rho,T);
scalar dpdv2=this->dpdv(rho,T)*this->dpdv(rho,T);
scalar dpdv3=dpdv2*this->dpdv(rho,T);
return
-(
dpdT2*this->d2pdv2(rho,T)
+ dpdv2*this->d2pdT2(rho,T)
- 2*this->dpdv(rho,T)*this->dpdT(rho,T)*this->d2pdvdT(rho,T)
)
/(dpdv3);
}
//(molar values)
inline scalar soaveRedlichKwong::d2pdvdT(const scalar rho, const scalar T) const
{
scalar Vm = this->W()/rho;
scalar Vm2 = Vm*Vm;
scalar Vm3 = Vm2*Vm;
return
(
dadT(T)*(b3()-3*b_*Vm2+2*Vm3)
-this->RR*Vm2*(b2()+2*b_*Vm+Vm2)
)
/(Vm2*pow(b_+Vm,2)*pow(b_-Vm,2));
}
// the result of this intergal is needed for the nasa based cp polynomial
//(molar values)
inline scalar soaveRedlichKwong::integral_d2pdT2_dv(const scalar rho,const scalar T) const
{
scalar Vm = this->W()/rho;
return d2adT2(T)*log(b_+Vm)/b_-d2adT2(T)*log(Vm)/b_;
}
//Isobar expansion Coefficent beta = 1/v (dv/dt) at constant p
//(molar values)
inline scalar soaveRedlichKwong::isobarExpCoef(const scalar rho,const scalar T) const
{
return this->dvdT(rho, T)*rho/this->W();
}
//isothemal compressiblity kappa (not Thermal conductivity)
//(molar values)
inline scalar soaveRedlichKwong::isothermalCompressiblity(const scalar rho,const scalar T) const
{
return this->isobarExpCoef(rho, T)/this->dpdT(rho, T);
}
//- Return density [kg/m^3]
inline scalar soaveRedlichKwong::rho(
const scalar p,
const scalar T,
const scalar rho0
) const
{
scalar molarVolumePrevIteration;
scalar molarVolume;
label iter=0;
label maxIter_=400;
scalar tol_=1e-8;
scalar rho1=rhoMax_;
scalar rho2=rhoMin_;
molarVolume=this->W()/rho0;
do
{
molarVolumePrevIteration= molarVolume;
label i=0;
do
{
molarVolume=molarVolumePrevIteration
-(
(this->p((this->W()/molarVolumePrevIteration),T) - p)
/(this->dpdv((this->W()/molarVolumePrevIteration),T))
)/pow(2,i);
i++;
if (i>8)
{
//CL: using bisection methode as backup,
//CL: solution must be between rho=0.001 to rho=1500;
//CL: if not, change rhoMax_ and rhoMin_
for(i=0; i<200; i++)
{
scalar f1 = this->p(rho1,T) - p;
scalar f2 = this->p(rho2,T) - p;
scalar rho3 = (rho1 + rho2)/2;
scalar f3 = this->p(rho3,T) - p;
if ((f2 < 0 && f3 > 0) || (f2 > 0 && f3 < 0))
{
rho1=rho3;
}
else if ((f1 < 0 && f3 > 0)||(f1 > 0 && f3 < 0))
{
rho2=rho3;
}
else
{
rho2=(rho2 + rho3)/2;
}
if(mag(f3) < p*tol_)
{
molarVolume=this->W()/rho3;
molarVolumePrevIteration=this->W()/rho3;
break;
}
else
{
molarVolumePrevIteration=this->W()/rho3;
}
}
}
}
while
(
mag(this->p((this->W()/molarVolume),T) - p)
> mag(this->p((this->W()/molarVolumePrevIteration),T) - p)
);
if (iter++ > maxIter_)
{
FatalErrorIn
(
"inline scalar soaveRedlichKwong::rho(const scalar p, const scalar T, const scalar rho0) const "
) << "Maximum number of iterations exceeded"
<< abort(FatalError);
}
}
while(mag(molarVolumePrevIteration-molarVolume) > tol_*(this->W()/rho0));
return this->W()/molarVolume;
}
//- Return density [kg/m^3]on
inline scalar soaveRedlichKwong::rho(const scalar p,const scalar T) const
{
//CL: using perfect gas equation as starting point
return rho(p,T,p/(this->R()*T));
}
//- Return compressibility drho/dp at T=constant [s^2/m^2]
inline scalar soaveRedlichKwong::psi(const scalar rho, const scalar T) const
{
return -this->dvdp(rho,T)*rho*rho/this->W();
}
//- Return compression factor []
inline scalar soaveRedlichKwong::Z( const scalar p, const scalar T,const scalar rho0) const
{
return p/(this->R()*T*this->rho(p,T,rho0));
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
inline void soaveRedlichKwong::operator+=(const soaveRedlichKwong& srk)
{
specie::operator+=(srk);
}
inline void soaveRedlichKwong::operator*=(const scalar s)
{
specie::operator*=(s);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
inline soaveRedlichKwong operator+
(
const soaveRedlichKwong& srk1,
const soaveRedlichKwong& srk2
)
{
return soaveRedlichKwong
(
static_cast<const specie&>(srk1)
+ static_cast<const specie&>(srk2)
);
}
inline soaveRedlichKwong operator*
(
const scalar s,
const soaveRedlichKwong& srk
)
{
return soaveRedlichKwong(s*static_cast<const specie&>(srk));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "constantHeatCapacity.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class equationOfState>
Foam::constantHeatCapacity<equationOfState>::constantHeatCapacity(Istream& is)
:
equationOfState(is),
Cp0_(readScalar(is)),
cp0_(Cp0_*this->W()),
//values for some need terms at std
e0_std(e0(this->Tstd)),
s0_std(s0(this->Tstd)),
integral_p_dv_std(this->integral_p_dv(this->rhostd(),this->Tstd)),
integral_dpdT_dv_std(this->integral_dpdT_dv(this->rhostd(),this->Tstd)),
// cp @ STD (needed to limit cp for stability
cp_std(this->cp_nonLimited(this->rhostd(),this->Tstd))
{
is.check("constantHeatCapacity::constantHeatCapacity(Istream& is)");
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class equationOfState>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const constantHeatCapacity<equationOfState>& np
)
{
os << static_cast<const equationOfState&>(np) << tab
<< np.Cp0_;
os.check("Ostream& operator<<(Ostream& os, const constantHeatCapacity& np)");
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,256 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::constantHeatCapacity
Description
real gas thermodynamic class --> constant perfect gas heat capacity
Important: the perfect gas heat capacity is constant, the real heat capacity is not constant due to real gas corrections
templated into the equationOfState
-> uses the equation of state to calculate all real Gas properties like Enthalpy, Entropy ...
-> can not be used with the perfectGas equation of state
Equations for the real gas correction: Have a look at thermodnamics books e.g. Thermodynamics:
An Engineering Approch, 5 Edition, Chapter 12
SourceFiles
constantHeatCapacityI.H
constantHeatCapacity.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef constantHeatCapacity_H
#define constantHeatCapacity_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class equationOfState> class constantHeatCapacity;
template<class equationOfState>
inline constantHeatCapacity<equationOfState> operator+
(
const constantHeatCapacity<equationOfState>&,
const constantHeatCapacity<equationOfState>&
);
template<class equationOfState>
inline constantHeatCapacity<equationOfState> operator-
(
const constantHeatCapacity<equationOfState>&,
const constantHeatCapacity<equationOfState>&
);
template<class equationOfState>
inline constantHeatCapacity<equationOfState> operator*
(
const scalar,
const constantHeatCapacity<equationOfState>&
);
template<class equationOfState>
inline constantHeatCapacity<equationOfState> operator==
(
const constantHeatCapacity<equationOfState>&,
const constantHeatCapacity<equationOfState>&
);
template<class equationOfState>
Ostream& operator<<
(
Ostream&,
const constantHeatCapacity<equationOfState>&
);
/*---------------------------------------------------------------------------*\
Class constantHeatCapacity Thermo Declaration
\*---------------------------------------------------------------------------*/
template<class equationOfState>
class constantHeatCapacity
:
public equationOfState
{
// Private data
//CL: spec. cp
scalar Cp0_;
//CL: molar values
scalar cp0_;
scalar e0_std;
scalar s0_std;
scalar integral_p_dv_std;
scalar integral_dpdT_dv_std;
scalar cp_std;
// Private member functions
//- Construct from components
//CL: used for the operator+
inline constantHeatCapacity
(
const equationOfState& st,
const scalar cp0_
);
//- Construct from components
//CL: used for the operator*
inline constantHeatCapacity
(
const equationOfState& st,
const scalar cp0_,
const scalar e0_std_,
const scalar s0_std_,
const scalar integral_p_dv_std_,
const scalar integral_dpdT_dv_std_,
const scalar cp_std_
);
public:
//Variable
// Constructors
//- Construct from Istream
constantHeatCapacity(Istream&);
//- Construct as named copy
inline constantHeatCapacity(const word&, const constantHeatCapacity&);
//- Construct and return a clone
inline autoPtr<constantHeatCapacity> clone() const;
//- Selector from Istream
inline static autoPtr<constantHeatCapacity> New(Istream& is);
// Member Functions
//- perfect Gas Enthalpy [J/kmol]
inline scalar h0(const scalar T) const;
//- perfect Gas Entropy [J/(kmol K)]
inline scalar s0(const scalar T) const;
//- perfect Gas internal Energy [J/kmol]
inline scalar e0(const scalar T) const;
//- perfect gas Heat capacity at constant pressure [J/(kmol K)]
inline scalar cv0(const scalar T) const;
//- perfect gas Heat capacity at constant pressure [J/(kmol K)]
inline scalar cp0(const scalar T) const;
//- Limited Heat capacity at constant pressure [J/(kmol K)]
inline scalar cp(const scalar rho, const scalar T) const;
//- non Limited Heat capacity at constant pressure [J/(kmol K)]
inline scalar cp_nonLimited(const scalar rho, const scalar T) const;
//- Heat capacity at constant pressure [J/(kmol K)]
inline scalar cv(const scalar rho, const scalar T) const;
//- Enthalpy [J/kmol]
inline scalar h(const scalar rho, const scalar T) const;
//- Entropy [J/(kmol K)]
inline scalar s(const scalar rho,const scalar T) const;
//- Internal Energy [J/kmol]
inline scalar e(const scalar rho, const scalar T) const;
// Member operators
inline void operator+=(const constantHeatCapacity&);
inline void operator-=(const constantHeatCapacity&);
// Friend operators
friend constantHeatCapacity operator+ <equationOfState>
(
const constantHeatCapacity&,
const constantHeatCapacity&
);
friend constantHeatCapacity operator- <equationOfState>
(
const constantHeatCapacity&,
const constantHeatCapacity&
);
friend constantHeatCapacity operator* <equationOfState>
(
const scalar,
const constantHeatCapacity&
);
friend constantHeatCapacity operator== <equationOfState>
(
const constantHeatCapacity&,
const constantHeatCapacity&
);
// IOstream Operators
friend Ostream& operator<< <equationOfState>
(
Ostream&,
const constantHeatCapacity&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "constantHeatCapacityI.H"
#ifdef NoRepository
# include "constantHeatCapacity.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,402 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components
//CL: used for the operator+
template<class equationOfState>
inline Foam::constantHeatCapacity<equationOfState>::constantHeatCapacity
(
const equationOfState& st,
const scalar cp0_
)
:
equationOfState(st),
cp0_(cp0_),
e0_std(e0(this->Tstd)),
s0_std(s0(this->Tstd)),
integral_p_dv_std(this->integral_p_dv(this->rhostd(),this->Tstd)),
integral_dpdT_dv_std(this->integral_dpdT_dv(this->rhostd(),this->Tstd)),
cp_std(this->cp_nonLimited(this->rhostd(),this->Tstd))
{}
//- Construct from components
//CL: used for the operator*
template<class equationOfState>
inline Foam::constantHeatCapacity<equationOfState>::constantHeatCapacity
(
const equationOfState& st,
const scalar cp0_,
const scalar e0_std_,
const scalar s0_std_,
const scalar integral_p_dv_std_,
const scalar integral_dpdT_dv_std_,
const scalar cp_std_
)
:
equationOfState(st),
cp0_(cp0_),
e0_std(e0_std_),
s0_std(s0_std_),
integral_p_dv_std(integral_p_dv_std_),
integral_dpdT_dv_std(integral_dpdT_dv_std_),
cp_std(cp_std_)
{}
template<class equationOfState>
inline Foam::constantHeatCapacity<equationOfState>::constantHeatCapacity
(
const word& name,
const constantHeatCapacity& np
)
:
equationOfState(name, np),
cp0_(np.cp0_),
e0_std(np.e0_std),
s0_std(np.s0_std),
integral_p_dv_std(np.integral_p_dv_std),
integral_dpdT_dv_std(np.integral_dpdT_dv_std),
cp_std(np.cp_std)
{}
template<class equationOfState>
inline Foam::autoPtr<Foam::constantHeatCapacity<equationOfState> >
Foam::constantHeatCapacity<equationOfState>::clone() const
{
return autoPtr<constantHeatCapacity<equationOfState> >
(
new constantHeatCapacity<equationOfState>(*this)
);
}
template<class equationOfState>
inline Foam::autoPtr<Foam::constantHeatCapacity<equationOfState> >
Foam::constantHeatCapacity<equationOfState>::New(Istream& is)
{
return autoPtr<constantHeatCapacity<equationOfState> >
(
new constantHeatCapacity<equationOfState>(is)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//used to calculate the internal energy
//perfect gas enthalpy
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::h0
(
const scalar T
) const
{
return cp0_*T;
}
//used to calculate the internal energy
//perfect gas internal energy
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::e0
(
const scalar T
) const
{
return this->h0(T) - this->RR*T;
}
// used to calculate the entropy
// perfect gas entropy
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::s0
(
const scalar T
) const
{
return cp0_*log(T);
}
//perfect gas cp
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::cp0
(
const scalar T
) const
{
return cp0_;
}
//perfect gas cv
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::cv0
(
const scalar T
) const
{
return this->cp0(T)-this->RR;
}
//function to calculate real gas cp
//using cp=cv+(dp/dT)^2/(dp/dv)
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::cp
(
const scalar rho,
const scalar T
) const
{
// Problem --> dpdv(rho,T) is =0 at some points within the vapour dome. To increase stability, (dp/dv) has to be limited
// cp can be negative within the vapor dome. To avoid this nonphysical result, the absolute value is used.
// within the vapourdome and at the critical point, cp increases to very high values --> infinity,
// this would decrease the stability, so cp will be limited to 20 times the cp @ STD
return
min
(
cp_std*20,
fabs
(
this->cv(rho,T)
-T*pow((this->dpdT(rho, T)),2)
/min(this->dpdv(rho, T),-1)
)
);
}
// this function is needed to get cp @ STD (without the limit imposed in the function above),
// which in turn is needed to limit the cp in the function above
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::cp_nonLimited
(
const scalar rho,
const scalar T
) const
{
return fabs(this->cv(rho,T)-T*pow((this->dpdT(rho, T)),2)/min(this->dpdv(rho, T),-1));
}
//function to calculate real gas cv
//cv=cv0+T*integral d2p/dT2 dv
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::cv
(
const scalar rho,
const scalar T
) const
{
return this->cv0(T)+T*this->integral_d2pdT2_dv(rho, T);
}
//function to calculate real gas enthalpy
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::h
(
const scalar rho,
const scalar T
) const
{
return this->e(rho,T)+this->p(rho,T)/rho*this->W()-this->Pstd/this->rhostd()*this->W();
}
// function to calculate real gas internal energy
// important assumption used: internal Energie is 0 at STD conditions.
// equation: du= cv0 dT +[T*dp/dT -p]dv
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::e
(
const scalar rho,
const scalar T
) const
{
return
(
-this->Tstd*integral_dpdT_dv_std
+integral_p_dv_std
+this->e0(T)-e0_std
+T*this->integral_dpdT_dv(rho,T)
-this->integral_p_dv(rho,T)
);
}
//function to calculate real gas entropy
// important assumption used: the Entropy is 0 at STD conditions.
// equation: ds= cv0/T * dT + dp/dT *dv
// --> integral cv0/T dT = s0(T) -s0(Tstd) - R*ln(T/Tstd) --> due to s0(T)-s0(Tstd)=integral cp0/T dT
template<class equationOfState>
inline Foam::scalar Foam::constantHeatCapacity<equationOfState>::s
(
const scalar rho,
const scalar T
) const
{
return -integral_dpdT_dv_std
+(this->s0(T)-s0_std)
-this->RR*log(T/this->Tstd)
+ this->integral_dpdT_dv(rho,T);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class equationOfState>
inline void Foam::constantHeatCapacity<equationOfState>::operator+=
(
const constantHeatCapacity<equationOfState>& np
)
{
scalar molr1 = this->nMoles();
equationOfState::operator+=(np);
molr1 /= this->nMoles();
scalar molr2 = np.nMoles()/this->nMoles();
cp0_ = molr1*cp0_ + molr2*np.cp0_;
}
template<class equationOfState>
inline void Foam::constantHeatCapacity<equationOfState>::operator-=
(
const constantHeatCapacity<equationOfState>& np
)
{
scalar molr1 = this->nMoles();
constantHeatCapacity::operator-=(np);
molr1 /= this->nMoles();
scalar molr2 = np.nMoles()/this->nMoles();
cp0_ = molr1*cp0_ - molr2*np.cp0_;
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class equationOfState>
inline Foam::constantHeatCapacity<equationOfState> Foam::operator+
(
const constantHeatCapacity<equationOfState>& np1,
const constantHeatCapacity<equationOfState>& np2
)
{
equationOfState eofs
(
static_cast<const equationOfState&>(np1)
+ static_cast<const equationOfState&>(np2)
);
//CL: Important, calls a different constructor as operator*
//CL: the coefficients as well as the EOS (coefficients) changed
//CL: therefore, the values at STD needs to be recalculated
return constantHeatCapacity<equationOfState>
(
eofs,
np1.nMoles()/eofs.nMoles()*np1.cp0_
+ np2.nMoles()/eofs.nMoles()*np2.cp0_
);
}
template<class equationOfState>
inline Foam::constantHeatCapacity<equationOfState> Foam::operator-
(
const constantHeatCapacity<equationOfState>& np1,
const constantHeatCapacity<equationOfState>& np2
)
{
equationOfState eofs
(
static_cast<const equationOfState&>(np1)
- static_cast<const equationOfState&>(np2)
);
return constantHeatCapacity<equationOfState>
(
eofs,
np1.nMoles()/eofs.nMoles()*np1.cp0_
- np2.nMoles()/eofs.nMoles()*np2.cp0_
);
}
template<class equationOfState>
inline Foam::constantHeatCapacity<equationOfState> Foam::operator*
(
const scalar s,
const constantHeatCapacity<equationOfState>& np
)
{
//CL: values at STD don't need to be recalculated,
//CL: therefore, providing the values in the constructor
return constantHeatCapacity<equationOfState>
(
s*static_cast<const equationOfState&>(np),
np.cp0_,
np.e0_std,
np.s0_std,
np.integral_p_dv_std,
np.integral_dpdT_dv_std,
np.cp_std
);
}
template<class equationOfState>
inline Foam::constantHeatCapacity<equationOfState> Foam::operator==
(
const constantHeatCapacity<equationOfState>& np1,
const constantHeatCapacity<equationOfState>& np2
)
{
return np2 - np1;
}
// ************************************************************************* //

View file

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#include "nasaHeatCapacityPolynomial.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class equationOfState>
Foam::nasaHeatCapacityPolynomial<equationOfState>::nasaHeatCapacityPolynomial(Istream& is)
:
equationOfState(is),
a1_(readScalar(is)),
a2_(readScalar(is)),
a3_(readScalar(is)),
a4_(readScalar(is)),
a5_(readScalar(is)),
a6_(readScalar(is)),
a7_(readScalar(is)),
//values for some need terms at std
e0_std(e0(this->Tstd)),
s0_std(s0(this->Tstd)),
integral_p_dv_std(this->integral_p_dv(this->rhostd(),this->Tstd)),
integral_dpdT_dv_std(this->integral_dpdT_dv(this->rhostd(),this->Tstd)),
//cp @ STD (needed to limit cp for stability
cp_std(this->cp_nonLimited(this->rhostd(),this->Tstd))
{
is.check("nasaHeatCapacityPolynomial::nasaHeatCapacityPolynomial(Istream& is)");
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class equationOfState>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const nasaHeatCapacityPolynomial<equationOfState>& np
)
{
os << static_cast<const equationOfState&>(np) << tab
<< np.a1_ << tab<< np.a2_ << tab << np.a3_ << tab << np.a4_ << tab << np.a5_ << tab << np.a6_ << tab << np.a7_ ;
os.check("Ostream& operator<<(Ostream& os, const nasaHeatCapacityPolynomial& np)");
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,274 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::nasaHeatCapacityPolynomial
Description
Nasa Heat Capacity Polynomial for perfect Gas (7.order polynominal) --> freely available for many fluids
--> paper title: NASA Glenn Coefficients for Calculating Thermodynamic Properties of Individual Species
templated into the equationOfState
-> uses the equation of state to calculate all real Gas properties like Enthalpy, Entropy ...
-> can not be used with the perfectGas equation of state
Equations for the real gas correction: Have a look at thermodnamics books
e.g. Thermodynamics: An Engineering Approch, 5 Edition, Chapter 12
SourceFiles
nasaHeatCapacityPolynomialI.H
nasaHeatCapacityPolynomial.C
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
#ifndef nasaHeatCapacityPolynomial_H
#define nasaHeatCapacityPolynomial_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class equationOfState> class nasaHeatCapacityPolynomial;
template<class equationOfState>
inline nasaHeatCapacityPolynomial<equationOfState> operator+
(
const nasaHeatCapacityPolynomial<equationOfState>&,
const nasaHeatCapacityPolynomial<equationOfState>&
);
template<class equationOfState>
inline nasaHeatCapacityPolynomial<equationOfState> operator-
(
const nasaHeatCapacityPolynomial<equationOfState>&,
const nasaHeatCapacityPolynomial<equationOfState>&
);
template<class equationOfState>
inline nasaHeatCapacityPolynomial<equationOfState> operator*
(
const scalar,
const nasaHeatCapacityPolynomial<equationOfState>&
);
template<class equationOfState>
inline nasaHeatCapacityPolynomial<equationOfState> operator==
(
const nasaHeatCapacityPolynomial<equationOfState>&,
const nasaHeatCapacityPolynomial<equationOfState>&
);
template<class equationOfState>
Ostream& operator<<
(
Ostream&,
const nasaHeatCapacityPolynomial<equationOfState>&
);
/*---------------------------------------------------------------------------*\
Class nasaHeatCapacityPolynomial Thermo Declaration
\*---------------------------------------------------------------------------*/
template<class equationOfState>
class nasaHeatCapacityPolynomial
:
public equationOfState
{
// Private data
scalar a1_;
scalar a2_;
scalar a3_;
scalar a4_;
scalar a5_;
scalar a6_;
scalar a7_;
scalar e0_std;
scalar s0_std;
scalar integral_p_dv_std;
scalar integral_dpdT_dv_std;
scalar cp_std;
// Private member functions
//- Construct from components
//CL: used for the operator+
inline nasaHeatCapacityPolynomial
(
const equationOfState& st,
const scalar a1,
const scalar a2,
const scalar a3,
const scalar a4,
const scalar a5,
const scalar a6,
const scalar a7
);
//- Construct from components
//CL: used for the operator*
inline nasaHeatCapacityPolynomial
(
const equationOfState& st,
const scalar a1,
const scalar a2,
const scalar a3,
const scalar a4,
const scalar a5,
const scalar a6,
const scalar a7,
const scalar e0_std_,
const scalar s0_std_,
const scalar integral_p_dv_std_,
const scalar integral_dpdT_dv_std_,
const scalar cp_std_
);
public:
//Variable
// Constructors
//- Construct from Istream
nasaHeatCapacityPolynomial(Istream&);
//- Construct from dictionary
nasaHeatCapacityPolynomial(const dictionary& dict);
//- Construct as named copy
inline nasaHeatCapacityPolynomial(const word&, const nasaHeatCapacityPolynomial&);
//- Construct and return a clone
inline autoPtr<nasaHeatCapacityPolynomial> clone() const;
//- Selector from Istream
inline static autoPtr<nasaHeatCapacityPolynomial> New(Istream& is);
// Member Functions
//- perfect Gas Enthalpy [J/kmol]
inline scalar h0(const scalar T) const;
//- perfect Gas Entropy [J/(kmol K)]
inline scalar s0(const scalar T) const;
//- perfect Gas internal Energy [J/kmol]
inline scalar e0(const scalar T) const;
//- perfect gas Heat capacity at constant pressure [J/(kmol K)]
inline scalar cv0(const scalar T) const;
//- perfect gas Heat capacity at constant pressure [J/(kmol K)]
inline scalar cp0(const scalar T) const;
//- Limited Heat capacity at constant pressure [J/(kmol K)]
inline scalar cp(const scalar rho, const scalar T) const;
//- non Limited Heat capacity at constant pressure [J/(kmol K)]
inline scalar cp_nonLimited(const scalar rho, const scalar T) const;
//- Heat capacity at constant pressure [J/(kmol K)]
inline scalar cv(const scalar rho, const scalar T) const;
//- Enthalpy [J/kmol]
inline scalar h(const scalar rho, const scalar T) const;
//- Entropy [J/(kmol K)]
inline scalar s(const scalar rho,const scalar T) const;
//- Internal Energy [J/kmol]
inline scalar e(const scalar rho, const scalar T) const;
// Member operators
inline void operator+=(const nasaHeatCapacityPolynomial&);
inline void operator-=(const nasaHeatCapacityPolynomial&);
// Friend operators
friend nasaHeatCapacityPolynomial operator+ <equationOfState>
(
const nasaHeatCapacityPolynomial&,
const nasaHeatCapacityPolynomial&
);
friend nasaHeatCapacityPolynomial operator- <equationOfState>
(
const nasaHeatCapacityPolynomial&,
const nasaHeatCapacityPolynomial&
);
friend nasaHeatCapacityPolynomial operator* <equationOfState>
(
const scalar,
const nasaHeatCapacityPolynomial&
);
friend nasaHeatCapacityPolynomial operator== <equationOfState>
(
const nasaHeatCapacityPolynomial&,
const nasaHeatCapacityPolynomial&
);
// IOstream Operators
friend Ostream& operator<< <equationOfState>
(
Ostream&,
const nasaHeatCapacityPolynomial&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "nasaHeatCapacityPolynomialI.H"
#ifdef NoRepository
# include "nasaHeatCapacityPolynomial.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,501 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Author
Christian Lucas
Institut für Thermodynamik
Technische Universität Braunschweig
Germany
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components
//CL: used for the operator+
template<class equationOfState>
inline Foam::nasaHeatCapacityPolynomial<equationOfState>::nasaHeatCapacityPolynomial
(
const equationOfState& st,
const scalar a1,
const scalar a2,
const scalar a3,
const scalar a4,
const scalar a5,
const scalar a6,
const scalar a7
)
:
equationOfState(st),
a1_(a1),
a2_(a2),
a3_(a3),
a4_(a4),
a5_(a5),
a6_(a6),
a7_(a7),
e0_std(e0(this->Tstd)),
s0_std(s0(this->Tstd)),
integral_p_dv_std(this->integral_p_dv(this->rhostd(),this->Tstd)),
integral_dpdT_dv_std(this->integral_dpdT_dv(this->rhostd(),this->Tstd)),
cp_std(this->cp_nonLimited(this->rhostd(),this->Tstd))
{}
//- Construct from components
//CL: used for the operator*
template<class equationOfState>
inline Foam::nasaHeatCapacityPolynomial<equationOfState>::nasaHeatCapacityPolynomial
(
const equationOfState& st,
const scalar a1,
const scalar a2,
const scalar a3,
const scalar a4,
const scalar a5,
const scalar a6,
const scalar a7,
const scalar e0_std_,
const scalar s0_std_,
const scalar integral_p_dv_std_,
const scalar integral_dpdT_dv_std_,
const scalar cp_std_
)
:
equationOfState(st),
a1_(a1),
a2_(a2),
a3_(a3),
a4_(a4),
a5_(a5),
a6_(a6),
a7_(a7),
e0_std(e0_std_),
s0_std(s0_std_),
integral_p_dv_std(integral_p_dv_std_),
integral_dpdT_dv_std(integral_dpdT_dv_std_),
cp_std(cp_std_)
{}
template<class equationOfState>
inline Foam::nasaHeatCapacityPolynomial<equationOfState>::nasaHeatCapacityPolynomial
(
const word& name,
const nasaHeatCapacityPolynomial& np
)
:
equationOfState(name, np),
a1_(np.a1_),
a2_(np.a2_),
a3_(np.a3_),
a4_(np.a4_),
a5_(np.a5_),
a6_(np.a6_),
a7_(np.a7_),
e0_std(np.e0_std),
s0_std(np.s0_std),
integral_p_dv_std(np.integral_p_dv_std),
integral_dpdT_dv_std(np.integral_dpdT_dv_std),
cp_std(np.cp_std)
{}
template<class equationOfState>
inline Foam::autoPtr<Foam::nasaHeatCapacityPolynomial<equationOfState> >
Foam::nasaHeatCapacityPolynomial<equationOfState>::clone() const
{
return autoPtr<nasaHeatCapacityPolynomial<equationOfState> >
(
new nasaHeatCapacityPolynomial<equationOfState>(*this)
);
}
template<class equationOfState>
inline Foam::autoPtr<Foam::nasaHeatCapacityPolynomial<equationOfState> >
Foam::nasaHeatCapacityPolynomial<equationOfState>::New(Istream& is)
{
return autoPtr<nasaHeatCapacityPolynomial<equationOfState> >
(
new nasaHeatCapacityPolynomial<equationOfState>(is)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//used to calculate the internal energy
//perfect gas enthalpy
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::h0
(
const scalar T
) const
{
return
this->RR*T*
(
-this->a1_*pow(T,-2)
+this->a2_*log(T)/T
+this->a3_
+0.5*this->a4_*T
+(this->a5_*pow(T,2))/3
+(this->a6_*pow(T,3))/4
+(this->a7_*pow(T,4))/5
);
}
//used to calculate the internal energy
//perfect gas internal energy
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::e0
(
const scalar T
) const
{
return this->h0(T) - this->RR*T;
}
// used to calculate the entropy
// perfect gas entropy
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::s0
(
const scalar T
) const
{
return this->RR*
(
this->a1_*(-1)/(2*pow(T,2))
-this->a2_/T+this->a3_*log(T)
+this->a4_*T
+(this->a5_*pow(T,2))/2
+(this->a6_*pow(T,3))/3
+(this->a7_*pow(T,4))/4
);
}
//perfect gas cp
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::cp0
(
const scalar T
) const
{
return this->RR*
(
this->a1_*1/pow(T,2)
+this->a2_*1/T
+this->a3_
+this->a4_*T
+this->a5_*pow(T,2)
+this->a6_*pow(T,3)
+this->a7_*pow(T,4)
);
}
//perfect gas cv
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::cv0
(
const scalar T
) const
{
return this->cp0(T)-this->RR;
}
//function to calculate real gas cp
//using cp=cv+(dp/dT)^2/(dp/dv)
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::cp
(
const scalar rho,
const scalar T
) const
{
// Problem --> dpdv(rho,T) is =0 at some points within the vapour dome. To increase stability, (dp/dv) has to be limited
// cp can be negative within the vapor dome. To avoid this nonphysical result, the absolute value is used.
// within the vapourdome and at the critical point, cp increases to very high values --> infinity,
// this would decrease the stability, so cp will be limited to 20 times the cp @ STD
return
min
(
cp_std*20,
fabs
(
this->cv(rho,T)
-T*pow((this->dpdT(rho, T)),2)
/min(this->dpdv(rho, T),-1)
)
);
}
// this function is needed to get cp @ STD (without the limit imposed in the function above),
// which in turn is needed to limit the cp in the function above
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::cp_nonLimited
(
const scalar rho,
const scalar T
) const
{
return fabs(this->cv(rho,T)-T*pow((this->dpdT(rho, T)),2)/min(this->dpdv(rho, T),-1));
}
//function to calculate real gas cv
//cv=cv0+T*integral d2p/dT2 dv
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::cv
(
const scalar rho,
const scalar T
) const
{
return this->cv0(T)+T*this->integral_d2pdT2_dv(rho, T);
}
//function to calculate real gas enthalpy
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::h
(
const scalar rho,
const scalar T
) const
{
return this->e(rho,T)+this->p(rho,T)/rho*this->W()-this->Pstd/this->rhostd()*this->W();
}
// function to calculate real gas internal energy
// important assumption used: internal Energie is 0 at STD conditions.
// equation: du= cv0 dT +[T*dp/dT -p]dv
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::e
(
const scalar rho,
const scalar T
) const
{
return
(
-this->Tstd*integral_dpdT_dv_std
+integral_p_dv_std
+this->e0(T)-e0_std
+T*this->integral_dpdT_dv(rho,T)
-this->integral_p_dv(rho,T)
);
}
//function to calculate real gas entropy
// important assumption used: the Entropy is 0 at STD conditions.
// equation: ds= cv0/T * dT + dp/dT *dv
// --> integral cv0/T dT = s0(T) -s0(Tstd) - R*ln(T/Tstd) --> due to s0(T)-s0(Tstd)=integral cp0/T dT
template<class equationOfState>
inline Foam::scalar Foam::nasaHeatCapacityPolynomial<equationOfState>::s
(
const scalar rho,
const scalar T
) const
{
return -integral_dpdT_dv_std
+(this->s0(T)-s0_std)
-this->RR*log(T/this->Tstd)
+ this->integral_dpdT_dv(rho,T);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class equationOfState>
inline void Foam::nasaHeatCapacityPolynomial<equationOfState>::operator+=
(
const nasaHeatCapacityPolynomial<equationOfState>& np
)
{
scalar molr1 = this->nMoles();
equationOfState::operator+=(np);
molr1 /= this->nMoles();
scalar molr2 = np.nMoles()/this->nMoles();
a1_ = molr1*a1_ + molr2*np.a1_;
a2_ = molr1*a2_ + molr2*np.a2_;
a3_ = molr1*a3_ + molr2*np.a3_;
a4_ = molr1*a4_ + molr2*np.a4_;
a5_ = molr1*a5_ + molr2*np.a5_;
a6_ = molr1*a6_ + molr2*np.a6_;
a7_ = molr1*a7_ + molr2*np.a7_;
}
template<class equationOfState>
inline void Foam::nasaHeatCapacityPolynomial<equationOfState>::operator-=
(
const nasaHeatCapacityPolynomial<equationOfState>& np
)
{
scalar molr1 = this->nMoles();
nasaHeatCapacityPolynomial::operator-=(np);
molr1 /= this->nMoles();
scalar molr2 = np.nMoles()/this->nMoles();
a1_ = molr1*a1_ - molr2*np.a1_;
a2_ = molr1*a2_ - molr2*np.a2_;
a3_ = molr1*a3_ - molr2*np.a3_;
a4_ = molr1*a4_ - molr2*np.a4_;
a5_ = molr1*a5_ - molr2*np.a5_;
a6_ = molr1*a6_ - molr2*np.a6_;
a7_ = molr1*a7_ - molr2*np.a7_;
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class equationOfState>
inline Foam::nasaHeatCapacityPolynomial<equationOfState> Foam::operator+
(
const nasaHeatCapacityPolynomial<equationOfState>& np1,
const nasaHeatCapacityPolynomial<equationOfState>& np2
)
{
equationOfState eofs
(
static_cast<const equationOfState&>(np1)
+ static_cast<const equationOfState&>(np2)
);
//CL: Important, calls a different constructor as operator*
//CL: the coefficients as well as the EOS (coefficients) changed
//CL: therefore, the values at STD needs to be recalculated
return nasaHeatCapacityPolynomial<equationOfState>
(
eofs,
np1.nMoles()/eofs.nMoles()*np1.a1_
+ np2.nMoles()/eofs.nMoles()*np2.a1_,
np1.nMoles()/eofs.nMoles()*np1.a2_
+ np2.nMoles()/eofs.nMoles()*np2.a2_,
np1.nMoles()/eofs.nMoles()*np1.a3_
+ np2.nMoles()/eofs.nMoles()*np2.a3_,
np1.nMoles()/eofs.nMoles()*np1.a4_
+ np2.nMoles()/eofs.nMoles()*np2.a4_,
np1.nMoles()/eofs.nMoles()*np1.a5_
+ np2.nMoles()/eofs.nMoles()*np2.a5_,
np1.nMoles()/eofs.nMoles()*np1.a6_
+ np2.nMoles()/eofs.nMoles()*np2.a6_,
np1.nMoles()/eofs.nMoles()*np1.a7_
+ np2.nMoles()/eofs.nMoles()*np2.a7_
);
}
template<class equationOfState>
inline Foam::nasaHeatCapacityPolynomial<equationOfState> Foam::operator-
(
const nasaHeatCapacityPolynomial<equationOfState>& np1,
const nasaHeatCapacityPolynomial<equationOfState>& np2
)
{
equationOfState eofs
(
static_cast<const equationOfState&>(np1)
- static_cast<const equationOfState&>(np2)
);
return nasaHeatCapacityPolynomial<equationOfState>
(
eofs,
np1.nMoles()/eofs.nMoles()*np1.a1_
- np2.nMoles()/eofs.nMoles()*np2.a1_,
np1.nMoles()/eofs.nMoles()*np1.a2_
- np2.nMoles()/eofs.nMoles()*np2.a2_,
np1.nMoles()/eofs.nMoles()*np1.a3_
- np2.nMoles()/eofs.nMoles()*np2.a3_,
np1.nMoles()/eofs.nMoles()*np1.a4_
- np2.nMoles()/eofs.nMoles()*np2.a4_,
np1.nMoles()/eofs.nMoles()*np1.a5_
- np2.nMoles()/eofs.nMoles()*np2.a5_,
np1.nMoles()/eofs.nMoles()*np1.a6_
- np2.nMoles()/eofs.nMoles()*np2.a6_,
np1.nMoles()/eofs.nMoles()*np1.a7_
- np2.nMoles()/eofs.nMoles()*np2.a7_
);
}
template<class equationOfState>
inline Foam::nasaHeatCapacityPolynomial<equationOfState> Foam::operator*
(
const scalar s,
const nasaHeatCapacityPolynomial<equationOfState>& np
)
{
//CL: values at STD don't need to be recalculated,
//CL: therefore, providing the values in the constructor
return nasaHeatCapacityPolynomial<equationOfState>
(
s*static_cast<const equationOfState&>(np),
np.a1_,
np.a2_,
np.a3_,
np.a4_,
np.a5_,
np.a6_,
np.a7_,
np.e0_std,
np.s0_std,
np.integral_p_dv_std,
np.integral_dpdT_dv_std,
np.cp_std
);
}
template<class equationOfState>
inline Foam::nasaHeatCapacityPolynomial<equationOfState> Foam::operator==
(
const nasaHeatCapacityPolynomial<equationOfState>& np1,
const nasaHeatCapacityPolynomial<equationOfState>& np2
)
{
return np2 - np1;
}
// ************************************************************************* //

View file

@ -0,0 +1,63 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "realGasSpecieThermo.H"
#include "IOstreams.H"
/* * * * * * * * * * * * * * * private static data * * * * * * * * * * * * * */
template<class thermo>
const Foam::scalar Foam::realGasSpecieThermo<thermo>::tol_ = 1.0e-9;
template<class thermo>
const int Foam::realGasSpecieThermo<thermo>::maxIter_ = 500;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class thermo>
Foam::realGasSpecieThermo<thermo>::realGasSpecieThermo(Istream& is)
:
thermo(is)
{
is.check("realGasSpecieThermo::realGasSpecieThermo(Istream& is)");
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class thermo>
Foam::Ostream& Foam::operator<<(Ostream& os, const realGasSpecieThermo<thermo>& st)
{
os << static_cast<const thermo&>(st);
os.check("Ostream& operator<<(Ostream& os, const realGasSpecieThermo& st)");
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,276 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::realGasSpecieThermo
Description
This is an subversion of the specieThermo function. While the "orginal" specieThermo function
is only valid for perfect gases, this function is valid for real gases.
Basic thermodynamics type based on the use of fitting functions for
cp, h, s obtained from the template argument type thermo. All other
properties are derived from these primitive functions.
SourceFiles
realGasSpecieThermoI.H
realGasSpecieThermo.C
\*---------------------------------------------------------------------------*/
#ifndef realGasSpecieThermo_H
#define realGasSpecieThermo_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class thermo> class realGasSpecieThermo;
template<class thermo>
inline realGasSpecieThermo<thermo> operator+
(
const realGasSpecieThermo<thermo>&,
const realGasSpecieThermo<thermo>&
);
template<class thermo>
inline realGasSpecieThermo<thermo> operator-
(
const realGasSpecieThermo<thermo>&,
const realGasSpecieThermo<thermo>&
);
template<class thermo>
inline realGasSpecieThermo<thermo> operator*
(
const scalar,
const realGasSpecieThermo<thermo>&
);
template<class thermo>
inline realGasSpecieThermo<thermo> operator==
(
const realGasSpecieThermo<thermo>&,
const realGasSpecieThermo<thermo>&
);
template<class thermo>
Ostream& operator<<
(
Ostream&,
const realGasSpecieThermo<thermo>&
);
/*---------------------------------------------------------------------------*\
Class realGasSpecieThermo Declaration
\*---------------------------------------------------------------------------*/
template<class thermo>
class realGasSpecieThermo
:
public thermo
{
// Private data
//- Convergence tolerance of energy -> temperature inversion functions
static const scalar tol_;
//- Max number of iterations in energy->temperature inversion functions
static const int maxIter_;
// Private member functions
// return the temperature corresponding to the value of the
// thermodynamic property f, given the function f = F(rho,T) and dF(rho,T)/dT
inline void T
(
scalar f,
scalar &T0,
scalar p,
scalar &rho0,
scalar (realGasSpecieThermo::*F)(const scalar,const scalar) const,
scalar (realGasSpecieThermo::*dFdT)(const scalar,const scalar) const
) const;
public:
// Constructors
//- construct from components
inline realGasSpecieThermo(const thermo& sp);
//- Construct from Istream
realGasSpecieThermo(Istream&);
//- Construct as named copy
inline realGasSpecieThermo(const word& name, const realGasSpecieThermo&);
// Member Functions
// Fundamaental properties
// (These functions must be provided in derived types)
// Sensible enthalpy [J/kmol]
//virtual scalar hs(const scalar) const;
// Chemical enthalpy [J/kmol]
//virtual scalar hc(const scalar) const;
// Calculate and return derived properties
// (These functions need not provided in derived types)
//CL: isentropic expansion factor "gamma" (heat capacity ratio for perfect gas)
inline scalar gamma(const scalar T, const scalar rho) const;
//- Sensible internal energy [J/kmol]
// inline scalar es(const scalar p, const scalar rho) const;
//- Gibbs free energy [J/kmol]
inline scalar g(const scalar rho, const scalar T ) const;
//- Helmholtz free energy [J/kmol]
inline scalar a(const scalar rho, const scalar T ) const;
// Mass specific properties
//- Heat capacity at constant pressure [J/(kg K)]
inline scalar Cp(const scalar rho, const scalar T) const;
//- Heat capacity at constant volume [J/(kg K)]
inline scalar Cv(const scalar rho, const scalar T) const;
//- Enthalpy [J/kg]
inline scalar H(const scalar rho, const scalar T) const;
//- Sensible enthalpy [J/kg]
// inline scalar Hs(const scalar T) const;
//- Chemical enthalpy [J/kg]
// inline scalar Hc() const;
//- Entropy [J/(kg K)]
inline scalar S(const scalar rho, const scalar T) const;
//- Internal energy [J/kg]
inline scalar E(const scalar rho, const scalar T) const;
//- Gibbs free energy [J/kg]
inline scalar G(const scalar rho, const scalar T) const;
//- Helmholtz free energy [J/kg]
inline scalar A(const scalar rho, const scalar T) const;
//CL: Other variables
//- Return compressibility drho/dp at h=constant [s^2/m^2]
inline scalar psiH(const scalar rho, const scalar T) const;
//- Return compressibility drho/dp at e=constant [s^2/m^2]
inline scalar psiE(const scalar rho, const scalar T) const;
//- Return compressibility drho/dH at p=constant
inline scalar drhodH(const scalar rho, const scalar T) const;
//- Return compressibility drho/dE at p=constant
inline scalar drhodE(const scalar rho, const scalar T) const;
// Energy->temperature inversion functions
//- Temperature from Enthalpy given an initial temperature T0
inline void TH(const scalar H, scalar &T0,const scalar p, scalar &psi0) const;
//- Temperature from internal energy given an initial temperature T0
inline void TE(const scalar E, scalar &T0,const scalar p, scalar &psi0) const;
// Member operators
inline void operator+=(const realGasSpecieThermo&);
inline void operator-=(const realGasSpecieThermo&);
inline void operator*=(const scalar);
// Friend operators
friend realGasSpecieThermo operator+ <thermo>
(
const realGasSpecieThermo&,
const realGasSpecieThermo&
);
friend realGasSpecieThermo operator- <thermo>
(
const realGasSpecieThermo&,
const realGasSpecieThermo&
);
friend realGasSpecieThermo operator* <thermo>
(
const scalar s,
const realGasSpecieThermo&
);
friend realGasSpecieThermo operator== <thermo>
(
const realGasSpecieThermo&,
const realGasSpecieThermo&
);
// Ostream Operator
friend Ostream& operator<< <thermo>
(
Ostream&,
const realGasSpecieThermo&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "realGasSpecieThermoI.H"
#ifdef NoRepository
# include "realGasSpecieThermo.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,382 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "realGasSpecieThermo.H"
template<class thermo>
inline Foam::realGasSpecieThermo<thermo>::realGasSpecieThermo
(
const thermo& sp
)
:
thermo(sp)
{}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
//CL: using two one dimensional newton solvers in a row
template<class thermo>
inline void Foam::realGasSpecieThermo<thermo>::T
(
scalar f,
scalar &T0,
scalar p,
scalar &rho0,
scalar (realGasSpecieThermo<thermo>::*F)(const scalar,const scalar) const,
scalar (realGasSpecieThermo<thermo>::*dFdT)(const scalar,const scalar) const
) const
{
scalar Test ;
scalar Tnew = T0;
scalar rhoOld;
scalar rho=rho0;
scalar Ttol = T0*tol_;
scalar rhotol=rho0*tol_;
label iter = 0;
label i;
do
{
Test = Tnew;
rhoOld=rho;
rho=this->rho(p,Test,rhoOld);
i=0;
do
{
//CL: using a stabilizing newton solver
//CL: if the solve is diverging, the step is reduced until the solver converges
Tnew = Test - ((this->*F)(rho,Test) - f)/(this->*dFdT)(rho,Test)/(pow(2,i));
i++;
}while
(
(i<20)
&&
((
mag((this->*F)(rho,Tnew) - f)
>
mag((this->*F)(rho,Test) - f)
))
);
if (iter++ > maxIter_)
{
FatalErrorIn
(
"realGasSpecieThermo<thermo>::T(scalar f, scalar T0, scalar p, scalar rho0, "
"scalar (realGasSpecieThermo<thermo>::*F)(const scalar) const, "
"scalar (realGasSpecieThermo<thermo>::*dFdT)(const scalar) const"
") const"
) << "Maximum number of iterations exceeded"
<< abort(FatalError);
}
} while
//CL: both fields must converge
(
(mag(mag(Tnew) - mag(Test)) > Ttol)
||
(mag(mag(rho) - mag(rhoOld)) > rhotol)
);
rho0=rho;
T0=Tnew;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class thermo>
inline Foam::realGasSpecieThermo<thermo>::realGasSpecieThermo
(
const word& name,
const realGasSpecieThermo& st
)
:
thermo(name, st)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::gamma(const scalar rho, const scalar T ) const
{
return -1/(rho*this->p(rho,T))*this->cp(rho,T)/this->cv(rho,T)*this->dpdv(rho,T);
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::g(const scalar rho, const scalar T ) const
{
return this->h(rho, T) - T*this->s(rho, T);
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::a(const scalar rho, const scalar T ) const
{
return this->e(rho,T ) - T*this->s(rho, T);
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::Cp( const scalar rho, const scalar T) const
{
return this->cp(rho, T)/this->W();
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::Cv( const scalar rho, const scalar T) const
{
return this->cv(rho, T)/this->W();
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::H(const scalar rho, const scalar T) const
{
return this->h(rho, T)/this->W();
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::S(const scalar rho, const scalar T) const
{
return this->s(rho, T)/this->W();
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::E(const scalar rho, const scalar T) const
{
return this->e(rho, T)/this->W();
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::G(const scalar rho, const scalar T) const
{
return this->g(rho, T)/this->W();
}
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::A(const scalar rho, const scalar T) const
{
return this->a(rho, T)/this->W();
}
//CL:- Return compressibility drho/dp at h=constant [s^2/m^2]
//CL:- using Bridgeman's Table
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::psiH
(
const scalar rho,
const scalar T
) const
{
scalar beta=this->isobarExpCoef(rho,T);
return
-(
(T*beta*beta-beta)/this->Cp(rho,T)
-this->isothermalCompressiblity(rho,T)*rho
);
}
//CL:- Return compressibility drho/dp at e=constant [s^2/m^2]
//CL:- using Bridgeman's Table
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::psiE
(
const scalar rho,
const scalar T
) const
{
scalar V = 1/rho;
scalar cp=this->Cp(rho,T);
scalar beta=this->isobarExpCoef(rho,T);
return
-(
(
T*pow(beta,2)*V
-this->isothermalCompressiblity(rho,T)*cp
)
/
(
cp*V
-beta*this->p(rho,T)*pow(V,2)
)
);
}
//CL:- Returns drho/dH at p=constant
//CL:- using Bridgeman's Table
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::drhodH
(
const scalar rho,
const scalar T
) const
{
return -(rho*this->isobarExpCoef(rho,T))/this->Cp(rho,T);
}
//CL:- Returns drho/dE at p=constant
//CL:- using Bridgeman's Table
template<class thermo>
inline Foam::scalar Foam::realGasSpecieThermo<thermo>::drhodE
(
const scalar rho,
const scalar T
) const
{
scalar beta=this->isobarExpCoef(rho,T);
return -(rho*beta)/(this->Cp(rho,T)-beta*this->p(rho,T)/rho);
}
template<class thermo>
inline void Foam::realGasSpecieThermo<thermo>::TH
(
const scalar h,
scalar &T0,
const scalar p,
scalar &rho0
) const
{
T(h, T0, p,rho0, &realGasSpecieThermo<thermo>::H, &realGasSpecieThermo<thermo>::Cp);
}
template<class thermo>
inline void Foam::realGasSpecieThermo<thermo>::TE
(
const scalar e,
scalar &T0,
const scalar p,
scalar &rho0
) const
{
T(e, T0, p,rho0, &realGasSpecieThermo<thermo>::E, &realGasSpecieThermo<thermo>::Cv);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class thermo>
inline void Foam::realGasSpecieThermo<thermo>::operator+=
(
const realGasSpecieThermo<thermo>& st
)
{
thermo::operator+=(st);
}
template<class thermo>
inline void Foam::realGasSpecieThermo<thermo>::operator-=
(
const realGasSpecieThermo<thermo>& st
)
{
thermo::operator-=(st);
}
template<class thermo>
inline void Foam::realGasSpecieThermo<thermo>::operator*=(const scalar s)
{
thermo::operator*=(s);
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class thermo>
inline Foam::realGasSpecieThermo<thermo> Foam::operator+
(
const realGasSpecieThermo<thermo>& st1,
const realGasSpecieThermo<thermo>& st2
)
{
return realGasSpecieThermo<thermo>
(
static_cast<const thermo&>(st1) + static_cast<const thermo&>(st2)
);
}
template<class thermo>
inline Foam::realGasSpecieThermo<thermo> Foam::operator-
(
const realGasSpecieThermo<thermo>& st1,
const realGasSpecieThermo<thermo>& st2
)
{
return realGasSpecieThermo<thermo>
(
static_cast<const thermo&>(st1) - static_cast<const thermo&>(st2)
);
}
template<class thermo>
inline Foam::realGasSpecieThermo<thermo> Foam::operator*
(
const scalar s,
const realGasSpecieThermo<thermo>& st
)
{
return realGasSpecieThermo<thermo>
(
s*static_cast<const thermo&>(st)
);
}
template<class thermo>
inline Foam::realGasSpecieThermo<thermo> Foam::operator==
(
const realGasSpecieThermo<thermo>& st1,
const realGasSpecieThermo<thermo>& st2
)
{
return st2 - st1;
}
// ************************************************************************* //

View file

@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "constRealGasTransport.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Thermo>
Foam::constRealGasTransport<Thermo>::constRealGasTransport(Istream& is)
:
Thermo(is),
mu_(readScalar(is)),
rPr_(1.0/readScalar(is))
{
is.check("constRealGasTransport::constRealGasTransport(Istream& is)");
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class Thermo>
Foam::Ostream& Foam::operator<<(Ostream& os, const constRealGasTransport<Thermo>& ct)
{
operator<<(os, static_cast<const Thermo&>(ct));
os << tab << ct.mu_ << tab << 1.0/ct.rPr_;
os.check("Ostream& operator<<(Ostream&, const constRealGasTransport&)");
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,202 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::constRealGasTransport
Description
Constant properties Transport package.
Templated into a given thermodynamics package (needed for thermal
conductivity).
SourceFiles
constRealGasTransportI.H
constRealGasTransport.C
\*---------------------------------------------------------------------------*/
#ifndef constRealGasTransport_H
#define constRealGasTransport_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class Thermo> class constRealGasTransport;
template<class Thermo>
inline constRealGasTransport<Thermo> operator+
(
const constRealGasTransport<Thermo>&,
const constRealGasTransport<Thermo>&
);
template<class Thermo>
inline constRealGasTransport<Thermo> operator-
(
const constRealGasTransport<Thermo>&,
const constRealGasTransport<Thermo>&
);
template<class Thermo>
inline constRealGasTransport<Thermo> operator*
(
const scalar,
const constRealGasTransport<Thermo>&
);
template<class Thermo>
inline constRealGasTransport<Thermo> operator==
(
const constRealGasTransport<Thermo>&,
const constRealGasTransport<Thermo>&
);
template<class Thermo>
Ostream& operator<<
(
Ostream&,
const constRealGasTransport<Thermo>&
);
/*---------------------------------------------------------------------------*\
Class constRealGasTransport Declaration
\*---------------------------------------------------------------------------*/
template<class Thermo>
class constRealGasTransport
:
public Thermo
{
// Private data
//- Constant dynamic viscosity [Pa.s]
scalar mu_;
//- Reciprocal Prandtl Number []
scalar rPr_;
// Private Member Functions
//- Construct from components
inline constRealGasTransport
(
const Thermo& t,
const scalar mu,
const scalar Pr
);
public:
// Constructors
//- Construct as named copy
inline constRealGasTransport(const word&, const constRealGasTransport&);
//- Construct from Istream
constRealGasTransport(Istream&);
// Member functions
//- Dynamic viscosity [kg/ms]
inline scalar mu(const scalar T) const;
//- Thermal conductivity [W/mK]
inline scalar kappa(const scalar rho, const scalar T) const;
//- Thermal diffusivity for enthalpy [kg/ms]
inline scalar alpha(const scalar rho, const scalar T) const;
// Species diffusivity
//inline scalar D(const scalar T) const;
// Member operators
inline constRealGasTransport& operator=
(
const constRealGasTransport&
);
// Friend operators
friend constRealGasTransport operator+ <Thermo>
(
const constRealGasTransport&,
const constRealGasTransport&
);
friend constRealGasTransport operator- <Thermo>
(
const constRealGasTransport&,
const constRealGasTransport&
);
friend constRealGasTransport operator* <Thermo>
(
const scalar,
const constRealGasTransport&
);
friend constRealGasTransport operator== <Thermo>
(
const constRealGasTransport&,
const constRealGasTransport&
);
// Ostream Operator
friend Ostream& operator<< <Thermo>
(
Ostream&,
const constRealGasTransport&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "constRealGasTransportI.H"
#ifdef NoRepository
# include "constRealGasTransport.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,182 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::constRealGasTransport<Thermo>::constRealGasTransport
(
const Thermo& t,
const scalar mu,
const scalar Pr
)
:
Thermo(t),
mu_(mu),
rPr_(1.0/Pr)
{}
template<class Thermo>
inline Foam::constRealGasTransport<Thermo>::constRealGasTransport
(
const word& name,
const constRealGasTransport& ct
)
:
Thermo(name, ct),
mu_(ct.mu_),
rPr_(ct.rPr_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::scalar Foam::constRealGasTransport<Thermo>::mu(const scalar) const
{
return mu_;
}
// CL: for real gas thermo
// Thermal conductivity [W/mK]
template<class thermo>
inline Foam::scalar Foam::constRealGasTransport<thermo>::kappa(const scalar rho,const scalar T) const
{
return this->Cp(rho,T)*mu(T)*rPr_;
}
// CL: for real gas thermo
// Thermal diffusivity for enthalpy [kg/ms]
template<class thermo>
inline Foam::scalar Foam::constRealGasTransport<thermo>::alpha(const scalar rho,const scalar T) const
{
scalar Cp_ = this->Cp(rho,T);
scalar deltaT = T - specie::Tstd;
scalar CpBar =
(deltaT*(this->H(rho,T) - this->H(this->rhostd(),specie::Tstd)) + Cp_)/(sqr(deltaT) + 1);
return Cp_*mu(T)*rPr_/CpBar;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::constRealGasTransport<Thermo>& Foam::constRealGasTransport<Thermo>::operator=
(
const constRealGasTransport<Thermo>& ct
)
{
Thermo::operator=(ct);
mu_ = ct.mu_;
rPr_ = ct.rPr_;
return *this;
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::constRealGasTransport<Thermo> Foam::operator+
(
const constRealGasTransport<Thermo>& ct1,
const constRealGasTransport<Thermo>& ct2
)
{
Thermo t
(
static_cast<const Thermo&>(ct1) + static_cast<const Thermo&>(ct2)
);
scalar molr1 = ct1.nMoles()/t.nMoles();
scalar molr2 = ct2.nMoles()/t.nMoles();
return constRealGasTransport<Thermo>
(
t,
molr1*ct1.mu_ + molr2*ct2.mu_,
molr1*ct1.rPr_ + molr2*ct2.rPr_
);
}
template<class Thermo>
inline Foam::constRealGasTransport<Thermo> Foam::operator-
(
const constRealGasTransport<Thermo>& ct1,
const constRealGasTransport<Thermo>& ct2
)
{
Thermo t
(
static_cast<const Thermo&>(ct1) - static_cast<const Thermo&>(ct2)
);
scalar molr1 = ct1.nMoles()/t.nMoles();
scalar molr2 = ct2.nMoles()/t.nMoles();
return constRealGasTransport<Thermo>
(
t,
molr1*ct1.mu_ - molr2*ct2.mu_,
molr1*ct1.rPr_ - molr2*ct2.rPr_
);
}
template<class Thermo>
inline Foam::constRealGasTransport<Thermo> Foam::operator*
(
const scalar s,
const constRealGasTransport<Thermo>& ct
)
{
return constRealGasTransport<Thermo>
(
s*static_cast<const Thermo&>(ct),
ct.mu_,
ct.rPr_
);
}
template<class Thermo>
inline Foam::constRealGasTransport<Thermo> Foam::operator==
(
const constRealGasTransport<Thermo>& ct1,
const constRealGasTransport<Thermo>& ct2
)
{
return ct2 - ct1;
}
// ************************************************************************* //

View file

@ -0,0 +1,62 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "sutherlandRealGasTransport.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Thermo>
Foam::sutherlandRealGasTransport<Thermo>::sutherlandRealGasTransport(Istream& is)
:
Thermo(is),
As_(readScalar(is)),
Ts_(readScalar(is))
{
is.check("sutherlandRealGasTransport<Thermo>::sutherlandRealGasTransport(Istream&)");
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class Thermo>
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const sutherlandRealGasTransport<Thermo>& st
)
{
os << static_cast<const Thermo&>(st) << tab << st.As_ << tab << st.Ts_;
os.check
(
"Ostream& operator<<(Ostream&, const sutherlandRealGasTransport<Thermo>&)"
);
return os;
}
// ************************************************************************* //

View file

@ -0,0 +1,227 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::sutherlandRealGasTransport
Description
Transport package using Sutherland's formula.
Templated into a given thermodynamics package (needed for thermal
conductivity).
Dynamic viscosity [kg/m.s]
\f[
\mu = A_s \frac{\sqrt{T}}{1 + T_s / T}
\f]
SourceFiles
sutherlandRealGasTransportI.H
sutherlandRealGasTransport.C
\*---------------------------------------------------------------------------*/
#ifndef sutherlandRealGasTransport_H
#define sutherlandRealGasTransport_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
template<class Thermo> class sutherlandRealGasTransport;
template<class Thermo>
inline sutherlandRealGasTransport<Thermo> operator+
(
const sutherlandRealGasTransport<Thermo>&,
const sutherlandRealGasTransport<Thermo>&
);
template<class Thermo>
inline sutherlandRealGasTransport<Thermo> operator-
(
const sutherlandRealGasTransport<Thermo>&,
const sutherlandRealGasTransport<Thermo>&
);
template<class Thermo>
inline sutherlandRealGasTransport<Thermo> operator*
(
const scalar,
const sutherlandRealGasTransport<Thermo>&
);
template<class Thermo>
inline sutherlandRealGasTransport<Thermo> operator==
(
const sutherlandRealGasTransport<Thermo>&,
const sutherlandRealGasTransport<Thermo>&
);
template<class Thermo>
Ostream& operator<<
(
Ostream&,
const sutherlandRealGasTransport<Thermo>&
);
/*---------------------------------------------------------------------------*\
Class sutherlandRealGasTransport Declaration
\*---------------------------------------------------------------------------*/
template<class Thermo>
class sutherlandRealGasTransport
:
public Thermo
{
// Private data
// Sutherland's coefficients
scalar As_, Ts_;
// Private Member Functions
//- Calculate the Sutherland coefficients
// given two viscosities and temperatures
inline void calcCoeffs
(
const scalar mu1, const scalar T1,
const scalar mu2, const scalar T2
);
public:
// Constructors
//- Construct from components
inline sutherlandRealGasTransport
(
const Thermo& t,
const scalar As,
const scalar Ts
);
//- Construct from two viscosities
inline sutherlandRealGasTransport
(
const Thermo& t,
const scalar mu1, const scalar T1,
const scalar mu2, const scalar T2
);
//- Construct as named copy
inline sutherlandRealGasTransport(const word&, const sutherlandRealGasTransport&);
//- Construct from Istream
sutherlandRealGasTransport(Istream&);
//- Construct and return a clone
inline autoPtr<sutherlandRealGasTransport> clone() const;
// Selector from Istream
inline static autoPtr<sutherlandRealGasTransport> New(Istream& is);
// Selector from dictionary
inline static autoPtr<sutherlandRealGasTransport> New(const dictionary& dict);
// Member functions
//- Dynamic viscosity [kg/ms]
inline scalar mu(const scalar T) const;
//- Thermal conductivity [W/mK]
inline scalar kappa(const scalar rho,const scalar T) const;
//- Thermal diffusivity for enthalpy [kg/ms]
inline scalar alpha(const scalar rho,const scalar T) const;
// Member operators
inline sutherlandRealGasTransport& operator=
(
const sutherlandRealGasTransport&
);
// Friend operators
friend sutherlandRealGasTransport operator+ <Thermo>
(
const sutherlandRealGasTransport&,
const sutherlandRealGasTransport&
);
friend sutherlandRealGasTransport operator- <Thermo>
(
const sutherlandRealGasTransport&,
const sutherlandRealGasTransport&
);
friend sutherlandRealGasTransport operator* <Thermo>
(
const scalar,
const sutherlandRealGasTransport&
);
friend sutherlandRealGasTransport operator== <Thermo>
(
const sutherlandRealGasTransport&,
const sutherlandRealGasTransport&
);
// Ostream Operator
friend Ostream& operator<< <Thermo>
(
Ostream&,
const sutherlandRealGasTransport&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "sutherlandRealGasTransportI.H"
#ifdef NoRepository
# include "sutherlandRealGasTransport.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -0,0 +1,266 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "specie.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Thermo>
inline void Foam::sutherlandRealGasTransport<Thermo>::calcCoeffs
(
const scalar mu1, const scalar T1,
const scalar mu2, const scalar T2
)
{
scalar rootT1 = sqrt(T1);
scalar mu1rootT2 = mu1*sqrt(T2);
scalar mu2rootT1 = mu2*rootT1;
Ts_ = (mu2rootT1 - mu1rootT2)/(mu1rootT2/T1 - mu2rootT1/T2);
As_ = mu1*(1.0 + Ts_/T1)/rootT1;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo>::sutherlandRealGasTransport
(
const Thermo& t,
const scalar As,
const scalar Ts
)
:
Thermo(t),
As_(As),
Ts_(Ts)
{}
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo>::sutherlandRealGasTransport
(
const Thermo& t,
const scalar mu1, const scalar T1,
const scalar mu2, const scalar T2
)
:
Thermo(t)
{
calcCoeffs(mu1, T1, mu2, T2);
}
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo>::sutherlandRealGasTransport
(
const word& name,
const sutherlandRealGasTransport& st
)
:
Thermo(name, st),
As_(st.As_),
Ts_(st.Ts_)
{}
template<class Thermo>
inline Foam::autoPtr<Foam::sutherlandRealGasTransport<Thermo> >
Foam::sutherlandRealGasTransport<Thermo>::clone() const
{
return autoPtr<sutherlandRealGasTransport<Thermo> >
(
new sutherlandRealGasTransport<Thermo>(*this)
);
}
template<class Thermo>
inline Foam::autoPtr<Foam::sutherlandRealGasTransport<Thermo> >
Foam::sutherlandRealGasTransport<Thermo>::New
(
Istream& is
)
{
return autoPtr<sutherlandRealGasTransport<Thermo> >
(
new sutherlandRealGasTransport<Thermo>(is)
);
}
template<class Thermo>
inline Foam::autoPtr<Foam::sutherlandRealGasTransport<Thermo> >
Foam::sutherlandRealGasTransport<Thermo>::New
(
const dictionary& dict
)
{
return autoPtr<sutherlandRealGasTransport<Thermo> >
(
new sutherlandRealGasTransport<Thermo>(dict)
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::scalar Foam::sutherlandRealGasTransport<Thermo>::mu(const scalar T) const
{
return As_*::sqrt(T)/(1.0 + Ts_/T);
}
// CL: for real gas thermo
// Thermal conductivity [W/mK]
template<class thermo>
inline Foam::scalar Foam::sutherlandRealGasTransport<thermo>::kappa
(
const scalar rho,
const scalar T
) const
{
scalar Cv_ = this->Cv(rho,T);
return mu(T)*Cv_*(1.32 + 1.77*this->R()/Cv_);
}
// CL: for real gas thermo
// Thermal diffusivity for enthalpy [kg/ms]
template<class thermo>
inline Foam::scalar Foam::sutherlandRealGasTransport<thermo>::alpha
(
const scalar rho,
const scalar T
) const
{
scalar Cv_ = this->Cv(rho,T);
scalar Cp_ = this->Cp(rho,T);
scalar deltaT = T - specie::Tstd;
scalar CpBar =
(deltaT*(this->H(rho, T) - this->H(this->rhostd(),specie::Tstd)) + Cp_)/(sqr(deltaT) + 1);
return mu(T)*Cv_*(1.32 + 1.77*this->R()/Cv_)/CpBar;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo>&
Foam::sutherlandRealGasTransport<Thermo>::operator=
(
const sutherlandRealGasTransport<Thermo>& st
)
{
Thermo::operator=(st);
As_ = st.As_;
Ts_ = st.Ts_;
return *this;
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo> Foam::operator+
(
const sutherlandRealGasTransport<Thermo>& st1,
const sutherlandRealGasTransport<Thermo>& st2
)
{
Thermo t
(
static_cast<const Thermo&>(st1) + static_cast<const Thermo&>(st2)
);
scalar molr1 = st1.nMoles()/t.nMoles();
scalar molr2 = st2.nMoles()/t.nMoles();
return sutherlandRealGasTransport<Thermo>
(
t,
molr1*st1.As_ + molr2*st2.As_,
molr1*st1.Ts_ + molr2*st2.Ts_
);
}
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo> Foam::operator-
(
const sutherlandRealGasTransport<Thermo>& st1,
const sutherlandRealGasTransport<Thermo>& st2
)
{
Thermo t
(
static_cast<const Thermo&>(st1) - static_cast<const Thermo&>(st2)
);
scalar molr1 = st1.nMoles()/t.nMoles();
scalar molr2 = st2.nMoles()/t.nMoles();
return sutherlandRealGasTransport<Thermo>
(
t,
molr1*st1.As_ - molr2*st2.As_,
molr1*st1.Ts_ - molr2*st2.Ts_
);
}
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo> Foam::operator*
(
const scalar s,
const sutherlandRealGasTransport<Thermo>& st
)
{
return sutherlandRealGasTransport<Thermo>
(
s*static_cast<const Thermo&>(st),
st.As_,
st.Ts_
);
}
template<class Thermo>
inline Foam::sutherlandRealGasTransport<Thermo> Foam::operator==
(
const sutherlandRealGasTransport<Thermo>& st1,
const sutherlandRealGasTransport<Thermo>& st2
)
{
return st2 - st1;
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 333.15;
boundaryField
{
inlet
{
type fixedValue;
value uniform 333.15;
}
outlet
{
type zeroGradient;
}
upperWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type pressureInletVelocity;
value uniform (1 0 0);
}
outlet
{
type zeroGradient;
}
upperWall
{
type fixedValue;
value uniform (0 0 0);
}
lowerWall
{
type fixedValue;
value uniform (0 0 0);
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 1120;
boundaryField
{
inlet
{
type fixedValue;
value uniform 1120;
}
outlet
{
type inletOutlet;
inletValue uniform 1120;
value uniform 1120;
}
upperWall
{
type compressible::epsilonWallFunction;
refValue uniform 0;
value uniform 1120;
Cmu 0.09;
kappa 0.41;
E 9.8;
}
lowerWall
{
type compressible::epsilonWallFunction;
refValue uniform 0;
value uniform 1120;
Cmu 0.09;
kappa 0.41;
E 9.8;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 5;
boundaryField
{
inlet
{
type turbulentIntensityKineticEnergyInlet;
intensity 0.01;
U U;
phi phi;
value uniform 5;
}
outlet
{
type zeroGradient;
}
upperWall
{
type compressible::kqRWallFunction;
value uniform 5;
}
lowerWall
{
type compressible::kqRWallFunction;
value uniform 5;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 80e5;
boundaryField
{
inlet
{
type totalPressure;
rho rho;
psi none;
gamma 1.4;
p0 uniform 80.01e5;
value uniform 80.01e5;
}
outlet
{
type fixedValue;
value uniform 8e+06;
}
upperWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,9 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication blockMesh
runApplication `getApplication`

View file

@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object RASProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
RASModel kEpsilon;
turbulence on;
printCoeffs on;
// ************************************************************************* //

View file

@ -0,0 +1,173 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 0.001;
vertices
(
(-20.6 0 -0.5)
(-20.6 3 -0.5)
(-20.6 12.7 -0.5)
(-20.6 25.4 -0.5)
(0 -25.4 -0.5)
(0 -5 -0.5)
(0 0 -0.5)
(0 3 -0.5)
(0 12.7 -0.5)
(0 25.4 -0.5)
(206 -25.4 -0.5)
(206 -8.5 -0.5)
(206 0 -0.5)
(206 6.5 -0.5)
(206 17 -0.5)
(206 25.4 -0.5)
(290 -16.6 -0.5)
(290 -6.3 -0.5)
(290 0 -0.5)
(290 4.5 -0.5)
(290 11 -0.5)
(290 16.6 -0.5)
(-20.6 0 0.5)
(-20.6 3 0.5)
(-20.6 12.7 0.5)
(-20.6 25.4 0.5)
(0 -25.4 0.5)
(0 -5 0.5)
(0 0 0.5)
(0 3 0.5)
(0 12.7 0.5)
(0 25.4 0.5)
(206 -25.4 0.5)
(206 -8.5 0.5)
(206 0 0.5)
(206 6.5 0.5)
(206 17 0.5)
(206 25.4 0.5)
(290 -16.6 0.5)
(290 -6.3 0.5)
(290 0 0.5)
(290 4.5 0.5)
(290 11 0.5)
(290 16.6 0.5)
);
blocks
(
hex (0 6 7 1 22 28 29 23) (18 7 1) simpleGrading (0.5 1.8 1)
hex (1 7 8 2 23 29 30 24) (18 10 1) simpleGrading (0.5 4 1)
hex (2 8 9 3 24 30 31 25) (18 13 1) simpleGrading (0.5 0.25 1)
hex (4 10 11 5 26 32 33 27) (180 18 1) simpleGrading (4 1 1)
hex (5 11 12 6 27 33 34 28) (180 9 1) edgeGrading (4 4 4 4 0.5 1 1 0.5 1 1 1 1)
hex (6 12 13 7 28 34 35 29) (180 7 1) edgeGrading (4 4 4 4 1.8 1 1 1.8 1 1 1 1)
hex (7 13 14 8 29 35 36 30) (180 10 1) edgeGrading (4 4 4 4 4 1 1 4 1 1 1 1)
hex (8 14 15 9 30 36 37 31) (180 13 1) simpleGrading (4 0.25 1)
hex (10 16 17 11 32 38 39 33) (25 18 1) simpleGrading (2.5 1 1)
hex (11 17 18 12 33 39 40 34) (25 9 1) simpleGrading (2.5 1 1)
hex (12 18 19 13 34 40 41 35) (25 7 1) simpleGrading (2.5 1 1)
hex (13 19 20 14 35 41 42 36) (25 10 1) simpleGrading (2.5 1 1)
hex (14 20 21 15 36 42 43 37) (25 13 1) simpleGrading (2.5 0.25 1)
);
edges
(
);
boundary
(
inlet
{
type patch;
faces
(
(0 22 23 1)
(1 23 24 2)
(2 24 25 3)
);
}
outlet
{
type patch;
faces
(
(16 17 39 38)
(17 18 40 39)
(18 19 41 40)
(19 20 42 41)
(20 21 43 42)
);
}
upperWall
{
type wall;
faces
(
(3 25 31 9)
(9 31 37 15)
(15 37 43 21)
);
}
lowerWall
{
type wall;
faces
(
(0 6 28 22)
(6 5 27 28)
(5 4 26 27)
(4 10 32 26)
(10 16 38 32)
);
}
frontAndBack
{
type empty;
faces
(
(22 28 29 23)
(23 29 30 24)
(24 30 31 25)
(26 32 33 27)
(27 33 34 28)
(28 34 35 29)
(29 35 36 30)
(30 36 37 31)
(32 38 39 33)
(33 39 40 34)
(34 40 41 35)
(35 41 42 36)
(36 42 43 37)
(0 1 7 6)
(1 2 8 7)
(2 3 9 8)
(4 5 11 10)
(5 6 12 11)
(6 7 13 12)
(7 8 14 13)
(8 9 15 14)
(10 11 17 16)
(11 12 18 17)
(12 13 19 18)
(13 14 20 19)
(14 15 21 20)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View file

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object thermophysicalProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//CL: List of possible real gas models
thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<redlichKwong>>>>>;
mixture CO2 1 44.01 73.773e5 304.13 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116;
//thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<aungierRedlichKwong>>>>>;
//mixture CO2 1 44.01 73.773e5 304.13 0.22394 467.6 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801E-13 1.4792e-06 116;
//thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<pengRobinson>>>>>;
//mixture CO2 1 44.01 73.773e5 304.13 0.22394 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116;
//thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<soaveRedlichKwong>>>>>;
//mixture CO2 1 44.01 73.773e5 304.13 0.22394 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116;
//thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<constantHeatCapacity<redlichKwong>>>>>;
//mixture CO2 1 44.01 73.773e5 304.13 839 1.4792e-06 116;
//thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<constantHeatCapacity<aungierRedlichKwong>>>>>;
//thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<constantHeatCapacity<pengRobinson>>>>>;
//thermoType realGasHThermo<pureMixture<sutherlandRealGasTransport<realGasSpecieThermo<constantHeatCapacity<soaveRedlichKwong>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<redlichKwong>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<pengRobinson>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<aungierRedlichKwong>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<nasaHeatCapacityPolynomial<soaveRedlichKwong>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<constantHeatCapacity<redlichKwong>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<constantHeatCapacity<pengRobinson>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<constantHeatCapacity<aungierRedlichKwong>>>>>;
//thermoType realGasHThermo<pureMixture<constRealGasTransport<realGasSpecieThermo<constantHeatCapacity<soaveRedlichKwong>>>>>;
//CL: description of coefficients
// *********************************************************************************************************************** //
// Coefficient:
// CO2 --> Name
// 1
// 44.01 --> Molar Volume
// 77.773e5 --> critical pressure
// 304.13 --> critical temperatur
// 0.22394 --> acentric factor (not needed for redlich kwong)
// 467.6 --> critical density (only for aungier redlich kwong)
// 49436.5054 --> 2.849677801e-13 --> 7 heat capacity polynomial coefficent's
// .... --> two coefficent's for sutherlandRealGasTransport or for the constRealGasTransport model
// 839 --> perfect gas heat capacity Cp0 (J/kgK), needed for constantHeatCapacity
// *********************************************************************************************************************** //

View file

@ -0,0 +1,20 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType RASModel;
// ************************************************************************* //

View file

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application realFluidPisoFoam;
startFrom latestTime;
//startTime 0;
stopAt endTime;
endTime 0.5;
deltaT 1e-5;
writeControl runTime;
writeInterval 0.1;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression uncompressed;
timeFormat general;
timePrecision 10;
adjustTimeStep yes;
maxCo 0.5;
maxDeltaT 1e-2;
runTimeModifiable yes;
// ************************************************************************* //

View file

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
grad(p) Gauss linear;
}
divSchemes
{
default Gauss linear;
div(phi,U) Gauss limitedLinearV 1;
div(phid,p) Gauss limitedLinear 1;
div(phiU,p) Gauss linear;
div(phi,h) Gauss limitedLinear 1;
div(phi,k) Gauss limitedLinear 1;
div(phi,epsilon) Gauss limitedLinear 1;
div(phi,R) Gauss limitedLinear 1;
div(phi,omega) Gauss limitedLinear 1;
div((rho*R)) Gauss linear;
div(R) Gauss linear;
div(U) Gauss linear;
div((muEff*dev2(grad(U).T()))) Gauss linear;
}
laplacianSchemes
{
default none;
laplacian(muEff,U) Gauss linear corrected;
laplacian(mut,U) Gauss linear corrected;
laplacian(DkEff,k) Gauss linear corrected;
laplacian(DepsilonEff,epsilon) Gauss linear corrected;
laplacian(DREff,R) Gauss linear corrected;
laplacian(DomegaEff,omega) Gauss linear corrected;
laplacian((rho*(1|A(U))),p) Gauss linear corrected;
laplacian(alphaEff,h) Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
fluxRequired
{
default no;
p ;
}
// ************************************************************************* //

View file

@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
p
{
solver GAMG;
tolerance 1e-14;
relTol 0.001;
smoother GaussSeidel;
minIter 4;
//maxIter 100;
cacheAgglomeration true;
nPreSweeps 1;
nPostSweeps 3;
nFinestSweeps 3;
nCellsInCoarsestLevel 20;
agglomerator faceAreaPair;
mergeLevels 1;
}
U
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-14;
relTol 0.001;
}
rho
{
solver PCG;
preconditioner DIC;
tolerance 1e-10;
relTol 0;
}
htot
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-14;
relTol 0.001;
}
h
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-14;
relTol 0.001;
}
k
{
solver PBiCG;
preconditioner DILU;
tolerance 1e-10;
relTol 0;
}
epsilon
{
solver PBiCG;
preconditioner DILU;
tolerance 1e-10;
relTol 0;
}
}
PISO
{
nNonOrthogonalCorrectors 0;
nCorrectors 2;
momentumPredictor yes;
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 500;
boundaryField
{
inlet
{
type fixedValue;
value uniform 500;
}
outlet
{
type zeroGradient;
}
upperWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type fixedValue;
value uniform (1 0 0);
}
outlet
{
type zeroGradient;
}
upperWall
{
type fixedValue;
value uniform (0 0 0);
}
lowerWall
{
type fixedValue;
value uniform (0 0 0);
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 1120;
boundaryField
{
upperWall
{
type compressible::epsilonWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 1120;
}
lowerWall
{
type compressible::epsilonWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 1120;
}
inlet
{
type fixedValue;
value uniform 1120;
}
outlet
{
type inletOutlet;
inletValue uniform 1120;
value uniform 1120;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 5;
boundaryField
{
upperWall
{
type compressible::kqRWallFunction;
value uniform 5;
}
lowerWall
{
type compressible::kqRWallFunction;
value uniform 5;
}
inlet
{
type turbulentIntensityKineticEnergyInlet;
intensity 0.01;
U U;
phi phi;
value uniform 5;
}
outlet
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 10e5;
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type fixedValue;
value uniform 1e+06;
}
upperWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 500;
boundaryField
{
inlet
{
type fixedValue;
value uniform 500;
}
outlet
{
type zeroGradient;
}
upperWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
inlet
{
type fixedValue;
value uniform (1 0 0);
}
outlet
{
type zeroGradient;
}
upperWall
{
type fixedValue;
value uniform (0 0 0);
}
lowerWall
{
type fixedValue;
value uniform (0 0 0);
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 1120;
boundaryField
{
upperWall
{
type compressible::epsilonWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 1120;
}
lowerWall
{
type compressible::epsilonWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 1120;
}
inlet
{
type fixedValue;
value uniform 1120;
}
outlet
{
type inletOutlet;
inletValue uniform 1120;
value uniform 1120;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 5;
boundaryField
{
upperWall
{
type compressible::kqRWallFunction;
value uniform 5;
}
lowerWall
{
type compressible::kqRWallFunction;
value uniform 5;
}
inlet
{
type turbulentIntensityKineticEnergyInlet;
intensity 0.01;
U U;
phi phi;
value uniform 5;
}
outlet
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 10e5;
boundaryField
{
inlet
{
type zeroGradient;
}
outlet
{
type fixedValue;
value uniform 1e+06;
}
upperWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,9 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication blockMesh
runApplication `getApplication`

View file

@ -0,0 +1,48 @@
This tutorial is to show how the IAPWSThermo work in foam
//***********************INFORMATION TO TEST CASE*******************************//
Important files in this case:
1. thermophysicalProperties
--> see thermotype
2. controlDict:
the dynamic libraries used for the IAPWS 97 water properties are not directly link into foam.
Therefore, the dynamic libraries need to be defined in controlDict
//************************NEW CODE NEEDED FOR THIS CASE*************************//
1. Code in foam: $WM_PROJECT_DIR/src/thermophysicalModels/externalMedia/
just run wmake libso in the folder
2. FreeSteam: download the code @ http://freesteam.sourceforge.net/example.php
//***********************Problems*******************************//
If problems occur using the IAPWS 97 water properties, please check the following points
1. have you successfully compiled freeSteam?
a: If no, have you installed gsl, scons and so on (see README.txt in the freeSteam)
b: If yes, is the libfreesteam.so in a folder where foam finds it e.g. $WM_PROJECT_DIR/lib/...
2. have you compiled the thermophysical models that connect freeSteam to foam. They can be found in this folder: $WM_PROJECT_DIR/src/
thermophysicalModels/externalMedia/
3. IS THE SOLVER STARTING TO RUN THE CASE? NO
check b23.c file at line 39 (or at least somewhere in the code:
if you find the following code:
return B23_N[4] + sqrt((pi - B23_N[5])/B23_N[3]) /* * 1{K} */;
change it to this:
return B23_N[4] + sqrt(fabs(pi - B23_N[5])/B23_N[3]) /* * 1{K} */;

View file

@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object RASProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
RASModel kEpsilon;
turbulence on;
printCoeffs on;
// ************************************************************************* //

View file

@ -0,0 +1,173 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 0.001;
vertices
(
(-20.6 0 -0.5)
(-20.6 3 -0.5)
(-20.6 12.7 -0.5)
(-20.6 25.4 -0.5)
(0 -25.4 -0.5)
(0 -5 -0.5)
(0 0 -0.5)
(0 3 -0.5)
(0 12.7 -0.5)
(0 25.4 -0.5)
(206 -25.4 -0.5)
(206 -8.5 -0.5)
(206 0 -0.5)
(206 6.5 -0.5)
(206 17 -0.5)
(206 25.4 -0.5)
(290 -16.6 -0.5)
(290 -6.3 -0.5)
(290 0 -0.5)
(290 4.5 -0.5)
(290 11 -0.5)
(290 16.6 -0.5)
(-20.6 0 0.5)
(-20.6 3 0.5)
(-20.6 12.7 0.5)
(-20.6 25.4 0.5)
(0 -25.4 0.5)
(0 -5 0.5)
(0 0 0.5)
(0 3 0.5)
(0 12.7 0.5)
(0 25.4 0.5)
(206 -25.4 0.5)
(206 -8.5 0.5)
(206 0 0.5)
(206 6.5 0.5)
(206 17 0.5)
(206 25.4 0.5)
(290 -16.6 0.5)
(290 -6.3 0.5)
(290 0 0.5)
(290 4.5 0.5)
(290 11 0.5)
(290 16.6 0.5)
);
blocks
(
hex (0 6 7 1 22 28 29 23) (18 7 1) simpleGrading (0.5 1.8 1)
hex (1 7 8 2 23 29 30 24) (18 10 1) simpleGrading (0.5 4 1)
hex (2 8 9 3 24 30 31 25) (18 13 1) simpleGrading (0.5 0.25 1)
hex (4 10 11 5 26 32 33 27) (180 18 1) simpleGrading (4 1 1)
hex (5 11 12 6 27 33 34 28) (180 9 1) edgeGrading (4 4 4 4 0.5 1 1 0.5 1 1 1 1)
hex (6 12 13 7 28 34 35 29) (180 7 1) edgeGrading (4 4 4 4 1.8 1 1 1.8 1 1 1 1)
hex (7 13 14 8 29 35 36 30) (180 10 1) edgeGrading (4 4 4 4 4 1 1 4 1 1 1 1)
hex (8 14 15 9 30 36 37 31) (180 13 1) simpleGrading (4 0.25 1)
hex (10 16 17 11 32 38 39 33) (25 18 1) simpleGrading (2.5 1 1)
hex (11 17 18 12 33 39 40 34) (25 9 1) simpleGrading (2.5 1 1)
hex (12 18 19 13 34 40 41 35) (25 7 1) simpleGrading (2.5 1 1)
hex (13 19 20 14 35 41 42 36) (25 10 1) simpleGrading (2.5 1 1)
hex (14 20 21 15 36 42 43 37) (25 13 1) simpleGrading (2.5 0.25 1)
);
edges
(
);
boundary
(
inlet
{
type patch;
faces
(
(0 22 23 1)
(1 23 24 2)
(2 24 25 3)
);
}
outlet
{
type patch;
faces
(
(16 17 39 38)
(17 18 40 39)
(18 19 41 40)
(19 20 42 41)
(20 21 43 42)
);
}
upperWall
{
type wall;
faces
(
(3 25 31 9)
(9 31 37 15)
(15 37 43 21)
);
}
lowerWall
{
type wall;
faces
(
(0 6 28 22)
(6 5 27 28)
(5 4 26 27)
(4 10 32 26)
(10 16 38 32)
);
}
frontAndBack
{
type empty;
faces
(
(22 28 29 23)
(23 29 30 24)
(24 30 31 25)
(26 32 33 27)
(27 33 34 28)
(28 34 35 29)
(29 35 36 30)
(30 36 37 31)
(32 38 39 33)
(33 39 40 34)
(34 40 41 35)
(35 41 42 36)
(36 42 43 37)
(0 1 7 6)
(1 2 8 7)
(2 3 9 8)
(4 5 11 10)
(5 6 12 11)
(6 7 13 12)
(7 8 14 13)
(8 9 15 14)
(10 11 17 16)
(11 12 18 17)
(12 13 19 18)
(13 14 20 19)
(14 15 21 20)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View file

@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class polyBoundaryMesh;
location "constant/polyMesh";
object boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
5
(
inlet
{
type patch;
nFaces 30;
startFace 24170;
}
outlet
{
type patch;
nFaces 57;
startFace 24200;
}
upperWall
{
type wall;
nFaces 223;
startFace 24257;
}
lowerWall
{
type wall;
nFaces 250;
startFace 24480;
}
frontAndBack
{
type empty;
nFaces 24450;
startFace 24730;
}
)
// ************************************************************************* //

View file

@ -0,0 +1,23 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object thermophysicalProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//CL: this is all
thermoType IAPWSThermo;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -0,0 +1,21 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType RASModel;
// ************************************************************************* //

View file

@ -0,0 +1,61 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 1.6 |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application realFluidPisoFoam;
startFrom latestTime;
//startTime 0;
stopAt endTime;
endTime 0.5;
deltaT 1e-5;
writeControl runTime;
writeInterval 1e-1;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression uncompressed;
timeFormat general;
timePrecision 10;
adjustTimeStep yes;
maxCo 0.75;
maxDeltaT 0.01;
runTimeModifiable yes;
libs
(
"libIAPWSThermo.so"
"libfreesteam.so"
);
// ************************************************************************* //

View file

@ -0,0 +1,75 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
grad(p) Gauss linear;
}
divSchemes
{
default Gauss linear;
div(phi,U) Gauss limitedLinearV 1;
div(phid,p) Gauss limitedLinear 1;
div(phiU,p) Gauss linear;
div(phi,h) Gauss limitedLinear 1;
div(phi,k) Gauss limitedLinear 1;
div(phi,epsilon) Gauss limitedLinear 1;
div(phi,R) Gauss limitedLinear 1;
div(phi,omega) Gauss limitedLinear 1;
div((rho*R)) Gauss linear;
div(R) Gauss linear;
div(U) Gauss linear;
div((muEff*dev2(grad(U).T()))) Gauss linear;
}
laplacianSchemes
{
default none;
laplacian(muEff,U) Gauss linear corrected;
laplacian(mut,U) Gauss linear corrected;
laplacian(DkEff,k) Gauss linear corrected;
laplacian(DepsilonEff,epsilon) Gauss linear corrected;
laplacian(DREff,R) Gauss linear corrected;
laplacian(DomegaEff,omega) Gauss linear corrected;
laplacian((rho*(1|A(U))),p) Gauss linear corrected;
laplacian(alphaEff,h) Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
fluxRequired
{
default no;
p ;
}
// ************************************************************************* //

View file

@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
p
{
solver GAMG;
tolerance 1e-14;
relTol 0.001;
smoother GaussSeidel;
minIter 4;
//maxIter 100;
cacheAgglomeration true;
nPreSweeps 1;
nPostSweeps 3;
nFinestSweeps 3;
nCellsInCoarsestLevel 20;
agglomerator faceAreaPair;
mergeLevels 1;
}
U
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-14;
relTol 0.001;
}
rho
{
solver PCG;
preconditioner DIC;
tolerance 1e-10;
relTol 0;
}
htot
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-14;
relTol 0.001;
}
h
{
solver smoothSolver;
smoother GaussSeidel;
nSweeps 2;
tolerance 1e-14;
relTol 0.001;
}
k
{
solver PBiCG;
preconditioner DILU;
tolerance 1e-10;
relTol 0;
}
epsilon
{
solver PBiCG;
preconditioner DILU;
tolerance 1e-10;
relTol 0;
}
}
PISO
{
nNonOrthogonalCorrectors 0;
nCorrectors 2;
momentumPredictor yes;
}
// ************************************************************************* //

View file

@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 300;
boundaryField
{
movingWall
{
type zeroGradient;
}
fixedWalls
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
movingWall
{
type fixedValue;
// Field Value
value uniform (1 0 0);
}
fixedWalls
{
type fixedValue;
// Field Value
value uniform (0 0 0);
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | foam-extend: Open Source CFD |
| \\ / O peration | Version: 3.1 |
| \\ / A nd | Web: http://www.extend-project.de |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 0.000765;
boundaryField
{
movingWall
{
type compressible::epsilonWallFunction;
refValue uniform 0;
value uniform 0.000765;
Cmu 0.09;
kappa 0.41;
E 9.8;
}
fixedWalls
{
type compressible::epsilonWallFunction;
refValue uniform 0;
value uniform 0.000765;
Cmu 0.09;
kappa 0.41;
E 9.8;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,41 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | foam-extend: Open Source CFD |
| \\ / O peration | Version: 3.1 |
| \\ / A nd | Web: http://www.extend-project.de |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0.00325;
boundaryField
{
movingWall
{
type compressible::kqRWallFunction;
value uniform 0.00325;
}
fixedWalls
{
type compressible::kqRWallFunction;
value uniform 0.00325;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 100000;
boundaryField
{
movingWall
{
type zeroGradient;
}
fixedWalls
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 300;
boundaryField
{
movingWall
{
type zeroGradient;
}
fixedWalls
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
movingWall
{
type fixedValue;
// Field Value
value uniform (1 0 0);
}
fixedWalls
{
type fixedValue;
// Field Value
value uniform (0 0 0);
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,49 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | foam-extend: Open Source CFD |
| \\ / O peration | Version: 3.1 |
| \\ / A nd | Web: http://www.extend-project.de |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 0.000765;
boundaryField
{
movingWall
{
type compressible::epsilonWallFunction;
refValue uniform 0;
value uniform 0.000765;
Cmu 0.09;
kappa 0.41;
E 9.8;
}
fixedWalls
{
type compressible::epsilonWallFunction;
refValue uniform 0;
value uniform 0.000765;
Cmu 0.09;
kappa 0.41;
E 9.8;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,41 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | foam-extend: Open Source CFD |
| \\ / O peration | Version: 3.1 |
| \\ / A nd | Web: http://www.extend-project.de |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0.00325;
boundaryField
{
movingWall
{
type compressible::kqRWallFunction;
value uniform 0.00325;
}
fixedWalls
{
type compressible::kqRWallFunction;
value uniform 0.00325;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration |
\\ / A nd | For copyright notice see file Copyright
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 100000;
boundaryField
{
movingWall
{
type zeroGradient;
}
fixedWalls
{
type zeroGradient;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View file

@ -0,0 +1,9 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication blockMesh
runApplication `getApplication`

Some files were not shown because too many files have changed in this diff Show more