diff --git a/README_RealGasBranch b/README_RealGasBranch new file mode 100644 index 000000000..d97432011 --- /dev/null +++ b/README_RealGasBranch @@ -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 + + + diff --git a/applications/solvers/compressible/realFluidPisoFoam/Make/files b/applications/solvers/compressible/realFluidPisoFoam/Make/files new file mode 100644 index 000000000..9e9cf08de --- /dev/null +++ b/applications/solvers/compressible/realFluidPisoFoam/Make/files @@ -0,0 +1,3 @@ +realFluidPisoFoam.C + +EXE = $(FOAM_APPBIN)/realFluidPisoFoam diff --git a/applications/solvers/compressible/realFluidPisoFoam/Make/options b/applications/solvers/compressible/realFluidPisoFoam/Make/options new file mode 100644 index 000000000..3ae0c0cb7 --- /dev/null +++ b/applications/solvers/compressible/realFluidPisoFoam/Make/options @@ -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 diff --git a/applications/solvers/compressible/realFluidPisoFoam/UEqn.H b/applications/solvers/compressible/realFluidPisoFoam/UEqn.H new file mode 100644 index 000000000..3016e1b9a --- /dev/null +++ b/applications/solvers/compressible/realFluidPisoFoam/UEqn.H @@ -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)); + } diff --git a/applications/solvers/compressible/realFluidPisoFoam/createFields.H b/applications/solvers/compressible/realFluidPisoFoam/createFields.H new file mode 100644 index 000000000..c52746923 --- /dev/null +++ b/applications/solvers/compressible/realFluidPisoFoam/createFields.H @@ -0,0 +1,59 @@ + Info<< "Reading thermophysical properties\n" << endl; + + autoPtr 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 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()); diff --git a/applications/solvers/compressible/realFluidPisoFoam/hEqn.H b/applications/solvers/compressible/realFluidPisoFoam/hEqn.H new file mode 100644 index 000000000..ae60d3316 --- /dev/null +++ b/applications/solvers/compressible/realFluidPisoFoam/hEqn.H @@ -0,0 +1,12 @@ +{ + solve + ( + fvm::ddt(rho, h) + + fvm::div(phi, h) + - fvm::laplacian(turbulence->alphaEff(), h) + == + DpDt + ); + + thermo.correct(); +} diff --git a/applications/solvers/compressible/realFluidPisoFoam/pEqn.H b/applications/solvers/compressible/realFluidPisoFoam/pEqn.H new file mode 100644 index 000000000..38b46e0a4 --- /dev/null +++ b/applications/solvers/compressible/realFluidPisoFoam/pEqn.H @@ -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); diff --git a/applications/solvers/compressible/realFluidPisoFoam/realFluidPisoFoam.C b/applications/solvers/compressible/realFluidPisoFoam/realFluidPisoFoam.C new file mode 100644 index 000000000..3f4ffe519 --- /dev/null +++ b/applications/solvers/compressible/realFluidPisoFoam/realFluidPisoFoam.C @@ -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; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWS-IF97.C b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWS-IF97.C new file mode 100644 index 000000000..415a8e555 --- /dev/null +++ b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWS-IF97.C @@ -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 hx=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"< 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"<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::IAPWSThermo::h +( + const scalarField& T, + const labelList& cells +) const +{ + //getting pressure field + const scalarField& pCells = this->p_.internalField(); + + tmp 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::IAPWSThermo::h +( + const scalarField& T, + const label patchi +) const +{ + // getting pressure at the patch + const fvPatchScalarField& pp = this->p_.boundaryField()[patchi]; + + tmp 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::IAPWSThermo::rho +( + const scalarField& p, + const scalarField& h, + const label patchi +) const +{ + tmp trho(new scalarField(h.size())); + scalarField& rho = trho(); + + forAll(h, facei) + { + rho[facei] = rho_ph(p[facei], h[facei]); + } + + return trho; +} + + +Foam::tmp Foam::IAPWSThermo::Cp +( + const scalarField& T, + const label patchi +) const +{ + // getting pressure at the patch + const fvPatchScalarField& pp = this->p_.boundaryField()[patchi]; + + tmp 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::IAPWSThermo::Cp() const +{ + const fvMesh& mesh = this->T_.mesh(); + + tmp 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::IAPWSThermo::rho() const +{ + const fvMesh& mesh = this->p_.mesh(); + + tmp 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::IAPWSThermo::Cv +( + const scalarField& T, + const label patchi +) const +{ + // getting pressure at the patch + const fvPatchScalarField& pp = this->p_.boundaryField()[patchi]; + + tmp 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::IAPWSThermo::Cv() const +{ + const fvMesh& mesh = this->T_.mesh(); + + tmp 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; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermo.H b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermo.H new file mode 100755 index 000000000..0eb3824ff --- /dev/null +++ b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermo.H @@ -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 h + ( + const scalarField& T, + const labelList& cells + ) const; + + + //- Enthalpy for patch [J/kg] + virtual tmp h + ( + const scalarField& T, + const label patchi + ) const; + + + //- Density for patch [J/kg] + virtual tmp 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 Cp + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant pressure [J/kg/K] + virtual tmp Cp() const; + + //- Heat capacity at constant volume for patch [J/kg/K] + virtual tmp Cv + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant volume [J/kg/K] + virtual tmp Cv() const; + + //- Gradient drhodh @ constant pressure + virtual const volScalarField& drhodh() const + { + return drhodh_; + } + + //- Density [kg/m^3] - uses current value of pressure + virtual tmp rho() const; + + + //- Read thermophysicalProperties dictionary + virtual bool read(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository +# include "IAPWSThermo.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermos.C b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermos.C new file mode 100755 index 000000000..c88f04641 --- /dev/null +++ b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/IAPWSThermos.C @@ -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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/steam.H b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/steam.H new file mode 100644 index 000000000..d634767ea --- /dev/null +++ b/src/thermophysicalModels/basic/IAPWS_Waterproperties/IAPWSThermo/steam.H @@ -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); + diff --git a/src/thermophysicalModels/basic/Make/files b/src/thermophysicalModels/basic/Make/files index aeda7414b..1297f150b 100644 --- a/src/thermophysicalModels/basic/Make/files +++ b/src/thermophysicalModels/basic/Make/files @@ -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 diff --git a/src/thermophysicalModels/basic/Make/options b/src/thermophysicalModels/basic/Make/options index e3fe7ea04..cfb01ff17 100644 --- a/src/thermophysicalModels/basic/Make/options +++ b/src/thermophysicalModels/basic/Make/options @@ -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 diff --git a/src/thermophysicalModels/basic/mixtures/basicMixture/basicMixtures.C b/src/thermophysicalModels/basic/mixtures/basicMixture/basicMixtures.C index 7228eb180..74054df89 100644 --- a/src/thermophysicalModels/basic/mixtures/basicMixture/basicMixtures.C +++ b/src/thermophysicalModels/basic/mixtures/basicMixture/basicMixtures.C @@ -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 . + 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 +); + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/thermophysicalModels/basic/mixtures/basicMixture/makeBasicMixture.H b/src/thermophysicalModels/basic/mixtures/basicMixture/makeBasicMixture.H index 42e3b41e9..53574cd95 100644 --- a/src/thermophysicalModels/basic/mixtures/basicMixture/makeBasicMixture.H +++ b/src/thermophysicalModels/basic/mixtures/basicMixture/makeBasicMixture.H @@ -56,6 +56,26 @@ defineTemplateTypeNameAndDebugWithName \ 0 \ ); +#define makeBasicRealFluidMixture(Mixture,Transport,SpecieThermo,Thermo,EqnOfState) \ + \ +typedef Mixture > > > \ + 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 > > > \ + Mixture##Transport##SpecieThermo##Thermo##EqnOfState; \ + \ +defineTemplateTypeNameAndDebugWithName \ + (Mixture##Transport##SpecieThermo##Thermo##EqnOfState, \ + #Mixture"<"#Transport"<"#SpecieThermo"<"#Thermo"<"#EqnOfState">>>>", 0) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.C b/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.C index 10bd1d4b4..e5f8d733b 100644 --- a/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.C +++ b/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.C @@ -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::null()); +} + +const Foam::volScalarField& Foam::basicPsiThermo::drhode() const +{ + notImplemented("basicPsiThermo::drhode()"); + return const_cast(volScalarField::null()); +} + + // ************************************************************************* // diff --git a/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.H b/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.H index 2bd1e1e46..591f1c98d 100644 --- a/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.H +++ b/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/basicPsiThermo.H @@ -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; }; diff --git a/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/makeBasicPsiThermo.H b/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/makeBasicPsiThermo.H index 05964ec4f..5072c47a7 100644 --- a/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/makeBasicPsiThermo.H +++ b/src/thermophysicalModels/basic/psiThermo/basicPsiThermo/makeBasicPsiThermo.H @@ -58,6 +58,46 @@ addToRunTimeSelectionTable \ ) +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#define makeBasicRealGasThermo(Cthermo,Mixture,Transport,SpecieThermo,Thermo,EqnOfState) \ + \ +typedef Cthermo > > > > \ + 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 diff --git a/src/thermophysicalModels/basic/psiThermo/hPsiThermo/hPsiThermo.C b/src/thermophysicalModels/basic/psiThermo/hPsiThermo/hPsiThermo.C index 49e9f002b..b72d3ac61 100644 --- a/src/thermophysicalModels/basic/psiThermo/hPsiThermo/hPsiThermo.C +++ b/src/thermophysicalModels/basic/psiThermo/hPsiThermo/hPsiThermo.C @@ -111,7 +111,7 @@ Foam::hPsiThermo::hPsiThermo ( "h", mesh.time().timeName(), - mesh, + obj, IOobject::NO_READ, IOobject::NO_WRITE ), diff --git a/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.C b/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.C new file mode 100755 index 000000000..c06345247 --- /dev/null +++ b/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.C @@ -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 +void Foam::realGasEThermo::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 +Foam::realGasEThermo::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 +Foam::realGasEThermo::~realGasEThermo() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +void Foam::realGasEThermo::correct() +{ + if (debug) + { + Info<< "entering realGasEThermo::correct()" << endl; + } + + // force the saving of the old-time values + this->psi_.oldTime(); + + calculate(); + + if (debug) + { + Info<< "exiting realGasEThermo::correct()" << endl; + } +} + + +template +Foam::tmp Foam::realGasEThermo::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 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 +Foam::tmp Foam::realGasEThermo::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 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 +Foam::tmp Foam::realGasEThermo::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 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 +Foam::tmp Foam::realGasEThermo::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 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 +Foam::tmp Foam::realGasEThermo::Cp() const +{ + const fvMesh& mesh = this->T_.mesh(); + + tmp 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 +Foam::tmp Foam::realGasEThermo::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 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 +Foam::tmp Foam::realGasEThermo::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 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 +Foam::tmp Foam::realGasEThermo::Cv() const +{ + const fvMesh& mesh = this->T_.mesh(); + + tmp 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 +bool Foam::realGasEThermo::read() +{ + if (basicPsiThermo::read()) + { + MixtureType::read(*this); + return true; + } + else + { + return false; + } +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.H b/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.H new file mode 100755 index 000000000..d49310f64 --- /dev/null +++ b/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermo.H @@ -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 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&); + + +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 e + ( + const scalarField& T, + const labelList& cells + ) const; + + //- Internal energy for patch [J/kg] + virtual tmp e + ( + const scalarField& T, + const label patchi + ) const; + + //- Density for patch [J/kg] + virtual tmp rho + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant pressure for patch [J/kg/K] + virtual tmp Cp + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant pressure [J/kg/K] + virtual tmp Cp() const; + + //- Heat capacity at constant volume for patch [J/kg/K] + virtual tmp Cv + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant volume [J/kg/K] + virtual tmp Cv() const; + + //- Density [kg/m^3] - uses current value of pressure + virtual tmp rho() const; + + + //- Read thermophysicalProperties dictionary + virtual bool read(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +#ifdef NoRepository +# include "realGasEThermo.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermos.C b/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermos.C new file mode 100755 index 000000000..8b1eddd18 --- /dev/null +++ b/src/thermophysicalModels/basic/psiThermo/realGasEThermo/realGasEThermos.C @@ -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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.C b/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.C new file mode 100755 index 000000000..218997f29 --- /dev/null +++ b/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.C @@ -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 +void Foam::realGasHThermo::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 +Foam::realGasHThermo::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 +Foam::realGasHThermo::~realGasHThermo() +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +void Foam::realGasHThermo::correct() +{ + if (debug) + { + Info<< "entering realGasHThermo::correct()" << endl; + } + + // force the saving of the old-time values + this->psi_.oldTime(); + + calculate(); + + if (debug) + { + Info<< "exiting realGasHThermo::correct()" << endl; + } +} + + +template +Foam::tmp Foam::realGasHThermo::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 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 +Foam::tmp Foam::realGasHThermo::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 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 +Foam::tmp Foam::realGasHThermo::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 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 +Foam::tmp Foam::realGasHThermo::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 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 +Foam::tmp Foam::realGasHThermo::Cp() const +{ + const fvMesh& mesh = this->T_.mesh(); + + tmp 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 +Foam::tmp Foam::realGasHThermo::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 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 +Foam::tmp Foam::realGasHThermo::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 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 +Foam::tmp Foam::realGasHThermo::Cv() const +{ + const fvMesh& mesh = this->T_.mesh(); + + tmp 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 +bool Foam::realGasHThermo::read() +{ + if (basicPsiThermo::read()) + { + MixtureType::read(*this); + return true; + } + else + { + return false; + } +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.H b/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.H new file mode 100755 index 000000000..7f9042a2c --- /dev/null +++ b/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermo.H @@ -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 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&); + + +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 h + ( + const scalarField& T, + const labelList& cells + ) const; + + //- Enthalpy for patch [J/kg] + virtual tmp h + ( + const scalarField& T, + const label patchi + ) const; + + //- Density for patch [J/kg] + virtual tmp rho + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant pressure for patch [J/kg/K] + virtual tmp Cp + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant pressure [J/kg/K] + virtual tmp Cp() const; + + //- Heat capacity at constant volume for patch [J/kg/K] + virtual tmp Cv + ( + const scalarField& T, + const label patchi + ) const; + + //- Heat capacity at constant volume [J/kg/K] + virtual tmp Cv() const; + + //- Density [kg/m^3] - uses current value of pressure + virtual tmp rho() const; + + + //- Read thermophysicalProperties dictionary + virtual bool read(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +#ifdef NoRepository +# include "realGasHThermo.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermos.C b/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermos.C new file mode 100755 index 000000000..7e5a9eaeb --- /dev/null +++ b/src/thermophysicalModels/basic/psiThermo/realGasHThermo/realGasHThermos.C @@ -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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/Make/files b/src/thermophysicalModels/specie/Make/files index 428f6d8fc..3aa166ed1 100644 --- a/src/thermophysicalModels/specie/Make/files +++ b/src/thermophysicalModels/specie/Make/files @@ -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 diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/aungierRedlichKwong/aungierRedlichKwong.C b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/aungierRedlichKwong/aungierRedlichKwong.C new file mode 100755 index 000000000..2c4716ce6 --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/aungierRedlichKwong/aungierRedlichKwong.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(ark)<< token::SPACE + << ark.pcrit_ << tab<< ark.Tcrit_<< tab< clone() const; + + // Selector from Istream + inline static autoPtr 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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/aungierRedlichKwong/aungierRedlichKwongI.H b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/aungierRedlichKwong/aungierRedlichKwongI.H new file mode 100755 index 000000000..78a195e6d --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/aungierRedlichKwong/aungierRedlichKwongI.H @@ -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::clone() const +{ + return autoPtr(new aungierRedlichKwong(*this)); +} + + +// Selector from Istream +inline autoPtr aungierRedlichKwong::New(Istream& is) +{ + return autoPtr(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(ark1) + + static_cast(ark2) + ); +} + + +inline aungierRedlichKwong operator* +( + const scalar s, + const aungierRedlichKwong& ark +) +{ + return aungierRedlichKwong(s*static_cast(ark)); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinson.C b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinson.C new file mode 100755 index 000000000..1050f777b --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinson.C @@ -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 . + +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(pr)<< token::SPACE + << pr.pcrit_ << tab<< pr.Tcrit_<< tab << pr.azentricFactor_; + + os.check("Ostream& operator<<(Ostream& os, const pengRobinson& st)"); + return os; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinson.H b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinson.H new file mode 100755 index 000000000..90739c075 --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinson.H @@ -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 . + +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 clone() const; + + // Selector from Istream + inline static autoPtr 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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinsonI.H b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinsonI.H new file mode 100755 index 000000000..92ec2f30b --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/pengRobinson/pengRobinsonI.H @@ -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::clone() const +{ + return autoPtr(new pengRobinson(*this)); +} + + +// Selector from Istream +inline autoPtr pengRobinson::New(Istream& is) +{ + return autoPtr(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(pr1) + + static_cast(pr2) + ); +} + + +inline pengRobinson operator* +( + const scalar s, + const pengRobinson& pr +) +{ + return pengRobinson(s*static_cast(pr)); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwong.C b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwong.C new file mode 100755 index 000000000..bb623d6e1 --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwong.C @@ -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(rk)<< token::SPACE + << rk.pcrit_ << tab<< rk.Tcrit_; + + os.check("Ostream& operator<<(Ostream& os, const redlichKwong& st)"); + return os; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwong.H b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwong.H new file mode 100755 index 000000000..6bd3cd3b7 --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwong.H @@ -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 clone() const; + + // Selector from Istream + inline static autoPtr 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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwongI.H b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwongI.H new file mode 100755 index 000000000..253b1fb00 --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/redlichKwong/redlichKwongI.H @@ -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::clone() const +{ + return autoPtr(new redlichKwong(*this)); +} + + +// Selector from Istream +inline autoPtr redlichKwong::New(Istream& is) +{ + return autoPtr(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(rk1) + + static_cast(rk2) + ); +} + + +inline redlichKwong operator* +( + const scalar s, + const redlichKwong& rk +) +{ + return redlichKwong(s*static_cast(rk)); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/soaveRedlichKwong/soaveRedlichKwong.C b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/soaveRedlichKwong/soaveRedlichKwong.C new file mode 100755 index 000000000..1ad68fba6 --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/soaveRedlichKwong/soaveRedlichKwong.C @@ -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(srk)<< token::SPACE + << srk.pcrit_ << tab<< srk.Tcrit_< clone() const; + + // Selector from Istream + inline static autoPtr 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 + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/soaveRedlichKwong/soaveRedlichKwongI.H b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/soaveRedlichKwong/soaveRedlichKwongI.H new file mode 100755 index 000000000..58bd76efc --- /dev/null +++ b/src/thermophysicalModels/specie/equationOfState/cubicEquationOfState/soaveRedlichKwong/soaveRedlichKwongI.H @@ -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::clone() const +{ + return autoPtr(new soaveRedlichKwong(*this)); +} + + +// Selector from Istream +inline autoPtr soaveRedlichKwong::New(Istream& is) +{ + return autoPtr(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(srk1) + + static_cast(srk2) + ); +} + + +inline soaveRedlichKwong operator* +( + const scalar s, + const soaveRedlichKwong& srk +) +{ + return soaveRedlichKwong(s*static_cast(srk)); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacity.C b/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacity.C new file mode 100755 index 000000000..a9d178362 --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacity.C @@ -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 . + +Author +Christian Lucas +Institut für Thermodynamik +Technische Universität Braunschweig +Germany + +\*---------------------------------------------------------------------------*/ + +#include "constantHeatCapacity.H" +#include "IOstreams.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::constantHeatCapacity::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 +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const constantHeatCapacity& np +) +{ + os << static_cast(np) << tab + << np.Cp0_; + os.check("Ostream& operator<<(Ostream& os, const constantHeatCapacity& np)"); + return os; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacity.H b/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacity.H new file mode 100755 index 000000000..438b386f2 --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacity.H @@ -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 . + +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 constantHeatCapacity; + +template +inline constantHeatCapacity operator+ +( + const constantHeatCapacity&, + const constantHeatCapacity& +); + +template +inline constantHeatCapacity operator- +( + const constantHeatCapacity&, + const constantHeatCapacity& +); + +template +inline constantHeatCapacity operator* +( + const scalar, + const constantHeatCapacity& +); + +template +inline constantHeatCapacity operator== +( + const constantHeatCapacity&, + const constantHeatCapacity& +); + +template +Ostream& operator<< +( + Ostream&, + const constantHeatCapacity& +); + + +/*---------------------------------------------------------------------------*\ + Class constantHeatCapacity Thermo Declaration +\*---------------------------------------------------------------------------*/ + +template +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 clone() const; + + //- Selector from Istream + inline static autoPtr 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+ + ( + const constantHeatCapacity&, + const constantHeatCapacity& + ); + + friend constantHeatCapacity operator- + ( + const constantHeatCapacity&, + const constantHeatCapacity& + ); + + friend constantHeatCapacity operator* + ( + const scalar, + const constantHeatCapacity& + ); + + friend constantHeatCapacity operator== + ( + const constantHeatCapacity&, + const constantHeatCapacity& + ); + + + // IOstream Operators + + friend Ostream& operator<< + ( + Ostream&, + const constantHeatCapacity& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "constantHeatCapacityI.H" + +#ifdef NoRepository +# include "constantHeatCapacity.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacityI.H b/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacityI.H new file mode 100755 index 000000000..f851be3ef --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/constantHeatCapacity/constantHeatCapacityI.H @@ -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 . + +Author +Christian Lucas +Institut für Thermodynamik +Technische Universität Braunschweig +Germany + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +//- Construct from components +//CL: used for the operator+ +template +inline Foam::constantHeatCapacity::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 +inline Foam::constantHeatCapacity::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 +inline Foam::constantHeatCapacity::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 +inline Foam::autoPtr > +Foam::constantHeatCapacity::clone() const +{ + return autoPtr > + ( + new constantHeatCapacity(*this) + ); +} + + +template +inline Foam::autoPtr > +Foam::constantHeatCapacity::New(Istream& is) +{ + return autoPtr > + ( + new constantHeatCapacity(is) + ); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +//used to calculate the internal energy +//perfect gas enthalpy +template +inline Foam::scalar Foam::constantHeatCapacity::h0 +( + const scalar T +) const +{ + return cp0_*T; +} + + +//used to calculate the internal energy +//perfect gas internal energy +template +inline Foam::scalar Foam::constantHeatCapacity::e0 +( + const scalar T +) const +{ + return this->h0(T) - this->RR()*T; +} + + +// used to calculate the entropy +// perfect gas entropy +template +inline Foam::scalar Foam::constantHeatCapacity::s0 +( + const scalar T +) const +{ + return cp0_*log(T); +} + + +//perfect gas cp +template +inline Foam::scalar Foam::constantHeatCapacity::cp0 +( + const scalar T +) const +{ + return cp0_; +} + + +//perfect gas cv +template +inline Foam::scalar Foam::constantHeatCapacity::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 +inline Foam::scalar Foam::constantHeatCapacity::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 +inline Foam::scalar Foam::constantHeatCapacity::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 +inline Foam::scalar Foam::constantHeatCapacity::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 +inline Foam::scalar Foam::constantHeatCapacity::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 +inline Foam::scalar Foam::constantHeatCapacity::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 +inline Foam::scalar Foam::constantHeatCapacity::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 +inline void Foam::constantHeatCapacity::operator+= +( + const constantHeatCapacity& np +) +{ + + scalar molr1 = this->nMoles(); + + equationOfState::operator+=(np); + + molr1 /= this->nMoles(); + scalar molr2 = np.nMoles()/this->nMoles(); + + cp0_ = molr1*cp0_ + molr2*np.cp0_; +} + + +template +inline void Foam::constantHeatCapacity::operator-= +( + const constantHeatCapacity& 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 +inline Foam::constantHeatCapacity Foam::operator+ +( + const constantHeatCapacity& np1, + const constantHeatCapacity& np2 +) +{ + equationOfState eofs + ( + static_cast(np1) + + static_cast(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 + ( + eofs, + np1.nMoles()/eofs.nMoles()*np1.cp0_ + + np2.nMoles()/eofs.nMoles()*np2.cp0_ + ); +} + + +template +inline Foam::constantHeatCapacity Foam::operator- +( + const constantHeatCapacity& np1, + const constantHeatCapacity& np2 +) +{ + equationOfState eofs + ( + static_cast(np1) + - static_cast(np2) + ); + + return constantHeatCapacity + ( + eofs, + np1.nMoles()/eofs.nMoles()*np1.cp0_ + - np2.nMoles()/eofs.nMoles()*np2.cp0_ + ); +} + + +template +inline Foam::constantHeatCapacity Foam::operator* +( + const scalar s, + const constantHeatCapacity& np +) +{ + //CL: values at STD don't need to be recalculated, + //CL: therefore, providing the values in the constructor + return constantHeatCapacity + ( + s*static_cast(np), + np.cp0_, + np.e0_std, + np.s0_std, + np.integral_p_dv_std, + np.integral_dpdT_dv_std, + np.cp_std + ); +} + + +template +inline Foam::constantHeatCapacity Foam::operator== +( + const constantHeatCapacity& np1, + const constantHeatCapacity& np2 +) +{ + return np2 - np1; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomial.C b/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomial.C new file mode 100755 index 000000000..20af3b65d --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomial.C @@ -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 +Foam::nasaHeatCapacityPolynomial::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 +Foam::Ostream& Foam::operator<< +( + Ostream& os, + const nasaHeatCapacityPolynomial& np +) +{ + os << static_cast(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; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomial.H b/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomial.H new file mode 100755 index 000000000..f463411cb --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomial.H @@ -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 nasaHeatCapacityPolynomial; + +template +inline nasaHeatCapacityPolynomial operator+ +( + const nasaHeatCapacityPolynomial&, + const nasaHeatCapacityPolynomial& +); + +template +inline nasaHeatCapacityPolynomial operator- +( + const nasaHeatCapacityPolynomial&, + const nasaHeatCapacityPolynomial& +); + +template +inline nasaHeatCapacityPolynomial operator* +( + const scalar, + const nasaHeatCapacityPolynomial& +); + +template +inline nasaHeatCapacityPolynomial operator== +( + const nasaHeatCapacityPolynomial&, + const nasaHeatCapacityPolynomial& +); + +template +Ostream& operator<< +( + Ostream&, + const nasaHeatCapacityPolynomial& +); + + +/*---------------------------------------------------------------------------*\ + Class nasaHeatCapacityPolynomial Thermo Declaration +\*---------------------------------------------------------------------------*/ + +template +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 clone() const; + + //- Selector from Istream + inline static autoPtr 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+ + ( + const nasaHeatCapacityPolynomial&, + const nasaHeatCapacityPolynomial& + ); + + friend nasaHeatCapacityPolynomial operator- + ( + const nasaHeatCapacityPolynomial&, + const nasaHeatCapacityPolynomial& + ); + + friend nasaHeatCapacityPolynomial operator* + ( + const scalar, + const nasaHeatCapacityPolynomial& + ); + + friend nasaHeatCapacityPolynomial operator== + ( + const nasaHeatCapacityPolynomial&, + const nasaHeatCapacityPolynomial& + ); + + + // IOstream Operators + + friend Ostream& operator<< + ( + Ostream&, + const nasaHeatCapacityPolynomial& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "nasaHeatCapacityPolynomialI.H" + +#ifdef NoRepository +# include "nasaHeatCapacityPolynomial.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomialI.H b/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomialI.H new file mode 100755 index 000000000..dbdd3016c --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/nasaHeatCapacityPolynomial/nasaHeatCapacityPolynomialI.H @@ -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 +inline Foam::nasaHeatCapacityPolynomial::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 +inline Foam::nasaHeatCapacityPolynomial::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 +inline Foam::nasaHeatCapacityPolynomial::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 +inline Foam::autoPtr > +Foam::nasaHeatCapacityPolynomial::clone() const +{ + return autoPtr > + ( + new nasaHeatCapacityPolynomial(*this) + ); +} + + +template +inline Foam::autoPtr > +Foam::nasaHeatCapacityPolynomial::New(Istream& is) +{ + return autoPtr > + ( + new nasaHeatCapacityPolynomial(is) + ); +} + + + // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +//used to calculate the internal energy +//perfect gas enthalpy +template +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::e0 +( + const scalar T +) const +{ + return this->h0(T) - this->RR()*T; +} +// used to calculate the entropy +// perfect gas entropy +template +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline Foam::scalar Foam::nasaHeatCapacityPolynomial::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 +inline void Foam::nasaHeatCapacityPolynomial::operator+= +( + const nasaHeatCapacityPolynomial& 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 +inline void Foam::nasaHeatCapacityPolynomial::operator-= +( + const nasaHeatCapacityPolynomial& 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 +inline Foam::nasaHeatCapacityPolynomial Foam::operator+ +( + const nasaHeatCapacityPolynomial& np1, + const nasaHeatCapacityPolynomial& np2 +) +{ + equationOfState eofs + ( + static_cast(np1) + + static_cast(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 + ( + 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 +inline Foam::nasaHeatCapacityPolynomial Foam::operator- +( + const nasaHeatCapacityPolynomial& np1, + const nasaHeatCapacityPolynomial& np2 +) +{ + equationOfState eofs + ( + static_cast(np1) + - static_cast(np2) + ); + + return nasaHeatCapacityPolynomial + ( + 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 +inline Foam::nasaHeatCapacityPolynomial Foam::operator* +( + const scalar s, + const nasaHeatCapacityPolynomial& np +) +{ + //CL: values at STD don't need to be recalculated, + //CL: therefore, providing the values in the constructor + return nasaHeatCapacityPolynomial + ( + s*static_cast(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 +inline Foam::nasaHeatCapacityPolynomial Foam::operator== +( + const nasaHeatCapacityPolynomial& np1, + const nasaHeatCapacityPolynomial& np2 +) +{ + return np2 - np1; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermo.C b/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermo.C new file mode 100755 index 000000000..0bf1b691a --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermo.C @@ -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 +const Foam::debug::tolerancesSwitch +Foam::realGasSpecieThermo::tol_ +( + "realGasSpecieThermoTol", + 1.0e-9 +); + +template +const Foam::debug::optimisationSwitch +Foam::realGasSpecieThermo::maxIter_ +( + "realGasSpecieThermoMaxIter", + 500 +); + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::realGasSpecieThermo::realGasSpecieThermo(Istream& is) +: + thermo(is) +{ + is.check("realGasSpecieThermo::realGasSpecieThermo(Istream& is)"); +} + + +// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // + +template +Foam::Ostream& Foam::operator<<(Ostream& os, const realGasSpecieThermo& st) +{ + os << static_cast(st); + + os.check("Ostream& operator<<(Ostream& os, const realGasSpecieThermo& st)"); + return os; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermo.H b/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermo.H new file mode 100755 index 000000000..1f0932f4f --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermo.H @@ -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 realGasSpecieThermo; + +template +inline realGasSpecieThermo operator+ +( + const realGasSpecieThermo&, + const realGasSpecieThermo& +); + +template +inline realGasSpecieThermo operator- +( + const realGasSpecieThermo&, + const realGasSpecieThermo& +); + +template +inline realGasSpecieThermo operator* +( + const scalar, + const realGasSpecieThermo& +); + +template +inline realGasSpecieThermo operator== +( + const realGasSpecieThermo&, + const realGasSpecieThermo& +); + +template +Ostream& operator<< +( + Ostream&, + const realGasSpecieThermo& +); + + +/*---------------------------------------------------------------------------*\ + Class realGasSpecieThermo Declaration +\*---------------------------------------------------------------------------*/ + +template +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+ + ( + const realGasSpecieThermo&, + const realGasSpecieThermo& + ); + + friend realGasSpecieThermo operator- + ( + const realGasSpecieThermo&, + const realGasSpecieThermo& + ); + + friend realGasSpecieThermo operator* + ( + const scalar s, + const realGasSpecieThermo& + ); + + friend realGasSpecieThermo operator== + ( + const realGasSpecieThermo&, + const realGasSpecieThermo& + ); + + + // Ostream Operator + + friend Ostream& operator<< + ( + Ostream&, + const realGasSpecieThermo& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "realGasSpecieThermoI.H" + +#ifdef NoRepository +# include "realGasSpecieThermo.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermoI.H b/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermoI.H new file mode 100755 index 000000000..c8834608e --- /dev/null +++ b/src/thermophysicalModels/specie/thermo/realGasThermo/realGasSpecieThermo/realGasSpecieThermoI.H @@ -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 +inline Foam::realGasSpecieThermo::realGasSpecieThermo +( + const thermo& sp +) +: + thermo(sp) +{} + + +// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // + + +//CL: using two one dimensional newton solvers in a row +template +inline void Foam::realGasSpecieThermo::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 +{ + 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::T(scalar f, scalar T0, scalar p, scalar rho0, " + "scalar (realGasSpecieThermo::*F)(const scalar) const, " + "scalar (realGasSpecieThermo::*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 +inline Foam::realGasSpecieThermo::realGasSpecieThermo +( + const word& name, + const realGasSpecieThermo& st +) +: + thermo(name, st) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +inline Foam::scalar Foam::realGasSpecieThermo::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 +inline Foam::scalar Foam::realGasSpecieThermo::g(const scalar rho, const scalar T ) const +{ + return this->h(rho, T) - T*this->s(rho, T); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::a(const scalar rho, const scalar T ) const +{ + return this->e(rho,T ) - T*this->s(rho, T); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::Cp( const scalar rho, const scalar T) const +{ + return this->cp(rho, T)/this->W(); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::Cv( const scalar rho, const scalar T) const +{ + return this->cv(rho, T)/this->W(); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::H(const scalar rho, const scalar T) const +{ + return this->h(rho, T)/this->W(); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::S(const scalar rho, const scalar T) const +{ + return this->s(rho, T)/this->W(); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::E(const scalar rho, const scalar T) const +{ + return this->e(rho, T)/this->W(); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::G(const scalar rho, const scalar T) const +{ + return this->g(rho, T)/this->W(); +} + + +template +inline Foam::scalar Foam::realGasSpecieThermo::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 +inline Foam::scalar Foam::realGasSpecieThermo::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 +inline Foam::scalar Foam::realGasSpecieThermo::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 +inline Foam::scalar Foam::realGasSpecieThermo::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 +inline Foam::scalar Foam::realGasSpecieThermo::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 +inline void Foam::realGasSpecieThermo::TH +( + const scalar h, + scalar &T0, + const scalar p, + scalar &rho0 +) const +{ + T(h, T0, p,rho0, &realGasSpecieThermo::H, &realGasSpecieThermo::Cp); +} + + +template +inline void Foam::realGasSpecieThermo::TE +( + const scalar e, + scalar &T0, + const scalar p, + scalar &rho0 +) const +{ + T(e, T0, p,rho0, &realGasSpecieThermo::E, &realGasSpecieThermo::Cv); +} + + +// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // + +template +inline void Foam::realGasSpecieThermo::operator+= +( + const realGasSpecieThermo& st +) +{ + thermo::operator+=(st); +} + +template +inline void Foam::realGasSpecieThermo::operator-= +( + const realGasSpecieThermo& st +) +{ + thermo::operator-=(st); +} + +template +inline void Foam::realGasSpecieThermo::operator*=(const scalar s) +{ + thermo::operator*=(s); +} + + +// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // + +template +inline Foam::realGasSpecieThermo Foam::operator+ +( + const realGasSpecieThermo& st1, + const realGasSpecieThermo& st2 +) +{ + return realGasSpecieThermo + ( + static_cast(st1) + static_cast(st2) + ); +} + + +template +inline Foam::realGasSpecieThermo Foam::operator- +( + const realGasSpecieThermo& st1, + const realGasSpecieThermo& st2 +) +{ + return realGasSpecieThermo + ( + static_cast(st1) - static_cast(st2) + ); +} + + +template +inline Foam::realGasSpecieThermo Foam::operator* +( + const scalar s, + const realGasSpecieThermo& st +) +{ + return realGasSpecieThermo + ( + s*static_cast(st) + ); +} + + +template +inline Foam::realGasSpecieThermo Foam::operator== +( + const realGasSpecieThermo& st1, + const realGasSpecieThermo& st2 +) +{ + return st2 - st1; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/transport/const/constTransport.H b/src/thermophysicalModels/specie/transport/const/constTransport.H index a19d9809c..72b738d72 100644 --- a/src/thermophysicalModels/specie/transport/const/constTransport.H +++ b/src/thermophysicalModels/specie/transport/const/constTransport.H @@ -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; diff --git a/src/thermophysicalModels/specie/transport/const/constTransportI.H b/src/thermophysicalModels/specie/transport/const/constTransportI.H index 2f45f02bc..9232537b4 100644 --- a/src/thermophysicalModels/specie/transport/const/constTransportI.H +++ b/src/thermophysicalModels/specie/transport/const/constTransportI.H @@ -116,7 +116,34 @@ inline scalar constTransport::alpha(const scalar T) const return Cp_*mu(T)*rPr/CpBar; } +// CL: for real gas thermo +// Thermal conductivity [W/mK] +template +inline scalar constTransport::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 +inline scalar constTransport::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 diff --git a/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransport.C b/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransport.C new file mode 100644 index 000000000..1892116c0 --- /dev/null +++ b/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransport.C @@ -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 . + +\*---------------------------------------------------------------------------*/ + +#include "constRealGasTransport.H" +#include "IOstreams.H" + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +Foam::constRealGasTransport::constRealGasTransport(Istream& is) +: + Thermo(is), + mu_(readScalar(is)), + rPr_(1.0/readScalar(is)) +{ + is.check("constRealGasTransport::constRealGasTransport(Istream& is)"); +} + + +// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // + +template +Foam::Ostream& Foam::operator<<(Ostream& os, const constRealGasTransport& ct) +{ + operator<<(os, static_cast(ct)); + os << tab << ct.mu_ << tab << 1.0/ct.rPr_; + + os.check("Ostream& operator<<(Ostream&, const constRealGasTransport&)"); + + return os; +} + + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransport.H b/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransport.H new file mode 100644 index 000000000..7b73a4df1 --- /dev/null +++ b/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransport.H @@ -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 . + +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 constRealGasTransport; + +template +inline constRealGasTransport operator+ +( + const constRealGasTransport&, + const constRealGasTransport& +); + +template +inline constRealGasTransport operator- +( + const constRealGasTransport&, + const constRealGasTransport& +); + +template +inline constRealGasTransport operator* +( + const scalar, + const constRealGasTransport& +); + +template +inline constRealGasTransport operator== +( + const constRealGasTransport&, + const constRealGasTransport& +); + +template +Ostream& operator<< +( + Ostream&, + const constRealGasTransport& +); + + +/*---------------------------------------------------------------------------*\ + Class constRealGasTransport Declaration +\*---------------------------------------------------------------------------*/ + +template +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+ + ( + const constRealGasTransport&, + const constRealGasTransport& + ); + + friend constRealGasTransport operator- + ( + const constRealGasTransport&, + const constRealGasTransport& + ); + + friend constRealGasTransport operator* + ( + const scalar, + const constRealGasTransport& + ); + + friend constRealGasTransport operator== + ( + const constRealGasTransport&, + const constRealGasTransport& + ); + + + // Ostream Operator + + friend Ostream& operator<< + ( + Ostream&, + const constRealGasTransport& + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#include "constRealGasTransportI.H" + +#ifdef NoRepository +# include "constRealGasTransport.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransportI.H b/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransportI.H new file mode 100644 index 000000000..24211f178 --- /dev/null +++ b/src/thermophysicalModels/specie/transport/constRealGas/constRealGasTransportI.H @@ -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 . + +\*---------------------------------------------------------------------------*/ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +template +inline Foam::constRealGasTransport::constRealGasTransport +( + const Thermo& t, + const scalar mu, + const scalar Pr +) +: + Thermo(t), + mu_(mu), + rPr_(1.0/Pr) +{} + + +template +inline Foam::constRealGasTransport::constRealGasTransport +( + const word& name, + const constRealGasTransport& ct +) +: + Thermo(name, ct), + mu_(ct.mu_), + rPr_(ct.rPr_) +{} + + +// Construct and return a clone +template +inline autoPtr > constTransport::clone +() const +{ + return autoPtr > + ( + new constTransport(*this) + ); +} + + +// Selector from Istream +template +inline autoPtr > constTransport::New +( + Istream& is +) +{ + return autoPtr > + ( + new constRealGasTransport(is) + ); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +template +inline Foam::scalar Foam::constRealGasTransport::mu(const scalar) const +{ + return mu_; +} + + +// CL: for real gas thermo +// Thermal conductivity [W/mK] +template +inline Foam::scalar Foam::constRealGasTransport::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 +inline Foam::scalar Foam::constRealGasTransport::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 +inline Foam::constRealGasTransport& Foam::constRealGasTransport::operator= +( + const constRealGasTransport& ct +) +{ + Thermo::operator=(ct); + + mu_ = ct.mu_; + rPr_ = ct.rPr_; + + return *this; +} + + +// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // + +template +inline Foam::constRealGasTransport Foam::operator+ +( + const constRealGasTransport& ct1, + const constRealGasTransport& ct2 +) +{ + Thermo t + ( + static_cast(ct1) + static_cast(ct2) + ); + + scalar molr1 = ct1.nMoles()/t.nMoles(); + scalar molr2 = ct2.nMoles()/t.nMoles(); + + return constRealGasTransport + ( + t, + molr1*ct1.mu_ + molr2*ct2.mu_, + molr1*ct1.rPr_ + molr2*ct2.rPr_ + ); +} + + +template +inline Foam::constRealGasTransport Foam::operator- +( + const constRealGasTransport& ct1, + const constRealGasTransport& ct2 +) +{ + Thermo t + ( + static_cast(ct1) - static_cast(ct2) + ); + + scalar molr1 = ct1.nMoles()/t.nMoles(); + scalar molr2 = ct2.nMoles()/t.nMoles(); + + return constRealGasTransport + ( + t, + molr1*ct1.mu_ - molr2*ct2.mu_, + molr1*ct1.rPr_ - molr2*ct2.rPr_ + ); +} + + +template +inline Foam::constRealGasTransport Foam::operator* +( + const scalar s, + const constRealGasTransport& ct +) +{ + return constRealGasTransport + ( + s*static_cast(ct), + ct.mu_, + ct.rPr_ + ); +} + + +template +inline Foam::constRealGasTransport Foam::operator== +( + const constRealGasTransport& ct1, + const constRealGasTransport& ct2 +) +{ + return ct2 - ct1; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// ************************************************************************* // diff --git a/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransport.H b/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransport.H index 9cc9d0c09..0623ee71d 100644 --- a/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransport.H +++ b/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransport.H @@ -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; diff --git a/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransportI.H b/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransportI.H index 241605991..4c05c5308 100644 --- a/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransportI.H +++ b/src/thermophysicalModels/specie/transport/sutherland/sutherlandTransportI.H @@ -150,7 +150,45 @@ inline scalar sutherlandTransport::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 +inline scalar sutherlandTransport::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 +inline scalar sutherlandTransport::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; } diff --git a/src/thermophysicalModels/thermophysicalFunctions/Make/files b/src/thermophysicalModels/thermophysicalFunctions/Make/files index 4fbfc660d..c4b22314d 100644 --- a/src/thermophysicalModels/thermophysicalFunctions/Make/files +++ b/src/thermophysicalModels/thermophysicalFunctions/Make/files @@ -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 diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/.cproject b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/.cproject new file mode 100644 index 000000000..d79ccac3d --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/.cproject @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/.project b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/.project new file mode 100644 index 000000000..d96828587 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/.project @@ -0,0 +1,79 @@ + + + freesteam + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/LICENSE.txt b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/LICENSE.txt new file mode 100644 index 000000000..d7c31ed3f --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/LICENSE.txt @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/README.txt b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/README.txt new file mode 100644 index 000000000..fb6cd3b80 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/README.txt @@ -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/ + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/b23.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/b23.c new file mode 100644 index 000000000..3be4a9232 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/b23.c @@ -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 + +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} */; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/b23.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/b23.h new file mode 100644 index 000000000..0dbf678cf --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/b23.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards.c new file mode 100644 index 000000000..57f20998c --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards.c @@ -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 + +/*------------------------------------------------------------------------------ + 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; in * 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; in * 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; in * 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; in * 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; dn * 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; dn * 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; in * 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; in * ipow(p1, d->I) * ipow(s1, d->J); + } + + return sum * vstar; +} + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards.h new file mode 100644 index 000000000..76ba99efa --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards_impl.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards_impl.h new file mode 100644 index 000000000..2c0dd8e20 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/backwards_impl.h @@ -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 + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/common.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/common.c new file mode 100644 index 000000000..0aeb3ab33 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/common.c @@ -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; +} diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/common.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/common.h new file mode 100644 index 000000000..3b0268daa --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/common.h @@ -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__ "" +#endif + +//#include + +#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 +# define isnan _isnan +# endif +#endif + +#endif /* FREESTEAM_COMMON_H */ diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/compat.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/compat.h new file mode 100644 index 000000000..b67882ba9 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/compat.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 +#include +#include +#include +#include +#include +#include +}; + +template +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(&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 +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::Solver2() + : solvefunc(&freesteam_set_ph), regionfunc(&freesteam_region_ph), boundfunc(&freesteam_bounds_ph) + {} + +template<> +Solver2::Solver2() + : solvefunc(&freesteam_set_Ts), regionfunc(&freesteam_region_Ts), boundfunc(&freesteam_bounds_Ts) + {} + +#endif + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/config.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/config.h new file mode 100644 index 000000000..a1443e47c --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/config.h @@ -0,0 +1,7 @@ +#ifndef FREESTEAM_CONFIG_H +#define FREESTEAM_CONFIG_H + +#define FREESTEAM_VERSION "2.1" + +#endif + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region1.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region1.c new file mode 100644 index 000000000..2f1009617 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region1.c @@ -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 + +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; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region1.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region1.h new file mode 100644 index 000000000..b0f43fb50 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region1.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region2.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region2.c new file mode 100644 index 000000000..a896cdf0c --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region2.c @@ -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 +#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; +} + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region2.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region2.h new file mode 100644 index 000000000..ac70435ef --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region2.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region3.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region3.c new file mode 100644 index 000000000..187c9781d --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region3.c @@ -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 + +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; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region3.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region3.h new file mode 100644 index 000000000..7083a254e --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region3.h @@ -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 + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region4.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region4.c new file mode 100644 index 000000000..c6696ef48 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region4.c @@ -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 +#include + +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; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region4.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region4.h new file mode 100644 index 000000000..8597f348b --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/region4.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/solver2.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/solver2.c new file mode 100644 index 000000000..7bea8b309 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/solver2.c @@ -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 +#include +#include +#include +#include + +/*------------------------------------------------------------------------------ + 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; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/solver2.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/solver2.h new file mode 100644 index 000000000..5e5a4d404 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/solver2.h @@ -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 diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam.c new file mode 100644 index 000000000..9e6420e11 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam.c @@ -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 +#include + +#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); + } +} diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam.h new file mode 100644 index 000000000..98dc4236c --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam.h @@ -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 + +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 + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pT.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pT.c new file mode 100644 index 000000000..45061e0a4 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pT.c @@ -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 +#include +#include + +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 +#include + +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(hhg){ + 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; + } +} + + + + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_ph.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_ph.h new file mode 100644 index 000000000..6bb170198 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_ph.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pv.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pv.c new file mode 100644 index 000000000..cfdb9eb8f --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pv.c @@ -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 +#include + +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; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pv.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pv.h new file mode 100644 index 000000000..5d92a3aa4 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/steam_pv.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/surftens.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/surftens.c new file mode 100644 index 000000000..7c6087898 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/surftens.c @@ -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 + +/** + 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); +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/surftens.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/surftens.h new file mode 100644 index 000000000..e2f3ac260 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/surftens.h @@ -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 */ + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.c new file mode 100644 index 000000000..4de4bd4d7 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.c @@ -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 + +#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; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.h new file mode 100644 index 000000000..9da427e37 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.h @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.py b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.py new file mode 100644 index 000000000..1aab8704d --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/thcond.py @@ -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 + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/viscosity.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/viscosity.c new file mode 100644 index 000000000..540800ee5 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/viscosity.c @@ -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 + +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; +} + diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/viscosity.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/viscosity.h new file mode 100644 index 000000000..93ac70a64 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/viscosity.h @@ -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 diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/zeroin.c b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/zeroin.c new file mode 100644 index 000000000..c5e6852c7 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/zeroin.c @@ -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 +#include + +#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))) +} diff --git a/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/zeroin.h b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/zeroin.h new file mode 100644 index 000000000..32ac967b4 --- /dev/null +++ b/src/thermophysicalModels/thermophysicalFunctions/freesteam-2.1/zeroin.h @@ -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 + diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/T b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/T new file mode 100755 index 000000000..ceeeae899 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/T @@ -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; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/U b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/U new file mode 100755 index 000000000..4eeb59065 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/U @@ -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; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/epsilon b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/epsilon new file mode 100644 index 000000000..bc5ec76b0 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/epsilon @@ -0,0 +1,58 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2.1.1 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 1120; + +boundaryField +{ + upperWall + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1120; + } + lowerWall + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1120; + } + inlet + { + type fixedValue; + value uniform 1120; + } + outlet + { + type inletOutlet; + inletValue uniform 1120; + value uniform 1120; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/k b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/k new file mode 100644 index 000000000..e17091353 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/k @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2.1.1 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 5; + +boundaryField +{ + upperWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + lowerWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + inlet + { + type turbulentIntensityKineticEnergyInlet; + intensity 0.01; + U U; + phi phi; + value uniform 5; + } + outlet + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/p b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/p new file mode 100755 index 000000000..532c994bb --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0.org/p @@ -0,0 +1,54 @@ +/*--------------------------------*- 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 p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 80e5; + +boundaryField +{ + inlet + { + type totalPressure; + rho rho; + psi none; + gamma 1.4; + p0 uniform 80.01e5; + value uniform 80.01e5; + } + outlet + { + type fixedValue; + value uniform 8e+06; + } + + upperWall + { + type zeroGradient; + } + lowerWall + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/T b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/T new file mode 100755 index 000000000..ceeeae899 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/T @@ -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; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/U b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/U new file mode 100755 index 000000000..601e606ff --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/U @@ -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 (1 0 0); + } + outlet + { + type zeroGradient; + } + + upperWall + { + type fixedValue; + value uniform (0 0 0); + } + lowerWall + { + type fixedValue; + value uniform (0 0 0); + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/epsilon b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/epsilon new file mode 100644 index 000000000..1c6c7e947 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/epsilon @@ -0,0 +1,60 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 1120; + +boundaryField +{ + inlet + { + type fixedValue; + value uniform 1120; + } + outlet + { + type inletOutlet; + inletValue uniform 1120; + value uniform 1120; + } + upperWall + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 1120; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + lowerWall + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 1120; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/k b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/k new file mode 100644 index 000000000..79ac0dc11 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/k @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 5; + +boundaryField +{ + inlet + { + type turbulentIntensityKineticEnergyInlet; + intensity 0.01; + U U; + phi phi; + value uniform 5; + } + outlet + { + type zeroGradient; + } + upperWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + lowerWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/p b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/p new file mode 100755 index 000000000..781404e7b --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/0/p @@ -0,0 +1,54 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 80e5; + +boundaryField +{ + inlet + { + type totalPressure; + rho rho; + psi none; + gamma 1.4; + p0 uniform 80.01e5; + value uniform 80.01e5; + } + outlet + { + type fixedValue; + value uniform 8e+06; + } + + upperWall + { + type zeroGradient; + } + lowerWall + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/Allrun b/tutorials/compressible/realFluidPisoFoam/ras/backStep/Allrun new file mode 100755 index 000000000..30b386dfe --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/Allrun @@ -0,0 +1,9 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +runApplication blockMesh +runApplication `getApplication` diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/RASProperties b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/RASProperties new file mode 100755 index 000000000..334f83e39 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/RASProperties @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +RASModel kEpsilon; + +turbulence on; + +printCoeffs on; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/polyMesh/blockMeshDict b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/polyMesh/blockMeshDict new file mode 100644 index 000000000..c5ed430e1 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/polyMesh/blockMeshDict @@ -0,0 +1,173 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +convertToMeters 0.001; + +vertices +( + (-20.6 0 -0.5) + (-20.6 3 -0.5) + (-20.6 12.7 -0.5) + (-20.6 25.4 -0.5) + (0 -25.4 -0.5) + (0 -5 -0.5) + (0 0 -0.5) + (0 3 -0.5) + (0 12.7 -0.5) + (0 25.4 -0.5) + (206 -25.4 -0.5) + (206 -8.5 -0.5) + (206 0 -0.5) + (206 6.5 -0.5) + (206 17 -0.5) + (206 25.4 -0.5) + (290 -16.6 -0.5) + (290 -6.3 -0.5) + (290 0 -0.5) + (290 4.5 -0.5) + (290 11 -0.5) + (290 16.6 -0.5) + (-20.6 0 0.5) + (-20.6 3 0.5) + (-20.6 12.7 0.5) + (-20.6 25.4 0.5) + (0 -25.4 0.5) + (0 -5 0.5) + (0 0 0.5) + (0 3 0.5) + (0 12.7 0.5) + (0 25.4 0.5) + (206 -25.4 0.5) + (206 -8.5 0.5) + (206 0 0.5) + (206 6.5 0.5) + (206 17 0.5) + (206 25.4 0.5) + (290 -16.6 0.5) + (290 -6.3 0.5) + (290 0 0.5) + (290 4.5 0.5) + (290 11 0.5) + (290 16.6 0.5) +); + +blocks +( + hex (0 6 7 1 22 28 29 23) (18 7 1) simpleGrading (0.5 1.8 1) + hex (1 7 8 2 23 29 30 24) (18 10 1) simpleGrading (0.5 4 1) + hex (2 8 9 3 24 30 31 25) (18 13 1) simpleGrading (0.5 0.25 1) + hex (4 10 11 5 26 32 33 27) (180 18 1) simpleGrading (4 1 1) + hex (5 11 12 6 27 33 34 28) (180 9 1) edgeGrading (4 4 4 4 0.5 1 1 0.5 1 1 1 1) + hex (6 12 13 7 28 34 35 29) (180 7 1) edgeGrading (4 4 4 4 1.8 1 1 1.8 1 1 1 1) + hex (7 13 14 8 29 35 36 30) (180 10 1) edgeGrading (4 4 4 4 4 1 1 4 1 1 1 1) + hex (8 14 15 9 30 36 37 31) (180 13 1) simpleGrading (4 0.25 1) + hex (10 16 17 11 32 38 39 33) (25 18 1) simpleGrading (2.5 1 1) + hex (11 17 18 12 33 39 40 34) (25 9 1) simpleGrading (2.5 1 1) + hex (12 18 19 13 34 40 41 35) (25 7 1) simpleGrading (2.5 1 1) + hex (13 19 20 14 35 41 42 36) (25 10 1) simpleGrading (2.5 1 1) + hex (14 20 21 15 36 42 43 37) (25 13 1) simpleGrading (2.5 0.25 1) +); + +edges +( +); + +boundary +( + inlet + { + type patch; + faces + ( + (0 22 23 1) + (1 23 24 2) + (2 24 25 3) + ); + } + outlet + { + type patch; + faces + ( + (16 17 39 38) + (17 18 40 39) + (18 19 41 40) + (19 20 42 41) + (20 21 43 42) + ); + } + upperWall + { + type wall; + faces + ( + (3 25 31 9) + (9 31 37 15) + (15 37 43 21) + ); + } + lowerWall + { + type wall; + faces + ( + (0 6 28 22) + (6 5 27 28) + (5 4 26 27) + (4 10 32 26) + (10 16 38 32) + ); + } + frontAndBack + { + type empty; + faces + ( + (22 28 29 23) + (23 29 30 24) + (24 30 31 25) + (26 32 33 27) + (27 33 34 28) + (28 34 35 29) + (29 35 36 30) + (30 36 37 31) + (32 38 39 33) + (33 39 40 34) + (34 40 41 35) + (35 41 42 36) + (36 42 43 37) + (0 1 7 6) + (1 2 8 7) + (2 3 9 8) + (4 5 11 10) + (5 6 12 11) + (6 7 13 12) + (7 8 14 13) + (8 9 15 14) + (10 11 17 16) + (11 12 18 17) + (12 13 19 18) + (13 14 20 19) + (14 15 21 20) + ); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/polyMesh/boundary b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/polyMesh/boundary new file mode 100644 index 000000000..3a93a6794 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/polyMesh/boundary @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class polyBoundaryMesh; + location "constant/polyMesh"; + object boundary; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +5 +( + inlet + { + type patch; + nFaces 30; + startFace 24170; + } + outlet + { + type patch; + nFaces 57; + startFace 24200; + } + upperWall + { + type wall; + nFaces 223; + startFace 24257; + } + lowerWall + { + type wall; + nFaces 250; + startFace 24480; + } + frontAndBack + { + type empty; + nFaces 24450; + startFace 24730; + } +) + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/thermophysicalProperties b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/thermophysicalProperties new file mode 100755 index 000000000..cc2797e09 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/thermophysicalProperties @@ -0,0 +1,68 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//CL: List of possible real gas models + +thermoType realGasHThermo>>>>; +mixture CO2 1 44.01 73.773e5 304.13 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 0.22394 467.6 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801E-13 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 0.22394 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 0.22394 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116; + + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 839 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; + + +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; + +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; + + + +//CL: description of coefficients +// *********************************************************************************************************************** // +// Coefficient: +// CO2 --> Name +// 1 +// 44.01 --> Molar Volume +// 77.773e5 --> critical pressure +// 304.13 --> critical temperatur +// 0.22394 --> acentric factor (not needed for redlich kwong) +// 467.6 --> critical density (only for aungier redlich kwong) +// 49436.5054 --> 2.849677801e-13 --> 7 heat capacity polynomial coefficent's +// .... --> two coefficent's for sutherlandTransport or for the constRealGasTransport model +// 839 --> perfect gas heat capacity Cp0 (J/kgK), needed for constantHeatCapacity +// *********************************************************************************************************************** // + diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/turbulenceProperties b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/turbulenceProperties new file mode 100755 index 000000000..09e0fc845 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType RASModel; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/controlDict b/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/controlDict new file mode 100644 index 000000000..17ef143fc --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/controlDict @@ -0,0 +1,55 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application realFluidPisoFoam; + +startFrom latestTime; + +//startTime 0; + +stopAt endTime; + +endTime 0.5; + +deltaT 1e-5; + +writeControl runTime; + +writeInterval 0.1; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression uncompressed; + +timeFormat general; + +timePrecision 10; + +adjustTimeStep yes; + +maxCo 0.5; + +maxDeltaT 1e-2; + +runTimeModifiable yes; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/fvSchemes b/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/fvSchemes new file mode 100644 index 000000000..a66a8b79a --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/fvSchemes @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; +} + +divSchemes +{ + default none; + div(phi,U) Gauss limitedLinearV 1; + div(phid,p) Gauss limitedLinear 1; + div(phiU,p) Gauss linear; + div(phi,h) Gauss limitedLinear 1; + div(phi,k) Gauss limitedLinear 1; + div(phi,epsilon) Gauss limitedLinear 1; + div(phi,R) Gauss limitedLinear 1; + div(phi,omega) Gauss limitedLinear 1; + div((rho*R)) Gauss linear; + div(R) Gauss linear; + div(U) Gauss linear; + div((muEff*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default none; + laplacian(muEff,U) Gauss linear corrected; + laplacian(mut,U) Gauss linear corrected; + laplacian(DkEff,k) Gauss linear corrected; + laplacian(DepsilonEff,epsilon) Gauss linear corrected; + laplacian(DREff,R) Gauss linear corrected; + laplacian(DomegaEff,omega) Gauss linear corrected; + laplacian((rho*(1|A(U))),p) Gauss linear corrected; + laplacian(alphaEff,h) Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/fvSolution b/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/fvSolution new file mode 100755 index 000000000..0ceb8e5ea --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep/system/fvSolution @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + p + { + solver GAMG; + tolerance 1e-14; + relTol 0.001; + smoother GaussSeidel; + minIter 4; + //maxIter 100; + cacheAgglomeration true; + nPreSweeps 1; + nPostSweeps 3; + nFinestSweeps 3; + nCellsInCoarsestLevel 20; + agglomerator faceAreaPair; + mergeLevels 1; +} + + U + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + rho + { + solver PCG; + preconditioner DIC; + tolerance 1e-10; + relTol 0; + } + + htot + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + h + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + k + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } + epsilon + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } +} + +PISO +{ + nNonOrthogonalCorrectors 0; + nCorrectors 2; + momentumPredictor yes; +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/T b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/T new file mode 100755 index 000000000..de08c916e --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/T @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 500; + +boundaryField +{ + inlet + { + type fixedValue; + value uniform 500; + } + outlet + { + type zeroGradient; + } + + upperWall + { + type zeroGradient; + } + lowerWall + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/U b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/U new file mode 100755 index 000000000..a4d73fd53 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/U @@ -0,0 +1,51 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + inlet + { + type fixedValue; + value uniform (1 0 0); + } + outlet + { + type zeroGradient; + } + + upperWall + { + type fixedValue; + value uniform (0 0 0); + } + lowerWall + { + type fixedValue; + value uniform (0 0 0); + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/epsilon b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/epsilon new file mode 100644 index 000000000..543162521 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/epsilon @@ -0,0 +1,58 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 1120; + +boundaryField +{ + upperWall + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1120; + } + lowerWall + { + type compressible::epsilonWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 1120; + } + inlet + { + type fixedValue; + value uniform 1120; + } + outlet + { + type inletOutlet; + inletValue uniform 1120; + value uniform 1120; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/k b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/k new file mode 100644 index 000000000..c80afacb1 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/k @@ -0,0 +1,53 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 5; + +boundaryField +{ + upperWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + lowerWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + inlet + { + type turbulentIntensityKineticEnergyInlet; + intensity 0.01; + U U; + phi phi; + value uniform 5; + } + outlet + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/p b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/p new file mode 100755 index 000000000..4b562e9da --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0.org/p @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 10e5; + +boundaryField +{ + inlet + { + type zeroGradient; + } + outlet + { + type fixedValue; + value uniform 1e+06; + } + + upperWall + { + type zeroGradient; + } + lowerWall + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/T b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/T new file mode 100755 index 000000000..de08c916e --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/T @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 500; + +boundaryField +{ + inlet + { + type fixedValue; + value uniform 500; + } + outlet + { + type zeroGradient; + } + + upperWall + { + type zeroGradient; + } + lowerWall + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/U b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/U new file mode 100755 index 000000000..a4d73fd53 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/U @@ -0,0 +1,51 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + location "0"; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + inlet + { + type fixedValue; + value uniform (1 0 0); + } + outlet + { + type zeroGradient; + } + + upperWall + { + type fixedValue; + value uniform (0 0 0); + } + lowerWall + { + type fixedValue; + value uniform (0 0 0); + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/epsilon b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/epsilon new file mode 100644 index 000000000..1c6c7e947 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/epsilon @@ -0,0 +1,60 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 1120; + +boundaryField +{ + inlet + { + type fixedValue; + value uniform 1120; + } + outlet + { + type inletOutlet; + inletValue uniform 1120; + value uniform 1120; + } + upperWall + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 1120; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + lowerWall + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 1120; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/k b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/k new file mode 100644 index 000000000..79ac0dc11 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/k @@ -0,0 +1,53 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 5; + +boundaryField +{ + inlet + { + type turbulentIntensityKineticEnergyInlet; + intensity 0.01; + U U; + phi phi; + value uniform 5; + } + outlet + { + type zeroGradient; + } + upperWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + lowerWall + { + type compressible::kqRWallFunction; + value uniform 5; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/p b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/p new file mode 100755 index 000000000..4b562e9da --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/0/p @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 10e5; + +boundaryField +{ + inlet + { + type zeroGradient; + } + outlet + { + type fixedValue; + value uniform 1e+06; + } + + upperWall + { + type zeroGradient; + } + lowerWall + { + type zeroGradient; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/Allrun b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/Allrun new file mode 100755 index 000000000..30b386dfe --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/Allrun @@ -0,0 +1,9 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +runApplication blockMesh +runApplication `getApplication` diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/RASProperties b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/RASProperties new file mode 100755 index 000000000..334f83e39 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/RASProperties @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +RASModel kEpsilon; + +turbulence on; + +printCoeffs on; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/polyMesh/blockMeshDict b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/polyMesh/blockMeshDict new file mode 100644 index 000000000..c5ed430e1 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/polyMesh/blockMeshDict @@ -0,0 +1,173 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +convertToMeters 0.001; + +vertices +( + (-20.6 0 -0.5) + (-20.6 3 -0.5) + (-20.6 12.7 -0.5) + (-20.6 25.4 -0.5) + (0 -25.4 -0.5) + (0 -5 -0.5) + (0 0 -0.5) + (0 3 -0.5) + (0 12.7 -0.5) + (0 25.4 -0.5) + (206 -25.4 -0.5) + (206 -8.5 -0.5) + (206 0 -0.5) + (206 6.5 -0.5) + (206 17 -0.5) + (206 25.4 -0.5) + (290 -16.6 -0.5) + (290 -6.3 -0.5) + (290 0 -0.5) + (290 4.5 -0.5) + (290 11 -0.5) + (290 16.6 -0.5) + (-20.6 0 0.5) + (-20.6 3 0.5) + (-20.6 12.7 0.5) + (-20.6 25.4 0.5) + (0 -25.4 0.5) + (0 -5 0.5) + (0 0 0.5) + (0 3 0.5) + (0 12.7 0.5) + (0 25.4 0.5) + (206 -25.4 0.5) + (206 -8.5 0.5) + (206 0 0.5) + (206 6.5 0.5) + (206 17 0.5) + (206 25.4 0.5) + (290 -16.6 0.5) + (290 -6.3 0.5) + (290 0 0.5) + (290 4.5 0.5) + (290 11 0.5) + (290 16.6 0.5) +); + +blocks +( + hex (0 6 7 1 22 28 29 23) (18 7 1) simpleGrading (0.5 1.8 1) + hex (1 7 8 2 23 29 30 24) (18 10 1) simpleGrading (0.5 4 1) + hex (2 8 9 3 24 30 31 25) (18 13 1) simpleGrading (0.5 0.25 1) + hex (4 10 11 5 26 32 33 27) (180 18 1) simpleGrading (4 1 1) + hex (5 11 12 6 27 33 34 28) (180 9 1) edgeGrading (4 4 4 4 0.5 1 1 0.5 1 1 1 1) + hex (6 12 13 7 28 34 35 29) (180 7 1) edgeGrading (4 4 4 4 1.8 1 1 1.8 1 1 1 1) + hex (7 13 14 8 29 35 36 30) (180 10 1) edgeGrading (4 4 4 4 4 1 1 4 1 1 1 1) + hex (8 14 15 9 30 36 37 31) (180 13 1) simpleGrading (4 0.25 1) + hex (10 16 17 11 32 38 39 33) (25 18 1) simpleGrading (2.5 1 1) + hex (11 17 18 12 33 39 40 34) (25 9 1) simpleGrading (2.5 1 1) + hex (12 18 19 13 34 40 41 35) (25 7 1) simpleGrading (2.5 1 1) + hex (13 19 20 14 35 41 42 36) (25 10 1) simpleGrading (2.5 1 1) + hex (14 20 21 15 36 42 43 37) (25 13 1) simpleGrading (2.5 0.25 1) +); + +edges +( +); + +boundary +( + inlet + { + type patch; + faces + ( + (0 22 23 1) + (1 23 24 2) + (2 24 25 3) + ); + } + outlet + { + type patch; + faces + ( + (16 17 39 38) + (17 18 40 39) + (18 19 41 40) + (19 20 42 41) + (20 21 43 42) + ); + } + upperWall + { + type wall; + faces + ( + (3 25 31 9) + (9 31 37 15) + (15 37 43 21) + ); + } + lowerWall + { + type wall; + faces + ( + (0 6 28 22) + (6 5 27 28) + (5 4 26 27) + (4 10 32 26) + (10 16 38 32) + ); + } + frontAndBack + { + type empty; + faces + ( + (22 28 29 23) + (23 29 30 24) + (24 30 31 25) + (26 32 33 27) + (27 33 34 28) + (28 34 35 29) + (29 35 36 30) + (30 36 37 31) + (32 38 39 33) + (33 39 40 34) + (34 40 41 35) + (35 41 42 36) + (36 42 43 37) + (0 1 7 6) + (1 2 8 7) + (2 3 9 8) + (4 5 11 10) + (5 6 12 11) + (6 7 13 12) + (7 8 14 13) + (8 9 15 14) + (10 11 17 16) + (11 12 18 17) + (12 13 19 18) + (13 14 20 19) + (14 15 21 20) + ); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/polyMesh/boundary b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/polyMesh/boundary new file mode 100644 index 000000000..3a93a6794 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/polyMesh/boundary @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class polyBoundaryMesh; + location "constant/polyMesh"; + object boundary; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +5 +( + inlet + { + type patch; + nFaces 30; + startFace 24170; + } + outlet + { + type patch; + nFaces 57; + startFace 24200; + } + upperWall + { + type wall; + nFaces 223; + startFace 24257; + } + lowerWall + { + type wall; + nFaces 250; + startFace 24480; + } + frontAndBack + { + type empty; + nFaces 24450; + startFace 24730; + } +) + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/thermophysicalProperties b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/thermophysicalProperties new file mode 100755 index 000000000..09ade9ab7 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/thermophysicalProperties @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//CL: this is all +thermoType IAPWSThermo; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/turbulenceProperties b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/turbulenceProperties new file mode 100755 index 000000000..09e0fc845 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType RASModel; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/controlDict b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/controlDict new file mode 100755 index 000000000..0c49e76d9 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/controlDict @@ -0,0 +1,61 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application realFluidPisoFoam; + +startFrom latestTime; + +//startTime 0; + +stopAt endTime; + +endTime 0.5; + +deltaT 1e-5; + +writeControl runTime; + +writeInterval 1e-1; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression uncompressed; + +timeFormat general; + +timePrecision 10; + +adjustTimeStep yes; + +maxCo 0.75; + +maxDeltaT 0.01; + +runTimeModifiable yes; + +libs +( + "libIAPWSThermo.so" + "libfreesteam.so" +); + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/fvSchemes b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/fvSchemes new file mode 100644 index 000000000..a66a8b79a --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/fvSchemes @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; +} + +divSchemes +{ + default none; + div(phi,U) Gauss limitedLinearV 1; + div(phid,p) Gauss limitedLinear 1; + div(phiU,p) Gauss linear; + div(phi,h) Gauss limitedLinear 1; + div(phi,k) Gauss limitedLinear 1; + div(phi,epsilon) Gauss limitedLinear 1; + div(phi,R) Gauss limitedLinear 1; + div(phi,omega) Gauss limitedLinear 1; + div((rho*R)) Gauss linear; + div(R) Gauss linear; + div(U) Gauss linear; + div((muEff*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default none; + laplacian(muEff,U) Gauss linear corrected; + laplacian(mut,U) Gauss linear corrected; + laplacian(DkEff,k) Gauss linear corrected; + laplacian(DepsilonEff,epsilon) Gauss linear corrected; + laplacian(DREff,R) Gauss linear corrected; + laplacian(DomegaEff,omega) Gauss linear corrected; + laplacian((rho*(1|A(U))),p) Gauss linear corrected; + laplacian(alphaEff,h) Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/fvSolution b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/fvSolution new file mode 100755 index 000000000..0ceb8e5ea --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/backStep_IAPWS97/system/fvSolution @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + p + { + solver GAMG; + tolerance 1e-14; + relTol 0.001; + smoother GaussSeidel; + minIter 4; + //maxIter 100; + cacheAgglomeration true; + nPreSweeps 1; + nPostSweeps 3; + nFinestSweeps 3; + nCellsInCoarsestLevel 20; + agglomerator faceAreaPair; + mergeLevels 1; +} + + U + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + rho + { + solver PCG; + preconditioner DIC; + tolerance 1e-10; + relTol 0; + } + + htot + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + h + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + k + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } + epsilon + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } +} + +PISO +{ + nNonOrthogonalCorrectors 0; + nCorrectors 2; + momentumPredictor yes; +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/T b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/T new file mode 100644 index 000000000..c5c4ad3ab --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/T @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + movingWall + { + type zeroGradient; + } + + fixedWalls + { + type zeroGradient; + } + + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/U b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/U new file mode 100644 index 000000000..4016c89b8 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/U @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + movingWall + { + type fixedValue; + // Field Value + value uniform (1 0 0); + } + + fixedWalls + { + type fixedValue; + // Field Value + value uniform (0 0 0); + } + + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/epsilon b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/epsilon new file mode 100644 index 000000000..d66cb9f2f --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/epsilon @@ -0,0 +1,49 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 3.1 | +| \\ / A nd | Web: http://www.extend-project.de | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 0.000765; + +boundaryField +{ + movingWall + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 0.000765; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + fixedWalls + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 0.000765; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/k b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/k new file mode 100644 index 000000000..1ff821e29 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/k @@ -0,0 +1,41 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 3.1 | +| \\ / A nd | Web: http://www.extend-project.de | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 0.00325; + +boundaryField +{ + movingWall + { + type compressible::kqRWallFunction; + value uniform 0.00325; + } + fixedWalls + { + type compressible::kqRWallFunction; + value uniform 0.00325; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/omega b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/omega new file mode 100644 index 000000000..63e1b3d75 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/omega @@ -0,0 +1,47 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2.1.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object omega; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 -1 0 0 0 0]; + +internalField uniform 2.6; + +boundaryField +{ + movingWall + { + type compressible::omegaWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 2.6; + } + fixedWalls + { + type compressible::omegaWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 2.6; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/p b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/p new file mode 100644 index 000000000..343aff8a0 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0.org/p @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 100000; + +boundaryField +{ + movingWall + { + type zeroGradient; + } + + fixedWalls + { + type zeroGradient; + } + + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/T b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/T new file mode 100644 index 000000000..c5c4ad3ab --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/T @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 300; + +boundaryField +{ + movingWall + { + type zeroGradient; + } + + fixedWalls + { + type zeroGradient; + } + + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/U b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/U new file mode 100644 index 000000000..4016c89b8 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/U @@ -0,0 +1,43 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 0 0); + +boundaryField +{ + movingWall + { + type fixedValue; + // Field Value + value uniform (1 0 0); + } + + fixedWalls + { + type fixedValue; + // Field Value + value uniform (0 0 0); + } + + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/epsilon b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/epsilon new file mode 100644 index 000000000..46326337c --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/epsilon @@ -0,0 +1,49 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 0.000765; + +boundaryField +{ + movingWall + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 0.000765; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + fixedWalls + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 0.000765; + Cmu 0.09; + kappa 0.41; + E 9.8; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/k b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/k new file mode 100644 index 000000000..0ce4a2cd7 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/k @@ -0,0 +1,41 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 0.00325; + +boundaryField +{ + movingWall + { + type compressible::kqRWallFunction; + value uniform 0.00325; + } + fixedWalls + { + type compressible::kqRWallFunction; + value uniform 0.00325; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/omega b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/omega new file mode 100644 index 000000000..63e1b3d75 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/omega @@ -0,0 +1,47 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 2.1.x | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object omega; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 -1 0 0 0 0]; + +internalField uniform 2.6; + +boundaryField +{ + movingWall + { + type compressible::omegaWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 2.6; + } + fixedWalls + { + type compressible::omegaWallFunction; + Cmu 0.09; + kappa 0.41; + E 9.8; + value uniform 2.6; + } + frontAndBack + { + type empty; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/p b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/p new file mode 100644 index 000000000..343aff8a0 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/0/p @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 100000; + +boundaryField +{ + movingWall + { + type zeroGradient; + } + + fixedWalls + { + type zeroGradient; + } + + frontAndBack + { + type empty; + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/Allrun b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/Allrun new file mode 100755 index 000000000..30b386dfe --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/Allrun @@ -0,0 +1,9 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +runApplication blockMesh +runApplication `getApplication` diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/RASProperties b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/RASProperties new file mode 100755 index 000000000..334f83e39 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/RASProperties @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +RASModel kEpsilon; + +turbulence on; + +printCoeffs on; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/polyMesh/blockMeshDict b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/polyMesh/blockMeshDict new file mode 100644 index 000000000..4a8472f71 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/polyMesh/blockMeshDict @@ -0,0 +1,75 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +convertToMeters 0.1; + +vertices +( + (0 0 0) + (1 0 0) + (1 1 0) + (0 1 0) + (0 0 0.1) + (1 0 0.1) + (1 1 0.1) + (0 1 0.1) +); + +blocks +( + hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1) +); + +edges +( +); + +boundary +( + movingWall + { + type wall; + faces + ( + (3 7 6 2) + ); + } + fixedWalls + { + type wall; + faces + ( + (0 4 7 3) + (2 6 5 1) + (1 5 4 0) + ); + } + frontAndBack + { + type empty; + faces + ( + (0 3 2 1) + (4 5 6 7) + ); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/polyMesh/boundary b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/polyMesh/boundary new file mode 100644 index 000000000..6d96c9f4d --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/polyMesh/boundary @@ -0,0 +1,40 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class polyBoundaryMesh; + location "constant/polyMesh"; + object boundary; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +3 +( + movingWall + { + type wall; + nFaces 20; + startFace 760; + } + fixedWalls + { + type wall; + nFaces 60; + startFace 780; + } + frontAndBack + { + type empty; + nFaces 800; + startFace 840; + } +) + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/thermophysicalProperties b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/thermophysicalProperties new file mode 100755 index 000000000..09ade9ab7 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/thermophysicalProperties @@ -0,0 +1,23 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//CL: this is all +thermoType IAPWSThermo; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/turbulenceProperties b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/turbulenceProperties new file mode 100755 index 000000000..09e0fc845 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/constant/turbulenceProperties @@ -0,0 +1,21 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType RASModel; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/controlDict b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/controlDict new file mode 100644 index 000000000..7bf6c0e68 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/controlDict @@ -0,0 +1,55 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: 1.6 | +| \\ / A nd | Web: www.OpenFOAM.org | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application realFluidPisoFoam; + +startFrom latestTime; + +//startTime 0; + +stopAt endTime; + +endTime 0.2; + +deltaT 1e-5; + +writeControl runTime; + +writeInterval 1e-2; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression uncompressed; + +timeFormat general; + +timePrecision 10; + +adjustTimeStep yes; + +maxCo 0.75; + +maxDeltaT 0.01; + +runTimeModifiable yes; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/fvSchemes b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/fvSchemes new file mode 100755 index 000000000..a66a8b79a --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/fvSchemes @@ -0,0 +1,70 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; +} + +divSchemes +{ + default none; + div(phi,U) Gauss limitedLinearV 1; + div(phid,p) Gauss limitedLinear 1; + div(phiU,p) Gauss linear; + div(phi,h) Gauss limitedLinear 1; + div(phi,k) Gauss limitedLinear 1; + div(phi,epsilon) Gauss limitedLinear 1; + div(phi,R) Gauss limitedLinear 1; + div(phi,omega) Gauss limitedLinear 1; + div((rho*R)) Gauss linear; + div(R) Gauss linear; + div(U) Gauss linear; + div((muEff*dev2(T(grad(U))))) Gauss linear; +} + +laplacianSchemes +{ + default none; + laplacian(muEff,U) Gauss linear corrected; + laplacian(mut,U) Gauss linear corrected; + laplacian(DkEff,k) Gauss linear corrected; + laplacian(DepsilonEff,epsilon) Gauss linear corrected; + laplacian(DREff,R) Gauss linear corrected; + laplacian(DomegaEff,omega) Gauss linear corrected; + laplacian((rho*(1|A(U))),p) Gauss linear corrected; + laplacian(alphaEff,h) Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/fvSolution b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/fvSolution new file mode 100755 index 000000000..006929ca2 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/cavity_IAPWS97/system/fvSolution @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + p + { + solver GAMG; + tolerance 1e-14; + relTol 0.001; + smoother GaussSeidel; + minIter 4; + //maxIter 100; + cacheAgglomeration true; + nPreSweeps 1; + nPostSweeps 3; + nFinestSweeps 3; + nCellsInCoarsestLevel 20; + agglomerator faceAreaPair; + mergeLevels 1; + } + + U + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + rho + { + solver PCG; + preconditioner DIC; + tolerance 1e-10; + relTol 0; + } + + htot + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + h + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + k + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } + epsilon + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } +} + +PISO +{ + nNonOrthogonalCorrectors 0; + nCorrectors 2; + momentumPredictor yes; +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/T b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/T new file mode 100755 index 000000000..e9ec126c0 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/T @@ -0,0 +1,48 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object T; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 0 0 1 0 0 0]; + +internalField uniform 333.15; + +boundaryField +{ + outlet + { + type zeroGradient; + } + + inlet1 + { + type fixedValue; + value uniform 273.15; + } + + inlet2 + { + type fixedValue; + value uniform 333.15; + } + + wall + { + type zeroGradient; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/U b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/U new file mode 100644 index 000000000..d5527191c --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/U @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volVectorField; + object U; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 1 -1 0 0 0 0]; + +internalField uniform (0 1 0); + +boundaryField +{ + outlet + { + type zeroGradient; + } + + inlet1 + { + type fixedValue; + value uniform (0 1 0); + } + + inlet2 + { + type fixedValue; + value uniform (0 -1 0); + } + + wall + { + type fixedValue; + value uniform (0 0 0); + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/epsilon b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/epsilon new file mode 100644 index 000000000..785a65be2 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/epsilon @@ -0,0 +1,58 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object epsilon; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -3 0 0 0 0]; + +internalField uniform 200; + +boundaryField +{ + outlet + { + type inletOutlet; + inletValue uniform 200; + value uniform 200; + } + inlet1 + { + type compressible::turbulentMixingLengthDissipationRateInlet; + mixingLength 0.005; + phi phi; + k k; + value uniform 200; + } + inlet2 + { + type compressible::turbulentMixingLengthDissipationRateInlet; + mixingLength 0.005; + phi phi; + k k; + value uniform 200; + } + wall + { + type compressible::epsilonWallFunction; + refValue uniform 0; + value uniform 200; + Cmu 0.09; + kappa 0.41; + E 9.8; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/k b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/k new file mode 100644 index 000000000..4e70c50f9 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/k @@ -0,0 +1,52 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | foam-extend: Open Source CFD | +| \\ / O peration | Version: 4.0 | +| \\ / A nd | Web: http://www.foam-extend.org | +| \\/ M anipulation | For copyright notice see file Copyright | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + location "0"; + object k; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [0 2 -2 0 0 0 0]; + +internalField uniform 1; + +boundaryField +{ + outlet + { + type zeroGradient; + } + inlet1 + { + type turbulentIntensityKineticEnergyInlet; + intensity 0.05; + U U; + phi phi; + value uniform 1; + } + inlet2 + { + type turbulentIntensityKineticEnergyInlet; + intensity 0.05; + U U; + phi phi; + value uniform 1; + } + wall + { + type compressible::kqRWallFunction; + value uniform 1; + } +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/p b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/p new file mode 100644 index 000000000..6c0f9da9a --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/0/p @@ -0,0 +1,46 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class volScalarField; + object p; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +dimensions [1 -1 -2 0 0 0 0]; + +internalField uniform 80e5; + +boundaryField +{ + outlet + { + type fixedMeanValue; + meanValue 8e6; + value uniform 8e+06; + } + + inlet1 + { + type zeroGradient; + } + + inlet2 + { + type zeroGradient; + } + + wall + { + type zeroGradient; + } +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/Allrun b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/Allrun new file mode 100755 index 000000000..30b386dfe --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/Allrun @@ -0,0 +1,9 @@ +#!/bin/sh +cd ${0%/*} || exit 1 # run from this directory + + +# Source tutorial run functions +. $WM_PROJECT_DIR/bin/tools/RunFunctions + +runApplication blockMesh +runApplication `getApplication` diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/RASProperties b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/RASProperties new file mode 100755 index 000000000..334f83e39 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/RASProperties @@ -0,0 +1,25 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object RASProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +RASModel kEpsilon; + +turbulence on; + +printCoeffs on; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/polyMesh/blockMeshDict b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/polyMesh/blockMeshDict new file mode 100644 index 000000000..ec058b9c8 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/polyMesh/blockMeshDict @@ -0,0 +1,144 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object blockMeshDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// inlet1 +// +-+ +// | | +// | | +// | | +// | | +// +-----------+ | +// |outlet | +// +-----------+ | +// | | +// | | +// | | +// | | +// +-+ +// inlet2 + +convertToMeters 1; + +vertices +( + (0.0 -0.01 0) //0 + (0.2 -0.01 0) //1 + (0.2 0.01 0) //2 + (0.0 0.01 0) //3 + + (0.22 -0.01 0) //4 + (0.22 0.01 0) //5 + + (0.2 -0.21 0) //6 + (0.22 -0.21 0) //7 + + (0.2 0.21 0) //8 + (0.22 0.21 0) //9 + + // Z + (0.0 -0.01 0.02) //10 + (0.2 -0.01 0.02) + (0.2 0.01 0.02) //12 + (0.0 0.01 0.02) + + (0.22 -0.01 0.02) //14 + (0.22 0.01 0.02) + + (0.2 -0.21 0.02) //16 + (0.22 -0.21 0.02) + + (0.2 0.21 0.02) //18 + (0.22 0.21 0.02) + +); + +blocks +( + // inlet block + hex (0 1 2 3 10 11 12 13) (50 5 5) simpleGrading (1 1 1) + + // central block + hex (1 4 5 2 11 14 15 12) (5 5 5) simpleGrading (1 1 1) + + // bottom block + hex (6 7 4 1 16 17 14 11) (5 50 5) simpleGrading (1 1 1) + + // top block + hex (2 5 9 8 12 15 19 18) (5 50 5) simpleGrading (1 1 1) +); + +edges +( +); + +boundary +( + outlet + { + type patch; + faces + ( + (0 10 13 3) + ); + } + + inlet1 + { + type patch; + faces + ( + (6 7 17 16) + ); + } + + inlet2 + { + type patch; + faces + ( + (8 18 19 9) + ); + } + + wall + { + type wall; + faces + ( + (0 1 2 3) + (10 11 12 13) + (8 2 5 9) + (18 12 15 19) + (1 4 5 2) + (11 14 15 12) + (1 6 7 4) + (11 16 17 14) + (6 16 11 1) + (2 12 18 8) + (3 2 12 13) + (0 1 11 10) + (7 17 14 4) + (4 14 15 5) + (5 15 19 9) + ); + } +); + +mergePatchPairs +( +); + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/thermophysicalProperties b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/thermophysicalProperties new file mode 100755 index 000000000..d284c4cc8 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/thermophysicalProperties @@ -0,0 +1,68 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + + location "constant"; + object thermophysicalProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +//CL: List of possible real gas models + +thermoType realGasHThermo>>>>; +mixture CO2 1 44.01 73.773e5 304.13 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 0.22394 467.6 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801E-13 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 0.22394 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 0.22394 49436.5054 -626.411601 5.30172524 0.002503813816 -0.0000002127308728 -0.000000000768998878 2.849677801e-13 1.4792e-06 116; + + +//thermoType realGasHThermo>>>>; +//mixture CO2 1 44.01 73.773e5 304.13 839 1.4792e-06 116; + +//thermoType realGasHThermo>>>>; + + +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; + +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; +//thermoType realGasHThermo>>>>; + + + +//CL: description of coefficients +// *********************************************************************************************************************** // +// Coefficient: +// CO2 --> Name +// 1 +// 44.01 --> Molar Volume +// 77.773e5 --> critical pressure +// 304.13 --> critical temperatur +// 0.22394 --> acentric factor (not needed for redlich kwong) +// 467.6 --> critical density (only for aungier redlich kwong) +// 49436.5054 --> 2.849677801e-13 --> 7 heat capacity polynomial coefficent's +// .... --> two coefficent's for sutherlandRealGasTransport or for the constRealGasTransport model +// 839 --> perfect gas heat capacity Cp0 (J/kgK), needed for constantHeatCapacity +// *********************************************************************************************************************** // + diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/turbulenceProperties b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/turbulenceProperties new file mode 100755 index 000000000..11e716e4e --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/constant/turbulenceProperties @@ -0,0 +1,20 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "constant"; + object turbulenceProperties; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +simulationType RASModel; + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/controlDict b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/controlDict new file mode 100755 index 000000000..aafc6e5d6 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/controlDict @@ -0,0 +1,55 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object controlDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +application realFluidPisoFoam; + +startFrom latestTime; + +//startTime 0; + +stopAt endTime; + +endTime 0.5; + +deltaT 1e-6; + +writeControl runTime; + +writeInterval 1e-2; + +purgeWrite 0; + +writeFormat ascii; + +writePrecision 6; + +writeCompression uncompressed; + +timeFormat general; + +timePrecision 10; + +adjustTimeStep yes; + +maxCo 0.25; + +maxDeltaT 1e-2; + +runTimeModifiable yes; + + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/fvSchemes b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/fvSchemes new file mode 100644 index 000000000..0088063cb --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/fvSchemes @@ -0,0 +1,73 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSchemes; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +ddtSchemes +{ + default Euler; +} + +gradSchemes +{ + default Gauss linear; + grad(p) Gauss linear; +} + +divSchemes +{ + default Gauss linear; + div(phi,U) Gauss upwind; + div(phi,h) Gauss upwind; + div(phi,k) Gauss upwind; + div(phi,epsilon) Gauss upwind; + div(phi,R) Gauss limitedLinear 1; + div(phi,omega) Gauss limitedLinear 1; + div((rho*R)) Gauss linear; + div(R) Gauss linear; + div(U) Gauss linear; + div((muEff*dev2(grad(U).T()))) Gauss linear; +} + +laplacianSchemes +{ + default none; + laplacian(muEff,U) Gauss linear corrected; + laplacian(mut,U) Gauss linear corrected; + laplacian(DkEff,k) Gauss linear corrected; + laplacian(DepsilonEff,epsilon) Gauss linear corrected; + laplacian(DREff,R) Gauss linear corrected; + laplacian(DomegaEff,omega) Gauss linear corrected; + laplacian((rho*(1|A(U))),p) Gauss linear corrected; + laplacian(alphaEff,h) Gauss linear corrected; +} + +interpolationSchemes +{ + default linear; +} + +snGradSchemes +{ + default corrected; +} + +fluxRequired +{ + default no; + p ; +} + +// ************************************************************************* // diff --git a/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/fvSolution b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/fvSolution new file mode 100755 index 000000000..59898dbc3 --- /dev/null +++ b/tutorials/compressible/realFluidPisoFoam/ras/t-junction/system/fvSolution @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | foam-extend: Open Source CFD + \\ / O peration | + \\ / A nd | For copyright notice see file Copyright + \\/ M anipulation | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + location "system"; + object fvSolution; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +solvers +{ + +p +{ + solver GAMG; + tolerance 1e-14; + relTol 0.001; + smoother GaussSeidel; + minIter 4; + //maxIter 100; + cacheAgglomeration true; + nPreSweeps 1; + nPostSweeps 3; + nFinestSweeps 3; + nCellsInCoarsestLevel 20; + agglomerator faceAreaPair; + mergeLevels 1; +} + + U + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + rho + { + solver PCG; + preconditioner DIC; + tolerance 1e-10; + relTol 0; + } + + h + { + solver smoothSolver; + smoother GaussSeidel; + nSweeps 2; + tolerance 1e-14; + relTol 0.001; + } + + k + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } + epsilon + { + solver PBiCG; + preconditioner DILU; + tolerance 1e-10; + relTol 0; + } +} + +PISO +{ + nNonOrthogonalCorrectors 0; + nCorrectors 1; + momentumPredictor yes; +} + + +// ************************************************************************* // diff --git a/tutorials/compressible/rhoPisoFoam/ras/cavity/system/fvSolution b/tutorials/compressible/rhoPisoFoam/ras/cavity/system/fvSolution index eee2770f8..e81a4c06c 100644 --- a/tutorials/compressible/rhoPisoFoam/ras/cavity/system/fvSolution +++ b/tutorials/compressible/rhoPisoFoam/ras/cavity/system/fvSolution @@ -89,4 +89,5 @@ PISO momentumPredictor yes; } + // ************************************************************************* //