Merge fully integrated real gas thermo. Author: Christian Lucas. Merge: Henrik Rusche
This commit is contained in:
commit
235d99bd8e
171 changed files with 19913 additions and 18 deletions
63
README_RealGasBranch
Normal file
63
README_RealGasBranch
Normal file
|
@ -0,0 +1,63 @@
|
|||
Features
|
||||
|
||||
|
||||
/*************************************Libraries**************************************************/
|
||||
|
||||
1. Included cubic equations of state for pure fluid.
|
||||
--> Redlich Kwong --> class = redlichKwong
|
||||
--> Peng Robinson --> class = pengRobinson
|
||||
--> Soave Redlich Kwong --> class = soaveRedlichKwong
|
||||
--> Aungier Redlich Kwong --> class = aungierRedlichKwong
|
||||
|
||||
2. Included cubic equations of state for mixtures.
|
||||
TODO: connect the classes to the reaction models
|
||||
-->class = mixtureRedlichKwong
|
||||
-->class = mixturePengRobinson
|
||||
-->class = mixtureSoaveRedlichKwong
|
||||
-->class = aungierSoaveRedlichKwong
|
||||
|
||||
3. Included a new Thermo model
|
||||
--> enthalpy calculated using NASA heat capacity polynomical
|
||||
Added real gas correction in class
|
||||
class = nasaHeatCapacityPolynomial
|
||||
|
||||
4. Minor changed in thermo related models so that they can be used with real gas classes
|
||||
--> class = realGasSpecieThermo
|
||||
--> class = sutherland
|
||||
--> class = const
|
||||
--> class = basicMixture
|
||||
--> class = basicPsiThermo
|
||||
|
||||
5. Added enthalpy and internal energy thermodynamic class based on basicPsiThermo for real gases
|
||||
--> enthalpy based thermo model, class = realGasHThermo
|
||||
--> internal energy based thermo model, class = realGasEThermo
|
||||
|
||||
6. Added high precision water properties (IAPWS97) based on freeSteam (external program, not included)
|
||||
Classes will not be compiled by Allwmake file
|
||||
Classes will compile without freeSteam. Freesteam is loaded at runTime (see Tutorial)
|
||||
--> classes = externalMedia/IAPWS_Waterproperties
|
||||
|
||||
/*************************************Solver**************************************************/
|
||||
|
||||
1. Changed pressure equation of rhoPisoFoam. Orginal pressure equation assumes perfect gas
|
||||
(linear relationship between pressure and density)
|
||||
--> new solver = realFluidPisoFoam
|
||||
|
||||
/*************************************Tutorials**************************************************/
|
||||
|
||||
1. pure fluid real gas mixture tutorial
|
||||
--> realFluidPisoFoam/ras/backStep
|
||||
|
||||
2. IAPWS97 water properties tutorial
|
||||
freeSteam must be installed for this tutorial
|
||||
additional classes loaded in controlDict
|
||||
--> realFluidPisoFoam/ras/cavity_IAPWS97
|
||||
|
||||
|
||||
/*************************************Change log**************************************************/
|
||||
|
||||
git commit: "add branch ReadMe file"
|
||||
--> added this file
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
realFluidPisoFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/realFluidPisoFoam
|
|
@ -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
|
11
applications/solvers/compressible/realFluidPisoFoam/UEqn.H
Normal file
11
applications/solvers/compressible/realFluidPisoFoam/UEqn.H
Normal file
|
@ -0,0 +1,11 @@
|
|||
fvVectorMatrix UEqn
|
||||
(
|
||||
fvm::ddt(rho, U)
|
||||
+ fvm::div(phi, U)
|
||||
+ turbulence->divDevRhoReff(U)
|
||||
);
|
||||
|
||||
if (piso.momentumPredictor())
|
||||
{
|
||||
solve(UEqn == -fvc::grad(p));
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
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);
|
||||
|
||||
mesh.schemesDict().setFluxRequired(p.name());
|
12
applications/solvers/compressible/realFluidPisoFoam/hEqn.H
Normal file
12
applications/solvers/compressible/realFluidPisoFoam/hEqn.H
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
solve
|
||||
(
|
||||
fvm::ddt(rho, h)
|
||||
+ fvm::div(phi, h)
|
||||
- fvm::laplacian(turbulence->alphaEff(), h)
|
||||
==
|
||||
DpDt
|
||||
);
|
||||
|
||||
thermo.correct();
|
||||
}
|
37
applications/solvers/compressible/realFluidPisoFoam/pEqn.H
Normal file
37
applications/solvers/compressible/realFluidPisoFoam/pEqn.H
Normal 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)
|
||||
);
|
||||
|
||||
while (piso.correctNonOrthogonal())
|
||||
{
|
||||
fvScalarMatrix pEqn
|
||||
(
|
||||
psi*fvm::ddt(p)
|
||||
+ drhodh*fvc::ddt(h)
|
||||
+ fvc::div(phi)
|
||||
- fvm::laplacian(rho*rUA, p)
|
||||
);
|
||||
|
||||
pEqn.solve();
|
||||
|
||||
if (piso.finalNonOrthogonalIter())
|
||||
{
|
||||
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);
|
|
@ -0,0 +1,100 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
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"
|
||||
#include "pisoControl.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
|
||||
pisoControl piso(mesh);
|
||||
|
||||
#include "createFields.H"
|
||||
#include "initContinuityErrs.H"
|
||||
#include "createTimeControls.H"
|
||||
#include "compressibleCourantNo.H"
|
||||
#include "setInitialDeltaT.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
while (runTime.run())
|
||||
{
|
||||
#include "readTimeControls.H"
|
||||
#include "compressibleCourantNo.H"
|
||||
#include "setDeltaT.H"
|
||||
|
||||
runTime++;
|
||||
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
#include "rhoEqn.H"
|
||||
#include "UEqn.H"
|
||||
|
||||
// --- PISO loop
|
||||
while (piso.correct())
|
||||
{
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,599 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Author
|
||||
Christian Lucas
|
||||
Institut für Thermodynamik
|
||||
Technische Universität Braunschweig
|
||||
Germany
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "IAPWS-IF97.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,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)+cpl/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 kappa,cp,beta,psiH,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,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)+cpl/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;
|
||||
|
||||
//Keep compiler happy
|
||||
psiH = 0;
|
||||
}
|
||||
|
||||
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 cp,beta,drhodh,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;
|
||||
|
||||
// Keep compiler happy
|
||||
drhodh = 0;
|
||||
}
|
||||
|
||||
return drhodh;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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"
|
||||
|
||||
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_
|
477
src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermo.C
Executable file
477
src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermo.C
Executable file
|
@ -0,0 +1,477 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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(),
|
||||
obj,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionSet(0, 2, -2, 0, 0),
|
||||
this->hBoundaryTypes()
|
||||
),
|
||||
|
||||
rho_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"rhoThermo",
|
||||
mesh.time().timeName(),
|
||||
obj,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimDensity
|
||||
),
|
||||
|
||||
drhodh_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"drhodh",
|
||||
mesh.time().timeName(),
|
||||
obj,
|
||||
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(),
|
||||
this->T_.db(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionSet(0, 2, -2, -1, 0)
|
||||
)
|
||||
);
|
||||
|
||||
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(),
|
||||
this->T_.db(),
|
||||
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(),
|
||||
this->T_.db(),
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
201
src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermo.H
Executable file
201
src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermo.H
Executable file
|
@ -0,0 +1,201 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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();
|
||||
|
||||
//- Construct as copy (not implemented)
|
||||
IAPWSThermo(const IAPWSThermo&);
|
||||
|
||||
|
||||
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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,53 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
Author
|
||||
Christian Lucas
|
||||
Institut für Thermodynamik
|
||||
Technische Universität Braunschweig
|
||||
Germany
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "makeBasicPsiThermo.H"
|
||||
#include "IAPWSThermo.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/* * * * * * * * * * * * * * * private static data * * * * * * * * * * * * * */
|
||||
|
||||
makeBasicExternalLibraryBasedThermo
|
||||
(
|
||||
IAPWSThermo
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,135 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
|
||||
Description:
|
||||
|
||||
Includes the definition of a struct from freestream
|
||||
Code copied from freestream --> steam.h
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
//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);
|
||||
|
|
@ -8,12 +8,17 @@ 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
|
||||
rhoThermo/hRhoThermo/hRhoThermos.C
|
||||
rhoThermo/hsRhoThermo/hsRhoThermos.C
|
||||
|
||||
IAPWS_Waterproperties/IAPWSThermo/IAPWS-IF97.C
|
||||
IAPWS_Waterproperties/IAPWSThermo/IAPWSThermos.C
|
||||
|
||||
derivedFvPatchFields/fixedEnthalpy/fixedEnthalpyFvPatchScalarField.C
|
||||
derivedFvPatchFields/gradientEnthalpy/gradientEnthalpyFvPatchScalarField.C
|
||||
derivedFvPatchFields/mixedEnthalpy/mixedEnthalpyFvPatchScalarField.C
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude
|
||||
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
|
||||
-I$(LIB_SRC)/thermophysicalModels/thermophysicalFunctions/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
-lspecie \
|
||||
-lthermophysicalFunctions \
|
||||
-lfiniteVolume
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | foam-extend: Open Source CFD
|
||||
\\ / O peration | Version: 3.2
|
||||
\\ / A nd | Web: http://www.foam-extend.org
|
||||
\\/ M anipulation | For copyright notice see file Copyright
|
||||
\\ / 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 foam-extend.
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
foam-extend is free software: you can redistribute it and/or modify it
|
||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
Free Software Foundation; either version 2 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.
|
||||
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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
Mixture instantiation
|
||||
|
@ -32,12 +33,19 @@ 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"
|
||||
|
@ -101,6 +109,150 @@ makeBasicMixturePhys
|
|||
icoPoly8ThermoPhysics
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealFluidMixture
|
||||
(
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
|
|
@ -56,6 +56,26 @@ defineTemplateTypeNameAndDebugWithName \
|
|||
0 \
|
||||
);
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#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)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | foam-extend: Open Source CFD
|
||||
\\ / O peration | Version: 3.2
|
||||
\\ / A nd | Web: http://www.foam-extend.org
|
||||
\\/ M anipulation | For copyright notice see file Copyright
|
||||
\\ / O peration |
|
||||
\\ / A nd | For copyright notice see file Copyright
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of foam-extend.
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -58,6 +58,46 @@ 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 \
|
||||
)
|
||||
|
||||
#define makeBasicExternalLibraryBasedThermo(Cthermo) \
|
||||
\
|
||||
typedef Cthermo \
|
||||
Cthermo; \
|
||||
\
|
||||
defineTypeNameAndDebug \
|
||||
( \
|
||||
Cthermo, \
|
||||
0 \
|
||||
); \
|
||||
\
|
||||
addToRunTimeSelectionTable \
|
||||
( \
|
||||
basicPsiThermo, \
|
||||
Cthermo, \
|
||||
fvMesh \
|
||||
)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
|
|
@ -111,7 +111,7 @@ Foam::hPsiThermo<MixtureType>::hPsiThermo
|
|||
(
|
||||
"h",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
obj,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
|
|
505
src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.C
Executable file
505
src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.C
Executable file
|
@ -0,0 +1,505 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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,
|
||||
const objectRegistry& obj
|
||||
)
|
||||
:
|
||||
basicPsiThermo(mesh, obj),
|
||||
MixtureType(*this, mesh, obj),
|
||||
|
||||
e_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"e",
|
||||
mesh.time().timeName(),
|
||||
obj,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionSet(0, 2, -2, 0, 0),
|
||||
this->eBoundaryTypes()
|
||||
),
|
||||
rho_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"rhoThermo",
|
||||
mesh.time().timeName(),
|
||||
obj,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimDensity
|
||||
),
|
||||
drhode_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"drhode",
|
||||
mesh.time().timeName(),
|
||||
obj,
|
||||
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);
|
||||
}
|
||||
|
||||
this->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(),
|
||||
T_.db(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionSet(0, 2, -2, -1, 0)
|
||||
)
|
||||
);
|
||||
|
||||
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(),
|
||||
T_.db(),
|
||||
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(),
|
||||
T_.db(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
205
src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.H
Executable file
205
src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.H
Executable 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_;
|
||||
|
||||
//- Density field
|
||||
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 and object registry
|
||||
realGasEThermo(const fvMesh&, const objectRegistry&);
|
||||
|
||||
//- 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
|
||||
|
||||
//- Internal energy [J/kg]
|
||||
// Non-const access allowed for transport equations
|
||||
virtual volScalarField& e()
|
||||
{
|
||||
return e_;
|
||||
}
|
||||
|
||||
//- Internal energy [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
|
||||
|
||||
//- Internal energy for cell-set [J/kg]
|
||||
virtual tmp<scalarField> e
|
||||
(
|
||||
const scalarField& T,
|
||||
const labelList& cells
|
||||
) const;
|
||||
|
||||
//- Internal energy 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
|
||||
|
||||
// ************************************************************************* //
|
221
src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermos.C
Executable file
221
src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermos.C
Executable file
|
@ -0,0 +1,221 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "constantHeatCapacity.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
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasEThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
505
src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.C
Executable file
505
src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.C
Executable file
|
@ -0,0 +1,505 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "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(),
|
||||
obj,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionSet(0, 2, -2, 0, 0),
|
||||
this->hBoundaryTypes()
|
||||
),
|
||||
rho_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"rhoThermo",
|
||||
mesh.time().timeName(),
|
||||
obj,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimDensity
|
||||
),
|
||||
drhodh_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"drhodh",
|
||||
mesh.time().timeName(),
|
||||
obj,
|
||||
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(),
|
||||
this->T_.db(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionSet(0, 2, -2, -1, 0)
|
||||
)
|
||||
);
|
||||
|
||||
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(),
|
||||
this->T_.db(),
|
||||
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(),
|
||||
this->T_.db(),
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
205
src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.H
Executable file
205
src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.H
Executable 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::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
|
||||
|
||||
// ************************************************************************* //
|
221
src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermos.C
Executable file
221
src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermos.C
Executable file
|
@ -0,0 +1,221 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "constantHeatCapacity.H"
|
||||
#include "pureMixture.H"
|
||||
#include "realGasHThermo.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/* * * * * * * * * * * * * * * private static data * * * * * * * * * * * * * */
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
nasaHeatCapacityPolynomial,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
sutherlandTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
pengRobinson
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
aungierRedlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
redlichKwong
|
||||
);
|
||||
|
||||
makeBasicRealGasThermo
|
||||
(
|
||||
realGasHThermo,
|
||||
pureMixture,
|
||||
constTransport,
|
||||
realGasSpecieThermo,
|
||||
constantHeatCapacity,
|
||||
soaveRedlichKwong
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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)),
|
||||
rhocrit_(readScalar(is)),
|
||||
azentricFactor_(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_(b_*b_),
|
||||
b3_(b2_*b_),
|
||||
b4_(b3_*b_),
|
||||
b5_(b4_*b_),
|
||||
c2_(c_*c_),
|
||||
//CL: Only uses the default values
|
||||
rhoMin_(1e-3),
|
||||
rhoMax_(1500),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R()))),
|
||||
aSave(0.0),
|
||||
daSave(0.0),
|
||||
d2aSave(0.0),
|
||||
TSave(0.0)
|
||||
{
|
||||
is.check("aungierRedlichKwong::aungierRedlichKwong(Istream& is)");
|
||||
}
|
||||
|
||||
//CL: Constructed needed in OpenFOAM 2.x.x
|
||||
//CL: Code works fine, but compiling problem in OpenFOAM 1.6.ext
|
||||
//CL: because specie has no constructor using dict
|
||||
/*
|
||||
Foam::aungierRedlichKwong::aungierRedlichKwong(const dictionary& dict)
|
||||
:
|
||||
specie(dict),
|
||||
pcrit_(readScalar(dict.subDict("equationOfState").lookup("pCritical"))),
|
||||
Tcrit_(readScalar(dict.subDict("equationOfState").lookup("TCritical"))),
|
||||
rhocrit_(readScalar(dict.subDict("equationOfState").lookup("rhoCritical"))),
|
||||
azentricFactor_(readScalar(dict.subDict("equationOfState").lookup("azentricFactor"))),
|
||||
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_(b_*b_),
|
||||
b3_(b2_*b_),
|
||||
b4_(b3_*b_),
|
||||
b5_(b4_*b_),
|
||||
c2_(pow(c_,2)),
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection method (see rho function)
|
||||
//CL: important: rhoMin and rhoMax are not used as boundary for the newton solver
|
||||
//CL: therefore, rho can be larger than rhoMax and smaller than rhoMin
|
||||
rhoMin_(dict.subDict("equationOfState").lookupOrDefault("rhoMin",1e-3)),
|
||||
rhoMax_(dict.subDict("equationOfState").lookupOrDefault("rhoMax",1500)),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R()))),
|
||||
aSave(0.0),
|
||||
daSave(0.0),
|
||||
d2aSave(0.0),
|
||||
TSave(0.0)
|
||||
{
|
||||
is.check("aungierRedlichKwong::aungierRedlichKwong(Istream& is)");
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::aungierRedlichKwong::write(Ostream& os) const
|
||||
{
|
||||
specie::write(os);
|
||||
|
||||
dictionary dict("equationOfState");
|
||||
dict.add("pCritical", pcrit_);
|
||||
dict.add("TCritical", Tcrit_);
|
||||
dict.add("azentricFactor", azentricFactor_);
|
||||
dict.add("rhoCritical", rhocrit_);
|
||||
dict.add("rhoMin", rhoMin_);
|
||||
dict.add("rhoMax", rhoMax_);
|
||||
|
||||
os << indent << dict.dictName() << dict;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,285 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class aungierRedlichKwong Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class aungierRedlichKwong
|
||||
:
|
||||
public specie
|
||||
{
|
||||
// private data
|
||||
//CL: data at critical point
|
||||
scalar pcrit_;
|
||||
scalar Tcrit_;
|
||||
scalar rhocrit_;
|
||||
scalar azentricFactor_;
|
||||
|
||||
//Aungier Redlich Kwong factors
|
||||
scalar a0_;
|
||||
scalar b_;
|
||||
scalar c_;
|
||||
scalar n_;
|
||||
|
||||
//CL: pow of constants (b_, c_) used in the code e.g. b2_=b*b;
|
||||
scalar b2_;
|
||||
scalar b3_;
|
||||
scalar b4_;
|
||||
scalar b5_;
|
||||
scalar c2_;
|
||||
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
|
||||
scalar rhoMin_;
|
||||
scalar rhoMax_;
|
||||
|
||||
//- Density @STD, initialise after a0, b, c, n!
|
||||
scalar rhostd_;
|
||||
|
||||
//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 from dictionary
|
||||
//aungierRedlichKwong(const dictionary& dict);
|
||||
|
||||
//- 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
|
||||
|
||||
//Return Aungier Redlich Kwong factors
|
||||
inline scalar a0() const;
|
||||
|
||||
inline scalar b() const;
|
||||
|
||||
inline scalar c() const;
|
||||
|
||||
inline scalar n() const;
|
||||
|
||||
inline scalar rhostd() const;
|
||||
|
||||
inline scalar rhoMin() const;
|
||||
|
||||
inline scalar rhoMax() const;
|
||||
|
||||
inline scalar Tcrit() const;
|
||||
|
||||
inline scalar pcrit() const;
|
||||
|
||||
inline scalar rhocrit() const;
|
||||
|
||||
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;
|
||||
|
||||
//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;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write to Ostream
|
||||
//void write(Ostream& os) const;
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
inline void operator+=(const aungierRedlichKwong&);
|
||||
|
||||
inline void operator*=(const scalar);
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,574 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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),
|
||||
TSave(0)
|
||||
{}
|
||||
|
||||
|
||||
// Construct as named copy
|
||||
inline aungierRedlichKwong::aungierRedlichKwong(const word& name, const aungierRedlichKwong& pg)
|
||||
:
|
||||
specie(name, pg),
|
||||
pcrit_(pg.pcrit_),
|
||||
Tcrit_(pg.Tcrit_),
|
||||
rhocrit_(pg.rhocrit_),
|
||||
azentricFactor_(pg.azentricFactor_),
|
||||
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_),
|
||||
rhoMin_(pg.rhoMin_),
|
||||
rhoMax_(pg.rhoMax_),
|
||||
rhostd_(pg.rhostd_),
|
||||
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() const
|
||||
{
|
||||
return rhostd_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar aungierRedlichKwong::rhoMin() const
|
||||
{
|
||||
return rhoMin_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar aungierRedlichKwong::rhoMax() const
|
||||
{
|
||||
return rhoMax_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar aungierRedlichKwong::Tcrit() const
|
||||
{
|
||||
return Tcrit_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar aungierRedlichKwong::pcrit() const
|
||||
{
|
||||
return pcrit_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar aungierRedlichKwong::rhocrit() const
|
||||
{
|
||||
return rhocrit_;
|
||||
}
|
||||
|
||||
|
||||
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::b() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar aungierRedlichKwong::c() const
|
||||
{
|
||||
return c_;
|
||||
}
|
||||
|
||||
inline scalar aungierRedlichKwong::n() const
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
|
||||
//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 -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)/b_*(log(b_ + Vm) - log(Vm));
|
||||
//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)/b_*(log(b_ + Vm) - log(Vm));
|
||||
//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 = Vm2*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
|
||||
{
|
||||
//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 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
|
||||
{
|
||||
//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 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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,128 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
rhoMin_(1e-3),
|
||||
rhoMax_(1500),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R()))),
|
||||
aSave(0.0),
|
||||
daSave(0.0),
|
||||
d2aSave(0.0),
|
||||
TSave(0.0)
|
||||
{
|
||||
is.check("pengRobinson::pengRobinson(Istream& is)");
|
||||
}
|
||||
//CL: Constructed needed in OpenFOAM 2.x.x
|
||||
//CL: Code works fine, but compiling problem in OpenFOAM 1.6.ext
|
||||
//CL: because specie has no constructor using dict
|
||||
/*
|
||||
pengRobinson::pengRobinson(const dictionary& dict)
|
||||
:
|
||||
specie(dict),
|
||||
pcrit_(readScalar(dict.subDict("equationOfState").lookup("pCritical"))),
|
||||
Tcrit_(readScalar(dict.subDict("equationOfState").lookup("TCritical"))),
|
||||
azentricFactor_(readScalar(dict.subDict("equationOfState").lookup("azentricFactor"))),
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
|
||||
//CL: important: rhoMin and rhoMax are not used as boundary for the newton solver
|
||||
//CL: therefore, rho can be larger than rhoMax and smaller than rhoMin
|
||||
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_),
|
||||
rhoMin_(dict.subDict("equationOfState").lookupOrDefault("rhoMin",1e-3)),
|
||||
rhoMax_(dict.subDict("equationOfState").lookupOrDefault("rhoMax",1500)),
|
||||
aSave(0.0),
|
||||
daSave(0.0),
|
||||
d2aSave(0.0),
|
||||
TSave(0.0),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R())))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::pengRobinson::write(Ostream& os) const
|
||||
{
|
||||
specie::write(os);
|
||||
|
||||
dictionary dict("equationOfState");
|
||||
dict.add("pCritical", pcrit_);
|
||||
dict.add("TCritical", Tcrit_);
|
||||
dict.add("azentricFactor", azentricFactor_);
|
||||
dict.add("rhoMin", rhoMin_);
|
||||
dict.add("rhoMax", rhoMax_);
|
||||
|
||||
os << indent << dict.dictName() << dict;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -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::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 Peng Robinson Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class pengRobinson
|
||||
:
|
||||
public specie
|
||||
|
||||
{
|
||||
// private data
|
||||
//CL: data at critical point
|
||||
scalar pcrit_;
|
||||
scalar Tcrit_;
|
||||
scalar azentricFactor_;
|
||||
|
||||
//-Peng Robinson factors
|
||||
scalar a0_;
|
||||
scalar b_;
|
||||
scalar n_;
|
||||
|
||||
//CL: pow of constants b_ used in the code e.g. b2_=b*b;
|
||||
scalar b2_;
|
||||
scalar b3_;
|
||||
scalar b4_;
|
||||
scalar b5_;
|
||||
scalar b6_;
|
||||
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
|
||||
scalar rhoMin_;
|
||||
scalar rhoMax_;
|
||||
|
||||
//- Density @STD, initialise after a0, b!
|
||||
scalar rhostd_;
|
||||
|
||||
//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 from dictionary
|
||||
//pengRobinson(const dictionary& dict);
|
||||
|
||||
//- 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
|
||||
|
||||
//Return Peng Robinson factors
|
||||
inline scalar a0() const;
|
||||
|
||||
inline scalar b() const;
|
||||
|
||||
inline scalar n() const;
|
||||
|
||||
inline scalar rhostd() const;
|
||||
|
||||
inline scalar rhoMin() const;
|
||||
|
||||
inline scalar rhoMax() const;
|
||||
|
||||
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;
|
||||
|
||||
//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;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write to Ostream
|
||||
//void write(Ostream& os) 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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,578 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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_),
|
||||
rhoMin_(pr.rhoMin_),
|
||||
rhoMax_(pr.rhoMax_),
|
||||
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 scalar pengRobinson::rhostd() const
|
||||
{
|
||||
return rhostd_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar pengRobinson::rhoMin() const
|
||||
{
|
||||
return rhoMin_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar pengRobinson::rhoMax() const
|
||||
{
|
||||
return rhoMax_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar pengRobinson::Tcrit() const
|
||||
{
|
||||
return Tcrit_;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//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::b() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar pengRobinson::n() const
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
|
||||
//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 -this->dpdT(rho, T)/this->dpdv(rho, T);
|
||||
}
|
||||
|
||||
|
||||
//Real deviative dv/dp at constant temperature
|
||||
//(molar values)
|
||||
inline scalar pengRobinson::dvdp(const scalar rho, const scalar T) const
|
||||
{
|
||||
return 1/this->dpdv(rho, T);
|
||||
}
|
||||
|
||||
|
||||
//needed to calculate the internal energy
|
||||
//(molar values)
|
||||
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_);
|
||||
}
|
||||
|
||||
|
||||
//needed to calculate the entropy
|
||||
//(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)/(4*b_)
|
||||
*(log(b_*(root2 + 1) + Vm) - log(b_*(1 - root2) + Vm));
|
||||
|
||||
// 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
|
||||
{
|
||||
//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 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
|
||||
{
|
||||
//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 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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,115 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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_),
|
||||
b2_(pow(b_,2)),
|
||||
b3_(pow(b_,3)),
|
||||
b5_(pow(b_,5)),
|
||||
//CL: Only uses the default values
|
||||
rhoMin_(1e-3),
|
||||
rhoMax_(1500),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R())))
|
||||
{
|
||||
is.check("redlichKwong::redlichKwong(Istream& is)");
|
||||
}
|
||||
|
||||
//CL: Constructed needed in OpenFOAM 2.x.x
|
||||
//CL: Code works fine, but compiling problem in OpenFOAM 1.6.ext
|
||||
//CL: because specie has no constructor using dict
|
||||
/*
|
||||
Foam::redlichKwong::redlichKwong(const dictionary& dict)
|
||||
:
|
||||
specie(dict),
|
||||
pcrit_(readScalar(dict.subDict("equationOfState").lookup("pCritical"))),
|
||||
Tcrit_(readScalar(dict.subDict("equationOfState").lookup("TCritical"))),
|
||||
a_(0.42748*pow(this->RR(),2)*pow(Tcrit_,2.5)/pcrit_),
|
||||
b_(0.08664*this->RR()*Tcrit_/pcrit_),
|
||||
b2_(pow(b_,2)),
|
||||
b3_(pow(b_,3)),
|
||||
b5_(pow(b_,5)),
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
|
||||
//CL: important: rhoMin and rhoMax are not used as boundary for the newton solver
|
||||
//CL: therefore, rho can be larger than rhoMax and smaller than rhoMin
|
||||
rhoMin_(dict.subDict("equationOfState").lookupOrDefault("rhoMin",1e-3)),
|
||||
rhoMax_(dict.subDict("equationOfState").lookupOrDefault("rhoMax",1500)),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R())))
|
||||
{
|
||||
is.check("redlichKwong::redlichKwong(Istream& is)");
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::redlichKwong::write(Ostream& os) const
|
||||
{
|
||||
specie::write(os);
|
||||
|
||||
dictionary dict("equationOfState");
|
||||
dict.add("pCritical", pcrit_);
|
||||
dict.add("TCritical", Tcrit_);
|
||||
dict.add("rhoMin", rhoMin_);
|
||||
dict.add("rhoMax", rhoMax_);
|
||||
|
||||
os << indent << dict.dictName() << dict;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,234 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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
|
||||
{
|
||||
// private data
|
||||
//CL: data at critical point
|
||||
scalar pcrit_;
|
||||
scalar Tcrit_;
|
||||
|
||||
//CL: Redlich Kwong factors
|
||||
scalar a_;
|
||||
scalar b_;
|
||||
|
||||
//CL: pow of constants b_ used in the code e.g. b2_=b*b;
|
||||
scalar b2_;
|
||||
scalar b3_;
|
||||
scalar b5_;
|
||||
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
|
||||
scalar rhoMin_;
|
||||
scalar rhoMax_;
|
||||
|
||||
//- Density @STD, initialise after a, b!
|
||||
scalar rhostd_;
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
inline redlichKwong
|
||||
(
|
||||
const specie& sp
|
||||
);
|
||||
|
||||
//- Construct from Istream
|
||||
redlichKwong(Istream&);
|
||||
|
||||
//- Construct from dictionary
|
||||
//redlichKwong(const dictionary& dict);
|
||||
|
||||
//- 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
|
||||
|
||||
//Return Redlich Kwong factors
|
||||
inline scalar a() const;
|
||||
|
||||
inline scalar b() const;
|
||||
|
||||
inline scalar rhostd() const;
|
||||
|
||||
inline scalar rhoMin() const;
|
||||
|
||||
inline scalar rhoMax() const;
|
||||
|
||||
inline scalar Tcrit() const;
|
||||
|
||||
//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;
|
||||
|
||||
//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;
|
||||
|
||||
//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;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write to Ostream
|
||||
//void write(Ostream& os) 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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,468 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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_),
|
||||
b2_(rk.b2_),
|
||||
b3_(rk.b3_),
|
||||
b5_(rk.b5_),
|
||||
rhoMin_(rk.rhoMin_),
|
||||
rhoMax_(rk.rhoMax_),
|
||||
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::rhoMin() const
|
||||
{
|
||||
return rhoMin_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar redlichKwong::rhoMax() const
|
||||
{
|
||||
return rhoMax_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar redlichKwong::Tcrit() const
|
||||
{
|
||||
return Tcrit_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar redlichKwong::a() const
|
||||
{
|
||||
return a_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar redlichKwong::b() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
|
||||
|
||||
//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_/(b_*sqrt(T))*(log(b_ + Vm) - log(Vm));
|
||||
//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 Vm = this->W()/rho;
|
||||
return this->RR()*log(Vm - b_) - a_/(2*b_*pow(T, 1.5))*(log(b_ + Vm) - log(Vm));
|
||||
//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]
|
||||
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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,133 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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)),
|
||||
b2_(b_*b_),
|
||||
b3_(b2_*b_),
|
||||
b5_(b2_*b3_),
|
||||
//CL: Only uses the default values
|
||||
rhoMin_(1e-3),
|
||||
rhoMax_(1500),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R()))),
|
||||
aSave(0.0),
|
||||
daSave(0.0),
|
||||
d2aSave(0.0),
|
||||
TSave(0.0)
|
||||
{
|
||||
is.check("soaveRedlichKwong::soaveRedlichKwong(Istream& is)");
|
||||
}
|
||||
|
||||
//CL: Constructed needed in OpenFOAM 2.x.x
|
||||
//CL: Code works fine, but compiling problem in OpenFOAM 1.6.ext
|
||||
//CL: because specie has no constructor using dict
|
||||
/*
|
||||
soaveRedlichKwong::soaveRedlichKwong(const dictionary& dict)
|
||||
:
|
||||
specie(dict),
|
||||
pcrit_(readScalar(dict.subDict("equationOfState").lookup("pCritical"))),
|
||||
Tcrit_(readScalar(dict.subDict("equationOfState").lookup("TCritical"))),
|
||||
azentricFactor_(readScalar(dict.subDict("equationOfState").lookup("azentricFactor"))),
|
||||
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)),
|
||||
b2_(b_*b_),
|
||||
b3_(b_*b2_),
|
||||
b5_(b3_*b2_),
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection method (see rho function)
|
||||
//CL: important: rhoMin and rhoMax are not used as boundary for the newton solver
|
||||
//CL: therefore, rho can be larger than rhoMax and smaller than rhoMin
|
||||
rhoMin_(dict.subDict("equationOfState").lookupOrDefault("rhoMin",1e-3)),
|
||||
rhoMax_(dict.subDict("equationOfState").lookupOrDefault("rhoMax",1500)),
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection method (see rho function)
|
||||
//CL: important: rhoMin and rhoMax are not used as boundary for the newton solver
|
||||
//CL: therefore, rho can be larger than rhoMax and smaller than rhoMin
|
||||
rhoMin_(dict.subDict("equationOfState").lookupOrDefault("rhoMin",1e-3)),
|
||||
rhoMax_(dict.subDict("equationOfState").lookupOrDefault("rhoMax",1500)),
|
||||
// Starting GUESS for the density by ideal gas law
|
||||
rhostd_(this->rho(this->Pstd(), this->Tstd(), this->Pstd()/(this->Tstd()*this->R()))),
|
||||
aSave(0.0),
|
||||
daSave(0.0),
|
||||
d2aSave(0.0),
|
||||
TSave(0.0)
|
||||
{
|
||||
is.check("soaveRedlichKwong::soaveRedlichKwong(Istream& is)");
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::soaveRedlichKwong::write(Ostream& os) const
|
||||
{
|
||||
specie::write(os);
|
||||
|
||||
dictionary dict("equationOfState");
|
||||
dict.add("pCritical", pcrit_);
|
||||
dict.add("TCritical", Tcrit_);
|
||||
dict.add("azentricFactor", azentricFactor_);
|
||||
dict.add("rhoMin", rhoMin_);
|
||||
dict.add("rhoMax", rhoMax_);
|
||||
|
||||
os << indent << dict.dictName() << dict;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,274 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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
|
||||
//CL: data at critical point
|
||||
scalar pcrit_;
|
||||
scalar Tcrit_;
|
||||
scalar azentricFactor_;
|
||||
|
||||
//-Soave Redlich Kwong
|
||||
scalar a0_;
|
||||
scalar b_;
|
||||
scalar n_;
|
||||
|
||||
//CL: pow of constants b_ used in the code e.g. b2_=b*b;
|
||||
scalar b2_;
|
||||
scalar b3_;
|
||||
scalar b5_;
|
||||
|
||||
//CL: rhoMin and rhoMax are only used as boundaries for the bisection methode (see rho function)
|
||||
scalar rhoMin_;
|
||||
scalar rhoMax_;
|
||||
|
||||
//- Density @STD, initialise after a0, b!
|
||||
scalar rhostd_;
|
||||
|
||||
//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& sp
|
||||
);
|
||||
|
||||
//- Construct from Istream
|
||||
soaveRedlichKwong(Istream&);
|
||||
|
||||
//- Construct from dictionary
|
||||
//soaveRedlichKwong(const dictionary& dict);
|
||||
|
||||
//- 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
|
||||
|
||||
//Return Soave Redlich Kwong factors
|
||||
inline scalar a0() const;
|
||||
|
||||
inline scalar b() const;
|
||||
|
||||
inline scalar n() const;
|
||||
|
||||
inline scalar rhostd() const;
|
||||
|
||||
inline scalar rhoMin() const;
|
||||
|
||||
inline scalar rhoMax() const;
|
||||
|
||||
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;
|
||||
|
||||
//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;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write to Ostream
|
||||
//void write(Ostream& os) 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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,544 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
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_),
|
||||
b2_(srk.b2_),
|
||||
b3_(srk.b3_),
|
||||
b5_(srk.b5_),
|
||||
rhoMin_(srk.rhoMin_),
|
||||
rhoMax_(srk.rhoMax_),
|
||||
rhostd_(srk.rhostd_),
|
||||
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 scalar soaveRedlichKwong::rhostd() const
|
||||
{
|
||||
return rhostd_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar soaveRedlichKwong::rhoMin() const
|
||||
{
|
||||
return rhoMin_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar soaveRedlichKwong::rhoMax() const
|
||||
{
|
||||
return rhoMax_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar soaveRedlichKwong::Tcrit() const
|
||||
{
|
||||
return Tcrit_;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//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::b() const
|
||||
{
|
||||
return b_;
|
||||
}
|
||||
|
||||
|
||||
inline scalar soaveRedlichKwong::n() const
|
||||
{
|
||||
return n_;
|
||||
}
|
||||
|
||||
|
||||
//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 -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)/b_*(log(b_ + Vm) - log(Vm));
|
||||
//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)
|
||||
//needed to calculate the entropy
|
||||
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)/b_*(log(b_ + Vm) - log(Vm));
|
||||
//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);
|
||||
//CL: also possible
|
||||
//CL: return -this->dvdp(rho, T)*rho/this->W();
|
||||
}
|
||||
|
||||
|
||||
//- 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
|
||||
{
|
||||
//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 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]
|
||||
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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,407 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 c
|
||||
//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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,77 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,275 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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::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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,499 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,77 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "realGasSpecieThermo.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
/* * * * * * * * * * * * * * * Private Static Data * * * * * * * * * * * * * */
|
||||
|
||||
template<class thermo>
|
||||
const Foam::debug::tolerancesSwitch
|
||||
Foam::realGasSpecieThermo<thermo>::tol_
|
||||
(
|
||||
"realGasSpecieThermoTol",
|
||||
1.0e-9
|
||||
);
|
||||
|
||||
template<class thermo>
|
||||
const Foam::debug::optimisationSwitch
|
||||
Foam::realGasSpecieThermo<thermo>::maxIter_
|
||||
(
|
||||
"realGasSpecieThermoMaxIter",
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,282 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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::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
|
||||
|
||||
Author
|
||||
Christian Lucas
|
||||
Institut für Thermodynamik
|
||||
Technische Universität Braunschweig
|
||||
Germany
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#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 debug::tolerancesSwitch tol_;
|
||||
|
||||
//- Max number of iterations in energy->temperature inversion functions
|
||||
static const debug::optimisationSwitch 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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,384 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -137,6 +137,12 @@ public:
|
|||
//- Thermal diffusivity for enthalpy [kg/ms]
|
||||
inline scalar alpha(const scalar T) const;
|
||||
|
||||
//- Thermal conductivity [W/mK] for real gas
|
||||
inline scalar kappa(const scalar rho, const scalar T) const;
|
||||
|
||||
//- Thermal diffusivity for enthalpy [kg/ms] for real gas
|
||||
inline scalar alpha(const scalar rho, const scalar T) const;
|
||||
|
||||
// Species diffusivity
|
||||
//inline scalar D(const scalar T) const;
|
||||
|
||||
|
|
|
@ -116,7 +116,34 @@ inline scalar constTransport<thermo>::alpha(const scalar T) const
|
|||
return Cp_*mu(T)*rPr/CpBar;
|
||||
}
|
||||
|
||||
// CL: for real gas thermo
|
||||
// Thermal conductivity [W/mK]
|
||||
template<class thermo>
|
||||
inline scalar constTransport<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 scalar constTransport<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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -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
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,217 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * 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_)
|
||||
{}
|
||||
|
||||
|
||||
// Construct and return a clone
|
||||
template<class thermo>
|
||||
inline autoPtr<constRealGasTransport<Thermo> > constTransport<thermo>::clone
|
||||
() const
|
||||
{
|
||||
return autoPtr<constRealGasTransport<Thermo> >
|
||||
(
|
||||
new constTransport<thermo>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Selector from Istream
|
||||
template<class thermo>
|
||||
inline autoPtr<constRealGasTransport<Thermo> > constTransport<thermo>::New
|
||||
(
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
return autoPtr<constRealGasTransport<Thermo> >
|
||||
(
|
||||
new constRealGasTransport<thermo>(is)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * 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;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -159,6 +159,12 @@ public:
|
|||
//- Thermal diffusivity for enthalpy [kg/ms]
|
||||
inline scalar alpha(const scalar T) const;
|
||||
|
||||
//- Thermal conductivity [W/mK] for real gas
|
||||
inline scalar kappa(const scalar rho, const scalar T) const;
|
||||
|
||||
//- Thermal diffusivity for enthalpy [kg/ms] for real gas
|
||||
inline scalar alpha(const scalar rho, const scalar T) const;
|
||||
|
||||
// Species diffusivity
|
||||
//inline scalar D(const scalar T) const;
|
||||
|
||||
|
|
|
@ -150,7 +150,45 @@ inline scalar sutherlandTransport<thermo>::alpha(const scalar T) const
|
|||
|
||||
scalar deltaT = T - specie::Tstd();
|
||||
scalar CpBar =
|
||||
(deltaT*(this->H(T) - this->H(specie::Tstd())) + Cp_)/(sqr(deltaT) + 1);
|
||||
(deltaT*(this->H(T) - this->H(specie::Tstd())) + Cp_)
|
||||
/(sqr(deltaT) + 1);
|
||||
|
||||
return mu(T)*Cv_*(1.32 + 1.77*R_/Cv_)/CpBar;
|
||||
}
|
||||
|
||||
|
||||
// CL: for real gas thermo
|
||||
// Thermal conductivity [W/mK]
|
||||
template<class thermo>
|
||||
inline scalar sutherlandTransport<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 scalar sutherlandTransport<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;
|
||||
}
|
||||
|
|
|
@ -14,4 +14,19 @@ $(NSRDSfunctions)/NSRDSfunc7/NSRDSfunc7.C
|
|||
$(NSRDSfunctions)/NSRDSfunc14/NSRDSfunc14.C
|
||||
$(APIfunctions)/APIdiffCoefFunc/APIdiffCoefFunc.C
|
||||
|
||||
freesteam-2.1/common.c
|
||||
freesteam-2.1/steam.c
|
||||
freesteam-2.1/b23.c
|
||||
freesteam-2.1/backwards.c
|
||||
freesteam-2.1/viscosity.c
|
||||
freesteam-2.1/thcond.c
|
||||
freesteam-2.1/region1.c
|
||||
freesteam-2.1/region2.c
|
||||
freesteam-2.1/region3.c
|
||||
freesteam-2.1/region4.c
|
||||
freesteam-2.1/steam_pv.c
|
||||
freesteam-2.1/steam_ph.c
|
||||
freesteam-2.1/steam_pT.c
|
||||
freesteam-2.1/zeroin.c
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libthermophysicalFunctions
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?>
|
||||
|
||||
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.toolchain.gnu.base.487904684">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.toolchain.gnu.base.487904684" moduleId="org.eclipse.cdt.core.settings" name="Default">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration buildProperties="" id="cdt.managedbuild.toolchain.gnu.base.487904684" name="Default" parent="org.eclipse.cdt.build.core.emptycfg">
|
||||
<folderInfo id="cdt.managedbuild.toolchain.gnu.base.487904684.503514498" name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.base.1893306594" name="cdt.managedbuild.toolchain.gnu.base" superClass="cdt.managedbuild.toolchain.gnu.base">
|
||||
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.gnu.platform.base.1304117584" name="Debug Platform" osList="linux,hpux,aix,qnx" superClass="cdt.managedbuild.target.gnu.platform.base"/>
|
||||
<builder id="cdt.managedbuild.target.gnu.builder.base.227643906" managedBuildOn="false" name="Gnu Make Builder.Default" superClass="cdt.managedbuild.target.gnu.builder.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.475368644" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.base.758011200" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.base.1423750360" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.base.1494542762" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.base.590138482" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.base.304660451" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.base"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="freesteam.null.2007861953" name="freesteam"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</storageModule>
|
||||
</cproject>
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>freesteam</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
FREESTEAM
|
||||
=========
|
||||
|
||||
Note: We ripped out what we needed, here is the full description!
|
||||
|
||||
This is a package for calculating the properties of water and steam
|
||||
using the IAPWS-IF97 industry-standard steam properties correlations.
|
||||
|
||||
freesteam includes a thorough set of test cases; you are encouraged to inspect
|
||||
these for yourself to assure yourself that freesteam is accurate for the cases
|
||||
you required.
|
||||
|
||||
freesteam is not a stand-alone program in its own right. Rather, it is a 'shared
|
||||
library' that implements a range of functions that you can use to work out steam
|
||||
properties in your own program that you write yourself.
|
||||
|
||||
This version 2.x release of freesteam is a complete re-write of freesteam in
|
||||
pure C. We have removed all the complicated C++ template code (excessively
|
||||
complicated) as well as the units-of-measurement code (cute, but also
|
||||
rather hard to maintain). This has the immediate advantage that the resulting
|
||||
DLLs/libraries can be linked to from all C/C++ compilers, something which was
|
||||
not possible with the previous C++ version.
|
||||
|
||||
For more information, see
|
||||
http://freesteam.sourceforge.net/
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2005 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "b23.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
const double B23_N[6] = { 0, 0.34805185628969E+03, -0.11671859879975E+01
|
||||
, 0.10192970039326E-02, 0.57254459862746E+03, 0.13918839778870E+02
|
||||
};
|
||||
|
||||
const double B23_PSTAR = 1e6;
|
||||
|
||||
double freesteam_b23_p_T(double T){
|
||||
#define theta T
|
||||
return (B23_N[1] + B23_N[2] * theta + B23_N[3] * SQ(theta)) * B23_PSTAR;
|
||||
#undef theta
|
||||
}
|
||||
|
||||
double freesteam_b23_T_p(double p){
|
||||
double pi = p / B23_PSTAR;
|
||||
return B23_N[4] + sqrt((pi - B23_N[5])/B23_N[3]) /* * 1{K} */;
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2005 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/
|
||||
#ifndef FREESTEAM_B23_H
|
||||
#define FREESTEAM_B23_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FREESTEAM_DLL double freesteam_b23_p_T(double T);
|
||||
FREESTEAM_DLL double freesteam_b23_T_p(double p);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,869 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*//** @file
|
||||
Backwards equations for IAPWS-IF97. Facilitate calculation of
|
||||
properties in terms of (p,h) without requiring any iteration.
|
||||
|
||||
TODO add boundary curves?
|
||||
TODO add more equations for (p,s) calculation?
|
||||
|
||||
Numerical data for T(p,h) and v(p,h) correlations was extracted from
|
||||
the Matlab version 2.6 of Xsteam by by Magnus Holmgren.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "backwards.h"
|
||||
|
||||
#include "backwards_impl.h"
|
||||
#include <math.h>
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 1 BACKWARDS EQUATION T(P,H)
|
||||
*/
|
||||
|
||||
typedef struct{
|
||||
int I, J;
|
||||
double n;
|
||||
} BackwardsData;
|
||||
|
||||
/**
|
||||
Source: IAPWS-IF97-REV section 5.2.1
|
||||
*/
|
||||
BackwardsData REGION1_TPH_DATA[] = {
|
||||
{0, 0, -238.72489924521}
|
||||
,{0, 1, 404.21188637945}
|
||||
,{0, 2, 113.49746881718}
|
||||
,{0, 6, -5.8457616048039}
|
||||
,{0, 22, -1.528548241314E-04}
|
||||
,{0, 32, -1.0866707695377E-06}
|
||||
,{1, 0, -13.391744872602}
|
||||
,{1, 1, 43.211039183559}
|
||||
,{1, 2, -54.010067170506}
|
||||
,{1, 3, 30.535892203916}
|
||||
,{1, 4, -6.5964749423638}
|
||||
,{1,10, 9.3965400878363E-03}
|
||||
,{1,32, 1.157364750534E-07}
|
||||
,{2,10,-2.5858641282073E-05}
|
||||
,{2,32,-4.0644363084799E-09}
|
||||
,{3,10,6.6456186191635E-08}
|
||||
,{3,32,8.0670734103027E-11}
|
||||
,{4,32,-9.3477771213947E-13}
|
||||
,{5,32,5.8265442020601E-15}
|
||||
,{6,32,-1.5020185953503E-17}
|
||||
};
|
||||
|
||||
const unsigned REGION1_TPH_MAX = sizeof(REGION1_TPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
const double REGION1_TPH_HSTAR = 2500e3; /* J/kg */
|
||||
const double REGION1_TPH_PSTAR = 1e6; /* Pa */
|
||||
|
||||
/**
|
||||
Backward equation for temperature in terms of pressure and enthalpy
|
||||
in IAPWS-IF97 Region 1. Source: IAPWS-IF97-Rev section 5.2.1.
|
||||
|
||||
@param p pressure in Pa
|
||||
@param h enthalpy in J/kg
|
||||
@return temperature in K
|
||||
*/
|
||||
double freesteam_region1_T_ph(double p, double h){
|
||||
double pi = p / REGION1_TPH_PSTAR;
|
||||
double e1 = 1. + (h / REGION1_TPH_HSTAR);
|
||||
unsigned i;
|
||||
BackwardsData *d;
|
||||
double sum = 0;
|
||||
for(i=0, d = REGION1_TPH_DATA; i<REGION1_TPH_MAX; ++i, ++d){
|
||||
/* TODO some optimisations are possible here with pow(pi,...) */
|
||||
sum += d->n * ipow(pi,d->I) * ipow(e1, d->J);
|
||||
}
|
||||
return sum /* * REGION1_TPH_TSTAR = 1. */;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 2 BACKWARDS EQUATION T(P,H)
|
||||
*/
|
||||
|
||||
/* sub-region 2a */
|
||||
BackwardsData REGION2A_TPH_DATA[] = {
|
||||
{0, 0, 1089.8952318288}
|
||||
,{0, 1, 849.51654495535}
|
||||
,{0, 2, -107.81748091826}
|
||||
,{0, 3, 33.153654801263}
|
||||
,{0, 7, -7.4232016790248}
|
||||
,{0, 20, 11.765048724356}
|
||||
,{1, 0, 1.844574935579}
|
||||
,{1, 1, -4.1792700549624}
|
||||
,{1, 2, 6.2478196935812}
|
||||
,{1, 3, -17.344563108114}
|
||||
,{1, 7, -200.58176862096}
|
||||
,{1, 9, 271.96065473796}
|
||||
,{1, 11, -455.11318285818}
|
||||
,{1, 18, 3091.9688604755}
|
||||
,{1, 44, 252266.40357872}
|
||||
,{2, 0, -6.1707422868339E-03}
|
||||
,{2, 2, -0.31078046629583}
|
||||
,{2, 7, 11.670873077107}
|
||||
,{2, 36, 128127984.04046}
|
||||
,{2, 38, -985549096.23276}
|
||||
,{2, 40, 2822454697.3002}
|
||||
,{2, 42, -3594897141.0703}
|
||||
,{2, 44, 1722734991.3197}
|
||||
,{3, 24, -13551.334240775}
|
||||
,{3, 44, 12848734.66465}
|
||||
,{4, 12, 1.3865724283226}
|
||||
,{4, 32, 235988.32556514}
|
||||
,{4, 44, -13105236.545054}
|
||||
,{5, 32, 7399.9835474766}
|
||||
,{5, 36, -551966.9703006}
|
||||
,{5, 42, 3715408.5996233}
|
||||
,{6, 34, 19127.72923966}
|
||||
,{6, 44, -415351.64835634}
|
||||
,{7, 28, -62.459855192507}
|
||||
|
||||
};
|
||||
|
||||
const unsigned REGION2A_TPH_MAX = sizeof(REGION2A_TPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
/* sub-region 2b */
|
||||
|
||||
BackwardsData REGION2B_TPH_DATA[] = {
|
||||
{0, 0, 1489.5041079516}
|
||||
,{0, 1, 743.07798314034}
|
||||
,{0, 2, -97.708318797837}
|
||||
,{0, 12, 2.4742464705674}
|
||||
,{0, 18, -0.63281320016026}
|
||||
,{0, 24, 1.1385952129658}
|
||||
,{0, 28, -0.47811863648625}
|
||||
,{0, 40, 8.5208123431544E-03}
|
||||
,{1, 0, 0.93747147377932}
|
||||
,{1, 2, 3.3593118604916}
|
||||
,{1, 6, 3.3809355601454}
|
||||
,{1, 12, 0.16844539671904}
|
||||
,{1, 18, 0.73875745236695}
|
||||
,{1, 24, -0.47128737436186}
|
||||
,{1, 28, 0.15020273139707}
|
||||
,{1, 40, -0.002176411421975}
|
||||
,{2, 2, -0.021810755324761}
|
||||
,{2, 8, -0.10829784403677}
|
||||
,{2, 18, -0.046333324635812}
|
||||
,{2, 40, 7.1280351959551E-05}
|
||||
,{3, 1, 1.1032831789999E-04}
|
||||
,{3, 2, 1.8955248387902E-04}
|
||||
,{3, 12, 3.0891541160537E-03}
|
||||
,{3, 24, 1.3555504554949E-03}
|
||||
,{4, 2, 2.8640237477456E-07}
|
||||
,{4, 12, -1.0779857357512E-05}
|
||||
,{4, 18, -7.6462712454814E-05}
|
||||
,{4, 24, 1.4052392818316E-05}
|
||||
,{4, 28, -3.1083814331434E-05}
|
||||
,{4, 40, -1.0302738212103E-06}
|
||||
,{5, 18, 2.821728163504E-07}
|
||||
,{5, 24, 1.2704902271945E-06}
|
||||
,{5, 40, 7.3803353468292E-08}
|
||||
,{6, 28, -1.1030139238909E-08}
|
||||
,{7, 2, -8.1456365207833E-14}
|
||||
,{7, 28, -2.5180545682962E-11}
|
||||
,{9, 1, -1.7565233969407E-18}
|
||||
,{9, 40, 8.6934156344163E-15}
|
||||
|
||||
};
|
||||
|
||||
const unsigned REGION2B_TPH_MAX = sizeof(REGION2B_TPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
/* sub-region 2c */
|
||||
BackwardsData REGION2C_TPH_DATA[] ={
|
||||
{-7, 0, -3236839855524.2}
|
||||
,{-7, 4, 7326335090218.1}
|
||||
,{-6, 0, 358250899454.47}
|
||||
,{-6, 2, -583401318515.9}
|
||||
,{-5, 0, -10783068217.47}
|
||||
,{-5, 2, 20825544563.171}
|
||||
,{-2, 0, 610747.83564516}
|
||||
,{-2, 1, 859777.2253558}
|
||||
,{-1, 0, -25745.72360417}
|
||||
,{-1, 2, 31081.088422714}
|
||||
,{0, 0, 1208.2315865936}
|
||||
,{0, 1, 482.19755109255}
|
||||
,{1, 4, 3.7966001272486}
|
||||
,{1, 8, -10.842984880077}
|
||||
,{2, 4, -0.04536417267666}
|
||||
,{6, 0, 1.4559115658698E-13}
|
||||
,{6, 1, 1.126159740723E-12}
|
||||
,{6, 4, -1.7804982240686E-11}
|
||||
,{6, 10, 1.2324579690832E-07}
|
||||
,{6, 12, -1.1606921130984E-06}
|
||||
,{6, 16, 2.7846367088554E-05}
|
||||
,{6, 20, -5.9270038474176E-04}
|
||||
,{6, 22, 1.2918582991878E-03}
|
||||
|
||||
};
|
||||
|
||||
const unsigned REGION2C_TPH_MAX = sizeof(REGION2C_TPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
const double REGION2AB_P = 4.e6; /* Pa */
|
||||
|
||||
const double REGION2_HSTAR = 2000e3;
|
||||
const double REGION2_PSTAR = 1.e6;
|
||||
|
||||
/* REGION2_B2BC_PH defined in backwards_impl.h */
|
||||
|
||||
/**
|
||||
Backward equation for temperature in terms of pressure and enthalpy
|
||||
in IAPWS-IF97 Region 2 (composed of sub-regions 2a, 2b, 2c).
|
||||
Source: IAPWS-IF97-Rev section 5.2.1.
|
||||
|
||||
@param p pressure in Pa
|
||||
@param h enthalpy in J/kg
|
||||
@return temperature in K
|
||||
*/
|
||||
double freesteam_region2_T_ph(double p, double h){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double eta = h / REGION2_HSTAR;
|
||||
double pi = p / REGION2_PSTAR;
|
||||
double pi1, eta1;
|
||||
BackwardsData *d;
|
||||
unsigned i, n;
|
||||
double sum = 0;
|
||||
if(p < REGION2AB_P){
|
||||
//fprintf(stderr,"region 2a\n");
|
||||
pi1 = pi; eta1 = eta - 2.1;
|
||||
d = REGION2A_TPH_DATA;
|
||||
n = REGION2A_TPH_MAX;
|
||||
}else{
|
||||
if(REGION2_B2BC_PH(p,h) < 0.){
|
||||
//fprintf(stderr,"region 2b\n");
|
||||
pi1 = pi - 2.; eta1 = eta - 2.6;
|
||||
d = REGION2B_TPH_DATA;
|
||||
n = REGION2B_TPH_MAX;
|
||||
}else{
|
||||
//fprintf(stderr,"region 2c\n");
|
||||
pi1 = pi + 25.; eta1 = eta - 1.8;
|
||||
d = REGION2C_TPH_DATA;
|
||||
n = REGION2C_TPH_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i<n; ++i, ++d){
|
||||
sum += d->n * ipow(pi1, d->I) * ipow(eta1, d->J);
|
||||
}
|
||||
|
||||
return sum /* * REGION2_TSTAR = 1 K */;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 3 BACKWARDS EQUATION T(P,H)
|
||||
*/
|
||||
|
||||
/* sub-region 3a */
|
||||
BackwardsData REGION3A_TPH_DATA[] = {
|
||||
{-12, 0, -1.33645667811215E-07}
|
||||
,{-12, 1, 4.55912656802978E-06}
|
||||
,{-12, 2, -1.46294640700979E-05}
|
||||
,{-12, 6, 6.3934131297008E-03}
|
||||
,{-12, 14, 372.783927268847}
|
||||
,{-12, 16, -7186.54377460447}
|
||||
,{-12, 20, 573494.7521034}
|
||||
,{-12, 22, -2675693.29111439}
|
||||
,{-10, 1, -3.34066283302614E-05}
|
||||
,{-10, 5, -2.45479214069597E-02}
|
||||
,{-10, 12, 47.8087847764996}
|
||||
,{-8, 0, 7.64664131818904E-06}
|
||||
,{-8, 2, 1.28350627676972E-03}
|
||||
,{-8, 4, 1.71219081377331E-02}
|
||||
,{-8, 10, -8.51007304583213}
|
||||
,{-5, 2, -1.36513461629781E-02}
|
||||
,{-3, 0, -3.84460997596657E-06}
|
||||
,{-2, 1, 3.37423807911655E-03}
|
||||
,{-2, 3, -0.551624873066791}
|
||||
,{-2, 4, 0.72920227710747}
|
||||
,{-1, 0, -9.92522757376041E-03}
|
||||
,{-1, 2, -0.119308831407288}
|
||||
,{0, 0, 0.793929190615421}
|
||||
,{0, 1, 0.454270731799386}
|
||||
,{1, 1, 0.20999859125991}
|
||||
,{3, 0, -6.42109823904738E-03}
|
||||
,{3, 1, -0.023515586860454}
|
||||
,{4, 0, 2.52233108341612E-03}
|
||||
,{4, 3, -7.64885133368119E-03}
|
||||
,{10, 4, 1.36176427574291E-02}
|
||||
,{12, 5, -1.33027883575669E-02}
|
||||
};
|
||||
|
||||
const unsigned REGION3A_TPH_MAX = sizeof(REGION3A_TPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
BackwardsData REGION3B_TPH_DATA[] = {
|
||||
{-12, 0, 3.2325457364492E-05}
|
||||
,{-12, 1, -1.27575556587181E-04}
|
||||
,{-10, 0, -4.75851877356068E-04}
|
||||
,{-10, 1, 1.56183014181602E-03}
|
||||
,{-10, 5, 0.105724860113781}
|
||||
,{-10, 10, -85.8514221132534}
|
||||
,{-10, 12, 724.140095480911}
|
||||
,{-8, 0, 2.96475810273257E-03}
|
||||
,{-8, 1, -5.92721983365988E-03}
|
||||
,{-8, 2, -1.26305422818666E-02}
|
||||
,{-8, 4, -0.115716196364853}
|
||||
,{-8, 10, 84.9000969739595}
|
||||
,{-6, 0, -1.08602260086615E-02}
|
||||
,{-6, 1, 1.54304475328851E-02}
|
||||
,{-6, 2, 7.50455441524466E-02}
|
||||
,{-4, 0, 2.52520973612982E-02}
|
||||
,{-4, 1, -6.02507901232996E-02}
|
||||
,{-3, 5, -3.07622221350501}
|
||||
,{-2, 0, -5.74011959864879E-02}
|
||||
,{-2, 4, 5.03471360939849}
|
||||
,{-1, 2, -0.925081888584834}
|
||||
,{-1, 4, 3.91733882917546}
|
||||
,{-1, 6, -77.314600713019}
|
||||
,{-1, 10, 9493.08762098587}
|
||||
,{-1, 14, -1410437.19679409}
|
||||
,{-1, 16, 8491662.30819026}
|
||||
,{0, 0, 0.861095729446704}
|
||||
,{0, 2, 0.32334644281172}
|
||||
,{1, 1, 0.873281936020439}
|
||||
,{3, 1, -0.436653048526683}
|
||||
,{5, 1, 0.286596714529479}
|
||||
,{6, 1, -0.131778331276228}
|
||||
,{8, 1, 6.76682064330275E-03}
|
||||
};
|
||||
|
||||
const unsigned REGION3B_TPH_MAX = sizeof(REGION3B_TPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
/* REGION3_B3AB_PH(P,H) boundary test declared in backwards_impl.h */
|
||||
|
||||
const double REGION3A_TPH_HSTAR = 2300e3;
|
||||
const double REGION3A_TPH_PSTAR = 100.e6;
|
||||
const double REGION3A_TPH_TSTAR = 760;
|
||||
|
||||
const double REGION3B_TPH_HSTAR = 2800e3;
|
||||
const double REGION3B_TPH_PSTAR = 100.e6;
|
||||
const double REGION3B_TPH_TSTAR = 860;
|
||||
|
||||
/**
|
||||
Backward equation for temperature in terms of pressure and enthalpy
|
||||
in IAPWS-IF97 Region 3 (composed of sub-regions 3a, 3b).
|
||||
|
||||
Source: IAPWS 'Revised Supplementary Release on Backward Equations for the Functions
|
||||
T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS Industrial
|
||||
Formulation 1997 for the Thermodynamic Properties of Water and Steam', 2004.
|
||||
|
||||
@param p pressure in Pa
|
||||
@param h enthalpy in J/kg
|
||||
@return temperature in K
|
||||
*/
|
||||
double freesteam_region3_T_ph(double p, double h){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double pi1, eta1;
|
||||
double Tstar;
|
||||
BackwardsData *d;
|
||||
unsigned i, n;
|
||||
double sum = 0;
|
||||
if(REGION3_B3AB_PH(p,h) <= 0.){
|
||||
/* sub-region 3a */
|
||||
pi1 = p/REGION3A_TPH_PSTAR + 0.240; eta1 = h/REGION3A_TPH_HSTAR - 0.615;
|
||||
d = REGION3A_TPH_DATA;
|
||||
n = REGION3A_TPH_MAX;
|
||||
Tstar = REGION3A_TPH_TSTAR;
|
||||
}else{
|
||||
/* sub-region 3b */
|
||||
pi1 = p/REGION3B_TPH_PSTAR + 0.298; eta1 = h/REGION3B_TPH_HSTAR - 0.720;
|
||||
d = REGION3B_TPH_DATA;
|
||||
n = REGION3B_TPH_MAX;
|
||||
Tstar = REGION3B_TPH_TSTAR;
|
||||
}
|
||||
|
||||
for(i = 0; i<n; ++i, ++d){
|
||||
sum += d->n * ipow(pi1, d->I) * ipow(eta1, d->J);
|
||||
}
|
||||
|
||||
return sum * Tstar;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 3 V(P,H)
|
||||
*/
|
||||
|
||||
BackwardsData REGION3A_VPH_DATA[] = {
|
||||
{-12, 6, 5.29944062966028E-03}
|
||||
,{-12, 8, -0.170099690234461}
|
||||
,{-12, 12, 11.1323814312927}
|
||||
,{-12, 18, -2178.98123145125}
|
||||
,{-10, 4, -5.06061827980875E-04}
|
||||
,{-10, 7, 0.556495239685324}
|
||||
,{-10, 10, -9.43672726094016}
|
||||
,{-8, 5, -0.297856807561527}
|
||||
,{-8, 12, 93.9353943717186}
|
||||
,{-6, 3, 1.92944939465981E-02}
|
||||
,{-6, 4, 0.421740664704763}
|
||||
,{-6, 22, -3689141.2628233}
|
||||
,{-4, 2, -7.37566847600639E-03}
|
||||
,{-4, 3, -0.354753242424366}
|
||||
,{-3, 7, -1.99768169338727}
|
||||
,{-2, 3, 1.15456297059049}
|
||||
,{-2, 16, 5683.6687581596}
|
||||
,{-1, 0, 8.08169540124668E-03}
|
||||
,{-1, 1, 0.172416341519307}
|
||||
,{-1, 2, 1.04270175292927}
|
||||
,{-1, 3, -0.297691372792847}
|
||||
,{0, 0, 0.560394465163593}
|
||||
,{0, 1, 0.275234661176914}
|
||||
,{1, 0, -0.148347894866012}
|
||||
,{1, 1, -6.51142513478515E-02}
|
||||
,{1, 2, -2.92468715386302}
|
||||
,{2, 0, 6.64876096952665E-02}
|
||||
,{2, 2, 3.52335014263844}
|
||||
,{3, 0, -1.46340792313332E-02}
|
||||
,{4, 2, -2.24503486668184}
|
||||
,{5, 2, 1.10533464706142}
|
||||
,{8, 2, -4.08757344495612E-02}
|
||||
};
|
||||
|
||||
const unsigned REGION3A_VPH_MAX = sizeof(REGION3A_VPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
BackwardsData REGION3B_VPH_DATA[] = {
|
||||
{-12, 0, -2.25196934336318E-09}
|
||||
,{-12, 1, 1.40674363313486E-08}
|
||||
,{-8, 0, 2.3378408528056E-06}
|
||||
,{-8, 1, -3.31833715229001E-05}
|
||||
,{-8, 3, 1.07956778514318E-03}
|
||||
,{-8, 6, -0.271382067378863}
|
||||
,{-8, 7, 1.07202262490333}
|
||||
,{-8, 8, -0.853821329075382}
|
||||
,{-6, 0, -2.15214194340526E-05}
|
||||
,{-6, 1, 7.6965608822273E-04}
|
||||
,{-6, 2, -4.31136580433864E-03}
|
||||
,{-6, 5, 0.453342167309331}
|
||||
,{-6, 6, -0.507749535873652}
|
||||
,{-6, 10, -100.475154528389}
|
||||
,{-4, 3, -0.219201924648793}
|
||||
,{-4, 6, -3.21087965668917}
|
||||
,{-4, 10, 607.567815637771}
|
||||
,{-3, 0, 5.57686450685932E-04}
|
||||
,{-3, 2, 0.18749904002955}
|
||||
,{-2, 1, 9.05368030448107E-03}
|
||||
,{-2, 2, 0.285417173048685}
|
||||
,{-1, 0, 3.29924030996098E-02}
|
||||
,{-1, 1, 0.239897419685483}
|
||||
,{-1, 4, 4.82754995951394}
|
||||
,{-1, 5, -11.8035753702231}
|
||||
,{0, 0, 0.169490044091791}
|
||||
,{1, 0, -1.79967222507787E-02}
|
||||
,{1, 1, 3.71810116332674E-02}
|
||||
,{2, 2, -5.36288335065096E-02}
|
||||
,{2, 6, 1.6069710109252}
|
||||
};
|
||||
|
||||
const unsigned REGION3B_VPH_MAX = sizeof(REGION3B_VPH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
const double REGION3A_VPH_HSTAR = 2100e3; /* J/kg */
|
||||
const double REGION3A_VPH_PSTAR = 100.e6; /* Pa */
|
||||
const double REGION3A_VPH_VSTAR = 0.0028; /* m³/kg */
|
||||
|
||||
const double REGION3B_VPH_HSTAR = 2800e3;
|
||||
const double REGION3B_VPH_PSTAR = 100.e6;
|
||||
const double REGION3B_VPH_VSTAR = 0.0088;
|
||||
|
||||
/**
|
||||
Backward equation for specific volume in terms of pressure and enthalpy
|
||||
in IAPWS-IF97 Region 3 (composed of sub-regions 3a, 3b).
|
||||
|
||||
Source: IAPWS 'Revised Supplementary Release on Backward Equations for the Functions
|
||||
T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS Industrial
|
||||
Formulation 1997 for the Thermodynamic Properties of Water and Steam', 2004.
|
||||
|
||||
@param p pressure in Pa
|
||||
@param h enthalpy in J/kg
|
||||
@return temperature in K
|
||||
*/
|
||||
double freesteam_region3_v_ph(double p, double h){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double pi1, eta1;
|
||||
BackwardsData *d;
|
||||
unsigned i, n;
|
||||
double sum = 0;
|
||||
double vstar;
|
||||
if(REGION3_B3AB_PH(p,h) <= 0.){
|
||||
/* sub-region 3a */
|
||||
pi1 = p/REGION3A_VPH_PSTAR + 0.128; eta1 = h/REGION3A_VPH_HSTAR - 0.727;
|
||||
d = REGION3A_VPH_DATA;
|
||||
n = REGION3A_VPH_MAX;
|
||||
vstar = REGION3A_VPH_VSTAR;
|
||||
}else{
|
||||
/* sub-region 3b */
|
||||
pi1 = p/REGION3B_VPH_PSTAR + 0.0661; eta1 = h/REGION3B_VPH_HSTAR - 0.720;
|
||||
d = REGION3B_VPH_DATA;
|
||||
n = REGION3B_VPH_MAX;
|
||||
vstar = REGION3B_VPH_VSTAR;
|
||||
}
|
||||
|
||||
for(i = 0; i<n; ++i, ++d){
|
||||
sum += d->n * ipow(pi1, d->I) * ipow(eta1, d->J);
|
||||
}
|
||||
|
||||
return sum * vstar;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 3 PSAT(H) BOUNDARY
|
||||
*/
|
||||
|
||||
BackwardsData REGION3_PSATH_DATA[] = {
|
||||
{ 0, 0, 0.600073641753024}
|
||||
,{1, 1, -0.936203654849857e1}
|
||||
,{1, 3, 0.246590798594147e2}
|
||||
,{1, 4, -0.107014222858224e3}
|
||||
,{1, 36, -0.915821315805768e14}
|
||||
,{5, 3, -0.862332011700662e4}
|
||||
,{7, 0, -0.235837344740032e2}
|
||||
,{8, 24, 0.252304969384128e18}
|
||||
,{14, 16, -0.389718771997719e19}
|
||||
,{20, 16, -0.333775713645296e23}
|
||||
,{22, 3, 0.356499469636328e11}
|
||||
,{24, 18, -0.148547544720641e27}
|
||||
,{28, 8, 0.330611514838798e19}
|
||||
,{36, 24, 0.813641294467829e38}
|
||||
};
|
||||
|
||||
const unsigned REGION3_PSATH_MAX = sizeof(REGION3_PSATH_DATA)/sizeof(BackwardsData);
|
||||
|
||||
const double REGION3_PSATH_HSTAR = 2600e3;
|
||||
const double REGION3_PSATH_PSTAR = 22.e6;
|
||||
|
||||
double freesteam_region3_psat_h(double h){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
BackwardsData *d, *e = REGION3_PSATH_DATA + REGION3_PSATH_MAX;
|
||||
double eta = h / REGION3_PSATH_HSTAR;
|
||||
double eta1 = eta - 1.02;
|
||||
double eta2 = eta - 0.608;
|
||||
double sum = 0;
|
||||
for(d = REGION3_PSATH_DATA; d<e; ++d){
|
||||
sum += d->n * ipow(eta1, d->I) * ipow(eta2, d->J);
|
||||
}
|
||||
return sum * REGION3_PSATH_PSTAR;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 3 PSAT(S) BOUNDARY
|
||||
*/
|
||||
|
||||
BackwardsData REGION3_PSATS_DATA[] = {
|
||||
{ 0, 0, 0.639767553612785}
|
||||
, {1, 1, -0.129727445396014e2}
|
||||
, {1, 32, -0.224595125848403e16}
|
||||
, {4, 7, 0.177466741801846e7}
|
||||
, {12, 4, 0.717079349571538e10}
|
||||
, {12, 14, -0.378829107169011e18}
|
||||
, {16, 36, -0.955586736431328e35}
|
||||
, {24, 10, 0.187269814676188e24}
|
||||
, {28, 0, 0.119254746466473e12}
|
||||
, {32, 18, 0.110649277244882e37}
|
||||
};
|
||||
|
||||
const unsigned REGION3_PSATS_MAX = sizeof(REGION3_PSATS_DATA)/sizeof(BackwardsData);
|
||||
|
||||
const double REGION3_PSATS_SSTAR = 5.2e3;
|
||||
const double REGION3_PSATS_PSTAR = 22.e6;
|
||||
|
||||
double freesteam_region3_psat_s(double s){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
BackwardsData *d, *e = REGION3_PSATS_DATA + REGION3_PSATS_MAX;
|
||||
double sig = s / REGION3_PSATS_SSTAR;
|
||||
double sig1 = sig - 1.03;
|
||||
double sig2 = sig - 0.699;
|
||||
double sum = 0;
|
||||
for(d = REGION3_PSATS_DATA; d<e; ++d){
|
||||
sum += d->n * ipow(sig1, d->I) * ipow(sig2, d->J);
|
||||
}
|
||||
return sum * REGION3_PSATS_PSTAR;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 3 BACKWARDS EQUATION T(P,S)
|
||||
*/
|
||||
|
||||
/**
|
||||
Source: Revised_Release_Tv3ph_Tv3ps_Rev3.doc sect 3.4
|
||||
*/
|
||||
BackwardsData REGION3A_TPS_DATA[] = {
|
||||
{-12, 28, 1500420082.63875}
|
||||
,{-12, 32, -159397258480.424}
|
||||
,{-10, 4, 5.02181140217975E-04}
|
||||
,{-10, 10, -67.2057767855466}
|
||||
,{-10, 12, 1450.58545404456}
|
||||
,{-10, 14, -8238.8953488889}
|
||||
,{-8, 5, -0.154852214233853}
|
||||
,{-8, 7, 11.2305046746695}
|
||||
,{-8, 8, -29.7000213482822}
|
||||
,{-8, 28, 43856513263.5495}
|
||||
,{-6, 2, 1.37837838635464E-03}
|
||||
,{-6, 6, -2.97478527157462}
|
||||
,{-6, 32, 9717779473494.13}
|
||||
,{-5, 0, -5.71527767052398E-05}
|
||||
,{-5, 14, 28830.794977842}
|
||||
,{-5, 32, -74442828926270.3}
|
||||
,{-4, 6, 12.8017324848921}
|
||||
,{-4, 10, -368.275545889071}
|
||||
,{-4, 36, 6.64768904779177E+15}
|
||||
,{-2, 1, 0.044935925195888}
|
||||
,{-2, 4, -4.22897836099655}
|
||||
,{-1, 1, -0.240614376434179}
|
||||
,{-1, 6, -4.74341365254924}
|
||||
,{0, 0, 0.72409399912611}
|
||||
,{0, 1, 0.923874349695897}
|
||||
,{0, 4, 3.99043655281015}
|
||||
,{1, 0, 3.84066651868009E-02}
|
||||
,{2, 0, -3.59344365571848E-03}
|
||||
,{2, 3, -0.735196448821653}
|
||||
,{3, 2, 0.188367048396131}
|
||||
,{8, 0, 1.41064266818704E-04}
|
||||
,{8, 1, -2.57418501496337E-03}
|
||||
,{10, 2, 1.23220024851555E-03}
|
||||
};
|
||||
|
||||
const unsigned REGION3A_TPS_MAX = sizeof(REGION3A_TPS_DATA)/sizeof(BackwardsData);
|
||||
|
||||
/**
|
||||
Source: Revised_Release_Tv3ph_Tv3ps_Rev3.doc sect 3.4
|
||||
*/
|
||||
BackwardsData REGION3B_TPS_DATA[] = {
|
||||
{-12, 1, 0.52711170160166}
|
||||
,{-12, 3, -40.1317830052742}
|
||||
,{-12, 4, 153.020073134484}
|
||||
,{-12, 7, -2247.99398218827}
|
||||
,{-8, 0, -0.193993484669048}
|
||||
,{-8, 1, -1.40467557893768}
|
||||
,{-8, 3, 42.6799878114024}
|
||||
,{-6, 0, 0.752810643416743}
|
||||
,{-6, 2, 22.6657238616417}
|
||||
,{-6, 4, -622.873556909932}
|
||||
,{-5, 0, -0.660823667935396}
|
||||
,{-5, 1, 0.841267087271658}
|
||||
,{-5, 2, -25.3717501764397}
|
||||
,{-5, 4, 485.708963532948}
|
||||
,{-5, 6, 880.531517490555}
|
||||
,{-4, 12, 2650155.92794626}
|
||||
,{-3, 1, -0.359287150025783}
|
||||
,{-3, 6, -656.991567673753}
|
||||
,{-2, 2, 2.41768149185367}
|
||||
,{0, 0, 0.856873461222588}
|
||||
,{2, 1, 0.655143675313458}
|
||||
,{3, 1, -0.213535213206406}
|
||||
,{4, 0, 5.62974957606348E-03}
|
||||
,{5, 24, -316955725450471.}
|
||||
,{6, 0, -6.99997000152457E-04}
|
||||
,{8, 3, 1.19845803210767E-02}
|
||||
,{12, 1, 1.93848122022095E-05}
|
||||
,{14, 2, -2.15095749182309E-05}
|
||||
};
|
||||
|
||||
const unsigned REGION3B_TPS_MAX = sizeof(REGION3B_TPS_DATA)/sizeof(BackwardsData);
|
||||
|
||||
const double REGION3A_TPS_TSTAR = 760.; /* K */
|
||||
const double REGION3A_TPS_SSTAR = 4.4e3; /* J/kgK */
|
||||
const double REGION3A_TPS_PSTAR = 100e6; /* Pa */
|
||||
|
||||
const double REGION3B_TPS_TSTAR = 860.; /* K */
|
||||
const double REGION3B_TPS_SSTAR = 5.3e3; /* J/kgK */
|
||||
const double REGION3B_TPS_PSTAR = 100e6; /* Pa */
|
||||
|
||||
const double REGION3AB_SC = 4.41202148223476e3; /* J/kgK */
|
||||
|
||||
/**
|
||||
Backward equation for temperature in terms of pressure and entropy
|
||||
in IAPWS-IF97 Region 3 (composed of sub-regions 3a, 3b).
|
||||
|
||||
Source: IAPWS 'Revised Supplementary Release on Backward Equations for the Functions
|
||||
T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS Industrial
|
||||
Formulation 1997 for the Thermodynamic Properties of Water and Steam', 2004.
|
||||
|
||||
@param p pressure in Pa
|
||||
@param s specific entropy in J/kgK
|
||||
@return temperature in K
|
||||
*/
|
||||
double freesteam_region3_T_ps(double p, double s){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double p1, s1;
|
||||
double Tstar;
|
||||
BackwardsData *d;
|
||||
unsigned i, n;
|
||||
double sum = 0;
|
||||
if(s < REGION3AB_SC){
|
||||
/* sub-region 3a */
|
||||
p1 = p/REGION3A_TPS_PSTAR + 0.240; s1 = s/REGION3A_TPS_SSTAR - 0.703;
|
||||
d = REGION3A_TPS_DATA;
|
||||
n = REGION3A_TPS_MAX;
|
||||
Tstar = REGION3A_TPS_TSTAR;
|
||||
}else{
|
||||
/* sub-region 3b */
|
||||
p1 = p/REGION3B_TPS_PSTAR + 0.760; s1 = s/REGION3B_TPS_SSTAR - 0.818;
|
||||
d = REGION3B_TPS_DATA;
|
||||
n = REGION3B_TPS_MAX;
|
||||
Tstar = REGION3B_TPS_TSTAR;
|
||||
}
|
||||
|
||||
for(i = 0; i<n; ++i, ++d){
|
||||
sum += d->n * ipow(p1, d->I) * ipow(s1, d->J);
|
||||
}
|
||||
|
||||
return sum * Tstar;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Source: Revised_Release_Tv3ph_Tv3ps_Rev3.doc sect 3.4
|
||||
*/
|
||||
BackwardsData REGION3A_VPS_DATA[] = {
|
||||
{-12, 10, 0.795544074093975e2}
|
||||
, {-12, 12, -0.238261242984590e4}
|
||||
, {-12, 14, 0.176813100617787e5}
|
||||
, {-10, 4, -0.110524727080379e-2}
|
||||
, {-10, 8, -0.153213833655326e2}
|
||||
, {-10, 10, 0.297544599376982e3}
|
||||
, {-10, 20, -0.350315206871242e8}
|
||||
, {-8, 5, 0.277513761062119}
|
||||
, {-8, 6, -0.523964271036888}
|
||||
, {-8, 14, -0.148011182995403e6}
|
||||
, {-8, 16, 0.160014899374266e7}
|
||||
, {-6, 28, 0.170802322663427e13}
|
||||
, {-5, 1, 0.246866996006494e-3}
|
||||
, {-4, 5, 0.165326084797980e1}
|
||||
, {-3, 2, -0.118008384666987}
|
||||
, {-3, 4, 0.253798642355900e1}
|
||||
, {-2, 3, 0.965127704669424}
|
||||
, {-2, 8, -0.282172420532826e2}
|
||||
, {-1, 1, 0.203224612353823}
|
||||
, {-1, 2, 0.110648186063513e1}
|
||||
, {0, 0, 0.526127948451280}
|
||||
, {0, 1, 0.277000018736321}
|
||||
, {0, 3, 0.108153340501132e1}
|
||||
, {1, 0, -0.744127885357893e-1}
|
||||
, {2, 0, 0.164094443541384e-1}
|
||||
, {4, 2, -0.680468275301065e-1}
|
||||
, {5, 2, 0.257988576101640e-1}
|
||||
, {6, 0, -0.145749861944416e-3}
|
||||
};
|
||||
|
||||
const unsigned REGION3A_VPS_MAX = sizeof(REGION3A_VPS_DATA)/sizeof(BackwardsData);
|
||||
|
||||
/**
|
||||
Source: Revised_Release_Tv3ph_Tv3ps_Rev3.doc sect 3.4
|
||||
*/
|
||||
BackwardsData REGION3B_VPS_DATA[] = {
|
||||
{-12, 0, 0.591599780322238e-4}
|
||||
, {-12, 1, -0.185465997137856e-2}
|
||||
, {-12, 2, 0.104190510480013e-1}
|
||||
, {-12, 3, 0.598647302038590e-2}
|
||||
, {-12, 5, -0.771391189901699}
|
||||
, {-12, 6, 0.172549765557036e1}
|
||||
, {-10, 0, -0.467076079846526e-3}
|
||||
, {-10, 1, 0.134533823384439e-1}
|
||||
, {-10, 2, -0.808094336805495e-1}
|
||||
, {-10, 4, 0.508139374365767}
|
||||
, {-8, 0, 0.128584643361683e-2}
|
||||
, {-5, 1, -0.163899353915435e1}
|
||||
, {-5, 2, 0.586938199318063e1}
|
||||
, {-5, 3, -0.292466667918613e1}
|
||||
, {-4, 0, -0.614076301499537e-2}
|
||||
, {-4, 1, 0.576199014049172e1}
|
||||
, {-4, 2, -0.121613320606788e2}
|
||||
, {-4, 3, 0.167637540957944e1}
|
||||
, {-3, 1, -0.744135838773463e1}
|
||||
, {-2, 0, 0.378168091437659e-1}
|
||||
, {-2, 1, 0.401432203027688e1}
|
||||
, {-2, 2, 0.160279837479185e2}
|
||||
, {-2, 3, 0.317848779347728e1}
|
||||
, {-2, 4, -0.358362310304853e1}
|
||||
, {-2, 12, -0.115995260446827e7}
|
||||
, {0, 0, 0.199256573577909}
|
||||
, {0, 1, -0.122270624794624}
|
||||
, {0, 2, -0.191449143716586e2}
|
||||
, {1, 0, -0.150448002905284e-1}
|
||||
, {1, 2, 0.146407900162154e2}
|
||||
, {2, 2, -0.327477787188230e1}
|
||||
};
|
||||
|
||||
const unsigned REGION3B_VPS_MAX = sizeof(REGION3B_VPS_DATA)/sizeof(BackwardsData);
|
||||
|
||||
const double REGION3A_VPS_VSTAR = 0.0028; /* kg/m³ */
|
||||
const double REGION3A_VPS_SSTAR = 4.4e3; /* J/kgK */
|
||||
const double REGION3A_VPS_PSTAR = 100e6; /* Pa */
|
||||
|
||||
const double REGION3B_VPS_VSTAR = 0.0088; /* kg/m³ */
|
||||
const double REGION3B_VPS_SSTAR = 5.3e3; /* J/kgK */
|
||||
const double REGION3B_VPS_PSTAR = 100e6; /* Pa */
|
||||
|
||||
/**
|
||||
Backward equation for temperature in terms of pressure and entropy
|
||||
in IAPWS-IF97 Region 3 (composed of sub-regions 3a, 3b).
|
||||
|
||||
Source: IAPWS 'Revised Supplementary Release on Backward Equations for the Functions
|
||||
T(p,h), v(p,h) and T(p,s), v(p,s) for Region 3 of the IAPWS Industrial
|
||||
Formulation 1997 for the Thermodynamic Properties of Water and Steam', 2004.
|
||||
|
||||
@param p pressure in Pa
|
||||
@param s specific entropy in J/kgK
|
||||
@return temperature in K
|
||||
*/
|
||||
double freesteam_region3_v_ps(double p, double s){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double p1, s1;
|
||||
double vstar;
|
||||
BackwardsData *d;
|
||||
unsigned i, n;
|
||||
double sum = 0;
|
||||
if(s < REGION3AB_SC){
|
||||
/* sub-region 3a */
|
||||
//fprintf(stderr,"3A\n");
|
||||
p1 = p/REGION3A_VPS_PSTAR + 0.187; s1 = s/REGION3A_VPS_SSTAR - 0.755;
|
||||
d = REGION3A_VPS_DATA;
|
||||
n = REGION3A_VPS_MAX;
|
||||
vstar = REGION3A_VPS_VSTAR;
|
||||
}else{
|
||||
/* sub-region 3b */
|
||||
//fprintf(stderr,"3B\n");
|
||||
p1 = p/REGION3B_VPS_PSTAR + 0.298; s1 = s/REGION3B_VPS_SSTAR - 0.816;
|
||||
d = REGION3B_VPS_DATA;
|
||||
n = REGION3B_VPS_MAX;
|
||||
vstar = REGION3B_VPS_VSTAR;
|
||||
}
|
||||
|
||||
for(i = 0; i<n; ++i, ++d){
|
||||
sum += d->n * ipow(p1, d->I) * ipow(s1, d->J);
|
||||
}
|
||||
|
||||
return sum * vstar;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef FREESTEAM_BACKWARDS_H
|
||||
#define FREESTEAM_BACKWARDS_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FREESTEAM_DLL double freesteam_region1_T_ph(double p, double h);
|
||||
FREESTEAM_DLL double freesteam_region2_T_ph(double p, double h);
|
||||
FREESTEAM_DLL double freesteam_region3_T_ph(double p, double h);
|
||||
FREESTEAM_DLL double freesteam_region3_v_ph(double p, double h);
|
||||
FREESTEAM_DLL double freesteam_region3_psat_h(double h);
|
||||
FREESTEAM_DLL double freesteam_region3_psat_s(double s);
|
||||
|
||||
FREESTEAM_DLL double freesteam_region3_T_ps(double p, double h);
|
||||
FREESTEAM_DLL double freesteam_region3_v_ps(double p, double h);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*//** @file
|
||||
Implementation details for backwards equations. Intended that
|
||||
this header file would only be used for internal tests etc.
|
||||
*/
|
||||
#ifndef FREESTEAM_BACKWARDS_IMPL_H
|
||||
#define FREESTEAM_BACKWARDS_IMPL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define SQ(X) ((X)*(X))
|
||||
#define CUBE(X) ((X)*(X)*(X))
|
||||
|
||||
/* boundary between subregions 3a and 3b in region 3 for (p,h) */
|
||||
|
||||
#define REGION3_B3AB_PSTAR (1.e6)
|
||||
#define REGION3_B3AB_HSTAR (1.e3)
|
||||
#define REGION3_B3AB_ETA(H) ((H)/REGION3_B3AB_HSTAR)
|
||||
#define REGION3_B3AB_PI(P) ((P)/REGION3_B3AB_PSTAR)
|
||||
|
||||
#define REGION3_B3AB_PH(P,H) (REGION3_B3AB_ETA(H) - (\
|
||||
2014.64004206875 \
|
||||
+ 3.74696550136983*REGION3_B3AB_PI(P) \
|
||||
- 2.19921901054187E-02 * SQ(REGION3_B3AB_PI(P)) \
|
||||
+ 8.7513168600995E-05 * CUBE(REGION3_B3AB_PI(P)) \
|
||||
))
|
||||
|
||||
|
||||
/* boundary between subregions 2 and 3 in region 2 for (p,h) */
|
||||
|
||||
#define REGION2_B2BC_PSTAR (1.e6)
|
||||
#define REGION2_B2BC_HSTAR (1.e3)
|
||||
#define REGION2_B2BC_ETA(H) ((H)/REGION2_B2BC_HSTAR)
|
||||
#define REGION2_B2BC_PI(P) ((P)/REGION2_B2BC_PSTAR)
|
||||
|
||||
#define REGION2_B2BC_PH(P,H) (\
|
||||
(REGION2_B2BC_PI(P) - (\
|
||||
905.84278514723 \
|
||||
- 0.67955786399241*REGION2_B2BC_ETA(H) \
|
||||
+ 1.2809002730136E-04 * SQ(REGION2_B2BC_ETA(H)) \
|
||||
)))
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2005 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "common.h"
|
||||
|
||||
/* ipow: public domain by Mark Stephen with suggestions by Keiichi Nakasato */
|
||||
double ipow(double x, int n){
|
||||
double t = 1.0;
|
||||
|
||||
if(!n)return 1.0; /* At the top. x^0 = 1 */
|
||||
|
||||
if (n < 0){
|
||||
n = -n;
|
||||
x = 1.0/x; /* error if x == 0. Good */
|
||||
} /* ZTC/SC returns inf, which is even better */
|
||||
|
||||
if (x == 0.0)return 0.0;
|
||||
|
||||
do{
|
||||
if(n & 1)t *= x;
|
||||
n /= 2; /* KN prefers if (n/=2) x*=x; This avoids an */
|
||||
x *= x; /* unnecessary but benign multiplication on */
|
||||
}while(n); /* the last pass, but the comparison is always
|
||||
true _except_ on the last pass. */
|
||||
|
||||
return t;
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2005 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef FREESTEAM_COMMON_H
|
||||
#define FREESTEAM_COMMON_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define FREESTEAM_CHAR int
|
||||
|
||||
/*
|
||||
ASCEND code in base/generic only EXPORTS symbols, no imports.
|
||||
The FREESTEAM_DLLSPEC macro will, depending on whether we are
|
||||
FREESTEAM_BUILDING_LIBASCEND (building libascend.so aka ascend.dll)
|
||||
or FREESTEAM_BUILDING_INTERFACE (building for example _ascpy.dll or
|
||||
ascendtcl.dll), act respectively to declare symbols as being
|
||||
*exported* or *imported*.
|
||||
|
||||
New versions of GCC are able to make use of these declarations
|
||||
as well.
|
||||
*/
|
||||
#ifdef __WIN32__
|
||||
# define FREESTEAM_EXPORT __declspec(dllexport)
|
||||
# define FREESTEAM_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
# ifdef HAVE_GCCVISIBILITY
|
||||
# define FREESTEAM_EXPORT __attribute__ ((visibility("default")))
|
||||
# define FREESTEAM_IMPORT
|
||||
# else
|
||||
# define FREESTEAM_EXPORT
|
||||
# define FREESTEAM_IMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef FREESTEAM_BUILDING_LIB
|
||||
# define FREESTEAM_DLL extern FREESTEAM_EXPORT
|
||||
#else
|
||||
# define FREESTEAM_DLL extern FREESTEAM_IMPORT
|
||||
#endif
|
||||
|
||||
#if !defined(FREESTEAM_DLL) || !defined(FREESTEAM_EXPORT) || !defined(FREESTEAM_IMPORT)
|
||||
# error "NO FREESTEAM_DLL DEFINED"
|
||||
#endif
|
||||
|
||||
/* Constants used throughout IAPWS-IF97 */
|
||||
|
||||
#define IAPWS97_PMAX 100e6 /* Pa */
|
||||
#define IAPWS97_TMIN 273.15 /* K */
|
||||
#define IAPWS97_TMAX 1073.15 /* K */
|
||||
|
||||
#define IAPWS97_TCRIT 647.096 /* K */
|
||||
#define IAPWS97_PCRIT 22.064e6 /* Pa */
|
||||
#define IAPWS97_RHOCRIT 322. /* kg/m³ */
|
||||
|
||||
#define IAPWS97_PTRIPLE 611.657 /* Pa */
|
||||
|
||||
#define IAPWS97_R 461.526 /* J/kgK */
|
||||
|
||||
//#define IAPWS97_WARN_APPROX
|
||||
|
||||
#ifndef __GNUC__
|
||||
# define __func__ "<function>"
|
||||
#endif
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
#ifdef IAPWS97_WARN_APPROX
|
||||
# define IAPWS97_APPROXIMATE \
|
||||
static char _warn_approx=0; \
|
||||
if(!_warn_approx){ \
|
||||
_warn_approx = 1; \
|
||||
fprintf(stderr \
|
||||
,"WARNING: %s (%s:%d): backwards or approximation function used!\n" \
|
||||
,__func__,__FILE__,__LINE__ \
|
||||
); \
|
||||
}
|
||||
#else
|
||||
# define IAPWS97_APPROXIMATE
|
||||
#endif
|
||||
|
||||
#define SQ(X) ((X)*(X))
|
||||
|
||||
/* Basic math routines, if necesary... */
|
||||
|
||||
FREESTEAM_DLL double freesteam_ipow(double x, int n);
|
||||
|
||||
#ifdef FREESTEAM_BUILDING_LIB
|
||||
/* our local ipow implementation */
|
||||
# define ipow freesteam_ipow
|
||||
/* 'isnan' function for use with Windows */
|
||||
# ifdef WIN32
|
||||
# include <float.h>
|
||||
# define isnan _isnan
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* FREESTEAM_COMMON_H */
|
|
@ -0,0 +1,499 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2005 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
/** @file
|
||||
This file contains some initial attempts at a compatibility wrapping of
|
||||
freesteam 2.0 to enable it to be called using syntax hopefully identical to,
|
||||
or at least approaching, that used in freesteam 0.8.1.
|
||||
|
||||
John Pye, Mar 2010.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_COMPAT_H
|
||||
#define FREESTEAM_COMPAT_H
|
||||
|
||||
extern "C"{
|
||||
#include <freesteam/steam.h>
|
||||
#include <freesteam/steam_ph.h>
|
||||
#include <freesteam/steam_pT.h>
|
||||
#include <freesteam/steam_ps.h>
|
||||
#include <freesteam/steam_Ts.h>
|
||||
#include <freesteam/steam_Tx.h>
|
||||
#include <freesteam/region4.h>
|
||||
};
|
||||
|
||||
template<class T>
|
||||
T sq(const T& t){
|
||||
return t*t;
|
||||
};
|
||||
|
||||
typedef double Num;
|
||||
|
||||
/* UNITS OF MEASUREMENT ALL REDUCED TO DOUBLES */
|
||||
|
||||
//--------------------------------
|
||||
// BASE MEASURES
|
||||
|
||||
typedef double Mass;
|
||||
typedef double Length;
|
||||
typedef double Time;
|
||||
typedef double Temperature;
|
||||
typedef double Current;
|
||||
|
||||
//--------------------------------
|
||||
// DERIVED MEASURES
|
||||
|
||||
typedef double Area;
|
||||
typedef double Volume;
|
||||
|
||||
typedef double Density;
|
||||
typedef double SpecificVolume;
|
||||
|
||||
typedef double DensityPerTime;
|
||||
|
||||
typedef double Frequency;
|
||||
|
||||
typedef double Force;
|
||||
typedef double Pressure;
|
||||
typedef double Velocity;
|
||||
typedef double Acceleration;
|
||||
typedef double Torque;
|
||||
typedef double Energy;
|
||||
typedef double Power;
|
||||
typedef double SpecificEnergy;
|
||||
|
||||
typedef double DynamicViscosity;
|
||||
typedef double KinematicViscosity;
|
||||
typedef double PowerPerLength;
|
||||
typedef double PressurePerLength;
|
||||
typedef double ForcePerLength;
|
||||
typedef double PowerPerMass;
|
||||
|
||||
typedef double DensitySpecificEnergyPerTime;
|
||||
|
||||
typedef double VolFlowRate;
|
||||
typedef double MassFlowRate;
|
||||
typedef double MassFlowRatePerLength;
|
||||
typedef double MassFlowRatePerTime;
|
||||
|
||||
typedef double HeatFlux;
|
||||
typedef double MassFlux;
|
||||
|
||||
// Thermodynamics
|
||||
|
||||
typedef double Entropy;
|
||||
typedef double SpecificEntropy;
|
||||
typedef double ThermalConductivity;
|
||||
typedef double HeatTransferCoefficient;
|
||||
typedef double ThermalResistance;
|
||||
|
||||
typedef double HeatCapacityPerLength;
|
||||
typedef double PowerPerTemperature;
|
||||
|
||||
typedef double ThermalExpansionCoefficient;
|
||||
|
||||
// Electrical
|
||||
|
||||
typedef double Charge;
|
||||
typedef double ElecPotential;
|
||||
typedef double Capacitance;
|
||||
typedef double Resistance;
|
||||
typedef double Conductance;
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
// BASE UNITS FOR BASE MEASURES
|
||||
|
||||
#define kilogram 1.0
|
||||
#define metre 1.0
|
||||
#define second 1.0
|
||||
#define Kelvin 1.0
|
||||
#define ampere 1.0
|
||||
|
||||
//------------------------------------
|
||||
// SOME ALTERNATIVE NAMES
|
||||
|
||||
typedef Velocity Speed;
|
||||
typedef Length Distance;
|
||||
typedef Energy Heat;
|
||||
typedef Heat Work; // nice
|
||||
|
||||
typedef Power HeatRate;
|
||||
typedef PowerPerLength HeatRatePerLength;
|
||||
typedef PowerPerTemperature HeatRatePerTemperature;
|
||||
|
||||
typedef Pressure Stress;
|
||||
typedef HeatTransferCoefficient HTCoeff;
|
||||
typedef SpecificEntropy SpecificHeatCapacity; // not the same but the units are the same
|
||||
typedef SpecificHeatCapacity SpecHeatCap;
|
||||
typedef SpecificHeatCapacity SpecificGasConstant;
|
||||
typedef SpecificGasConstant SpecGasConst;
|
||||
|
||||
typedef ForcePerLength SurfaceTension;
|
||||
|
||||
//------------------------------------
|
||||
// SI MULTIPLIERS
|
||||
|
||||
const double Tera = 1e12;
|
||||
const double Giga = 1e9;
|
||||
const double Mega = 1e6;
|
||||
const double kilo = 1e3;
|
||||
const double hecta = 1e2;
|
||||
const double Deca = 10;
|
||||
const double deci = 0.1;
|
||||
const double centi = 1e-2;
|
||||
const double milli = 1e-3;
|
||||
const double micro = 1e-6;
|
||||
|
||||
//------------------------------------
|
||||
// COMMON MEASURES (SI)
|
||||
|
||||
const Mass gram = milli * kilogram;
|
||||
const Mass kg = kilogram;
|
||||
|
||||
const Length centimetre = metre / 100.0;
|
||||
const Length kilometre = 1000.0 * metre;
|
||||
|
||||
const Area metre2 = metre * metre;
|
||||
const Area hectare = (100.0 * metre) * (100.0 * metre);
|
||||
|
||||
const Volume metre3 = metre2 * metre;
|
||||
const Volume litre = milli * metre3;
|
||||
const Volume centimetre3 =
|
||||
(centi * metre) * (centi * metre) * (centi * metre);
|
||||
|
||||
const Time minute = 60.0 * second;
|
||||
const Time hour = 60.0 * minute;
|
||||
const Time day = 24.0 * hour;
|
||||
|
||||
const Frequency Hertz = 1.0 / second;
|
||||
|
||||
const Force Newton = kilogram * metre / (second * second);
|
||||
|
||||
const Pressure Pascal = Newton / (metre * metre);
|
||||
const Pressure bar = 100.0 * kilo * Pascal;
|
||||
const Pressure MPa = Mega * Pascal;
|
||||
const Pressure kPa = kilo * Pascal;
|
||||
const Energy Joule = Newton * metre;
|
||||
const Energy kJ = kilo * Joule;
|
||||
const Energy Btu = 1055.05585262 * Joule;
|
||||
|
||||
const Power Watt = Joule / second;
|
||||
|
||||
const HeatFlux W_m2 = Watt / metre2;
|
||||
|
||||
const double Percent = 1.0 / 100;
|
||||
|
||||
//------------------------------------
|
||||
// THERMODYNAMIC MEASURES
|
||||
|
||||
const SpecificEnergy kJ_kg = kilo * Joule / kilogram;
|
||||
const SpecificEnergy J_kg = Joule / kilogram;
|
||||
|
||||
const SpecificEntropy kJ_kgK = kilo * Joule / kilogram / Kelvin;
|
||||
const SpecificEntropy J_kgK = Joule / kilogram / Kelvin;
|
||||
|
||||
const HeatTransferCoefficient W_m2K = Watt / metre2 / Kelvin;
|
||||
const ThermalConductivity W_mK = Watt / metre / Kelvin;
|
||||
const ThermalConductivity mW_mK = milli * W_mK;
|
||||
const Density kg_m3 = kilogram / metre3;
|
||||
const SpecificVolume m3_kg = metre3 / kilogram;
|
||||
|
||||
const MassFlowRate kg_s = kilogram / second;
|
||||
const VolFlowRate m3_s = metre3 / second;
|
||||
|
||||
const HeatCapacityPerLength J_mK = Joule / metre / Kelvin;
|
||||
|
||||
//------------------------------------
|
||||
// ELECTRICAL STUFF
|
||||
|
||||
const ElecPotential volt = Watt / ampere;
|
||||
const Charge Coulomb = ampere * second;
|
||||
const Capacitance Farad = volt / Coulomb;
|
||||
const Resistance Ohm = volt / ampere;
|
||||
|
||||
//------------------------------------
|
||||
// SOME IMPERIAL MEASURES
|
||||
|
||||
const Temperature Rankin = 0.556 * Kelvin;
|
||||
const Frequency RPM = 1. / minute;
|
||||
|
||||
const Length yard = 0.9144 * metre;
|
||||
const Length foot = yard / 3.;
|
||||
const Length inch = foot / 12.;
|
||||
const Length mile = 1760. * yard;
|
||||
|
||||
const Mass lbm = 0.45359237 * kilogram;
|
||||
const Acceleration grav_accel = 9.80665 * metre / second / second;
|
||||
const Force lbf = grav_accel * lbm;
|
||||
const Pressure lbf_in2 = lbf / inch / inch;
|
||||
|
||||
//------------------------------------
|
||||
// HANDLING TEMPERATURES
|
||||
|
||||
const Temperature ZeroCelsius = 273.15 * Kelvin;
|
||||
const Temperature ZeroFahrenheit = ZeroCelsius - 32.0 * Rankin;
|
||||
|
||||
/**
|
||||
Convert a temperature (in Kelvin) to Celsius.
|
||||
@return the temperature, as a plain 'double' type
|
||||
*/
|
||||
inline double
|
||||
tocelsius(const Temperature& T){
|
||||
double d = *reinterpret_cast<const double*>(&T);
|
||||
return d - 273.15;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert a Celsius temperature to Kelvin
|
||||
@param T_C double value for the temperature in degrees
|
||||
@return Temperature object (Kelvin)
|
||||
*/
|
||||
inline Temperature
|
||||
fromcelsius(const double &T_C){
|
||||
return (T_C * Kelvin) + ZeroCelsius;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert from Fahrenheit temperature to Temperature object (Kelvin)
|
||||
*/
|
||||
inline double
|
||||
tofahrenheit(const Temperature &T){
|
||||
return (T - ZeroFahrenheit) / Rankin;
|
||||
}
|
||||
|
||||
/// Convert Temperature object to Fahrenheit
|
||||
/**
|
||||
@return temperature in Fahrenheit (as type 'double')
|
||||
*/
|
||||
inline Temperature
|
||||
fromfahrenheit(const double &T_F){
|
||||
return (T_F * Rankin) + ZeroFahrenheit;
|
||||
}
|
||||
|
||||
// USEFUL CONSTANTS
|
||||
|
||||
/// Stefan-Boltzmann Constant (radiation)
|
||||
const double SIGMA_C = (5.670e-8) * W_m2 /sq(sq(Kelvin));
|
||||
|
||||
/* STEAM-SPECIFIC CONSTANTS */
|
||||
|
||||
|
||||
const SpecificGasConstant R=0.461526 * kJ_kgK; // Specific gas constant for water from IF97
|
||||
|
||||
#define REG4_TOL 0.001 // relative err on pressures considerd to be equal to psat.
|
||||
|
||||
const Temperature TB_HIGH = 863.15 * Kelvin;
|
||||
const Temperature T_MIN = ZeroCelsius;
|
||||
const Temperature T_MAX = 1073.15 * Kelvin;
|
||||
const Temperature T_CRIT = 647.096 * Kelvin; // critical-point temperature
|
||||
const Temperature T_TRIPLE = 273.16 * Kelvin; // triple-point temperature
|
||||
const Temperature REG2_TEMP_REF = 540.0 * Kelvin;
|
||||
const Temperature REG1_TEMP_REF = 1386.0 * Kelvin;
|
||||
const Temperature REG1_T_LOW = ZeroCelsius;
|
||||
const Temperature REG2_T_LOW = ZeroCelsius;
|
||||
const Temperature REG2_T_HIGH = T_MAX;
|
||||
|
||||
const Temperature T_REG1_REG3 = 623.15 * Kelvin;
|
||||
const Temperature TB_LOW = T_REG1_REG3;
|
||||
|
||||
const Temperature T_MIN_VOL = fromcelsius(3.984);
|
||||
|
||||
const Pressure P_MAX = 100.0 * MPa;
|
||||
const Pressure PB_LOW = 16.5292 * MPa;
|
||||
const Pressure P_MIN = 0.0 * Pascal;
|
||||
const Pressure P_CRIT = 22.064 * MPa; // critical-point pressure
|
||||
const Pressure P_TRIPLE = 611.657 * Pascal; // triple-point pressure
|
||||
const Pressure REG4_P_MIN = 611.213 * Pascal; // minimum pressure for region 4 (IF-97 eq 31 & p 35) / [MPa]
|
||||
const Pressure REG2_P_HIGH = P_MAX;
|
||||
const Pressure REG1_P_HIGH = P_MAX;
|
||||
const Pressure REG1_PRES_REF = 16.53 * MPa;
|
||||
const Pressure REG2_PRES_REF = 1.0 * MPa;
|
||||
|
||||
const Density RHO_CRIT = 322.0 * kg / metre3; // critical-point density / [kg/m³]
|
||||
|
||||
/// @see http://www.iapws.org/relguide/visc.pdf#page=7 Eq (4)
|
||||
const DynamicViscosity IAPS85_VISC_REF = 55.071 * micro * Pascal * second;
|
||||
/// @see http://www.iapws.org/relguide/visc.pdf#page=7 Eq (2)
|
||||
const Density IAPS85_DENS_REF = 317.763 * kg_m3;
|
||||
/// @see http://www.iapws.org/relguide/visc.pdf#page=7 Eq (1)
|
||||
const Temperature IAPS85_TEMP_REF = 647.226 * Kelvin;
|
||||
/// @see http://www.iapws.org/relguide/visc.pdf#page=7 Eq (4)
|
||||
const Pressure IAPS85_PRES_REF = 22.115 * MPa; // MPa (THIS IS *NOT* EQUAL TO P_CRIT!)
|
||||
|
||||
const Temperature IAPS85_TEMP_REG2_REF = 540.0 * Kelvin;
|
||||
|
||||
const Pressure STEAM_P_EPS = 1.0e-5 * MPa;
|
||||
const Temperature STEAM_T_EPS = 5.0e-4 * Kelvin;
|
||||
|
||||
const Temperature EPS_T_CRIT=0.00007 * Kelvin;
|
||||
|
||||
const Temperature T_CRIT_PLUS=(T_CRIT + STEAM_T_EPS);
|
||||
|
||||
const Density REG3_ZEROIN_DENS_MAX = 765.0 * kg_m3;
|
||||
const Density REG3_ZEROIN_TOL= 1e-18 * kg_m3;
|
||||
|
||||
#define MPA_TO_BAR(PRES) (((Num)(PRES)) * 10.0 )
|
||||
#define BAR_TO_MPA(PRES) (((Num)(PRES)) * 0.1 )
|
||||
#define PA_TO_MPA(PRES) (((Num)(PRES)) * 0.000001 )
|
||||
#define MPA_TO_PA(PRES) (((Num)(PRES)) * 1.0E6 )
|
||||
#define KJKG_TO_JKG(JKG) (((Num)(KJKG)) * 1000.0 )
|
||||
#define BAR_TO_PA(PRES) (((Num)(PRES)) * 100.0E3 )
|
||||
#define KPA_TO_MPA(PRES) (((Num)(PRES)) * 0.001 )
|
||||
|
||||
#define W_TO_KW(W) (((Num)(W))*0.001)
|
||||
#define KJ_TO_J(KJ) (((Num)(KJ))*0.001)
|
||||
#define J_TO_KJ(J) (((Num)(J))*0.001)
|
||||
|
||||
const Acceleration GRAV = 9.81 * Newton / kg; // N/kg, gravitation acceleration
|
||||
|
||||
#ifndef PI
|
||||
# define PI 3.14159265358
|
||||
#endif
|
||||
|
||||
typedef enum{SOLVE_IENERGY, SOLVE_ENTHALPY, SOLVE_ENTROPY, SOLVE_CP, SOLVE_CV, SOLVE_TEMPERATURE, SOLVE_PRESSURE} SolveParam;
|
||||
|
||||
typedef SteamState SteamSolveFunction(double, double);
|
||||
typedef int SteamRegionFunction(double, double);
|
||||
typedef int SteamBoundsFunction(double, double, int);
|
||||
|
||||
class SteamCalculator{
|
||||
private:
|
||||
SteamState S;
|
||||
|
||||
public:
|
||||
SteamCalculator(){
|
||||
S.region = 1;
|
||||
S.R1.T = 300;
|
||||
S.R1.p = 1e5;
|
||||
}
|
||||
|
||||
SteamCalculator(const SteamState &S1){
|
||||
S = S1;
|
||||
}
|
||||
|
||||
/// Copy constructor
|
||||
SteamCalculator(const SteamCalculator & original){
|
||||
S = original.S;
|
||||
}
|
||||
|
||||
/// Assignment operator (assigns a copy)
|
||||
SteamCalculator const &operator=(SteamCalculator const &original){
|
||||
S = original.S;
|
||||
}
|
||||
|
||||
// Destructor
|
||||
~SteamCalculator(){}
|
||||
|
||||
// Defining state, simple methods
|
||||
|
||||
inline void set_pT(const Pressure &p, const Temperature &T){
|
||||
S = freesteam_set_pT(p,T);
|
||||
}
|
||||
|
||||
inline void setSatWater_p(const Pressure &p){
|
||||
S = freesteam_set_Tx(freesteam_region4_Tsat_p(p), 0.0);
|
||||
}
|
||||
|
||||
inline void setSatSteam_p(const Pressure &p){
|
||||
S = freesteam_set_Tx(freesteam_region4_Tsat_p(p), 1.0);
|
||||
}
|
||||
|
||||
inline void setSatWater_T(const Temperature &T){
|
||||
S = freesteam_set_Tx(T, 0.0);
|
||||
}
|
||||
|
||||
inline void setSatSteam_T(const Temperature &T){
|
||||
S = freesteam_set_Tx(T, 1.0);
|
||||
}
|
||||
|
||||
inline void setRegion1_pT(const Pressure &p, const Temperature &T){
|
||||
S.region = 1;
|
||||
S.R1.p = p;
|
||||
S.R1.T = T;
|
||||
}
|
||||
|
||||
inline void setRegion2_pT(const Pressure &p, const Temperature &T){
|
||||
S.region = 2;
|
||||
S.R2.p = p;
|
||||
S.R2.T = T;
|
||||
}
|
||||
|
||||
inline void setRegion4_Tx(const Temperature &T, const Num &x){
|
||||
S.region = 4;
|
||||
S.R4.T = T;
|
||||
S.R4.x = x;
|
||||
}
|
||||
|
||||
inline void setRegion3_rhoT(const Density &rho, const Temperature &T){
|
||||
S.region = 3;
|
||||
S.R3.T = T;
|
||||
S.R3.rho = rho;
|
||||
}
|
||||
|
||||
// Methods to return properties and state
|
||||
|
||||
inline int whichRegion(void) const{
|
||||
return S.region;
|
||||
}
|
||||
|
||||
inline double temp() const{return freesteam_T(S);}
|
||||
inline double pres() const{return freesteam_p(S);}
|
||||
inline double dens() const{return 1./freesteam_v(S);}
|
||||
inline double specvol() const{return freesteam_v(S);}
|
||||
inline double specienergy() const{return freesteam_u(S);}
|
||||
inline double specentropy() const{return freesteam_s(S);}
|
||||
inline double specenthalpy() const{return freesteam_h(S);}
|
||||
inline double speccp() const{return freesteam_cp(S);}
|
||||
inline double speccv() const{return freesteam_cv(S);}
|
||||
inline double quality() const{return freesteam_x(S);}
|
||||
inline double dynvisc() const{return freesteam_mu(S);}
|
||||
inline double conductivity() const{return freesteam_k(S);}
|
||||
};
|
||||
|
||||
template<SolveParam FirstProp, SolveParam SecondProp>
|
||||
class Solver2{
|
||||
|
||||
private:
|
||||
SteamSolveFunction *solvefunc;
|
||||
SteamRegionFunction *regionfunc;
|
||||
SteamBoundsFunction *boundfunc;
|
||||
|
||||
public:
|
||||
Solver2();
|
||||
~Solver2(){}
|
||||
|
||||
inline int whichRegion(const double &fp, const double &sp){return (*regionfunc)(fp,sp);}
|
||||
inline SteamCalculator solve(const double &fp, const double &sp){return SteamCalculator((*solvefunc)(fp,sp));}
|
||||
|
||||
/* ignore any provided guesses, we can't use those currently in freesteam 2.0 */
|
||||
inline SteamState solve(const double &fp, const double &sp, const SteamCalculator firstguess){return SteamCalculator((*solvefunc)(fp,sp));}
|
||||
};
|
||||
|
||||
template<>
|
||||
Solver2<SOLVE_PRESSURE, SOLVE_TEMPERATURE>::Solver2()
|
||||
: solvefunc(&freesteam_set_ph), regionfunc(&freesteam_region_ph), boundfunc(&freesteam_bounds_ph)
|
||||
{}
|
||||
|
||||
template<>
|
||||
Solver2<SOLVE_TEMPERATURE, SOLVE_ENTROPY>::Solver2()
|
||||
: solvefunc(&freesteam_set_Ts), regionfunc(&freesteam_region_Ts), boundfunc(&freesteam_bounds_Ts)
|
||||
{}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef FREESTEAM_CONFIG_H
|
||||
#define FREESTEAM_CONFIG_H
|
||||
|
||||
#define FREESTEAM_VERSION "2.1"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "region1.h"
|
||||
|
||||
static double gam(double pi, double tau);
|
||||
static double gampi(double pi, double tau);
|
||||
static double gampipi(double pi, double tau);
|
||||
static double gamtau(double pi, double tau);
|
||||
static double gamtautau(double pi, double tau);
|
||||
static double gampitau(double pi, double tau);
|
||||
|
||||
#define REGION1_GPT_PSTAR 16.53e6 /* Pa */
|
||||
#define REGION1_GPT_TSTAR 1386. /* K */
|
||||
|
||||
#define DEFINE_PITAU(P,T) \
|
||||
double pi = p / REGION1_GPT_PSTAR; \
|
||||
double tau = REGION1_GPT_TSTAR / T
|
||||
|
||||
#define R IAPWS97_R
|
||||
|
||||
#include <math.h>
|
||||
|
||||
double freesteam_region1_u_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return (R * T) * (tau * gamtau(pi,tau) - pi * gampi(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region1_v_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return (R * T / p) * pi * gampi(pi,tau);
|
||||
}
|
||||
|
||||
double freesteam_region1_s_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return R * (tau * gamtau(pi,tau) - gam(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region1_h_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return R * T * (tau * gamtau(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region1_cp_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return R * (-SQ(tau) * gamtautau(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region1_cv_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return R * (-SQ(tau) * gamtautau(pi,tau) + SQ(gampi(pi,tau) -
|
||||
tau * gampitau(pi,tau)) / gampipi(pi,tau)
|
||||
);
|
||||
}
|
||||
|
||||
double freesteam_region1_w_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
double gp = gampi(pi,tau);
|
||||
return sqrt(R * T * SQ(gp) / \
|
||||
(SQ(gp - tau*gampitau(pi,tau))/SQ(tau)/gamtautau(pi,tau) - gampipi(pi,tau))
|
||||
);
|
||||
}
|
||||
|
||||
double freesteam_region1_g_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * T * gam(pi,tau);
|
||||
}
|
||||
|
||||
double freesteam_region1_a_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * T * (gam(pi,tau) - gampi(pi,tau) * pi);
|
||||
}
|
||||
|
||||
|
||||
double freesteam_region1_alphav_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return 1./T * (1. - tau*gampitau(pi,tau)/gampi(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region1_kappaT_pT(double p, double T){
|
||||
DEFINE_PITAU(P,T);
|
||||
return -1./p * pi*gampipi(pi,tau)/gampi(pi,tau);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// REGION 1 G(p,T) EQUATIONS
|
||||
|
||||
typedef struct{
|
||||
int I, J;
|
||||
double n;
|
||||
} IJNData;
|
||||
|
||||
const IJNData REGION1_GPT_DATA[] = {
|
||||
{0, -2, 0.14632971213167E+00}
|
||||
,{0, -1, -0.84548187169114E+00}
|
||||
,{0, 0, -0.37563603672040E+01}
|
||||
,{0, 1, 0.33855169168385E+01}
|
||||
,{0, 2, -0.95791963387872E+00}
|
||||
,{0, 3, 0.15772038513228E+00}
|
||||
,{0, 4, -0.16616417199501E-01}
|
||||
,{0, 5, 0.81214629983568E-03}
|
||||
,{1, -9, 0.28319080123804E-03}
|
||||
,{1, -7, -0.60706301565874E-03}
|
||||
,{1, -1, -0.18990068218419E-01}
|
||||
,{1, 0, -0.32529748770505E-01}
|
||||
,{1, 1, -0.21841717175414E-01}
|
||||
,{1, 3, -0.52838357969930E-04}
|
||||
,{2, -3, -0.47184321073267E-03}
|
||||
,{2, 0, -0.30001780793026E-03}
|
||||
,{2, 1, 0.47661393906987E-04}
|
||||
,{2, 3, -0.44141845330846E-05}
|
||||
,{2, 17, -0.72694996297594E-15}
|
||||
,{3, -4, -0.31679644845054E-04}
|
||||
,{3, 0, -0.28270797985312E-05}
|
||||
,{3, 6, -0.85205128120103E-09}
|
||||
,{4, -5, -0.22425281908000E-05}
|
||||
,{4, -2, -0.65171222895601E-06}
|
||||
,{4, 10, -0.14341729937924E-12}
|
||||
,{5, -8, -0.40516996860117E-06}
|
||||
,{8, -11, -0.12734301741641E-08}
|
||||
,{8, -6, -0.17424871230634E-09}
|
||||
,{21, -29, -0.68762131295531E-18}
|
||||
,{23, -31, 0.14478307828521E-19}
|
||||
,{29, -38, 0.26335781662795E-22}
|
||||
,{30, -39, -0.11947622640071E-22}
|
||||
,{31, -40, 0.18228094581404E-23}
|
||||
,{32, -41, -0.93537087292458E-25}
|
||||
};
|
||||
|
||||
const unsigned REGION1_GPT_MAX = sizeof(REGION1_GPT_DATA)/sizeof(IJNData);
|
||||
|
||||
#define REGION1_GPT_LOOP \
|
||||
double sum = 0; \
|
||||
const IJNData *d, *e = REGION1_GPT_DATA + REGION1_GPT_MAX; \
|
||||
for(d = REGION1_GPT_DATA; d < e; ++d)
|
||||
|
||||
double gam(double pi, double tau){
|
||||
REGION1_GPT_LOOP{
|
||||
sum += d->n * ipow(7.1 - pi,d->I) * ipow(tau - 1.222,d->J);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gampi(double pi, double tau){
|
||||
REGION1_GPT_LOOP{
|
||||
sum += -d->n * d->I * ipow(7.1 - pi,d->I -1) * ipow(tau - 1.222,d->J);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gampipi(double pi, double tau){
|
||||
REGION1_GPT_LOOP{
|
||||
sum += d->n * d->I * (d->I - 1) * ipow(7.1 - pi, d->I - 2) * ipow(tau - 1.222, d->J);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gamtau(double pi, double tau){
|
||||
REGION1_GPT_LOOP{
|
||||
sum += d->n * ipow(7.1 - pi, d->I) * d->J * ipow(tau - 1.222, d->J - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gamtautau(double pi, double tau){
|
||||
REGION1_GPT_LOOP{
|
||||
sum += d->n * ipow(7.1 - pi, d->I) * d->J * (d->J - 1) * ipow(tau - 1.222, d->J - 2);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gampitau(double pi, double tau){
|
||||
REGION1_GPT_LOOP{
|
||||
sum += -d->n * d->I * ipow(7.1 - pi, d->I - 1) * d->J * ipow(tau - 1.222, d->J - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_REGION1_H
|
||||
#define FREESTEAM_REGION1_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FREESTEAM_DLL double freesteam_region1_u_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_v_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_s_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_h_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_cp_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_cv_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_w_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_a_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region1_g_pT(double p, double T);
|
||||
|
||||
/* used in calculations of derivatives, see derivs.c */
|
||||
double freesteam_region1_alphav_pT(double p, double T);
|
||||
double freesteam_region1_kappaT_pT(double p, double T);
|
||||
|
||||
#define REGION1_TMAX 623.15 /* K */
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "region2.h"
|
||||
|
||||
#define GAM0(PI,TAU) gam0(PI,TAU)
|
||||
#define GAM0PI(PI,TAU) (1./PI)
|
||||
#define GAM0PIPI(PI,TAU) (-1./SQ(PI))
|
||||
#define GAM0TAU(PI,TAU) gam0tau(TAU)
|
||||
#define GAM0TAUTAU(PI,TAU) gam0tautau(TAU)
|
||||
#define GAM0PITAU(PI,TAU) (0)
|
||||
|
||||
#define gam(PI,TAU) (GAM0(PI,TAU) + gamr(PI,TAU))
|
||||
#define gampi(PI,TAU) (GAM0PI(PI,TAU) + gamrpi(PI,TAU))
|
||||
#define gampipi(PI,TAU) (GAM0PIPI(PI,TAU) + gamrpipi(PI,TAU))
|
||||
#define gamtau(PI,TAU) (GAM0TAU(PI,TAU) + gamrtau(PI,TAU))
|
||||
#define gamtautau(PI,TAU) (GAM0TAUTAU(PI,TAU) + gamrtautau(PI,TAU))
|
||||
#define gampitau(PI,TAU) (GAM0PITAU(PI,TAU) + gamrpitau(PI,TAU))
|
||||
|
||||
static double gamr(double pi, double tau);
|
||||
static double gamrpi(double pi, double tau);
|
||||
static double gamrpipi(double pi, double tau);
|
||||
static double gamrtau(double pi, double tau);
|
||||
static double gamrtautau(double pi, double tau);
|
||||
static double gamrpitau(double pi, double tau);
|
||||
|
||||
static double gam0(double pi, double tau);
|
||||
static double gam0tau(double tau);
|
||||
static double gam0tautau(double tau);
|
||||
|
||||
#include <math.h>
|
||||
#include "common.h"
|
||||
|
||||
#define R IAPWS97_R
|
||||
|
||||
#define REGION2_GPT_PSTAR 1.e6 /* Pa */
|
||||
#define REGION2_GPT_TSTAR 540. /* K */
|
||||
|
||||
#define DEFINE_PITAU(P,T) \
|
||||
double pi = p / REGION2_GPT_PSTAR; \
|
||||
double tau = REGION2_GPT_TSTAR / T
|
||||
|
||||
|
||||
double freesteam_region2_v_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return (R * T / p) * pi * gampi(pi,tau);
|
||||
}
|
||||
|
||||
double freesteam_region2_u_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return (R * T) * (tau * gamtau(pi,tau) - pi * gampi(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region2_s_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * (tau * gamtau(pi,tau) - gam(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region2_h_pT(double p, double T){
|
||||
//fprintf(stderr,"%s: p = %f, T = %f\n",__func__,p,T);
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * T * (tau * gamtau(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region2_cp_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * (-SQ(tau) * gamtautau(pi,tau));
|
||||
}
|
||||
|
||||
double freesteam_region2_cv_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * (-SQ(tau) * gamtautau(pi,tau) + SQ(gampi(pi,tau) -
|
||||
tau * gampitau(pi,tau)) / gampipi(pi,tau)
|
||||
);
|
||||
}
|
||||
|
||||
double freesteam_region2_w_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
double gp = gamrpi(pi,tau);
|
||||
return sqrt(R * T * (1. + 2.*pi*gp+SQ(pi*gp))/
|
||||
((1. - SQ(pi)*gamrpipi(pi,tau)) + SQ(1. + pi*gp - tau*pi*gamrpitau(pi,tau))/SQ(tau)/gamtautau(pi,tau))
|
||||
);
|
||||
}
|
||||
|
||||
double freesteam_region2_g_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * T * gam(pi,tau);
|
||||
}
|
||||
|
||||
double freesteam_region2_a_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
return R * T * (gam(pi,tau) - gampi(pi,tau) * pi);
|
||||
}
|
||||
|
||||
double freesteam_region2_alphav_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
double pigamrpi = pi*gamrpi(pi,tau);
|
||||
double alphav = 1./T * (1. + pigamrpi - tau*pi*gamrpitau(pi,tau))/(1. + pigamrpi);
|
||||
//fprintf(stderr,"α_v = %g\n",alphav);
|
||||
return alphav;
|
||||
}
|
||||
|
||||
double freesteam_region2_kappaT_pT(double p, double T){
|
||||
DEFINE_PITAU(p,T);
|
||||
double kappaT = 1./p * (1.-SQ(pi)*gamrpipi(pi,tau)) / (1.+pi*gamrpi(pi,tau));
|
||||
//fprintf(stderr,"κ_T = %g\n",kappaT);
|
||||
return kappaT;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 2 IDEAL PART - GAM0(PI,TAU)
|
||||
*/
|
||||
|
||||
typedef struct{
|
||||
int J;
|
||||
double n;
|
||||
} JNData;
|
||||
|
||||
const JNData REGION2_GPT_IDEAL_DATA[] = {
|
||||
{0, -0.96927686500217E+01}
|
||||
,{1, 0.10086655968018E+02}
|
||||
,{-5, -0.56087911283020E-02}
|
||||
,{-4, 0.71452738081455E-01}
|
||||
,{-3, -0.40710498223928E+00}
|
||||
,{-2, 0.14240819171444E+01}
|
||||
,{-1, -0.43839511319450E+01}
|
||||
,{2, -0.28408632460772E+00}
|
||||
,{3, 0.21268463753307E-01}
|
||||
};
|
||||
|
||||
const unsigned REGION2_GPT_IDEAL_MAX = sizeof(REGION2_GPT_IDEAL_DATA)/sizeof(JNData);
|
||||
|
||||
#define REGION2_GPT_IDEAL_LOOP \
|
||||
double sum = 0; \
|
||||
const JNData *d, *e = REGION2_GPT_IDEAL_DATA + REGION2_GPT_IDEAL_MAX; \
|
||||
for(d = REGION2_GPT_IDEAL_DATA; d < e; ++d)
|
||||
|
||||
double gam0(double pi, double tau){
|
||||
REGION2_GPT_IDEAL_LOOP{
|
||||
sum += d->n * ipow(tau, d->J);
|
||||
}
|
||||
return log(pi) + sum;
|
||||
}
|
||||
|
||||
double gam0tau(double tau){
|
||||
REGION2_GPT_IDEAL_LOOP{
|
||||
sum += d->n * d->J * ipow(tau, d->J - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gam0tautau(double tau){
|
||||
REGION2_GPT_IDEAL_LOOP{
|
||||
sum += d->n * d->J * (d->J - 1) * ipow(tau, d->J - 2);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 2 RESIDUAL PART - GAMR(PI,TAU)
|
||||
*/
|
||||
|
||||
typedef struct{
|
||||
int I, J;
|
||||
double n;
|
||||
} IJNData;
|
||||
|
||||
const IJNData REGION2_GPT_RESID_DATA[] = {
|
||||
{1, 0, -0.17731742473213E-02}
|
||||
,{1, 1, -0.17834862292358E-01}
|
||||
,{1, 2, -0.45996013696365E-01}
|
||||
,{1, 3, -0.57581259083432E-01}
|
||||
,{1, 6, -0.50325278727930E-01}
|
||||
,{2, 1, -0.33032641670203E-04}
|
||||
,{2, 2, -0.18948987516315E-03}
|
||||
,{2, 4, -0.39392777243355E-02}
|
||||
,{2, 7, -0.43797295650573E-01}
|
||||
,{2, 36, -0.26674547914087E-04}
|
||||
,{3, 0, 0.20481737692309E-07}
|
||||
,{3, 1, 0.43870667284435E-06}
|
||||
,{3, 3, -0.32277677238570E-04}
|
||||
,{3, 6, -0.15033924542148E-02}
|
||||
,{3, 35, -0.40668253562649E-01}
|
||||
,{4, 1, -0.78847309559367E-09}
|
||||
,{4, 2, 0.12790717852285E-07}
|
||||
,{4, 3, 0.48225372718507E-06}
|
||||
,{5, 7, 0.22922076337661E-05}
|
||||
,{6, 3, -0.16714766451061E-10}
|
||||
,{6, 16, -0.21171472321355E-02}
|
||||
,{6, 35, -0.23895741934104E+02}
|
||||
,{7, 0, -0.59059564324270E-17}
|
||||
,{7, 11, -0.12621808899101E-05}
|
||||
,{7, 25, -0.38946842435739E-01}
|
||||
,{8, 8, 0.11256211360459E-10}
|
||||
,{8, 36, -0.82311340897998E+01}
|
||||
,{9, 13, 0.19809712802088E-07}
|
||||
,{10, 4, 0.10406965210174E-18}
|
||||
,{10, 10, -0.10234747095929E-12}
|
||||
,{10, 14, -0.10018179379511E-08}
|
||||
,{16, 29, -0.80882908646985E-10}
|
||||
,{16, 50, 0.10693031879409E+00}
|
||||
,{18, 57, -0.33662250574171E+00}
|
||||
,{20, 20, 0.89185845355421E-24}
|
||||
,{20, 35, 0.30629316876232E-12}
|
||||
,{20, 48, -0.42002467698208E-05}
|
||||
,{21, 21, -0.59056029685639E-25}
|
||||
,{22, 53, 0.37826947613457E-05}
|
||||
,{23, 39, -0.12768608934681E-14}
|
||||
,{24, 26, 0.73087610595061E-28}
|
||||
,{24, 40, 0.55414715350778E-16}
|
||||
,{24, 58, -0.94369707241210E-06}
|
||||
};
|
||||
|
||||
const unsigned REGION2_GPT_RESID_MAX = sizeof(REGION2_GPT_RESID_DATA)/sizeof(IJNData);
|
||||
|
||||
#define REGION2_GPT_RESID_LOOP \
|
||||
double sum = 0; \
|
||||
const IJNData *d, *e = REGION2_GPT_RESID_DATA + REGION2_GPT_RESID_MAX; \
|
||||
for(d = REGION2_GPT_RESID_DATA; d < e; ++d)
|
||||
|
||||
double gamr(double pi, double tau){
|
||||
REGION2_GPT_RESID_LOOP{
|
||||
sum += d->n * ipow(pi,d->I) * ipow(tau - 0.5,d->J);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gamrpi(double pi, double tau){
|
||||
REGION2_GPT_RESID_LOOP{
|
||||
sum += d->n * d->I * ipow(pi,d->I -1) * ipow(tau - 0.5,d->J);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gamrpipi(double pi, double tau){
|
||||
REGION2_GPT_RESID_LOOP{
|
||||
sum += d->n * d->I * (d->I - 1) * ipow(pi, d->I - 2) * ipow(tau - 0.5, d->J);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gamrtau(double pi, double tau){
|
||||
REGION2_GPT_RESID_LOOP{
|
||||
sum += d->n * ipow(pi, d->I) * d->J * ipow(tau - 0.5, d->J - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gamrtautau(double pi, double tau){
|
||||
REGION2_GPT_RESID_LOOP{
|
||||
sum += d->n * ipow(pi, d->I) * d->J * (d->J - 1) * ipow(tau - 0.5, d->J - 2);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double gamrpitau(double pi, double tau){
|
||||
REGION2_GPT_RESID_LOOP{
|
||||
sum += d->n * d->I * ipow(pi, d->I - 1) * d->J * ipow(tau - 0.5, d->J - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_REGION2_H
|
||||
#define FREESTEAM_REGION2_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define REGION2_TMAX 1073.15
|
||||
|
||||
FREESTEAM_DLL double freesteam_region2_v_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_u_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_s_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_h_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_cp_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_cv_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_w_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_a_pT(double p, double T);
|
||||
FREESTEAM_DLL double freesteam_region2_g_pT(double p, double T);
|
||||
|
||||
/* used in calculations of derivatives, see derivs.c */
|
||||
double freesteam_region2_alphav_pT(double p, double T);
|
||||
double freesteam_region2_kappaT_pT(double p, double T);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "region3.h"
|
||||
|
||||
const double REGION3_ARHOT_TSTAR = 647.096 /* K */;
|
||||
const double REGION3_ARHOT_RHOSTAR = 322. /* K */;
|
||||
|
||||
#define DEFINE_DELTAU(RHO,T) \
|
||||
double del = rho / REGION3_ARHOT_RHOSTAR; \
|
||||
double tau = REGION3_ARHOT_TSTAR / T
|
||||
|
||||
#define R 461.526
|
||||
|
||||
static double phi(double del, double tau);
|
||||
static double phidel(double del, double tau);
|
||||
static double phideldel(double del, double tau);
|
||||
static double phitau(double del, double tau);
|
||||
static double phitautau(double del, double tau);
|
||||
static double phideltau(double del, double tau);
|
||||
|
||||
#include <math.h>
|
||||
|
||||
double freesteam_region3_p_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return rho * R * T * del * phidel(del,tau);
|
||||
}
|
||||
|
||||
double freesteam_region3_u_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return R * T * tau * phitau(del,tau);
|
||||
}
|
||||
|
||||
double freesteam_region3_s_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return R * (tau * phitau(del,tau) - phi(del,tau));
|
||||
}
|
||||
|
||||
double freesteam_region3_h_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return R * T * (tau * phitau(del,tau) + del * phidel(del,tau));
|
||||
}
|
||||
|
||||
double freesteam_region3_cp_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return R * (
|
||||
-SQ(tau) * phitautau(del,tau)
|
||||
+ (
|
||||
ipow (del * phidel(del,tau) - del * tau * phideltau(del,tau), 2)
|
||||
/ (2 * del * phidel(del,tau) + SQ(del) * phideldel(del,tau))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
double freesteam_region3_cv_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return R * (-SQ(tau) * phitautau(del,tau));
|
||||
}
|
||||
|
||||
double freesteam_region3_w_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return sqrt(R * T * (
|
||||
2 * del * phidel(del,tau) + SQ(del) * phideldel(del,tau)
|
||||
- (
|
||||
ipow (del * phidel(del,tau) - del * tau * phideltau(del,tau), 2)
|
||||
/ (SQ(tau) * phitautau(del,tau))
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
double freesteam_region3_alphap_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return 1./T * (1. - tau*phideltau(del,tau)/phidel(del,tau));
|
||||
}
|
||||
|
||||
double freesteam_region3_betap_rhoT(double rho, double T){
|
||||
DEFINE_DELTAU(rho,T);
|
||||
return rho*(2. + del * phideldel(del,tau)/phidel(del,tau));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
typedef struct{
|
||||
int I, J;
|
||||
double n;
|
||||
} IJNData;
|
||||
|
||||
const double REGION3_N1 = 0.10658070028513E+01;
|
||||
|
||||
const IJNData REGION3_ARHOT_DATA[] = {
|
||||
{0, 0, -0.15732845290239E+02}
|
||||
,{0, 1, 0.20944396974307E+02}
|
||||
,{0, 2, -0.76867707878716E+01}
|
||||
,{0, 7, 0.26185947787954E+01}
|
||||
,{0, 10, -0.28080781148620E+01}
|
||||
,{0, 12, 0.12053369696517E+01}
|
||||
,{0, 23, -0.84566812812502E-02}
|
||||
,{1, 2, -0.12654315477714E+01}
|
||||
,{1, 6, -0.11524407806681E+01}
|
||||
,{1, 15, 0.88521043984318E+00}
|
||||
,{1, 17, -0.64207765181607E+00}
|
||||
,{2, 0, 0.38493460186671E+00}
|
||||
,{2, 2, -0.85214708824206E+00}
|
||||
,{2, 6, 0.48972281541877E+01}
|
||||
,{2, 7, -0.30502617256965E+01}
|
||||
,{2, 22, 0.39420536879154E-01}
|
||||
,{2, 26, 0.12558408424308E+00}
|
||||
,{3, 0, -0.27999329698710E+00}
|
||||
,{3, 2, 0.13899799569460E+01}
|
||||
,{3, 4, -0.20189915023570E+01}
|
||||
,{3, 16, -0.82147637173963E-02}
|
||||
,{3, 26, -0.47596035734923E+00}
|
||||
,{4, 0, 0.43984074473500E-01}
|
||||
,{4, 2, -0.44476435428739E+00}
|
||||
,{4, 4, 0.90572070719733E+00}
|
||||
,{4, 26, 0.70522450087967E+00}
|
||||
,{5, 1, 0.10770512626332E+00}
|
||||
,{5, 3, -0.32913623258954E+00}
|
||||
,{5, 26, -0.50871062041158E+00}
|
||||
,{6, 0, -0.22175400873096E-01}
|
||||
,{6, 2, 0.94260751665092E-01}
|
||||
,{6, 26, 0.16436278447961E+00}
|
||||
,{7, 2, -0.13503372241348E-01}
|
||||
,{8, 26, -0.14834345352472E-01}
|
||||
,{9, 2, 0.57922953628084E-03}
|
||||
,{9, 26, 0.32308904703711E-02}
|
||||
,{10, 0, 0.80964802996215E-04}
|
||||
,{10, 1, -0.16557679795037E-03}
|
||||
,{11, 26, -0.44923899061815E-04}
|
||||
};
|
||||
|
||||
const unsigned REGION3_ARHOT_MAX = sizeof(REGION3_ARHOT_DATA)/sizeof(IJNData);
|
||||
|
||||
#define REGION3_ARHOT_LOOP \
|
||||
double sum = 0; \
|
||||
const IJNData *d, *e = REGION3_ARHOT_DATA + REGION3_ARHOT_MAX; \
|
||||
for(d = REGION3_ARHOT_DATA; d < e; ++d)
|
||||
|
||||
double phi(double del, double tau){
|
||||
REGION3_ARHOT_LOOP{
|
||||
sum += d->n * ipow(del, d->I) * ipow(tau, d->J);
|
||||
}
|
||||
return sum + REGION3_N1 * log(del);
|
||||
}
|
||||
|
||||
double phidel(double del, double tau){
|
||||
REGION3_ARHOT_LOOP{
|
||||
sum += +d->n * d->I * ipow(del, d->I - 1) * ipow(tau, d->J);
|
||||
}
|
||||
return sum + REGION3_N1 / del;
|
||||
}
|
||||
|
||||
double phideldel(double del, double tau){
|
||||
REGION3_ARHOT_LOOP{
|
||||
sum += d->n * d->I * (d->I - 1) * ipow(del, d->I - 2) * ipow(tau, d->J);
|
||||
}
|
||||
return sum - REGION3_N1 / SQ(del) ;
|
||||
}
|
||||
|
||||
double phitau(double del, double tau){
|
||||
REGION3_ARHOT_LOOP{
|
||||
sum += d->n * ipow(del, d->I) * d->J * ipow(tau, d->J - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double phitautau(double del, double tau){
|
||||
REGION3_ARHOT_LOOP{
|
||||
sum += d->n * ipow(del, d->I) * d->J * (d->J - 1) * ipow(tau, d->J - 2);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
double phideltau(double del, double tau){
|
||||
REGION3_ARHOT_LOOP{
|
||||
sum += d->n * d->I * ipow(del, d->I - 1) * d->J * ipow(tau, d->J - 1);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_REGION3_H
|
||||
#define FREESTEAM_REGION3_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FREESTEAM_DLL double freesteam_region3_p_rhoT(double rho, double T);
|
||||
FREESTEAM_DLL double freesteam_region3_u_rhoT(double rho, double T);
|
||||
FREESTEAM_DLL double freesteam_region3_s_rhoT(double rho, double T);
|
||||
FREESTEAM_DLL double freesteam_region3_h_rhoT(double rho, double T);
|
||||
FREESTEAM_DLL double freesteam_region3_cp_rhoT(double rho, double T);
|
||||
FREESTEAM_DLL double freesteam_region3_cv_rhoT(double rho, double T);
|
||||
FREESTEAM_DLL double freesteam_region3_w_rhoT(double rho, double T);
|
||||
|
||||
/* used in calculations of derivatives, see derivs.c */
|
||||
double freesteam_region3_alphap_rhoT(double rho, double T);
|
||||
double freesteam_region3_betap_rhoT(double rho, double T);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "region4.h"
|
||||
|
||||
#include "region1.h"
|
||||
#include "region3.h"
|
||||
#include "region2.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const double REGION4_N[11] = { 0, 0.11670521452767E+04, -0.72421316703206E+06
|
||||
, -0.17073846940092E+02, 0.12020824702470E+05, -0.32325550322333E+07
|
||||
, 0.14915108613530E+02, -0.48232657361591E+04, 0.40511340542057E+06
|
||||
, -0.23855557567849E+00, 0.65017534844798E+03
|
||||
};
|
||||
|
||||
#define REGION4_PSTAR 1e6 /* Pa */
|
||||
#define REGION4_TSTAR 1 /* K */
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 4 SATURATION CURVE psat(T)
|
||||
*/
|
||||
|
||||
double freesteam_region4_psat_T(double T){
|
||||
|
||||
//fprintf(stderr,"freesteam_region4_psat_T(T = %f)\n", T );
|
||||
|
||||
double ups = T/REGION4_TSTAR + REGION4_N[9] / (T/REGION4_TSTAR - REGION4_N[10]);
|
||||
double A = SQ(ups) + REGION4_N[1] * ups + REGION4_N[2];
|
||||
double B = REGION4_N[3] * SQ(ups) + REGION4_N[4] * ups + REGION4_N[5];
|
||||
double C = REGION4_N[6] * SQ(ups) + REGION4_N[7] * ups + REGION4_N[8];
|
||||
|
||||
double expr = 2. * C / (- B + sqrt(SQ(B) - 4. * A * C));
|
||||
double psat = SQ(SQ(expr)) * REGION4_PSTAR;
|
||||
|
||||
/* fprintf(stderr,"freesteam_region4_psat_T = %f MPa\n", psat/1e6);*/
|
||||
return psat;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 4 SATURATION CURVE Tsat(p) (BACKWARDS EQUATION)
|
||||
*/
|
||||
|
||||
double freesteam_region4_Tsat_p(double p){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double beta = pow(p/REGION4_PSTAR, 0.25);
|
||||
double E = SQ(beta) + REGION4_N[3] * beta + REGION4_N[6];
|
||||
double F = REGION4_N[1] * SQ(beta) + REGION4_N[4] * beta + REGION4_N[7];
|
||||
double G = REGION4_N[2] * SQ(beta) + REGION4_N[5] * beta + REGION4_N[8];
|
||||
double D = 2. * G / (-F - sqrt(SQ(F) - 4. * E * G));
|
||||
|
||||
double theta = 0.5 * (REGION4_N[10] + D - sqrt(SQ(REGION4_N[10] + D) - 4.0 * (REGION4_N[9] + REGION4_N[10] * D)));
|
||||
|
||||
/* FIXME iterative improve this estimate? is it necessary? */
|
||||
|
||||
return theta /* * REGION4_TSTAR = 1 {K} */;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 4 DENSITIES rhof(T), rhog(T) (SUPPLEMENTARY EQUATIONS)
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Coefficients for getSatDensWater_T
|
||||
*/
|
||||
const double REGION4_B[7]
|
||||
= { 0, 1.99274064, 1.09965342, -0.510839303, -1.75493479, -45.5170352, -6.74694450E+05 };
|
||||
|
||||
/**
|
||||
Coefficients for getSatDensSteam_T
|
||||
*/
|
||||
const double REGION4_C[7]
|
||||
= { 0, -2.03150240, -2.68302940, -5.38626492, -17.2991605, -44.7586581, -63.9201063 };
|
||||
|
||||
|
||||
double freesteam_region4_rhof_T(double T){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double tau = 1 - T / IAPWS97_TCRIT;
|
||||
|
||||
double tau_1_3 = pow(tau,1./3);
|
||||
|
||||
double tau_2_3 = SQ(tau_1_3);
|
||||
double tau_5_3 = tau * tau_2_3;
|
||||
double tau_16_3 = SQ(tau_5_3) * tau_5_3 * tau_1_3;
|
||||
double tau_43_3 = SQ(tau_16_3) * SQ(tau_5_3) * tau_1_3;
|
||||
double tau_110_3 = SQ(tau_43_3) * tau_16_3 * tau_5_3 * tau;
|
||||
|
||||
double delta = 1
|
||||
+ REGION4_B[1]*tau_1_3
|
||||
+ REGION4_B[2]*tau_2_3
|
||||
+ REGION4_B[3]*tau_5_3
|
||||
+ REGION4_B[4]*tau_16_3
|
||||
+ REGION4_B[5]*tau_43_3
|
||||
+ REGION4_B[6]*tau_110_3;
|
||||
|
||||
return delta * IAPWS97_RHOCRIT;
|
||||
|
||||
/* FIXME iteratively improve vf estimate */
|
||||
}
|
||||
|
||||
double freesteam_region4_rhog_T(double T){
|
||||
|
||||
IAPWS97_APPROXIMATE;
|
||||
|
||||
double tau = 1. - T / IAPWS97_TCRIT;
|
||||
|
||||
double tau_1_6 = pow(tau,1.0/6);
|
||||
|
||||
double tau_2_6 = SQ(tau_1_6);
|
||||
double tau_4_6 = SQ(tau_2_6);
|
||||
double tau_8_6 = SQ(tau_4_6);
|
||||
double tau_16_6 = SQ(tau_8_6);
|
||||
double tau_18_6 = tau_16_6 * tau_2_6;
|
||||
double tau_37_6 = SQ(tau_18_6) * tau_1_6;
|
||||
double tau_71_6 = tau_37_6 * tau_18_6 * tau_16_6;
|
||||
|
||||
double ln_delta =
|
||||
REGION4_C[1]*tau_2_6
|
||||
+ REGION4_C[2]*tau_4_6
|
||||
+ REGION4_C[3]*tau_8_6
|
||||
+ REGION4_C[4]*tau_18_6
|
||||
+ REGION4_C[5]*tau_37_6
|
||||
+ REGION4_C[6]*tau_71_6;
|
||||
|
||||
return exp(ln_delta) * IAPWS97_RHOCRIT;
|
||||
|
||||
/* FIXME iteratively improve vg estimate */
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
INTERPOLATIONS FOR PROPERTIES WITHIN REGION 4
|
||||
*/
|
||||
|
||||
double freesteam_region4_v_Tx(double T, double x){
|
||||
double vf, vg;
|
||||
if(T < REGION1_TMAX){
|
||||
double psat = freesteam_region4_psat_T(T);
|
||||
vf = freesteam_region1_v_pT(psat,T);
|
||||
vg = freesteam_region2_v_pT(psat,T);
|
||||
}else{
|
||||
vf = 1./ freesteam_region4_rhof_T(T);
|
||||
vg = 1./ freesteam_region4_rhog_T(T);
|
||||
}
|
||||
return vf + x*(vg - vf);
|
||||
}
|
||||
|
||||
double freesteam_region4_u_Tx(double T, double x){
|
||||
double uf, ug;
|
||||
if(T < REGION1_TMAX){
|
||||
double psat = freesteam_region4_psat_T(T);
|
||||
uf = freesteam_region1_u_pT(psat,T);
|
||||
ug = freesteam_region2_u_pT(psat,T);
|
||||
}else{
|
||||
double rhof, rhog;
|
||||
rhof = freesteam_region4_rhof_T(T);
|
||||
rhog = freesteam_region4_rhog_T(T);
|
||||
uf = freesteam_region3_u_rhoT(rhof,T);
|
||||
ug = freesteam_region3_u_rhoT(rhog,T);
|
||||
}
|
||||
return uf + x*(ug - uf);
|
||||
}
|
||||
|
||||
double freesteam_region4_h_Tx(double T, double x){
|
||||
double hf, hg;
|
||||
if(T < REGION1_TMAX){
|
||||
double psat = freesteam_region4_psat_T(T);
|
||||
hf = freesteam_region1_h_pT(psat,T);
|
||||
hg = freesteam_region2_h_pT(psat,T);
|
||||
//fprintf(stderr,"%s: T = %f K, psat = %f MPa, hf = %f kJ/kg, hg = %f kJ/kg\n",__func__,T,psat/1e6,hf/1e3,hg);
|
||||
}else{
|
||||
double rhof, rhog;
|
||||
rhof = freesteam_region4_rhof_T(T);
|
||||
rhog = freesteam_region4_rhog_T(T);
|
||||
hf = freesteam_region3_h_rhoT(rhof,T);
|
||||
hg = freesteam_region3_h_rhoT(rhog,T);
|
||||
}
|
||||
return hf + x*(hg - hf);
|
||||
}
|
||||
|
||||
double freesteam_region4_s_Tx(double T, double x){
|
||||
double sf, sg;
|
||||
if(T < REGION1_TMAX){
|
||||
double psat = freesteam_region4_psat_T(T);
|
||||
sf = freesteam_region1_s_pT(psat,T);
|
||||
sg = freesteam_region2_s_pT(psat,T);
|
||||
}else{
|
||||
double rhof, rhog;
|
||||
rhof = freesteam_region4_rhof_T(T);
|
||||
rhog = freesteam_region4_rhog_T(T);
|
||||
sf = freesteam_region3_s_rhoT(rhof,T);
|
||||
sg = freesteam_region3_s_rhoT(rhog,T);
|
||||
}
|
||||
return sf + x*(sg - sf);
|
||||
}
|
||||
|
||||
double freesteam_region4_cp_Tx(double T, double x){
|
||||
double cpf, cpg;
|
||||
if(T < REGION1_TMAX){
|
||||
double psat = freesteam_region4_psat_T(T);
|
||||
cpf = freesteam_region1_cp_pT(psat,T);
|
||||
cpg = freesteam_region2_cp_pT(psat,T);
|
||||
}else{
|
||||
double rhof, rhog;
|
||||
rhof = freesteam_region4_rhof_T(T);
|
||||
rhog = freesteam_region4_rhog_T(T);
|
||||
cpf = freesteam_region3_cp_rhoT(rhof,T);
|
||||
cpg = freesteam_region3_cp_rhoT(rhog,T);
|
||||
}
|
||||
return cpf + x*(cpg - cpf);
|
||||
}
|
||||
|
||||
double freesteam_region4_cv_Tx(double T, double x){
|
||||
double cvf, cvg;
|
||||
if(T < REGION1_TMAX){
|
||||
double psat = freesteam_region4_psat_T(T);
|
||||
cvf = freesteam_region1_cv_pT(psat,T);
|
||||
cvg = freesteam_region2_cv_pT(psat,T);
|
||||
}else{
|
||||
double rhof, rhog;
|
||||
rhof = freesteam_region4_rhof_T(T);
|
||||
rhog = freesteam_region4_rhog_T(T);
|
||||
cvf = freesteam_region3_cv_rhoT(rhof,T);
|
||||
cvg = freesteam_region3_cv_rhoT(rhog,T);
|
||||
}
|
||||
return cvf + x*(cvg - cvf);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
double freesteam_region4_dpsatdT_T(double T){
|
||||
/* calculated this derivative using implicit differentiation of the
|
||||
quadratic expression, then derivatives of beta and script-theta */
|
||||
double beta = pow(freesteam_region4_psat_T(T)/REGION4_PSTAR, 0.25);
|
||||
#define N REGION4_N
|
||||
double theta = T/REGION4_TSTAR + N[9] / (T/REGION4_TSTAR - N[10]);
|
||||
double XBETA = (2.*beta + N[3])*SQ(theta) + (2.*beta*N[1] + N[4])*theta + 2.*N[2]*beta + N[5];
|
||||
double XTHETA = (2.*theta + N[1])*SQ(beta) + (2.*N[3]*theta + N[4])*beta + 2.*N[6]*theta + N[7];
|
||||
|
||||
double dthetadT = (1 - N[9] / (T/REGION4_TSTAR - N[10]))/REGION4_TSTAR;
|
||||
double dbetadtheta = -XTHETA/XBETA;
|
||||
double dpdbeta = 4*SQ(beta)*beta*REGION4_PSTAR;
|
||||
#undef N
|
||||
|
||||
return dpdbeta * dbetadtheta * dthetadT;
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_REGION4_H
|
||||
#define FREESTEAM_REGION4_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FREESTEAM_DLL double freesteam_region4_psat_T(double T);
|
||||
FREESTEAM_DLL double freesteam_region4_Tsat_p(double p);
|
||||
|
||||
FREESTEAM_DLL double freesteam_region4_rhof_T(double T);
|
||||
FREESTEAM_DLL double freesteam_region4_rhog_T(double T);
|
||||
|
||||
FREESTEAM_DLL double freesteam_region4_v_Tx(double T, double x);
|
||||
FREESTEAM_DLL double freesteam_region4_u_Tx(double T, double x);
|
||||
FREESTEAM_DLL double freesteam_region4_h_Tx(double T, double x);
|
||||
FREESTEAM_DLL double freesteam_region4_s_Tx(double T, double x);
|
||||
FREESTEAM_DLL double freesteam_region4_cp_Tx(double T, double x);
|
||||
FREESTEAM_DLL double freesteam_region4_cv_Tx(double T, double x);
|
||||
|
||||
FREESTEAM_DLL double freesteam_region4_dpsatdT_T(double T);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,427 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "solver2.h"
|
||||
|
||||
#include "region1.h"
|
||||
#include "region2.h"
|
||||
#include "region3.h"
|
||||
#include "region4.h"
|
||||
#include "b23.h"
|
||||
|
||||
#include "derivs.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <gsl/gsl_multiroots.h>
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
LOOKUP FOR APPROPRIATE PROPERTY EVALUATION FUNCTION
|
||||
*/
|
||||
|
||||
typedef double PropertyFunction(double, double);
|
||||
|
||||
static PropertyFunction *solver2_region3_propfn(FREESTEAM_CHAR A){
|
||||
switch(A){
|
||||
case 'p': return &freesteam_region3_p_rhoT;
|
||||
case 'u': return &freesteam_region3_u_rhoT;
|
||||
case 's': return &freesteam_region3_s_rhoT;
|
||||
case 'h': return &freesteam_region3_h_rhoT;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* this function is a needed bit of a redundancy with solver2 in region 4 */
|
||||
static double solver2_region4_p_Tx(double T, double x){
|
||||
(void)x;
|
||||
return freesteam_region4_psat_T(T);
|
||||
}
|
||||
|
||||
static PropertyFunction *solver2_region4_propfn(FREESTEAM_CHAR A){
|
||||
switch(A){
|
||||
case 'p': return &solver2_region4_p_Tx;
|
||||
case 'u': return &freesteam_region4_u_Tx;
|
||||
case 's': return &freesteam_region4_s_Tx;
|
||||
case 'h': return &freesteam_region4_h_Tx;
|
||||
case 'v': return &freesteam_region4_v_Tx;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* completely unnecessary... */
|
||||
static double solver2_region2_p_pT(double p, double T){
|
||||
(void)T;
|
||||
return p;
|
||||
}
|
||||
|
||||
static PropertyFunction *solver2_region2_propfn(FREESTEAM_CHAR A){
|
||||
switch(A){
|
||||
case 'p': return &solver2_region2_p_pT;
|
||||
case 'u': return &freesteam_region2_u_pT;
|
||||
case 's': return &freesteam_region2_s_pT;
|
||||
case 'h': return &freesteam_region2_h_pT;
|
||||
case 'v': return &freesteam_region2_v_pT;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* completely unnecessary... */
|
||||
static double solver2_region1_p_pT(double p, double T){
|
||||
(void)T;
|
||||
return p;
|
||||
}
|
||||
|
||||
static PropertyFunction *solver2_region1_propfn(FREESTEAM_CHAR A){
|
||||
switch(A){
|
||||
case 'p': return &solver2_region1_p_pT;
|
||||
case 'u': return &freesteam_region1_u_pT;
|
||||
case 's': return &freesteam_region1_s_pT;
|
||||
case 'h': return &freesteam_region1_h_pT;
|
||||
case 'v': return &freesteam_region1_v_pT;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct{
|
||||
FREESTEAM_CHAR A,B;
|
||||
PropertyFunction *Afn, *Bfn;
|
||||
double a,b;
|
||||
} Solver2Data;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 3
|
||||
*/
|
||||
|
||||
static int region3_f(const gsl_vector *x, void *user_data, gsl_vector *f){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
double rho = gsl_vector_get(x,0);
|
||||
double T = gsl_vector_get(x,1);
|
||||
gsl_vector_set(f, 0, (*(D->Afn))(rho,T) - (D->a));
|
||||
gsl_vector_set(f, 1, (*(D->Bfn))(rho,T) - (D->b));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region3_df(const gsl_vector *x, void *user_data, gsl_matrix *J){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
double rho = gsl_vector_get(x,0);
|
||||
double T = gsl_vector_get(x,1);
|
||||
SteamState S = freesteam_region3_set_rhoT(rho,T);
|
||||
gsl_matrix_set(J, 0, 0, -1./SQ(rho)*freesteam_region3_dAdvT(D->A,S));
|
||||
gsl_matrix_set(J, 0, 1, freesteam_region3_dAdTv(D->A,S));
|
||||
gsl_matrix_set(J, 1, 0, -1./SQ(rho)*freesteam_region3_dAdvT(D->B,S));
|
||||
gsl_matrix_set(J, 1, 1, freesteam_region3_dAdTv(D->B,S));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region3_fdf(const gsl_vector *x, void *user_data, gsl_vector *f, gsl_matrix *J){
|
||||
return region3_f(x, user_data, f) || region3_df(x, user_data, J);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void region3_print_state(size_t iter, gsl_multiroot_fdfsolver *s){
|
||||
double rho = gsl_vector_get(s->x,0);
|
||||
double T = gsl_vector_get(s->x,1);
|
||||
fprintf(stderr,"iter = %lu: rho = %g, T = %g\n", iter,rho,T);
|
||||
}
|
||||
#endif
|
||||
|
||||
SteamState freesteam_solver2_region3(FREESTEAM_CHAR A, FREESTEAM_CHAR B, double atarget, double btarget, SteamState guess, int *retstatus){
|
||||
const gsl_multiroot_fdfsolver_type *T;
|
||||
gsl_multiroot_fdfsolver *s;
|
||||
int status;
|
||||
size_t iter = 0;
|
||||
const size_t n = 2;
|
||||
|
||||
Solver2Data D = {A,B,solver2_region3_propfn(A), solver2_region3_propfn(B), atarget,btarget};
|
||||
|
||||
gsl_multiroot_function_fdf f = {®ion3_f, ®ion3_df, ®ion3_fdf, n, &D};
|
||||
|
||||
gsl_vector *x = gsl_vector_alloc(n);
|
||||
gsl_vector_set(x, 0, freesteam_rho(guess));
|
||||
gsl_vector_set(x, 1, freesteam_T(guess));
|
||||
T = gsl_multiroot_fdfsolver_gnewton;
|
||||
s = gsl_multiroot_fdfsolver_alloc(T, n);
|
||||
gsl_multiroot_fdfsolver_set(s, &f, x);
|
||||
//region3_print_state(iter, s);
|
||||
|
||||
do{
|
||||
iter++;
|
||||
status = gsl_multiroot_fdfsolver_iterate(s);
|
||||
//region3_print_state(iter, s);
|
||||
if(status){
|
||||
/* check if solver is stuck */
|
||||
break;
|
||||
}
|
||||
status = gsl_multiroot_test_residual(s->f, 2e-6);
|
||||
} while(status == GSL_CONTINUE && iter < 50);
|
||||
|
||||
SteamState S = freesteam_region3_set_rhoT(gsl_vector_get(s->x,0), gsl_vector_get(s->x,1));
|
||||
gsl_multiroot_fdfsolver_free(s);
|
||||
gsl_vector_free(x);
|
||||
*retstatus = status;
|
||||
if(status)fprintf(stderr,"%s (%s:%d): %s: ",__func__,__FILE__,__LINE__,gsl_strerror(status));
|
||||
//freesteam_fprint(stderr,S);
|
||||
return S;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 4
|
||||
*/
|
||||
|
||||
static int region4_f(const gsl_vector *X, void *user_data, gsl_vector *f){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
double T = gsl_vector_get(X,0);
|
||||
double x = gsl_vector_get(X,1);
|
||||
gsl_vector_set(f, 0, (*(D->Afn))(T,x) - (D->a));
|
||||
gsl_vector_set(f, 1, (*(D->Bfn))(T,x) - (D->b));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region4_df(const gsl_vector *x, void *user_data, gsl_matrix *J){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
SteamState S = freesteam_region4_set_Tx(gsl_vector_get(x,0),gsl_vector_get(x,1));
|
||||
gsl_matrix_set(J, 0, 0, freesteam_region4_dAdTx(D->A,S));
|
||||
gsl_matrix_set(J, 0, 1, freesteam_region4_dAdxT(D->A,S));
|
||||
gsl_matrix_set(J, 1, 0, freesteam_region4_dAdTx(D->B,S));
|
||||
gsl_matrix_set(J, 1, 1, freesteam_region4_dAdxT(D->B,S));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region4_fdf(const gsl_vector *x, void *user_data, gsl_vector *f, gsl_matrix *J){
|
||||
return region4_f(x, user_data, f) || region4_df(x, user_data, J);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void region4_print_state(size_t iter, gsl_multiroot_fdfsolver *s){
|
||||
double T = gsl_vector_get(s->x,0);
|
||||
double x = gsl_vector_get(s->x,1);
|
||||
fprintf(stderr,"iter = %lu: T = %g, x = %g\n", iter,T,x);
|
||||
}
|
||||
#endif
|
||||
|
||||
SteamState freesteam_solver2_region4(FREESTEAM_CHAR A, FREESTEAM_CHAR B, double atarget, double btarget, SteamState guess, int *retstatus){
|
||||
const gsl_multiroot_fdfsolver_type *T;
|
||||
gsl_multiroot_fdfsolver *s;
|
||||
int status;
|
||||
size_t iter = 0;
|
||||
const size_t n = 2;
|
||||
|
||||
Solver2Data D = {A,B,solver2_region4_propfn(A), solver2_region4_propfn(B), atarget,btarget};
|
||||
|
||||
gsl_multiroot_function_fdf f = {®ion4_f, ®ion4_df, ®ion4_fdf, n, &D};
|
||||
|
||||
gsl_vector *x = gsl_vector_alloc(n);
|
||||
assert(guess.region==4);
|
||||
gsl_vector_set(x, 0, guess.R4.T);
|
||||
gsl_vector_set(x, 1, guess.R4.x);
|
||||
T = gsl_multiroot_fdfsolver_gnewton;
|
||||
s = gsl_multiroot_fdfsolver_alloc(T, n);
|
||||
gsl_multiroot_fdfsolver_set(s, &f, x);
|
||||
//region4_print_state(iter, s);
|
||||
|
||||
do{
|
||||
iter++;
|
||||
status = gsl_multiroot_fdfsolver_iterate(s);
|
||||
//region4_print_state(iter, s);
|
||||
if(status){
|
||||
/* check if solver is stuck */
|
||||
break;
|
||||
}
|
||||
status = gsl_multiroot_test_residual(s->f, 1e-7);
|
||||
} while(status == GSL_CONTINUE && iter < 20);
|
||||
|
||||
fprintf(stderr,"status = %s\n", gsl_strerror (status));
|
||||
SteamState S = freesteam_region4_set_Tx(gsl_vector_get(s->x,0), gsl_vector_get(s->x,1));
|
||||
gsl_multiroot_fdfsolver_free(s);
|
||||
|
||||
gsl_vector_free(x);
|
||||
*retstatus = status;
|
||||
if(status)fprintf(stderr,"%s (%s:%d): %s: ",__func__,__FILE__,__LINE__,gsl_strerror(status));
|
||||
//freesteam_fprint(stderr,S);
|
||||
return S;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 2
|
||||
*/
|
||||
|
||||
static int region2_f(const gsl_vector *x, void *user_data, gsl_vector *f){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
double p = gsl_vector_get(x,0);
|
||||
double T = gsl_vector_get(x,1);
|
||||
gsl_vector_set(f, 0, (*(D->Afn))(p,T) - (D->a));
|
||||
gsl_vector_set(f, 1, (*(D->Bfn))(p,T) - (D->b));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region2_df(const gsl_vector *x, void *user_data, gsl_matrix *J){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
double p = gsl_vector_get(x,0);
|
||||
double T = gsl_vector_get(x,1);
|
||||
SteamState S = freesteam_region2_set_pT(p,T);
|
||||
gsl_matrix_set(J, 0, 0, freesteam_region2_dAdpT(D->A,S));
|
||||
gsl_matrix_set(J, 0, 1, freesteam_region2_dAdTp(D->A,S));
|
||||
gsl_matrix_set(J, 1, 0, freesteam_region2_dAdpT(D->B,S));
|
||||
gsl_matrix_set(J, 1, 1, freesteam_region2_dAdTp(D->B,S));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region2_fdf(const gsl_vector *x, void *user_data, gsl_vector *f, gsl_matrix *J){
|
||||
return region2_f(x, user_data, f) || region2_df(x, user_data, J);
|
||||
}
|
||||
|
||||
static void region2_print_state(size_t iter, gsl_multiroot_fdfsolver *s){
|
||||
double p = gsl_vector_get(s->x,0);
|
||||
double T = gsl_vector_get(s->x,1);
|
||||
fprintf(stderr,"iter = %lu: p = %g, T = %g\n", (long unsigned)iter,p,T);
|
||||
}
|
||||
|
||||
SteamState freesteam_solver2_region2(FREESTEAM_CHAR A, FREESTEAM_CHAR B, double atarget, double btarget, SteamState guess, int *retstatus){
|
||||
const gsl_multiroot_fdfsolver_type *T;
|
||||
gsl_multiroot_fdfsolver *s;
|
||||
int status;
|
||||
size_t iter = 0;
|
||||
const size_t n = 2;
|
||||
|
||||
fprintf(stderr,"region 2 solver...\n");
|
||||
Solver2Data D = {A,B,solver2_region2_propfn(A), solver2_region2_propfn(B), atarget,btarget};
|
||||
|
||||
gsl_multiroot_function_fdf f = {®ion2_f, ®ion2_df, ®ion2_fdf, n, &D};
|
||||
|
||||
gsl_vector *x = gsl_vector_alloc(n);
|
||||
gsl_vector_set(x, 0, freesteam_rho(guess));
|
||||
gsl_vector_set(x, 1, freesteam_T(guess));
|
||||
T = gsl_multiroot_fdfsolver_gnewton;
|
||||
s = gsl_multiroot_fdfsolver_alloc(T, n);
|
||||
gsl_multiroot_fdfsolver_set(s, &f, x);
|
||||
region2_print_state(iter, s);
|
||||
|
||||
do{
|
||||
iter++;
|
||||
status = gsl_multiroot_fdfsolver_iterate(s);
|
||||
region2_print_state(iter, s);
|
||||
if(status){
|
||||
/* check if solver is stuck */
|
||||
break;
|
||||
}
|
||||
status = gsl_multiroot_test_residual(s->f, 1e-7);
|
||||
} while(status == GSL_CONTINUE && iter < 20);
|
||||
|
||||
SteamState S = freesteam_region2_set_pT(gsl_vector_get(s->x,0), gsl_vector_get(s->x,1));
|
||||
gsl_multiroot_fdfsolver_free(s);
|
||||
|
||||
gsl_vector_free(x);
|
||||
*retstatus = status;
|
||||
if(status)fprintf(stderr,"%s (%s:%d): %s: ",__func__,__FILE__,__LINE__,gsl_strerror(status));
|
||||
//freesteam_fprint(stderr,S);
|
||||
return S;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
REGION 1
|
||||
*/
|
||||
|
||||
static int region1_f(const gsl_vector *x, void *user_data, gsl_vector *f){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
double p = gsl_vector_get(x,0);
|
||||
double T = gsl_vector_get(x,1);
|
||||
gsl_vector_set(f, 0, (*(D->Afn))(p,T) - (D->a));
|
||||
gsl_vector_set(f, 1, (*(D->Bfn))(p,T) - (D->b));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region1_df(const gsl_vector *x, void *user_data, gsl_matrix *J){
|
||||
#define D ((Solver2Data *)user_data)
|
||||
double p = gsl_vector_get(x,0);
|
||||
double T = gsl_vector_get(x,1);
|
||||
SteamState S = freesteam_region1_set_pT(p,T);
|
||||
gsl_matrix_set(J, 0, 0, freesteam_region1_dAdpT(D->A,S));
|
||||
gsl_matrix_set(J, 0, 1, freesteam_region1_dAdTp(D->A,S));
|
||||
gsl_matrix_set(J, 1, 0, freesteam_region1_dAdpT(D->B,S));
|
||||
gsl_matrix_set(J, 1, 1, freesteam_region1_dAdTp(D->B,S));
|
||||
return GSL_SUCCESS;
|
||||
#undef D
|
||||
}
|
||||
|
||||
static int region1_fdf(const gsl_vector *x, void *user_data, gsl_vector *f, gsl_matrix *J){
|
||||
return region1_f(x, user_data, f) || region1_df(x, user_data, J);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void region1_print_state(size_t iter, gsl_multiroot_fdfsolver *s){
|
||||
double p = gsl_vector_get(s->x,0);
|
||||
double T = gsl_vector_get(s->x,1);
|
||||
fprintf(stderr,"iter = %lu: p = %g, T = %g\n", iter,p,T);
|
||||
}
|
||||
#endif
|
||||
|
||||
SteamState freesteam_solver2_region1(FREESTEAM_CHAR A, FREESTEAM_CHAR B, double atarget, double btarget, SteamState guess, int *retstatus){
|
||||
const gsl_multiroot_fdfsolver_type *T;
|
||||
gsl_multiroot_fdfsolver *s;
|
||||
int status;
|
||||
size_t iter = 0;
|
||||
const size_t n = 2;
|
||||
|
||||
|
||||
//fprintf(stderr,"region 1 solver...\n");
|
||||
Solver2Data D = {A,B,solver2_region1_propfn(A), solver2_region1_propfn(B), atarget,btarget};
|
||||
|
||||
gsl_multiroot_function_fdf f = {®ion1_f, ®ion1_df, ®ion1_fdf, n, &D};
|
||||
|
||||
gsl_vector *x = gsl_vector_alloc(n);
|
||||
gsl_vector_set(x, 0, freesteam_rho(guess));
|
||||
gsl_vector_set(x, 1, freesteam_T(guess));
|
||||
T = gsl_multiroot_fdfsolver_gnewton;
|
||||
s = gsl_multiroot_fdfsolver_alloc(T, n);
|
||||
gsl_multiroot_fdfsolver_set(s, &f, x);
|
||||
//region1_print_state(iter, s);
|
||||
|
||||
do{
|
||||
iter++;
|
||||
status = gsl_multiroot_fdfsolver_iterate(s);
|
||||
//region1_print_state(iter, s);
|
||||
if(status){
|
||||
/* check if solver is stuck */
|
||||
break;
|
||||
}
|
||||
status = gsl_multiroot_test_residual(s->f, 1e-6);
|
||||
} while(status == GSL_CONTINUE && iter < 20);
|
||||
|
||||
SteamState S = freesteam_region1_set_pT(gsl_vector_get(s->x,0), gsl_vector_get(s->x,1));
|
||||
gsl_multiroot_fdfsolver_free(s);
|
||||
|
||||
gsl_vector_free(x);
|
||||
*retstatus = status;
|
||||
if(status){
|
||||
fprintf(stderr,"%s (%s:%d): %s: ",__func__,__FILE__,__LINE__,gsl_strerror(status));
|
||||
freesteam_fprint(stderr,S);
|
||||
}
|
||||
return S;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_SOLVER2_H
|
||||
#define FREESTEAM_SOLVER2_H
|
||||
|
||||
#include "common.h"
|
||||
#include "steam.h"
|
||||
|
||||
/*
|
||||
two-way solver interface, for unusual property pairs that are not
|
||||
implemented in official IAPWS releases.
|
||||
|
||||
this solver will use provided 'first guess' estimates, meaning that
|
||||
if correlations, even approximate, can be provided, then this will
|
||||
decrease unneeded iteration.
|
||||
|
||||
these solvers first require that you know which region you're in.
|
||||
This is because the correlation variables are different for the different
|
||||
regions.
|
||||
|
||||
'freesteam_region_XX functions will calculate the region for you; but
|
||||
these need to be hand-coded at this stage.
|
||||
*/
|
||||
|
||||
/**
|
||||
Two-variable Newton solver for Region 3, using finite difference
|
||||
approximations for derivatives. The names of the provided variables are
|
||||
given as X and Y (eg 'T' and 's') then the require state values are given
|
||||
as x and y (eg 300 and 5500). The solver will attempt to find a state
|
||||
that satisfies the provided input, and return it as output.
|
||||
|
||||
On return, the variable status will be set to 0 on success, or an error code
|
||||
if something has gone wrong, eg failed to converge.
|
||||
|
||||
A first guess must be provided via the 'guess' parameter.
|
||||
|
||||
FIXME provide 'default' guess functions.
|
||||
*/
|
||||
FREESTEAM_DLL SteamState freesteam_solver2_region1(FREESTEAM_CHAR X, FREESTEAM_CHAR Y, double x, double y, SteamState guess, int *status);
|
||||
FREESTEAM_DLL SteamState freesteam_solver2_region2(FREESTEAM_CHAR X, FREESTEAM_CHAR Y, double x, double y, SteamState guess, int *status);
|
||||
FREESTEAM_DLL SteamState freesteam_solver2_region3(FREESTEAM_CHAR X, FREESTEAM_CHAR Y, double x, double y, SteamState guess, int *status);
|
||||
FREESTEAM_DLL SteamState freesteam_solver2_region4(FREESTEAM_CHAR X, FREESTEAM_CHAR Y, double x, double y, SteamState guess, int *status);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "steam.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "region1.h"
|
||||
#include "region2.h"
|
||||
#include "region3.h"
|
||||
#include "region4.h"
|
||||
#include "b23.h"
|
||||
#include "backwards.h"
|
||||
#include "viscosity.h"
|
||||
#include "thcond.h"
|
||||
|
||||
/* 'setter' functions for SteamState (forwards equations) */
|
||||
|
||||
SteamState freesteam_region1_set_pT(double p, double T){
|
||||
SteamState S;
|
||||
S.region = 1;
|
||||
S.R1.p = p;
|
||||
S.R1.T = T;
|
||||
/* FIXME add bounds check? */
|
||||
return S;
|
||||
}
|
||||
|
||||
SteamState freesteam_region2_set_pT(double p, double T){
|
||||
SteamState S;
|
||||
S.region = 2;
|
||||
S.R2.p = p;
|
||||
S.R2.T = T;
|
||||
/* FIXME add bounds check? */
|
||||
return S;
|
||||
}
|
||||
|
||||
SteamState freesteam_region3_set_rhoT(double rho, double T){
|
||||
SteamState S;
|
||||
S.region = 3;
|
||||
S.R3.rho = rho;
|
||||
S.R3.T = T;
|
||||
/* FIXME add bounds check? */
|
||||
return S;
|
||||
}
|
||||
|
||||
SteamState freesteam_region4_set_Tx(double T, double x){
|
||||
SteamState S;
|
||||
S.region = 4;
|
||||
S.R4.T = T;
|
||||
S.R4.x = x;
|
||||
/* FIXME add bounds check? */
|
||||
return S;
|
||||
}
|
||||
|
||||
int freesteam_fprint(FILE *f, SteamState S){
|
||||
int n = 0;
|
||||
n += fprintf(f, "region %d: ", S.region);
|
||||
switch(S.region){
|
||||
case 1:
|
||||
n += fprintf(f, "p = %f MPa, T = %f K\n", S.R1.p/1e6, S.R1.T);
|
||||
break;
|
||||
case 2:
|
||||
n += fprintf(f, "p = %f MPa, T = %f K\n", S.R2.p/1e6, S.R2.T);
|
||||
break;
|
||||
case 3:
|
||||
n += fprintf(f, "rho = %f kg/m³, T = %f K\n", S.R3.rho, S.R1.T);
|
||||
break;
|
||||
case 4:
|
||||
n += fprintf(f, "T = %f, x = %f\n", S.R4.T, S.R4.x);
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/* 'getter' functions for SteamState */
|
||||
|
||||
int freesteam_region(SteamState S){
|
||||
return (int)S.region;
|
||||
}
|
||||
|
||||
double freesteam_T(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return S.R1.T;
|
||||
case 2:
|
||||
return S.R2.T;
|
||||
case 3:
|
||||
return S.R3.T;
|
||||
case 4:
|
||||
return S.R4.T;
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_T\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_p(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return S.R1.p;
|
||||
case 2:
|
||||
return S.R2.p;
|
||||
case 3:
|
||||
return freesteam_region3_p_rhoT(S.R3.rho, S.R3.T);
|
||||
case 4:
|
||||
return freesteam_region4_psat_T(S.R4.T);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_p\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double freesteam_v(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_region1_v_pT(S.R1.p,S.R1.T);
|
||||
case 2:
|
||||
return freesteam_region2_v_pT(S.R2.p,S.R2.T);
|
||||
case 3:
|
||||
return 1./S.R3.rho;
|
||||
case 4:
|
||||
return freesteam_region4_v_Tx(S.R4.T, S.R4.x);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_v\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_rho(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return 1./freesteam_region1_v_pT(S.R1.p,S.R1.T);
|
||||
case 2:
|
||||
return 1./freesteam_region2_v_pT(S.R2.p,S.R2.T);
|
||||
case 3:
|
||||
return S.R3.rho;
|
||||
case 4:
|
||||
return 1./freesteam_region4_v_Tx(S.R4.T, S.R4.x);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_rho\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double freesteam_u(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_region1_u_pT(S.R1.p, S.R1.T);
|
||||
case 2:
|
||||
return freesteam_region2_u_pT(S.R2.p, S.R2.T);
|
||||
case 3:
|
||||
return freesteam_region3_u_rhoT(S.R3.rho,S.R3.T);
|
||||
case 4:
|
||||
return freesteam_region4_u_Tx(S.R4.T, S.R4.x);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_u\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_h(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_region1_h_pT(S.R1.p, S.R1.T);
|
||||
case 2:
|
||||
return freesteam_region2_h_pT(S.R2.p, S.R2.T);
|
||||
case 3:
|
||||
return freesteam_region3_h_rhoT(S.R3.rho,S.R3.T);
|
||||
case 4:
|
||||
return freesteam_region4_h_Tx(S.R4.T, S.R4.x);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_h\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double freesteam_s(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_region1_s_pT(S.R1.p, S.R1.T);
|
||||
case 2:
|
||||
return freesteam_region2_s_pT(S.R2.p, S.R2.T);
|
||||
case 3:
|
||||
return freesteam_region3_s_rhoT(S.R3.rho,S.R3.T);
|
||||
case 4:
|
||||
return freesteam_region4_s_Tx(S.R4.T, S.R4.x);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_s\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_cp(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_region1_cp_pT(S.R1.p, S.R1.T);
|
||||
case 2:
|
||||
return freesteam_region2_cp_pT(S.R2.p, S.R2.T);
|
||||
case 3:
|
||||
return freesteam_region3_cp_rhoT(S.R3.rho,S.R3.T);
|
||||
case 4:
|
||||
return freesteam_region4_cp_Tx(S.R4.T, S.R4.x);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_cp\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_cv(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_region1_cv_pT(S.R1.p, S.R1.T);
|
||||
case 2:
|
||||
return freesteam_region2_cv_pT(S.R2.p, S.R2.T);
|
||||
case 3:
|
||||
return freesteam_region3_cv_rhoT(S.R3.rho,S.R3.T);
|
||||
case 4:
|
||||
return freesteam_region4_cv_Tx(S.R4.T, S.R4.x);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region in freesteam_cv\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_w(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_region1_w_pT(S.R1.p, S.R1.T);
|
||||
case 2:
|
||||
return freesteam_region2_w_pT(S.R2.p, S.R2.T);
|
||||
case 3:
|
||||
return freesteam_region3_w_rhoT(S.R3.rho,S.R3.T);
|
||||
#if 0
|
||||
case 4:
|
||||
return freesteam_region4_w_Tx(S.R4.T, S.R4.x);
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region '%d' in freesteam_w\n",S.region);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_x(SteamState S){
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return 0.;
|
||||
case 2:
|
||||
return 1.;
|
||||
case 3:
|
||||
if(S.R3.rho > IAPWS97_RHOCRIT)return 0.;
|
||||
return 1.;
|
||||
case 4:
|
||||
return S.R4.x;
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region '%d' in freesteam_x\n",S.region);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_mu(SteamState S){
|
||||
static char warned = 0;
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_mu_rhoT(1./freesteam_region1_v_pT(S.R1.p,S.R1.T), S.R1.T);
|
||||
case 2:
|
||||
return freesteam_mu_rhoT(1./freesteam_region2_v_pT(S.R2.p,S.R2.T), S.R2.T);
|
||||
case 3:
|
||||
return freesteam_mu_rhoT(S.R3.rho, S.R3.T);
|
||||
case 4:
|
||||
if(!warned){
|
||||
fprintf(stderr,"WARNING: viscosity evaluation in region 4 is poorly defined! (this warning is only shown once)\n");
|
||||
warned = 1;
|
||||
}
|
||||
return freesteam_mu_rhoT(1./freesteam_region4_v_Tx(S.R4.T, S.R4.x), S.R4.T);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region '%d' in freesteam_mu\n",S.region);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
double freesteam_k(SteamState S){
|
||||
static char warned = 0;
|
||||
switch(S.region){
|
||||
case 1:
|
||||
return freesteam_k_rhoT(1./freesteam_region1_v_pT(S.R1.p,S.R1.T), S.R1.T);
|
||||
case 2:
|
||||
return freesteam_k_rhoT(1./freesteam_region2_v_pT(S.R2.p,S.R2.T), S.R2.T);
|
||||
case 3:
|
||||
return freesteam_k_rhoT(S.R3.rho, S.R3.T);
|
||||
case 4:
|
||||
if(!warned){
|
||||
fprintf(stderr,"WARNING: thermal conductivity evaluation in region 4 is poorly defined! (this warning is only shown once)\n");
|
||||
warned = 1;
|
||||
}
|
||||
return freesteam_k_rhoT(1./freesteam_region4_v_Tx(S.R4.T, S.R4.x), S.R4.T);
|
||||
default:
|
||||
fprintf(stderr,"ERROR: invalid region '%d' in freesteam_k\n",S.region);
|
||||
exit(1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2005 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef FREESTEAM_STEAM_H
|
||||
#define FREESTEAM_STEAM_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdio.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;
|
||||
|
||||
FREESTEAM_DLL int freesteam_region(SteamState S);
|
||||
|
||||
FREESTEAM_DLL SteamState freesteam_region1_set_pT(double p, double T);
|
||||
FREESTEAM_DLL SteamState freesteam_region2_set_pT(double p, double T);
|
||||
FREESTEAM_DLL SteamState freesteam_region3_set_rhoT(double rho, double T);
|
||||
FREESTEAM_DLL SteamState freesteam_region4_set_Tx(double T, double x);
|
||||
|
||||
FREESTEAM_DLL int freesteam_fprint(FILE *f, SteamState S);
|
||||
|
||||
#if 0
|
||||
# define FREESTEAM_DEBUG(NAME,STATE)\
|
||||
fprintf(stderr,"%s (%s:%d): %s ",__func__,__FILE__,__LINE__,NAME);\
|
||||
freesteam_fprint(stderr,S);
|
||||
#else
|
||||
# define FREESTEAM_DEBUG(NAME,STATE)
|
||||
#endif
|
||||
|
||||
typedef double SteamPropertyFunction(SteamState S);
|
||||
|
||||
FREESTEAM_DLL double freesteam_p(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_T(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_rho(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_v(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_u(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_h(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_s(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_cp(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_cv(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_w(SteamState S);
|
||||
|
||||
FREESTEAM_DLL double freesteam_x(SteamState S);
|
||||
|
||||
FREESTEAM_DLL double freesteam_mu(SteamState S);
|
||||
FREESTEAM_DLL double freesteam_k(SteamState S);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "steam_pT.h"
|
||||
#include "region1.h"
|
||||
#include "region4.h"
|
||||
#include "region2.h"
|
||||
#include "region3.h"
|
||||
#include "zeroin.h"
|
||||
#include "b23.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
typedef struct{
|
||||
double p, T;
|
||||
} SteamPTData;
|
||||
|
||||
static double pT_region3_fn(double rho, void *user_data){
|
||||
#define D ((SteamPTData *)user_data)
|
||||
return D->p - freesteam_region3_p_rhoT(rho, D->T);
|
||||
#undef D
|
||||
}
|
||||
|
||||
/**
|
||||
This function will never return region 4, because it's not possible
|
||||
to 'sit on the knife' of saturation. If you need to set saturated states,
|
||||
you should use another function such as freesteam_region1_set_Tx.
|
||||
*/
|
||||
SteamState freesteam_set_pT(double p, double T){
|
||||
SteamState S;
|
||||
if(T < REGION1_TMAX){
|
||||
if(p > freesteam_region4_psat_T(T)){
|
||||
S.region = 1;
|
||||
S.R1.T = T;
|
||||
S.R1.p = p;
|
||||
}else{
|
||||
S.region = 2;
|
||||
S.R2.T = T;
|
||||
S.R2.p = p;
|
||||
}
|
||||
}else{
|
||||
//fprintf(stderr,"%s: T = %g >= REGION1_TMAX = %g\n",__func__,T,REGION1_TMAX);
|
||||
/* FIXME some optimisation possiblxe here with test for lower pressures */
|
||||
double T23 = freesteam_b23_T_p(p);
|
||||
double p23min = freesteam_b23_p_T(REGION1_TMAX);
|
||||
if(p < p23min || T > T23){
|
||||
//fprintf(stderr,"%s: T = %g > T23 = %g\n",__func__,T,T23);
|
||||
S.region = 2;
|
||||
S.R2.T = T;
|
||||
S.R2.p = p;
|
||||
}else{
|
||||
/* FIXME the limit values are all wrong here! */
|
||||
//fprintf(stderr,"%s: region 3\n",__func__);
|
||||
SteamPTData D = {p,T};
|
||||
double ub = 1./freesteam_region1_v_pT(IAPWS97_PMAX,REGION1_TMAX);
|
||||
double lb = 1./freesteam_region2_v_pT(freesteam_b23_p_T(T),T);
|
||||
/* if we're in the little wee area around the critical pt... */
|
||||
if(T < IAPWS97_TCRIT){
|
||||
double psat = freesteam_region4_psat_T(T);
|
||||
if(p < psat){
|
||||
ub = freesteam_region4_rhog_T(T);
|
||||
assert(lb<ub);
|
||||
}else{
|
||||
lb = freesteam_region4_rhof_T(T);
|
||||
//fprintf(stderr,"lb = %g, ub = %g\n",lb,ub);
|
||||
assert(lb<ub);
|
||||
}
|
||||
}
|
||||
double tol = 1e-7;
|
||||
double sol, err = 0;
|
||||
if(zeroin_solve(&pT_region3_fn, &D, lb, ub, tol, &sol, &err)){
|
||||
fprintf(stderr,"%s (%s:%d): failed to solve for rho\n",__func__,__FILE__,__LINE__);
|
||||
exit(1);
|
||||
}
|
||||
S.region = 3;
|
||||
S.R3.T = T;
|
||||
S.R3.rho = sol;
|
||||
//assert(fabs((freesteam_p(S) - p)/p) < tol);
|
||||
}
|
||||
}
|
||||
//fprintf(stderr,"%s: region %d\n",__func__,S.region);
|
||||
return S;
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_STEAMPT_H
|
||||
#define FREESTEAM_STEAMPT_H
|
||||
|
||||
#include "common.h"
|
||||
#include "steam.h"
|
||||
|
||||
FREESTEAM_DLL SteamState freesteam_set_pT(double p, double T);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "steam_ph.h"
|
||||
|
||||
#include "region1.h"
|
||||
#include "region2.h"
|
||||
#include "region3.h"
|
||||
#include "region4.h"
|
||||
#include "b23.h"
|
||||
#include "backwards.h"
|
||||
#include "solver2.h"
|
||||
#include "zeroin.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int freesteam_bounds_ph(double p, double h, int verbose){
|
||||
|
||||
#define BOUND_WARN(MSG) \
|
||||
if(verbose){\
|
||||
fprintf(stderr,"%s (%s:%d): WARNING " MSG " (p = %g MPa, h = %g kJ/kg)\n"\
|
||||
,__func__,__FILE__,__LINE__,p/1e6,h/1e3);\
|
||||
}
|
||||
|
||||
if(p <= 0){
|
||||
BOUND_WARN("p <= 0");
|
||||
return 1;
|
||||
}
|
||||
if(p > IAPWS97_PMAX){
|
||||
BOUND_WARN("p > PMAX");
|
||||
return 2;
|
||||
}
|
||||
|
||||
double hmax = freesteam_region2_h_pT(p,REGION2_TMAX);
|
||||
if(h>hmax){
|
||||
BOUND_WARN("h > hmax");
|
||||
return 3;
|
||||
}
|
||||
double hmin = freesteam_region1_h_pT(p,IAPWS97_TMIN);
|
||||
if(h < hmin){
|
||||
BOUND_WARN("h < hmin");
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
#undef BOUND_WARN
|
||||
}
|
||||
|
||||
int freesteam_region_ph(double p, double h){
|
||||
//fprintf(stderr,"freesteam_set_ph(p = %f, h = %f)\n",p,h);
|
||||
|
||||
double p13 = 0;
|
||||
p13 = freesteam_region4_psat_T(REGION1_TMAX);
|
||||
|
||||
//fprintf(stderr,"p13 = %lf MPa\n",p13/1.e6);
|
||||
//fprintf(stderr,"check: %f\n",freesteam_region4_psat_T(REGION1_TMAX));
|
||||
|
||||
if(p <= p13){
|
||||
double Tsat = freesteam_region4_Tsat_p(p);
|
||||
double hf = freesteam_region1_h_pT(p,Tsat);
|
||||
if(h<hf){
|
||||
return 1;
|
||||
}
|
||||
double hg = freesteam_region2_h_pT(p,Tsat);
|
||||
if(h>hg){
|
||||
return 2;
|
||||
}
|
||||
/* this is the low-pressure portion of region 4 */
|
||||
return 4;
|
||||
}
|
||||
|
||||
double h13 = freesteam_region1_h_pT(p,REGION1_TMAX);
|
||||
if(h <= h13){
|
||||
return 1;
|
||||
}
|
||||
|
||||
double T23 = freesteam_b23_T_p(p);
|
||||
//fprintf(stderr,"p = %f MPa --> T23(p) = %f K (%f °C)\n",p/1e6,T23,T23-273.15);
|
||||
double h23 = freesteam_region2_h_pT(p,T23);
|
||||
if(h >= h23){
|
||||
return 2;
|
||||
}
|
||||
|
||||
double psat = freesteam_region3_psat_h(h);
|
||||
if(p > psat){
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* high-pressure portion of region 4 */
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
typedef struct SolvePHData_struct{
|
||||
double p, h;
|
||||
} SolvePHData;
|
||||
|
||||
#define D ((SolvePHData *)user_data)
|
||||
static ZeroInSubjectFunction ph_region2_fn;
|
||||
double ph_region2_fn(double T, void *user_data){
|
||||
return D->h - freesteam_region2_h_pT(D->p, T);
|
||||
}
|
||||
#undef D
|
||||
|
||||
|
||||
SteamState freesteam_set_ph(double p, double h){
|
||||
SteamState S;
|
||||
S.region = (char)freesteam_region_ph(p,h);
|
||||
//int status;
|
||||
switch(S.region){
|
||||
case 1:
|
||||
S.R1.p = p;
|
||||
S.R1.T = freesteam_region1_T_ph(p, h);
|
||||
#if 0
|
||||
S = freesteam_solver2_region1('p','h', p, h, S, &status);
|
||||
if(status){
|
||||
fprintf(stderr,"%s: WARNING: Failed to converge in region 1\n",__func__);
|
||||
}
|
||||
#endif
|
||||
return S;
|
||||
case 2:
|
||||
S.R2.p = p;
|
||||
S.R2.T = freesteam_region2_T_ph(p, h);
|
||||
{
|
||||
double lb = S.R2.T * 0.999;
|
||||
double ub = S.R2.T * 1.001;
|
||||
double tol = 1e-9; /* ??? */
|
||||
double sol, err;
|
||||
SolvePHData D = {p, h};
|
||||
zeroin_solve(&ph_region2_fn, &D, lb, ub, tol, &sol, &err);
|
||||
S.R2.T = sol;
|
||||
}
|
||||
#if 0
|
||||
/* solver2 is not working in this region, for some reason. */
|
||||
S = freesteam_solver2_region2('p','h', p, h, S, &status);
|
||||
if(status){
|
||||
fprintf(stderr,"%s: WARNING: Failed to converge in region 2\n");
|
||||
}
|
||||
#endif
|
||||
return S;
|
||||
case 3:
|
||||
S.R3.rho = 1./freesteam_region3_v_ph(p, h);
|
||||
S.R3.T = freesteam_region3_T_ph(p, h);
|
||||
#if 0
|
||||
/* FIXME: this code doesn't work, see pTdiagram.h for example */
|
||||
/* by not iterating here, the relative error is increased from
|
||||
about 1e-12 to 1e-4 */
|
||||
S = freesteam_solver2_region3('p','h', p, h, S, &status);
|
||||
if(status){
|
||||
fprintf(stderr,"%s: WARNING: Failed to converge in region 3\n",__func__);
|
||||
}
|
||||
#endif
|
||||
return S;
|
||||
case 4:
|
||||
S.R4.T = freesteam_region4_Tsat_p(p);
|
||||
//fprintf(stderr,"%s: region 4, Tsat = %g\n",__func__,S.R4.T);
|
||||
double hf, hg;
|
||||
if(S.R4.T <= REGION1_TMAX){
|
||||
hf = freesteam_region1_h_pT(p,S.R4.T);
|
||||
hg = freesteam_region2_h_pT(p,S.R4.T);
|
||||
}else{
|
||||
/* TODO iteratively improve estimate of T */
|
||||
double rhof = freesteam_region4_rhof_T(S.R4.T);
|
||||
double rhog = freesteam_region4_rhog_T(S.R4.T);
|
||||
/* FIXME iteratively improve these estimates of rhof, rhog */
|
||||
hf = freesteam_region3_h_rhoT(rhof,S.R4.T);
|
||||
hg = freesteam_region3_h_rhoT(rhog,S.R4.T);
|
||||
}
|
||||
S.R4.x = (h - hf)/(hg - hf);
|
||||
return S;
|
||||
default:
|
||||
fprintf(stderr,"%s: invalid region %d\n",__func__,S.region);
|
||||
return S;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef FREESTEAM_STEAMPH_H
|
||||
#define FREESTEAM_STEAMPH_H
|
||||
|
||||
#include "common.h"
|
||||
#include "steam.h"
|
||||
|
||||
FREESTEAM_DLL int freesteam_bounds_ph(double p, double h, int verbose);
|
||||
|
||||
FREESTEAM_DLL int freesteam_region_ph(double p, double h);
|
||||
|
||||
FREESTEAM_DLL SteamState freesteam_set_ph(double p, double h);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "steam_pv.h"
|
||||
|
||||
#include "region1.h"
|
||||
#include "region2.h"
|
||||
#include "region3.h"
|
||||
#include "region4.h"
|
||||
#include "b23.h"
|
||||
#include "backwards.h"
|
||||
#include "solver2.h"
|
||||
#include "zeroin.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int freesteam_bounds_pv(double p, double v, int verbose){
|
||||
#define BOUND_WARN(MSG) \
|
||||
if(verbose){\
|
||||
fprintf(stderr,"%s (%s:%d): WARNING " MSG " (p = %g MPa, v = %g m3/kg)\n"\
|
||||
,__func__,__FILE__,__LINE__,p/1e6,v);\
|
||||
}
|
||||
|
||||
if(p <= 0){
|
||||
BOUND_WARN("p <= 0");
|
||||
return 1;
|
||||
}
|
||||
if(p > IAPWS97_PMAX){
|
||||
BOUND_WARN("p > PMAX");
|
||||
return 2;
|
||||
}
|
||||
|
||||
double vmin = freesteam_region1_v_pT(p,IAPWS97_TMIN);
|
||||
if(v < vmin){
|
||||
BOUND_WARN("v < v_region1(p,T_min)");
|
||||
return 3;
|
||||
}
|
||||
|
||||
double vmax = freesteam_region2_v_pT(p,REGION2_TMAX);
|
||||
if(v>vmax){
|
||||
BOUND_WARN("v > v_region2(p,T_max)");
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#undef BOUND_WARN
|
||||
}
|
||||
|
||||
int freesteam_region_pv(double p, double v){
|
||||
|
||||
double p13 = freesteam_region4_psat_T(REGION1_TMAX);
|
||||
|
||||
if(p > p13){
|
||||
double v13 = freesteam_region1_v_pT(p, REGION1_TMAX);
|
||||
if(v < v13) return 1;
|
||||
|
||||
/* region 2-3 */
|
||||
double T23 = freesteam_b23_T_p(p);
|
||||
double v23 = freesteam_region2_v_pT(p,T23);
|
||||
if(v > v23) return 2;
|
||||
|
||||
/* region 3? or high-pressure part of region 4? */
|
||||
if(p >= IAPWS97_PCRIT) return 3;
|
||||
|
||||
double Tsat = freesteam_region4_Tsat_p(p);
|
||||
double vf = 1./ freesteam_region4_rhof_T(Tsat);
|
||||
if(v < vf) return 3;
|
||||
double vg = 1./ freesteam_region4_rhog_T(Tsat);
|
||||
if(v > vg) return 3;
|
||||
|
||||
return 4;
|
||||
}else{
|
||||
double Tsat = freesteam_region4_Tsat_p(p);
|
||||
double vf = freesteam_region1_v_pT(p,Tsat);
|
||||
if(v < vf) return 1;
|
||||
|
||||
double vg = freesteam_region2_v_pT(p,Tsat);
|
||||
if(v > vg) return 2;
|
||||
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct SolvePVData_struct{
|
||||
double p, v;
|
||||
} SolvePVData;
|
||||
|
||||
#define D ((SolvePVData *)user_data)
|
||||
static ZeroInSubjectFunction pv_region1_fn;
|
||||
double pv_region1_fn(double T, void *user_data){
|
||||
return D->v - freesteam_region1_v_pT(D->p, T);
|
||||
}
|
||||
|
||||
static ZeroInSubjectFunction pv_region2_fn;
|
||||
double pv_region2_fn(double T, void *user_data){
|
||||
return D->v - freesteam_region2_v_pT(D->p, T);
|
||||
}
|
||||
#undef D
|
||||
|
||||
typedef struct SolvePRhoData_struct{
|
||||
double p, rho;
|
||||
} SolvePRhoData;
|
||||
|
||||
#define D ((SolvePRhoData *)user_data)
|
||||
static ZeroInSubjectFunction pv_region3_fn;
|
||||
double pv_region3_fn(double T, void *user_data){
|
||||
return D->p - freesteam_region3_p_rhoT(D->rho, T);
|
||||
}
|
||||
#undef D
|
||||
|
||||
|
||||
SteamState freesteam_set_pv(double p, double v){
|
||||
SteamState S;
|
||||
S.region = (char)freesteam_region_pv(p,v);
|
||||
#if 0
|
||||
int status;
|
||||
#endif
|
||||
switch(S.region){
|
||||
case 1:
|
||||
/* iterate T to get correct value of v */
|
||||
S.R1.p = p;
|
||||
S.R1.T = freesteam_region4_Tsat_p(p);
|
||||
{
|
||||
double lb = IAPWS97_TMIN;
|
||||
double ub = REGION1_TMAX;
|
||||
double tol = 1e-9; /* ??? */
|
||||
double sol, err;
|
||||
SolvePVData D = {p, v};
|
||||
zeroin_solve(&pv_region1_fn, &D, lb, ub, tol, &sol, &err);
|
||||
S.R1.T = sol;
|
||||
/* FIXME check convergence! */
|
||||
}
|
||||
#if 0
|
||||
S = freesteam_solver2_region1('p','v', p, v, S, &status);
|
||||
if(status){
|
||||
fprintf(stderr,"%s: WARNING: Failed to converge in region 1\n",__func__);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 2:
|
||||
/* iterate T to get correct value of v */
|
||||
S.R2.p = p;
|
||||
S.R2.T = freesteam_region4_Tsat_p(p);
|
||||
{
|
||||
double lb = IAPWS97_TMIN;
|
||||
double ub = IAPWS97_TMAX;
|
||||
double tol = 1e-9; /* ??? */
|
||||
double sol, err;
|
||||
SolvePVData D = {p, v};
|
||||
zeroin_solve(&pv_region2_fn, &D, lb, ub, tol, &sol, &err);
|
||||
S.R2.T = sol;
|
||||
/* FIXME check convergence! */
|
||||
}
|
||||
|
||||
#if 0
|
||||
S.R2.p = p;
|
||||
S.R2.T = freesteam_region4_Tsat_p(p);
|
||||
S = freesteam_solver2_region2('p','v', p, v, S, &status);
|
||||
if(status){
|
||||
fprintf(stderr,"%s: WARNING: Failed to converge in region 2\n",__func__);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 3:
|
||||
S.R3.rho = 1./ v;
|
||||
S.R3.T = REGION1_TMAX;
|
||||
{
|
||||
double lb = REGION1_TMAX;
|
||||
double ub = IAPWS97_TMAX;
|
||||
double tol = 1e-12; /* ??? */
|
||||
double sol, err;
|
||||
SolvePRhoData D = {p, S.R3.rho};
|
||||
zeroin_solve(&pv_region3_fn, &D, lb, ub, tol, &sol, &err);
|
||||
S.R3.T = sol;
|
||||
//fprintf(stderr,"%s: (p = %f MPa,v = %f m3/kg) region 3, error in p = %f\n",__func__,p,v, err);
|
||||
/* FIXME check convergence! */
|
||||
}
|
||||
#if 0
|
||||
S = freesteam_solver2_region3('p','v', p, v, S, &status);
|
||||
if(status){
|
||||
fprintf(stderr,"%s: WARNING: Failed to converge in region 3\n",__func__);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
S.R4.T = freesteam_region4_Tsat_p(p);
|
||||
//fprintf(stderr,"%s: region 4, Tsat = %g\n",__func__,S.R4.T);
|
||||
double vf, vg;
|
||||
if(S.R4.T <= REGION1_TMAX){
|
||||
vf = freesteam_region1_v_pT(p,S.R4.T);
|
||||
vg = freesteam_region2_v_pT(p,S.R4.T);
|
||||
}else{
|
||||
/* TODO iteratively improve estimate of T */
|
||||
vf = 1./ freesteam_region4_rhof_T(S.R4.T);
|
||||
vg = 1./ freesteam_region4_rhog_T(S.R4.T);
|
||||
}
|
||||
S.R4.x = (v - vf)/(vg - vf);
|
||||
}
|
||||
return S;
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef FREESTEAM_STEAMPV_H
|
||||
#define FREESTEAM_STEAMPV_H
|
||||
|
||||
#include "common.h"
|
||||
#include "steam.h"
|
||||
|
||||
FREESTEAM_DLL int freesteam_bounds_pv(double p, double v, int verbose);
|
||||
|
||||
FREESTEAM_DLL int freesteam_region_pv(double p, double v);
|
||||
|
||||
FREESTEAM_DLL SteamState freesteam_set_pv(double p, double v);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "surftens.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
Calculate surface tension between water phase and vapour phase
|
||||
|
||||
@param T temperature (Kelvin)
|
||||
@return surface tension (N/m)
|
||||
|
||||
The correlation is the IAPWS Release on Surface Tension of Ordinary Water
|
||||
Substance, September 1994.
|
||||
@since 0.7
|
||||
*/
|
||||
double freesteam_surftens_T(double T){
|
||||
double tau = 1. - T / IAPWS97_TCRIT;
|
||||
const double B = 235.8e-3; /* converted to N/m */
|
||||
const double b = -0.625;
|
||||
const double mu = 1.256;
|
||||
|
||||
return B * pow(tau,mu) * (1 + b * tau);
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2005 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*//** @file
|
||||
Function to calculate surface tension as a function of
|
||||
temperature.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_SURFTENS_H
|
||||
#define FREESTEAM_SURFTENS_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FREESTEAM_DLL double freesteam_surftens_T(double T);
|
||||
|
||||
#endif /* FREESTEAM_SURFTENS_H */
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/* Appendix B: Recommended Interpolating equation for Industrial Use */
|
||||
/* see http://www.iapws.org/relguide/thcond.pdf */
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "thcond.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define THCOND_TSTAR 647.26
|
||||
#define THCOND_RHOSTAR 317.7
|
||||
#define THCOND_KSTAR 1.0
|
||||
|
||||
#define THCOND_b0 -0.397070
|
||||
#define THCOND_b1 0.400302
|
||||
#define THCOND_b2 1.060000
|
||||
#define THCOND_B1 -0.171587
|
||||
#define THCOND_B2 2.392190
|
||||
|
||||
#define THCOND_C1 0.642857
|
||||
#define THCOND_C2 -4.11717
|
||||
#define THCOND_C3 -6.17937
|
||||
#define THCOND_C4 0.00308976
|
||||
#define THCOND_C5 0.0822994
|
||||
#define THCOND_C6 10.0932
|
||||
|
||||
#define THCOND_d1 0.0701309
|
||||
#define THCOND_d2 0.0118520
|
||||
#define THCOND_d3 0.00169937
|
||||
#define THCOND_d4 -1.0200
|
||||
|
||||
/* freesteam code */
|
||||
double freesteam_k_rhoT(double rho, double T){
|
||||
|
||||
#define THCOND_a_COUNT 4
|
||||
const double THCOND_a[THCOND_a_COUNT] = {
|
||||
0.0102811
|
||||
,0.0299621
|
||||
,0.0156146
|
||||
,-0.00422464
|
||||
};
|
||||
|
||||
double Tbar = T / THCOND_TSTAR;
|
||||
double rhobar = rho / THCOND_RHOSTAR;
|
||||
|
||||
/* fast implementation... minimised calls to 'pow' routine... */
|
||||
|
||||
double Troot = sqrt(Tbar);
|
||||
double Tpow = Troot;
|
||||
double lam = 0;
|
||||
|
||||
int k;
|
||||
for(k = 0; k < THCOND_a_COUNT; ++k) {
|
||||
lam += THCOND_a[k] * Tpow;
|
||||
Tpow *= Tbar;
|
||||
}
|
||||
|
||||
lam += THCOND_b0 + THCOND_b1 * rhobar + THCOND_b2 * exp(THCOND_B1 * SQ(rhobar + THCOND_B2));
|
||||
|
||||
double DTbar = fabs(Tbar - 1) + THCOND_C4;
|
||||
double DTbarpow = pow(DTbar, 3./5);
|
||||
double Q = 2. + THCOND_C5 / DTbarpow;
|
||||
|
||||
double S;
|
||||
if(Tbar >= 1){
|
||||
S = 1. / DTbar;
|
||||
}else{
|
||||
S = THCOND_C6 / DTbarpow;
|
||||
}
|
||||
|
||||
double rhobar18 = pow(rhobar, 1.8);
|
||||
double rhobarQ = pow(rhobar, Q);
|
||||
|
||||
lam +=
|
||||
(THCOND_d1 / ipow(Tbar,10) + THCOND_d2) * rhobar18 *
|
||||
exp(THCOND_C1 * (1 - rhobar * rhobar18))
|
||||
+ THCOND_d3 * S * rhobarQ *
|
||||
exp((Q/(1+Q))*(1 - rhobar*rhobarQ))
|
||||
+ THCOND_d4 *
|
||||
exp(THCOND_C2 * ipow(Troot,3) + THCOND_C3 / ipow(rhobar,5));
|
||||
|
||||
return THCOND_KSTAR * lam;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_THCOND_H
|
||||
#define FREESTEAM_THCOND_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/// Conductivity [W/m.K]
|
||||
/**
|
||||
Returns the thermal conductivity of water/steam.
|
||||
@see http://www.iapws.org/relguide/thcond.pdf
|
||||
|
||||
Range of validity is entire regions 1,2,3. The correlation is not
|
||||
really applicable in region 4, but will give 'sane' results there.
|
||||
|
||||
@return Thermal conductivity [W/m.K]
|
||||
*/
|
||||
FREESTEAM_DLL double freesteam_k_rhoT(double rho, double T);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# freesteam - IAPWS-IF97 steam tables library
|
||||
# Copyright (C) 2004-2009 John Pye
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
# This program 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 this program; if not, write to the Free
|
||||
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
# Boston, MA 02110-1301, USA.
|
||||
|
||||
from math import exp
|
||||
from freesteam import *
|
||||
|
||||
def tc_ptrho(p,T, rho):
|
||||
"""
|
||||
Revised release on the IAPS Formulation 1985 for the Thermal Conductivity of ordinary water
|
||||
IAPWS September 1998
|
||||
Page 8
|
||||
|
||||
Converted from Python from the XSteam OpenOffice version.
|
||||
"""
|
||||
|
||||
print "rho = %f, T = %f" % (rho, T)
|
||||
|
||||
# ver2.6 Start corrected bug
|
||||
if T < 273.15:
|
||||
raise RuntimeWarning("T under range")
|
||||
elif T < 500 + 273.15:
|
||||
if p > 100:
|
||||
raise RuntimeWarning("p over range for T<500°C")
|
||||
elif T <= 650 + 273.15:
|
||||
if p > 70:
|
||||
raise RuntimeWarning("p over range for T<650°C")
|
||||
elif T <= 800 + 273.15:
|
||||
if p > 40:
|
||||
raise RuntimeWarning("p over range for T<800°C")
|
||||
# ver2.6 End corrected bug
|
||||
|
||||
T = T / 647.26
|
||||
rho = rho / 317.7
|
||||
lam0 = T ** 0.5 * (0.0102811 + 0.0299621 * T + 0.0156146 * T ** 2 - 0.00422464 * T ** 3)
|
||||
lam1 = -0.39707 + 0.400302 * rho + 1.06 * exp(-0.171587 * (rho + 2.39219) ** 2)
|
||||
dT = abs(T - 1) + 0.00308976
|
||||
Q = 2 + 0.0822994 / dT ** (3. / 5)
|
||||
|
||||
if T >= 1:
|
||||
s = 1. / dT
|
||||
else:
|
||||
s = 10.0932 / dT ** (3. / 5)
|
||||
|
||||
lam2 = (0.0701309 / T ** 10 + 0.011852) * rho ** (9. / 5) * exp(0.642857 * (1 - rho ** (14. / 5))) + 0.00169937 * s * rho ** Q * exp((Q / (1. + Q)) * (1. - rho ** (1. + Q))) - 1.02 * exp(-4.11717 * T ** (3. / 2) - 6.17937 / rho ** 5)
|
||||
|
||||
print "lam0 = %f, lam1 = %f, lam2 = %f" % (lam0, lam1, lam2)
|
||||
|
||||
return lam0 + lam1 + lam2
|
||||
|
||||
if __name__=='__main__':
|
||||
p = 5
|
||||
T = 300
|
||||
rho = steam_pT(p * 1e6,T + 273.15).rho
|
||||
print "p = %f MPa" % p
|
||||
print "T = %f °C" % T
|
||||
print "rho = %f kg/m³" % rho
|
||||
|
||||
k = tc_ptrho(p, T + 273.15, rho)
|
||||
print "k =",k
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
Based on IAPWS Formulation 2008 for the Viscosity of Ordinary Water Substance
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "viscosity.h"
|
||||
|
||||
static double mu0(double tau);
|
||||
static double mu1(double del, double tau);
|
||||
|
||||
#define VISCOSITY_MUSTAR 1.0e-6 /* Pa-s */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static double mu0(double tau){
|
||||
// viscosity in the dilute-gas limit
|
||||
const double H[4] = {1.67752, 2.20462, 0.6366564, -0.241605};
|
||||
int i;
|
||||
double sum = 0;
|
||||
for (i = 0; i < 4; i++){
|
||||
sum += H[i] * ipow(tau, i) ;
|
||||
}
|
||||
return 100.0 / (sqrt(tau) * sum);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static double mu1(double del, double tau){
|
||||
// contribution to viscosity due to finite density
|
||||
const double H[6][7] = {
|
||||
{ 5.20094E-1, 2.22531E-1, -2.81378E-1, 1.61913E-1, -3.25372E-2, 0.0, 0.0},
|
||||
{ 8.50895E-2, 9.99115E-1, -9.06851E-1, 2.57399E-1, 0.0, 0.0, 0.0},
|
||||
{-1.08374, 1.88797, -7.72479E-1, 0.0, 0.0, 0.0, 0.0},
|
||||
{-2.89555E-1, 1.26613, -4.89837E-1, 0.0, 6.98452E-2, 0.0, -4.35673E-3},
|
||||
{ 0.0, 0.0, -2.57040E-1, 0.0, 0.0, 8.72102E-3, 0.0},
|
||||
{ 0.0, 1.20573E-1, 0.0, 0.0, 0.0, 0.0, -5.93264E-4}
|
||||
};
|
||||
|
||||
int i, j;
|
||||
double sum = 0;
|
||||
double tau1 = 0;
|
||||
for (i = 0; i < 6; i++){
|
||||
tau1 = ipow(tau - 1, i);
|
||||
for (j = 0; j < 7; j++){
|
||||
if(0==H[i][j])continue;
|
||||
sum += H[i][j] * tau1 * ipow(del - 1, j);
|
||||
}
|
||||
}
|
||||
return exp(del * sum);
|
||||
}
|
||||
|
||||
double freesteam_mu_rhoT(double rho, double T){
|
||||
double del = rho / IAPWS97_RHOCRIT;
|
||||
double tau = IAPWS97_TCRIT / T;
|
||||
|
||||
const int mu2 = 1; // critical enhancement to viscosity not implemented for IF-97, set to 1
|
||||
return VISCOSITY_MUSTAR * mu0(tau) * mu1(del,tau) * mu2;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
Based on IAPWS Formulation 2008 for the Viscosity of Ordinary Water Substance
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_VISCOSITY_H
|
||||
#define FREESTEAM_VISCOSITY_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
FREESTEAM_DLL double freesteam_mu_rhoT(double rho, double T);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define FREESTEAM_BUILDING_LIB
|
||||
#include "zeroin.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef DBL_EPSILON
|
||||
#define DBL_EPSILON 2e-16
|
||||
#endif
|
||||
|
||||
char zeroin_solve(ZeroInSubjectFunction *func, void *user_data, double lowerbound, double upperbound, double tol, double *solution, double *error){
|
||||
|
||||
double a, b, c; ///< Abscissae, descr. see above.
|
||||
double fa; ///< f(a)
|
||||
double fb; ///< f(b)
|
||||
double fc; ///< f(c)
|
||||
|
||||
a = lowerbound;
|
||||
b = upperbound;
|
||||
fa = (*func)(a,user_data);
|
||||
fb = (*func)(b,user_data);
|
||||
c = a;
|
||||
fc = fa;
|
||||
|
||||
if(fa == 0.){
|
||||
*error = 0.; // used by getError
|
||||
*solution = a;
|
||||
//fprintf(stderr,"perfect solution\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Main iteration loop
|
||||
|
||||
for (;;) {
|
||||
double prev_step = b - a; ///< Distance from the last but one to the last approximation
|
||||
double tol_act; ///< Actual tolerance
|
||||
double p; ///< Interpolation step is calculated in the form p/q; division
|
||||
double q; ///< operations is delayed until the last moment
|
||||
double new_step; ///< Step at this iteration
|
||||
|
||||
if (fabs(fc) < fabs(fb)) {
|
||||
a = b;
|
||||
b = c;
|
||||
c = a; // Swap data for b to be the best approximation
|
||||
fa = fb;
|
||||
fb = fc;
|
||||
fc = fa;
|
||||
}
|
||||
|
||||
// DBL_EPSILON is defined in math.h
|
||||
tol_act = 2.0* DBL_EPSILON * fabs(b) + tol / 2.0;
|
||||
|
||||
new_step = (c - b) / 2.0;
|
||||
//fprintf(stderr,"step = %g\n",new_step);
|
||||
|
||||
if (fabs(new_step) <= tol_act || fb == 0.) {
|
||||
*error = fb;
|
||||
*solution = b;
|
||||
//fprintf(stderr,"best solution is b: f(b=%g) = %g, f(a=%g) = %g\n",b,fb,a,fb);
|
||||
return 0;
|
||||
}
|
||||
// Decide if the interpolation can be tried
|
||||
|
||||
if (fabs(prev_step) >= tol_act // If prev_step was large enough and was in true direction,
|
||||
&& fabs(fa) > fabs(fb)) // Interpolatiom may be tried
|
||||
{
|
||||
register double t1, t2;
|
||||
double cb;
|
||||
|
||||
cb = c - b;
|
||||
if (a == c) {
|
||||
// If we have only two distinct points
|
||||
// then only linear interpolation can be applied
|
||||
t1 = fb / fa;
|
||||
p = cb * t1;
|
||||
q = 1.0 - t1;
|
||||
} else {
|
||||
// Quadric inverse interpolation
|
||||
|
||||
q = fa / fc;
|
||||
t1 = fb / fc;
|
||||
t2 = fb / fa;
|
||||
p = t2 * (cb * q * (q - t1) - (b - a) * (t1 - 1.0));
|
||||
q = (q - 1.0) * (t1 - 1.0) * (t2 - 1.0);
|
||||
}
|
||||
if (p > 0.) {
|
||||
// p was calculated with the opposite sign; make p positive-
|
||||
q = -q; // and assign possible minus to q
|
||||
} else {
|
||||
p = -p;
|
||||
}
|
||||
|
||||
if (p < (0.75 * cb * q - fabs(tol_act * q) / 2.0)
|
||||
&& p < fabs(prev_step * q / 2.0)
|
||||
) {
|
||||
// If b+p/q falls in [b,c] and
|
||||
// isn't too large it is accepted
|
||||
new_step = p / q;
|
||||
}
|
||||
// If p/q is too large then the bissection procedure can
|
||||
// reduce [b,c] range to more extent
|
||||
}
|
||||
|
||||
if (fabs(new_step) < tol_act) { // Adjust the step to be not less
|
||||
if (new_step > 0.) // than tolerance
|
||||
new_step = tol_act;
|
||||
else
|
||||
new_step = -tol_act;
|
||||
}
|
||||
|
||||
a = b;
|
||||
fa = fb; // Save the previous approx.
|
||||
b += new_step;
|
||||
fb = (*func)(b,user_data); // Do step to a new approxim.
|
||||
|
||||
if ((fb > 0. && fc > 0.)
|
||||
|| (fb < 0. && fc < 0.)) {
|
||||
c = a;
|
||||
fc = fa; // Adjust c for it to have a sign opposite to that of b
|
||||
}
|
||||
}
|
||||
// (((we never arrive here)))
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
freesteam - IAPWS-IF97 steam tables library
|
||||
Copyright (C) 2004-2009 John Pye
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef FREESTEAM_ZEROIN_H
|
||||
#define FREESTEAM_ZEROIN_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
Any function that you want to solve using the 'zeroin_solve' function
|
||||
needs to conform to this function prototype. Any parameters required
|
||||
internally by the function can be passed in to the function as a pointer
|
||||
to a struct, array, etc, via the void 'user_data' pointer. Your subject
|
||||
function can then cast the pointer to its correct type, and access the
|
||||
necesssary parameter data, for example:
|
||||
|
||||
-- in your main code
|
||||
typedef struct{double param1, param2} MyData;
|
||||
MyData D = {100., 3.141};
|
||||
double myfunc(double x, void *user_data){
|
||||
MyData *D1 = (MyData *)user_data;
|
||||
return x * D1->param1 + D1->param2;
|
||||
}
|
||||
zeroin_solve(&myfunc, &D, ...);
|
||||
*/
|
||||
typedef double ZeroInSubjectFunction(double, void *user_data);
|
||||
|
||||
/**
|
||||
Attempt to solve the function y = f(x) = 0 by varying x between
|
||||
a lower and upper bound, using the Brent algorithm.
|
||||
|
||||
Originally based on brent solver from netlib, then converted to C++ for
|
||||
used in earlier freesteam versions, and now converted back to pure C again.
|
||||
@see brent.shar at http://www.netlib.org/c/
|
||||
|
||||
@param func the function being solved, must be a ZeroInSubjectFunction.
|
||||
@param lowerbound the lower bound of the range in which a root is sought
|
||||
@param upperbound the upper bound of the range in which a root is sought
|
||||
@param tol maximum permissible magnitude of the function at the solved root location
|
||||
@param user_data additional data that will be passed to the subject function func.
|
||||
@param solution (returned) the value of 'x' at the solution
|
||||
@param error (returned) the value of 'y' at the solution.
|
||||
@return 0 on success
|
||||
*/
|
||||
|
||||
FREESTEAM_DLL char zeroin_solve(ZeroInSubjectFunction *func, void *user_data, double lowerbound, double upperbound, double tol, double *solution, double *error);
|
||||
|
||||
#endif
|
||||
|
49
tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/T
Executable file
49
tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/T
Executable file
|
@ -0,0 +1,49 @@
|
|||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: 1.7.1 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
51
tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/U
Executable file
51
tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/U
Executable file
|
@ -0,0 +1,51 @@
|
|||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: 1.7.1 |
|
||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||
| \\/ 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 (3.5 0 0);
|
||||
}
|
||||
outlet
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
upperWall
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
lowerWall
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform (0 0 0);
|
||||
}
|
||||
frontAndBack
|
||||
{
|
||||
type empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue