1162 lines
30 KiB
C++
1162 lines
30 KiB
C++
/**
|
|
* @file WaterPropsIAPWSphi.cpp
|
|
* Definitions for Lowest level of the classes which support a real water
|
|
* model (see class \link Cantera::WaterPropsIAPWS WaterPropsIAPWS\endlink and
|
|
* class \link Cantera::WaterPropsIAPWSphi WaterPropsIAPWSphi \endlink).
|
|
*/
|
|
/*
|
|
* Copyright (2006) Sandia Corporation. Under the terms of
|
|
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
|
|
* U.S. Government retains certain rights in this software.
|
|
*/
|
|
#include "cantera/thermo/WaterPropsIAPWSphi.h"
|
|
|
|
#include <cstdio>
|
|
#include <cmath>
|
|
#include <algorithm>
|
|
|
|
namespace Cantera
|
|
{
|
|
|
|
using std::printf;
|
|
using std::sqrt;
|
|
using std::log;
|
|
using std::exp;
|
|
using std::pow;
|
|
using std::fabs;
|
|
|
|
/*
|
|
* Critical Point values in mks units: Note, these aren't used in this
|
|
* routine, except for internal checks. All calculations here are done
|
|
* in dimensionless units.
|
|
*/
|
|
// \cond
|
|
static const doublereal T_c = 647.096; // Kelvin
|
|
static const doublereal P_c = 22.064E6; // Pascals
|
|
static const doublereal Rho_c = 322.; // kg m-3
|
|
static const doublereal M_water = 18.015268; // kg kmol-1
|
|
// \endcond
|
|
|
|
/*
|
|
* The added constants were calculated so that u = s = 0
|
|
* for liquid at the triple point. These where determined
|
|
* by the program testPress. I'm not quite satisfied with
|
|
* the result, but will let it stand for the moment.
|
|
* H didn't turn out to be .611872 J/kg, but .611782 J/kg.
|
|
* There may be a slight error here somehow.
|
|
*/
|
|
// \cond
|
|
static const doublereal ni0[9] = {
|
|
0.0,
|
|
-8.32044648201 - 0.000000001739715,
|
|
6.6832105268 + 0.000000000793232,
|
|
3.00632,
|
|
0.012436,
|
|
0.97315,
|
|
1.27950,
|
|
0.96956,
|
|
0.24873
|
|
};
|
|
|
|
static const doublereal gammi0[9] = {
|
|
0.0,
|
|
0.0,
|
|
0.0,
|
|
0.0,
|
|
1.28728967,
|
|
3.53734222,
|
|
7.74073708,
|
|
9.24437796,
|
|
27.5075105
|
|
};
|
|
|
|
static const int ciR[56] = {
|
|
0, // 0
|
|
0, // 1
|
|
0,
|
|
0,
|
|
0,
|
|
0, // 5
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
1, // 10
|
|
1,
|
|
1,
|
|
1,
|
|
1,
|
|
1, // 15
|
|
1,
|
|
1,
|
|
1,
|
|
1,
|
|
1, // 20
|
|
1,
|
|
1,
|
|
2,
|
|
2,
|
|
2, // 25
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
2, // 30
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
2, // 35
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
2, // 40
|
|
2,
|
|
2,
|
|
3,
|
|
3,
|
|
3, // 45
|
|
3,
|
|
4,
|
|
6,
|
|
6,
|
|
6, // 50
|
|
6,
|
|
0,
|
|
0,
|
|
0,
|
|
0 // 55
|
|
};
|
|
|
|
static const int diR[55] = {
|
|
0, // 0
|
|
1, // 1
|
|
1,
|
|
1,
|
|
2,
|
|
2, // 5
|
|
3,
|
|
4,
|
|
1,
|
|
1,
|
|
1, // 10
|
|
2,
|
|
2,
|
|
3,
|
|
4,
|
|
4, // 15
|
|
5,
|
|
7,
|
|
9,
|
|
10,
|
|
11, // 20
|
|
13,
|
|
15,
|
|
1,
|
|
2,
|
|
2, // 25
|
|
2,
|
|
3,
|
|
4,
|
|
4,
|
|
4, // 30
|
|
5,
|
|
6,
|
|
6,
|
|
7,
|
|
9, // 35
|
|
9,
|
|
9,
|
|
9,
|
|
9,
|
|
10, // 40
|
|
10,
|
|
12,
|
|
3,
|
|
4,
|
|
4, // 45
|
|
5,
|
|
14,
|
|
3,
|
|
6,
|
|
6, // 50
|
|
6,
|
|
3,
|
|
3,
|
|
3 // 54
|
|
};
|
|
|
|
static const int tiR[55] = {
|
|
0, // 0
|
|
0, // 1
|
|
0,
|
|
0,
|
|
0,
|
|
0, // 5
|
|
0,
|
|
0,
|
|
4, // 8
|
|
6,
|
|
12, // 10
|
|
1,
|
|
5,
|
|
4,
|
|
2,
|
|
13, // 15
|
|
9,
|
|
3,
|
|
4,
|
|
11,
|
|
4, // 20
|
|
13,
|
|
1,
|
|
7,
|
|
1,
|
|
9, // 25
|
|
10,
|
|
10,
|
|
3,
|
|
7,
|
|
10, // 30
|
|
10,
|
|
6,
|
|
10,
|
|
10,
|
|
1, // 35
|
|
2,
|
|
3,
|
|
4,
|
|
8,
|
|
6, // 40
|
|
9,
|
|
8,
|
|
16,
|
|
22,
|
|
23, // 45
|
|
23,
|
|
10,
|
|
50,
|
|
44,
|
|
46, // 50
|
|
50,
|
|
0,
|
|
1,
|
|
4 // 54
|
|
};
|
|
|
|
static const doublereal ni[57] = {
|
|
+0.0,
|
|
+0.12533547935523E-1, // 1
|
|
+0.78957634722828E1, // 2
|
|
-0.87803203303561E1, // 3
|
|
+0.31802509345418E0, // 4
|
|
-0.26145533859358E0, // 5
|
|
-0.78199751687981E-2, // 6
|
|
+0.88089493102134E-2, // 7
|
|
-0.66856572307965E0, // 8
|
|
+0.20433810950965, // 9
|
|
-0.66212605039687E-4, // 10
|
|
-0.19232721156002E0, // 11
|
|
-0.25709043003438E0, // 12
|
|
+0.16074868486251E0, // 13
|
|
-0.40092828925807E-1, // 14
|
|
+0.39343422603254E-6, // 15
|
|
-0.75941377088144E-5, // 16
|
|
+0.56250979351888E-3, // 17
|
|
-0.15608652257135E-4, // 18
|
|
+0.11537996422951E-8, // 19
|
|
+0.36582165144204E-6, // 20
|
|
-0.13251180074668E-11,// 21
|
|
-0.62639586912454E-9, // 22
|
|
-0.10793600908932E0, // 23
|
|
+0.17611491008752E-1, // 24
|
|
+0.22132295167546E0, // 25
|
|
-0.40247669763528E0, // 26
|
|
+0.58083399985759E0, // 27
|
|
+0.49969146990806E-2, // 28
|
|
-0.31358700712549E-1, // 29
|
|
-0.74315929710341E0, // 30
|
|
+0.47807329915480E0, // 31
|
|
+0.20527940895948E-1, // 32
|
|
-0.13636435110343E0, // 33
|
|
+0.14180634400617E-1, // 34
|
|
+0.83326504880713E-2, // 35
|
|
-0.29052336009585E-1, // 36
|
|
+0.38615085574206E-1, // 37
|
|
-0.20393486513704E-1, // 38
|
|
-0.16554050063734E-2, // 39
|
|
+0.19955571979541E-2, // 40
|
|
+0.15870308324157E-3, // 41
|
|
-0.16388568342530E-4, // 42
|
|
+0.43613615723811E-1, // 43
|
|
+0.34994005463765E-1, // 44
|
|
-0.76788197844621E-1, // 45
|
|
+0.22446277332006E-1, // 46
|
|
-0.62689710414685E-4, // 47
|
|
-0.55711118565645E-9, // 48
|
|
-0.19905718354408E0, // 49
|
|
+0.31777497330738E0, // 50
|
|
-0.11841182425981E0, // 51
|
|
-0.31306260323435E2, // 52
|
|
+0.31546140237781E2, // 53
|
|
-0.25213154341695E4, // 54
|
|
-0.14874640856724E0, // 55
|
|
+0.31806110878444E0 // 56
|
|
};
|
|
|
|
static const doublereal alphai[3] = {
|
|
+20.,
|
|
+20.,
|
|
+20.
|
|
};
|
|
|
|
static const doublereal betai[3] = {
|
|
+150.,
|
|
+150.,
|
|
+250.
|
|
};
|
|
|
|
static const doublereal gammai[3] = {
|
|
+1.21,
|
|
+1.21,
|
|
+1.25
|
|
};
|
|
|
|
static const doublereal epsi[3] = {
|
|
+1.0,
|
|
+1.0,
|
|
+1.0
|
|
};
|
|
|
|
static const doublereal ai[2] = {
|
|
+3.5,
|
|
+3.5
|
|
};
|
|
|
|
static const doublereal bi[2] = {
|
|
+0.85,
|
|
+0.95
|
|
};
|
|
|
|
static const doublereal Bi[2] = {
|
|
+0.2,
|
|
+0.2
|
|
};
|
|
|
|
static const doublereal Ci[2] = {
|
|
+28.0,
|
|
+32.0
|
|
};
|
|
|
|
static const doublereal Di[2] = {
|
|
+700.,
|
|
+800.
|
|
};
|
|
|
|
static const doublereal Ai[2] = {
|
|
+0.32,
|
|
+0.32
|
|
};
|
|
|
|
static const doublereal Bbetai[2] = {
|
|
+0.3,
|
|
+0.3
|
|
};
|
|
// \endcond
|
|
|
|
WaterPropsIAPWSphi::WaterPropsIAPWSphi() :
|
|
TAUsave(-1.0),
|
|
TAUsqrt(-1.0),
|
|
DELTAsave(-1.0)
|
|
{
|
|
for (int i = 0; i < 52; i++) {
|
|
TAUp[i] = 1.0;
|
|
}
|
|
for (int i = 0; i < 16; i++) {
|
|
DELTAp[i] = 1.0;
|
|
}
|
|
}
|
|
|
|
void WaterPropsIAPWSphi::intCheck(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal nau = phi0();
|
|
doublereal res = phiR();
|
|
doublereal res_d = phiR_d();
|
|
doublereal nau_d = phi0_d();
|
|
doublereal res_dd = phiR_dd();
|
|
doublereal nau_dd = phi0_dd();
|
|
doublereal res_t = phiR_t();
|
|
doublereal nau_t = phi0_t();
|
|
doublereal res_tt = phiR_tt();
|
|
doublereal nau_tt = phi0_tt();
|
|
doublereal res_dt = phiR_dt();
|
|
doublereal nau_dt = phi0_dt();
|
|
|
|
std::printf("nau = %20.12e\t\tres = %20.12e\n", nau, res);
|
|
std::printf("nau_d = %20.12e\t\tres_d = %20.12e\n", nau_d, res_d);
|
|
printf("nau_dd = %20.12e\t\tres_dd = %20.12e\n", nau_dd, res_dd);
|
|
printf("nau_t = %20.12e\t\tres_t = %20.12e\n", nau_t, res_t);
|
|
printf("nau_tt = %20.12e\t\tres_tt = %20.12e\n", nau_tt, res_tt);
|
|
printf("nau_dt = %20.12e\t\tres_dt = %20.12e\n", nau_dt, res_dt);
|
|
}
|
|
|
|
void WaterPropsIAPWSphi::check1()
|
|
{
|
|
doublereal T = 500.;
|
|
doublereal rho = 838.025;
|
|
doublereal tau = T_c/T;
|
|
doublereal delta = rho / Rho_c;
|
|
printf(" T = 500 K, rho = 838.025 kg m-3\n");
|
|
intCheck(tau, delta);
|
|
}
|
|
|
|
void WaterPropsIAPWSphi::check2()
|
|
{
|
|
doublereal T = 647;
|
|
doublereal rho = 358.0;
|
|
doublereal tau = T_c/T;
|
|
doublereal delta = rho / Rho_c;
|
|
printf(" T = 647 K, rho = 358.0 kg m-3\n");
|
|
intCheck(tau, delta);
|
|
}
|
|
|
|
void WaterPropsIAPWSphi::tdpolycalc(doublereal tau, doublereal delta)
|
|
{
|
|
if ((tau != TAUsave) || 1) {
|
|
TAUsave = tau;
|
|
TAUsqrt = sqrt(tau);
|
|
TAUp[0] = 1.0;
|
|
for (int i = 1; i < 51; i++) {
|
|
TAUp[i] = TAUp[i-1] * tau;
|
|
}
|
|
}
|
|
if ((delta != DELTAsave) || 1) {
|
|
DELTAsave = delta;
|
|
DELTAp[0] = 1.0;
|
|
for (int i = 1; i <= 15; i++) {
|
|
DELTAp[i] = DELTAp[i-1] * delta;
|
|
}
|
|
}
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi0() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
doublereal retn = log(delta) + ni0[1] + ni0[2]*tau + ni0[3]*log(tau);
|
|
|
|
retn += ni0[4] * log(1.0 - exp(-gammi0[4]*tau));
|
|
retn += ni0[5] * log(1.0 - exp(-gammi0[5]*tau));
|
|
retn += ni0[6] * log(1.0 - exp(-gammi0[6]*tau));
|
|
retn += ni0[7] * log(1.0 - exp(-gammi0[7]*tau));
|
|
retn += ni0[8] * log(1.0 - exp(-gammi0[8]*tau));
|
|
return retn;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phiR() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
int i, j;
|
|
|
|
/*
|
|
* Write out the first seven polynomials in the expression
|
|
*/
|
|
doublereal T375 = pow(tau, 0.375);
|
|
doublereal val = (ni[1] * delta / TAUsqrt +
|
|
ni[2] * delta * TAUsqrt * T375 +
|
|
ni[3] * delta * tau +
|
|
ni[4] * DELTAp[2] * TAUsqrt +
|
|
ni[5] * DELTAp[2] * T375 * T375 +
|
|
ni[6] * DELTAp[3] * T375 +
|
|
ni[7] * DELTAp[4] * tau);
|
|
/*
|
|
* Next, do polynomial contributions 8 to 51
|
|
*/
|
|
for (i = 8; i <= 51; i++) {
|
|
val += (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] * exp(-DELTAp[ciR[i]]));
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 52 to 54
|
|
*/
|
|
for (j = 0; j < 3; j++) {
|
|
i = 52 + j;
|
|
doublereal dtmp = delta - epsi[j];
|
|
doublereal ttmp = tau - gammai[j];
|
|
val += (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
|
|
exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 55 and 56
|
|
*/
|
|
for (j = 0; j < 2; j++) {
|
|
i = 55 + j;
|
|
doublereal deltam1 = delta - 1.0;
|
|
doublereal dtmp2 = deltam1 * deltam1;
|
|
doublereal atmp = 0.5 / Bbetai[j];
|
|
doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
|
|
doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
|
|
doublereal ttmp = tau - 1.0;
|
|
|
|
doublereal triagtmp = pow(triag, bi[j]);
|
|
|
|
doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
|
|
val += (ni[i] * triagtmp * delta * phi);
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal nau = phi0();
|
|
doublereal res = phiR();
|
|
return nau + res;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phiR_d() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
int i, j;
|
|
|
|
/*
|
|
* Write out the first seven polynomials in the expression
|
|
*/
|
|
doublereal T375 = pow(tau, 0.375);
|
|
doublereal val = (ni[1] / TAUsqrt +
|
|
ni[2] * TAUsqrt * T375 +
|
|
ni[3] * tau +
|
|
ni[4] * 2.0 * delta * TAUsqrt +
|
|
ni[5] * 2.0 * delta * T375 * T375 +
|
|
ni[6] * 3.0 * DELTAp[2] * T375 +
|
|
ni[7] * 4.0 * DELTAp[3] * tau);
|
|
/*
|
|
* Next, do polynomial contributions 8 to 51
|
|
*/
|
|
for (i = 8; i <= 51; i++) {
|
|
val += ((ni[i] * exp(-DELTAp[ciR[i]]) * DELTAp[diR[i] - 1] *
|
|
TAUp[tiR[i]]) * (diR[i] - ciR[i]* DELTAp[ciR[i]]));
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 52 to 54
|
|
*/
|
|
for (j = 0; j < 3; j++) {
|
|
i = 52 + j;
|
|
doublereal dtmp = delta - epsi[j];
|
|
doublereal ttmp = tau - gammai[j];
|
|
doublereal tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
|
|
exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
|
|
val += tmp * (diR[i]/delta - 2.0 * alphai[j] * dtmp);
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 55 and 56
|
|
*/
|
|
for (j = 0; j < 2; j++) {
|
|
i = 55 + j;
|
|
doublereal deltam1 = delta - 1.0;
|
|
doublereal dtmp2 = deltam1 * deltam1;
|
|
doublereal atmp = 0.5 / Bbetai[j];
|
|
doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
|
|
doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
|
|
doublereal ttmp = tau - 1.0;
|
|
|
|
doublereal triagtmp = pow(triag, bi[j]);
|
|
doublereal triagtmpm1 = pow(triag, bi[j]-1.0);
|
|
doublereal atmpM1 = atmp - 1.0;
|
|
doublereal ptmp = pow(dtmp2,atmpM1);
|
|
doublereal p2tmp = pow(dtmp2, ai[j]-1.0);
|
|
doublereal dtriagddelta =
|
|
deltam1 *(Ai[j] * theta * 2.0 / Bbetai[j] * ptmp +
|
|
2.0*Bi[j]*ai[j]*p2tmp);
|
|
|
|
doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
|
|
doublereal dphiddelta = -2.0*Ci[j]*deltam1*phi;
|
|
doublereal dtriagtmpddelta = bi[j] * triagtmpm1 * dtriagddelta;
|
|
|
|
doublereal tmp = ni[i] * (triagtmp * (phi + delta*dphiddelta) +
|
|
dtriagtmpddelta * delta * phi);
|
|
val += tmp;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi0_d() const
|
|
{
|
|
doublereal delta = DELTAsave;
|
|
return 1.0/delta;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi_d(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal nau = phi0_d();
|
|
doublereal res = phiR_d();
|
|
return nau + res;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::pressureM_rhoRT(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal res = phiR_d();
|
|
return 1.0 + delta * res;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phiR_dd() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
int i, j;
|
|
doublereal atmp;
|
|
|
|
/*
|
|
* Write out the first seven polynomials in the expression
|
|
*/
|
|
doublereal T375 = pow(tau, 0.375);
|
|
doublereal val = (ni[4] * 2.0 * TAUsqrt +
|
|
ni[5] * 2.0 * T375 * T375 +
|
|
ni[6] * 6.0 * delta * T375 +
|
|
ni[7] * 12.0 * DELTAp[2] * tau);
|
|
/*
|
|
* Next, do polynomial contributions 8 to 51
|
|
*/
|
|
for (i = 8; i <= 51; i++) {
|
|
doublereal dtmp = DELTAp[ciR[i]];
|
|
doublereal tmp = ni[i] * exp(-dtmp) * TAUp[tiR[i]];
|
|
if (diR[i] == 1) {
|
|
atmp = 1.0/delta;
|
|
} else {
|
|
atmp = DELTAp[diR[i] - 2];
|
|
}
|
|
tmp *= atmp *((diR[i] - ciR[i]*dtmp)*(diR[i]-1.0-ciR[i]*dtmp) -
|
|
ciR[i]*ciR[i]*dtmp);
|
|
val += tmp;
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 52 to 54
|
|
*/
|
|
for (j = 0; j < 3; j++) {
|
|
i = 52 + j;
|
|
doublereal dtmp = delta - epsi[j];
|
|
doublereal ttmp = tau - gammai[j];
|
|
doublereal tmp = (ni[i] * TAUp[tiR[i]] *
|
|
exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
|
|
doublereal deltmp = DELTAp[diR[i]];
|
|
doublereal deltmpM1 = deltmp/delta;
|
|
doublereal deltmpM2 = deltmpM1 / delta;
|
|
doublereal d2tmp = dtmp * dtmp;
|
|
|
|
val += tmp * (-2.0*alphai[j]*deltmp +
|
|
4.0 * alphai[j] * alphai[j] * deltmp * d2tmp -
|
|
4.0 * diR[i] * alphai[j] * deltmpM1 * dtmp +
|
|
diR[i] * (diR[i] - 1.0) * deltmpM2);
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 55 and 56
|
|
*/
|
|
for (j = 0; j < 2; j++) {
|
|
i = 55 + j;
|
|
doublereal deltam1 = delta - 1.0;
|
|
doublereal dtmp2 = deltam1 * deltam1;
|
|
atmp = 0.5 / Bbetai[j];
|
|
doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
|
|
doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
|
|
doublereal ttmp = tau - 1.0;
|
|
|
|
doublereal triagtmp = pow(triag, bi[j]);
|
|
doublereal triagtmpm1 = pow(triag, bi[j]-1.0);
|
|
doublereal atmpM1 = atmp - 1.0;
|
|
doublereal ptmp = pow(dtmp2,atmpM1);
|
|
doublereal p2tmp = pow(dtmp2, ai[j]-1.0);
|
|
doublereal dtriagddelta =
|
|
deltam1 *(Ai[j] * theta * 2.0 / Bbetai[j] * ptmp +
|
|
2.0*Bi[j]*ai[j]*p2tmp);
|
|
|
|
doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
|
|
doublereal dphiddelta = -2.0*Ci[j]*deltam1*phi;
|
|
doublereal dtriagtmpddelta = bi[j] * triagtmpm1 * dtriagddelta;
|
|
|
|
|
|
doublereal d2phiddelta2 = 2.0 * Ci[j] * phi * (2.0*Ci[j]*dtmp2 - 1.0);
|
|
|
|
doublereal pptmp = ptmp / dtmp2;
|
|
doublereal d2triagddelta2 = dtriagddelta / deltam1;
|
|
d2triagddelta2 +=
|
|
dtmp2 *(4.0*Bi[j]*ai[j]*(ai[j]-1.0)*pow(dtmp2,ai[j]-2.0) +
|
|
2.0*Ai[j]*Ai[j]/(Bbetai[j]*Bbetai[j])*ptmp*ptmp +
|
|
Ai[j]*theta*4.0/Bbetai[j]*(atmp-1.0)*pptmp);
|
|
|
|
doublereal d2triagtmpd2delta =
|
|
bi[j] * (triagtmpm1 * d2triagddelta2 +
|
|
(bi[j]-1.0)*triagtmpm1/triag*dtriagddelta*dtriagddelta);
|
|
|
|
doublereal ctmp = (triagtmp * (2.0*dphiddelta + delta*d2phiddelta2) +
|
|
2.0*dtriagtmpddelta*(phi + delta * dphiddelta) +
|
|
d2triagtmpd2delta * delta * phi);
|
|
|
|
val += ni[i] * ctmp;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi0_dd() const
|
|
{
|
|
doublereal delta = DELTAsave;
|
|
return -1.0/(delta*delta);
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi_dd(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal nau = phi0_dd();
|
|
doublereal res = phiR_dd();
|
|
return nau + res;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::dimdpdrho(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal res1 = phiR_d();
|
|
doublereal res2 = phiR_dd();
|
|
return 1.0 + delta * (2.0*res1 + delta*res2);
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::dimdpdT(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal res1 = phiR_d();
|
|
doublereal res2 = phiR_dt();
|
|
return (1.0 + delta * res1) - tau * delta * (res2);
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi0_t() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal retn = ni0[2] + ni0[3]/tau;
|
|
retn += (ni0[4] * gammi0[4] * (1.0/(1.0 - exp(-gammi0[4]*tau)) - 1.0));
|
|
retn += (ni0[5] * gammi0[5] * (1.0/(1.0 - exp(-gammi0[5]*tau)) - 1.0));
|
|
retn += (ni0[6] * gammi0[6] * (1.0/(1.0 - exp(-gammi0[6]*tau)) - 1.0));
|
|
retn += (ni0[7] * gammi0[7] * (1.0/(1.0 - exp(-gammi0[7]*tau)) - 1.0));
|
|
retn += (ni0[8] * gammi0[8] * (1.0/(1.0 - exp(-gammi0[8]*tau)) - 1.0));
|
|
return retn;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phiR_t() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
int i, j;
|
|
doublereal atmp, tmp;
|
|
|
|
/*
|
|
* Write out the first seven polynomials in the expression
|
|
*/
|
|
doublereal T375 = pow(tau, 0.375);
|
|
doublereal val = ((-0.5) *ni[1] * delta / TAUsqrt / tau +
|
|
ni[2] * delta * 0.875 / TAUsqrt * T375 +
|
|
ni[3] * delta +
|
|
ni[4] * DELTAp[2] * 0.5 / TAUsqrt +
|
|
ni[5] * DELTAp[2] * 0.75 * T375 * T375 / tau +
|
|
ni[6] * DELTAp[3] * 0.375 * T375 / tau +
|
|
ni[7] * DELTAp[4]);
|
|
/*
|
|
* Next, do polynomial contributions 8 to 51
|
|
*/
|
|
for (i = 8; i <= 51; i++) {
|
|
tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]-1] * exp(-DELTAp[ciR[i]]));
|
|
val += tiR[i] * tmp;
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 52 to 54
|
|
*/
|
|
for (j = 0; j < 3; j++) {
|
|
i = 52 + j;
|
|
doublereal dtmp = delta - epsi[j];
|
|
doublereal ttmp = tau - gammai[j];
|
|
tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
|
|
exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
|
|
val += tmp *(tiR[i]/tau - 2.0 * betai[j]*ttmp);
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 55 and 56
|
|
*/
|
|
for (j = 0; j < 2; j++) {
|
|
i = 55 + j;
|
|
doublereal deltam1 = delta - 1.0;
|
|
doublereal dtmp2 = deltam1 * deltam1;
|
|
atmp = 0.5 / Bbetai[j];
|
|
doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
|
|
doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
|
|
doublereal ttmp = tau - 1.0;
|
|
|
|
doublereal triagtmp = pow(triag, bi[j]);
|
|
|
|
doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
|
|
|
|
|
|
doublereal dtriagtmpdtau = -2.0*theta * bi[j] * triagtmp / triag;
|
|
|
|
doublereal dphidtau = - 2.0 * Di[j] * ttmp * phi;
|
|
|
|
val += ni[i] * delta * (dtriagtmpdtau * phi + triagtmp * dphidtau);
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi_t(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal nau = phi0_t();
|
|
doublereal res = phiR_t();
|
|
return nau + res;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi0_tt() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal tmp, itmp;
|
|
doublereal retn = - ni0[3]/(tau * tau);
|
|
for (int i = 4; i <= 8; i++) {
|
|
tmp = exp(-gammi0[i]*tau);
|
|
itmp = 1.0 - tmp;
|
|
retn -= (ni0[i] * gammi0[i] * gammi0[i] * tmp / (itmp * itmp));
|
|
}
|
|
return retn;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phiR_tt() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
int i, j;
|
|
doublereal atmp, tmp;
|
|
|
|
/*
|
|
* Write out the first seven polynomials in the expression
|
|
*/
|
|
doublereal T375 = pow(tau, 0.375);
|
|
doublereal val = ((-0.5) * (-1.5) * ni[1] * delta / (TAUsqrt * tau * tau) +
|
|
ni[2] * delta * 0.875 * (-0.125) * T375 / (TAUsqrt * tau) +
|
|
ni[4] * DELTAp[2] * 0.5 * (-0.5)/ (TAUsqrt * tau) +
|
|
ni[5] * DELTAp[2] * 0.75 *(-0.25) * T375 * T375 / (tau * tau) +
|
|
ni[6] * DELTAp[3] * 0.375 *(-0.625) * T375 / (tau * tau));
|
|
/*
|
|
* Next, do polynomial contributions 8 to 51
|
|
*/
|
|
for (i = 8; i <= 51; i++) {
|
|
if (tiR[i] > 1) {
|
|
tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]-2] * exp(-DELTAp[ciR[i]]));
|
|
val += tiR[i] * (tiR[i] - 1.0) * tmp;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 52 to 54
|
|
*/
|
|
for (j = 0; j < 3; j++) {
|
|
i = 52 + j;
|
|
doublereal dtmp = delta - epsi[j];
|
|
doublereal ttmp = tau - gammai[j];
|
|
tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
|
|
exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
|
|
atmp = tiR[i]/tau - 2.0 * betai[j]*ttmp;
|
|
val += tmp *(atmp * atmp - tiR[i]/(tau*tau) - 2.0*betai[j]);
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 55 and 56
|
|
*/
|
|
for (j = 0; j < 2; j++) {
|
|
i = 55 + j;
|
|
doublereal deltam1 = delta - 1.0;
|
|
doublereal dtmp2 = deltam1 * deltam1;
|
|
atmp = 0.5 / Bbetai[j];
|
|
doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
|
|
doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
|
|
doublereal ttmp = tau - 1.0;
|
|
|
|
doublereal triagtmp = pow(triag, bi[j]);
|
|
doublereal triagtmpM1 = triagtmp / triag;
|
|
|
|
doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
|
|
|
|
|
|
doublereal dtriagtmpdtau = -2.0*theta * bi[j] * triagtmp / triag;
|
|
|
|
doublereal dphidtau = - 2.0 * Di[j] * ttmp * phi;
|
|
|
|
doublereal d2triagtmpdtau2 =
|
|
(2 * bi[j] * triagtmpM1 +
|
|
4 * theta * theta * bi[j] * (bi[j]-1.0) * triagtmpM1 / triag);
|
|
|
|
doublereal d2phidtau2 = 2.0*Di[j]*phi *(2.0*Di[j]*ttmp*ttmp - 1.0);
|
|
|
|
tmp = (d2triagtmpdtau2 * phi +
|
|
2 * dtriagtmpdtau * dphidtau +
|
|
triagtmp * d2phidtau2);
|
|
val += ni[i] * delta * tmp;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi_tt(doublereal tau, doublereal delta)
|
|
{
|
|
tdpolycalc(tau, delta);
|
|
doublereal nau = phi0_tt();
|
|
doublereal res = phiR_tt();
|
|
return nau + res;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phi0_dt() const
|
|
{
|
|
return 0.0;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::phiR_dt() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
int i, j;
|
|
doublereal tmp;
|
|
/*
|
|
* Write out the first seven polynomials in the expression
|
|
*/
|
|
doublereal T375 = pow(tau, 0.375);
|
|
doublereal val = (ni[1] * (-0.5) / (TAUsqrt * tau) +
|
|
ni[2] * (0.875) * T375 / TAUsqrt +
|
|
ni[3] +
|
|
ni[4] * 2.0 * delta * (0.5) / TAUsqrt +
|
|
ni[5] * 2.0 * delta * (0.75) * T375 * T375 / tau +
|
|
ni[6] * 3.0 * DELTAp[2] * 0.375 * T375 / tau +
|
|
ni[7] * 4.0 * DELTAp[3]);
|
|
/*
|
|
* Next, do polynomial contributions 8 to 51
|
|
*/
|
|
for (i = 8; i <= 51; i++) {
|
|
tmp = (ni[i] * tiR[i] * exp(-DELTAp[ciR[i]]) * DELTAp[diR[i] - 1] *
|
|
TAUp[tiR[i] - 1]);
|
|
val += tmp * (diR[i] - ciR[i] * DELTAp[ciR[i]]);
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 52 to 54
|
|
*/
|
|
for (j = 0; j < 3; j++) {
|
|
i = 52 + j;
|
|
doublereal dtmp = delta - epsi[j];
|
|
doublereal ttmp = tau - gammai[j];
|
|
tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
|
|
exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
|
|
val += tmp * ((diR[i]/delta - 2.0 * alphai[j] * dtmp) *
|
|
(tiR[i]/tau - 2.0 * betai[j] * ttmp));
|
|
}
|
|
|
|
/*
|
|
* Next do contributions 55 and 56
|
|
*/
|
|
for (j = 0; j < 2; j++) {
|
|
i = 55 + j;
|
|
doublereal deltam1 = delta - 1.0;
|
|
doublereal dtmp2 = deltam1 * deltam1;
|
|
doublereal atmp = 0.5 / Bbetai[j];
|
|
doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
|
|
doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
|
|
doublereal ttmp = tau - 1.0;
|
|
|
|
doublereal triagtmp = pow(triag, bi[j]);
|
|
doublereal triagtmpm1 = pow(triag, bi[j]-1.0);
|
|
doublereal atmpM1 = atmp - 1.0;
|
|
doublereal ptmp = pow(dtmp2,atmpM1);
|
|
doublereal p2tmp = pow(dtmp2, ai[j]-1.0);
|
|
doublereal dtriagddelta =
|
|
deltam1 *(Ai[j] * theta * 2.0 / Bbetai[j] * ptmp +
|
|
2.0*Bi[j]*ai[j]*p2tmp);
|
|
|
|
doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
|
|
doublereal dphiddelta = -2.0*Ci[j]*deltam1*phi;
|
|
doublereal dtriagtmpddelta = bi[j] * triagtmpm1 * dtriagddelta;
|
|
|
|
|
|
doublereal dtriagtmpdtau = -2.0*theta * bi[j] * triagtmp / triag;
|
|
|
|
doublereal dphidtau = - 2.0 * Di[j] * ttmp * phi;
|
|
|
|
doublereal d2phiddeltadtau = 4.0 * Ci[j] * Di[j] * deltam1 * ttmp * phi;
|
|
|
|
doublereal d2triagtmpddeltadtau =
|
|
(-Ai[j] * bi[j] * 2.0 / Bbetai[j] * triagtmpm1 * deltam1 * ptmp
|
|
-2.0 * theta * bi[j] * (bi[j] - 1.0) * triagtmpm1 / triag * dtriagddelta);
|
|
|
|
|
|
doublereal tmp = ni[i] * (triagtmp * (dphidtau + delta*d2phiddeltadtau) +
|
|
delta * dtriagtmpddelta * dphidtau +
|
|
dtriagtmpdtau * (phi + delta * dphiddelta) +
|
|
d2triagtmpddeltadtau * delta * phi);
|
|
val += tmp;
|
|
}
|
|
|
|
return val;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::dfind(doublereal p_red, doublereal tau, doublereal deltaGuess)
|
|
{
|
|
doublereal dd = deltaGuess;
|
|
bool conv = false;
|
|
doublereal deldd = dd;
|
|
doublereal pcheck = 1.0E-30 + 1.0E-8 * p_red;
|
|
for (int n = 0; n < 200; n++) {
|
|
/*
|
|
* Calculate the internal polynomials, and then calculate the
|
|
* phi deriv functions needed by this routine.
|
|
*/
|
|
tdpolycalc(tau, dd);
|
|
doublereal q1 = phiR_d();
|
|
doublereal q2 = phiR_dd();
|
|
|
|
/*
|
|
* Calculate the predicted reduced pressure, pred0, based on the
|
|
* current tau and dd.
|
|
*/
|
|
doublereal pred0 = dd + dd * dd * q1;
|
|
/*
|
|
* Calculate the derivative of the predicted reduced pressure
|
|
* wrt the reduced density, dd, This is dpddelta
|
|
*/
|
|
doublereal dpddelta = 1.0 + 2.0 * dd * q1 + dd * dd * q2;
|
|
/*
|
|
* If dpddelta is negative, then we are in the middle of the
|
|
* 2 phase region, beyond the stability curve. We need to adjust
|
|
* the initial guess outwards and start a new iteration.
|
|
*/
|
|
if (dpddelta <= 0.0) {
|
|
if (deltaGuess > 1.0) {
|
|
dd = dd * 1.05;
|
|
}
|
|
if (deltaGuess < 1.0) {
|
|
dd = dd * 0.95;
|
|
}
|
|
continue;
|
|
}
|
|
/*
|
|
* Check for convergence
|
|
*/
|
|
if (fabs(pred0-p_red) < pcheck) {
|
|
conv = true;
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* Dampen and crop the update
|
|
*/
|
|
doublereal dpdx = dpddelta;
|
|
if (n < 10) {
|
|
dpdx = dpddelta * 1.1;
|
|
}
|
|
dpdx = std::max(dpdx, 0.001);
|
|
|
|
/*
|
|
* Formulate the update to reduced density using
|
|
* Newton's method. Then, crop it to a max value
|
|
* of 0.02
|
|
*/
|
|
deldd = - (pred0 - p_red) / dpdx;
|
|
if (fabs(deldd) > 0.05) {
|
|
deldd = deldd * 0.05 / fabs(deldd);
|
|
}
|
|
/*
|
|
* updated the reduced density value
|
|
*/
|
|
dd = dd + deldd;
|
|
if (fabs(deldd/dd) < 1.0E-14) {
|
|
conv = true;
|
|
break;
|
|
}
|
|
/*
|
|
* Check for negative densities
|
|
*/
|
|
if (dd <= 0.0) {
|
|
dd = 1.0E-24;
|
|
}
|
|
}
|
|
/*
|
|
* Check for convergence, and return 0.0 if it wasn't achieved.
|
|
*/
|
|
if (! conv) {
|
|
dd = 0.0;
|
|
}
|
|
return dd;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::gibbs_RT() const
|
|
{
|
|
doublereal delta = DELTAsave;
|
|
doublereal rd = phiR_d();
|
|
return 1.0 + phi0() + phiR() + delta * rd;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::enthalpy_RT() const
|
|
{
|
|
doublereal delta = DELTAsave;
|
|
doublereal tau = TAUsave;
|
|
doublereal rd = phiR_d();
|
|
doublereal nt = phi0_t();
|
|
doublereal rt = phiR_t();
|
|
return 1.0 + tau * (nt + rt) + delta * rd;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::entropy_R() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal nt = phi0_t();
|
|
doublereal rt = phiR_t();
|
|
doublereal p0 = phi0();
|
|
doublereal pR = phiR();
|
|
return tau * (nt + rt) - p0 - pR;
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::intEnergy_RT() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal nt = phi0_t();
|
|
doublereal rt = phiR_t();
|
|
return tau * (nt + rt);
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::cv_R() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal ntt = phi0_tt();
|
|
doublereal rtt = phiR_tt();
|
|
return - tau * tau * (ntt + rtt);
|
|
}
|
|
|
|
doublereal WaterPropsIAPWSphi::cp_R() const
|
|
{
|
|
doublereal tau = TAUsave;
|
|
doublereal delta = DELTAsave;
|
|
doublereal cvR = cv_R();
|
|
doublereal rd = phiR_d();
|
|
doublereal rdd = phiR_dd();
|
|
doublereal rdt = phiR_dt();
|
|
doublereal num = (1.0 + delta * rd - delta * tau * rdt);
|
|
doublereal cpR = cvR + (num * num /
|
|
(1.0 + 2.0 * delta * rd + delta * delta * rdd));
|
|
return cpR;
|
|
}
|
|
|
|
} // namespace Cantera
|