/** * @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 #include 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; } if (dpdx < 0.001) { 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 nd = phi0_d(); 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