internal energy for real gas

This commit is contained in:
Christian Lucas 2012-05-29 09:22:35 +02:00 committed by Henrik Rusche
parent f3aad56998
commit d0a3f80184
3 changed files with 854 additions and 0 deletions

View file

@ -0,0 +1,506 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ 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
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)
:
basicPsiThermo(mesh),
MixtureType(*this, mesh),
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,205 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | .
\\/ 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
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&);
//- 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,143 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\/ 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
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 "sutherlandTransport.H"
#include "pureMixture.H"
#include "realGasEThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/* * * * * * * * * * * * * * * private static data * * * * * * * * * * * * * */
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
sutherlandTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
pengRobinson
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
aungierRedlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
redlichKwong
);
makeBasicRealGasThermo
(
realGasEThermo,
pureMixture,
constTransport,
realGasSpecieThermo,
nasaHeatCapacityPolynomial,
soaveRedlichKwong
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //