Cantera  2.1.2
WaterPropsIAPWSphi.cpp
Go to the documentation of this file.
1 /**
2  * @file WaterPropsIAPWSphi.cpp
3  * Definitions for Lowest level of the classes which support a real water
4  * model (see class \link Cantera::WaterPropsIAPWS WaterPropsIAPWS\endlink and
5  * class \link Cantera::WaterPropsIAPWSphi WaterPropsIAPWSphi \endlink).
6  */
7 /*
8  * Copyright (2006) Sandia Corporation. Under the terms of
9  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
10  * U.S. Government retains certain rights in this software.
11  */
13 
14 #include <cstdio>
15 #include <cmath>
16 
17 namespace Cantera
18 {
19 
20 using std::printf;
21 using std::sqrt;
22 using std::log;
23 using std::exp;
24 using std::pow;
25 using std::fabs;
26 
27 /*
28  * Critical Point values in mks units: Note, these aren't used in this
29  * routine, except for internal checks. All calculations here are done
30  * in dimensionless units.
31  */
32 // \cond
33 static const doublereal T_c = 647.096; // Kelvin
34 static const doublereal P_c = 22.064E6; // Pascals
35 static const doublereal Rho_c = 322.; // kg m-3
36 static const doublereal M_water = 18.015268; // kg kmol-1
37 // \endcond
38 
39 /*
40  * The added constants were calculated so that u = s = 0
41  * for liquid at the triple point. These where determined
42  * by the program testPress. I'm not quite satisfied with
43  * the result, but will let it stand for the moment.
44  * H didn't turn out to be .611872 J/kg, but .611782 J/kg.
45  * There may be a slight error here somehow.
46  */
47 // \cond
48 static const doublereal ni0[9] = {
49  0.0,
50  -8.32044648201 - 0.000000001739715,
51  6.6832105268 + 0.000000000793232,
52  3.00632,
53  0.012436,
54  0.97315,
55  1.27950,
56  0.96956,
57  0.24873
58 };
59 
60 static const doublereal gammi0[9] = {
61  0.0,
62  0.0,
63  0.0,
64  0.0,
65  1.28728967,
66  3.53734222,
67  7.74073708,
68  9.24437796,
69  27.5075105
70 };
71 
72 static const int ciR[56] = {
73  0, // 0
74  0, // 1
75  0,
76  0,
77  0,
78  0, // 5
79  0,
80  0,
81  1,
82  1,
83  1, // 10
84  1,
85  1,
86  1,
87  1,
88  1, // 15
89  1,
90  1,
91  1,
92  1,
93  1, // 20
94  1,
95  1,
96  2,
97  2,
98  2, // 25
99  2,
100  2,
101  2,
102  2,
103  2, // 30
104  2,
105  2,
106  2,
107  2,
108  2, // 35
109  2,
110  2,
111  2,
112  2,
113  2, // 40
114  2,
115  2,
116  3,
117  3,
118  3, // 45
119  3,
120  4,
121  6,
122  6,
123  6, // 50
124  6,
125  0,
126  0,
127  0,
128  0 // 55
129 };
130 
131 static const int diR[55] = {
132  0, // 0
133  1, // 1
134  1,
135  1,
136  2,
137  2, // 5
138  3,
139  4,
140  1,
141  1,
142  1, // 10
143  2,
144  2,
145  3,
146  4,
147  4, // 15
148  5,
149  7,
150  9,
151  10,
152  11, // 20
153  13,
154  15,
155  1,
156  2,
157  2, // 25
158  2,
159  3,
160  4,
161  4,
162  4, // 30
163  5,
164  6,
165  6,
166  7,
167  9, // 35
168  9,
169  9,
170  9,
171  9,
172  10, // 40
173  10,
174  12,
175  3,
176  4,
177  4, // 45
178  5,
179  14,
180  3,
181  6,
182  6, // 50
183  6,
184  3,
185  3,
186  3 // 54
187 };
188 
189 static const int tiR[55] = {
190  0, // 0
191  0, // 1
192  0,
193  0,
194  0,
195  0, // 5
196  0,
197  0,
198  4, // 8
199  6,
200  12, // 10
201  1,
202  5,
203  4,
204  2,
205  13, // 15
206  9,
207  3,
208  4,
209  11,
210  4, // 20
211  13,
212  1,
213  7,
214  1,
215  9, // 25
216  10,
217  10,
218  3,
219  7,
220  10, // 30
221  10,
222  6,
223  10,
224  10,
225  1, // 35
226  2,
227  3,
228  4,
229  8,
230  6, // 40
231  9,
232  8,
233  16,
234  22,
235  23, // 45
236  23,
237  10,
238  50,
239  44,
240  46, // 50
241  50,
242  0,
243  1,
244  4 // 54
245 };
246 
247 static const doublereal ni[57] = {
248  +0.0,
249  +0.12533547935523E-1, // 1
250  +0.78957634722828E1, // 2
251  -0.87803203303561E1, // 3
252  +0.31802509345418E0, // 4
253  -0.26145533859358E0, // 5
254  -0.78199751687981E-2, // 6
255  +0.88089493102134E-2, // 7
256  -0.66856572307965E0, // 8
257  +0.20433810950965, // 9
258  -0.66212605039687E-4, // 10
259  -0.19232721156002E0, // 11
260  -0.25709043003438E0, // 12
261  +0.16074868486251E0, // 13
262  -0.40092828925807E-1, // 14
263  +0.39343422603254E-6, // 15
264  -0.75941377088144E-5, // 16
265  +0.56250979351888E-3, // 17
266  -0.15608652257135E-4, // 18
267  +0.11537996422951E-8, // 19
268  +0.36582165144204E-6, // 20
269  -0.13251180074668E-11,// 21
270  -0.62639586912454E-9, // 22
271  -0.10793600908932E0, // 23
272  +0.17611491008752E-1, // 24
273  +0.22132295167546E0, // 25
274  -0.40247669763528E0, // 26
275  +0.58083399985759E0, // 27
276  +0.49969146990806E-2, // 28
277  -0.31358700712549E-1, // 29
278  -0.74315929710341E0, // 30
279  +0.47807329915480E0, // 31
280  +0.20527940895948E-1, // 32
281  -0.13636435110343E0, // 33
282  +0.14180634400617E-1, // 34
283  +0.83326504880713E-2, // 35
284  -0.29052336009585E-1, // 36
285  +0.38615085574206E-1, // 37
286  -0.20393486513704E-1, // 38
287  -0.16554050063734E-2, // 39
288  +0.19955571979541E-2, // 40
289  +0.15870308324157E-3, // 41
290  -0.16388568342530E-4, // 42
291  +0.43613615723811E-1, // 43
292  +0.34994005463765E-1, // 44
293  -0.76788197844621E-1, // 45
294  +0.22446277332006E-1, // 46
295  -0.62689710414685E-4, // 47
296  -0.55711118565645E-9, // 48
297  -0.19905718354408E0, // 49
298  +0.31777497330738E0, // 50
299  -0.11841182425981E0, // 51
300  -0.31306260323435E2, // 52
301  +0.31546140237781E2, // 53
302  -0.25213154341695E4, // 54
303  -0.14874640856724E0, // 55
304  +0.31806110878444E0 // 56
305 };
306 
307 static const doublereal alphai[3] = {
308  +20.,
309  +20.,
310  +20.
311 };
312 
313 static const doublereal betai[3] = {
314  +150.,
315  +150.,
316  +250.
317 };
318 
319 static const doublereal gammai[3] = {
320  +1.21,
321  +1.21,
322  +1.25
323 };
324 
325 static const doublereal epsi[3] = {
326  +1.0,
327  +1.0,
328  +1.0
329 };
330 
331 static const doublereal ai[2] = {
332  +3.5,
333  +3.5
334 };
335 
336 static const doublereal bi[2] = {
337  +0.85,
338  +0.95
339 };
340 
341 static const doublereal Bi[2] = {
342  +0.2,
343  +0.2
344 };
345 
346 static const doublereal Ci[2] = {
347  +28.0,
348  +32.0
349 };
350 
351 static const doublereal Di[2] = {
352  +700.,
353  +800.
354 };
355 
356 static const doublereal Ai[2] = {
357  +0.32,
358  +0.32
359 };
360 
361 static const doublereal Bbetai[2] = {
362  +0.3,
363  +0.3
364 };
365 // \endcond
366 
368  TAUsave(-1.0),
369  TAUsqrt(-1.0),
370  DELTAsave(-1.0)
371 {
372  for (int i = 0; i < 52; i++) {
373  TAUp[i] = 1.0;
374  }
375  for (int i = 0; i < 16; i++) {
376  DELTAp[i] = 1.0;
377  }
378 }
379 
380 void WaterPropsIAPWSphi::intCheck(doublereal tau, doublereal delta)
381 {
382  tdpolycalc(tau, delta);
383  doublereal nau = phi0();
384  doublereal res = phiR();
385  doublereal res_d = phiR_d();
386  doublereal nau_d = phi0_d();
387  doublereal res_dd = phiR_dd();
388  doublereal nau_dd = phi0_dd();
389  doublereal res_t = phiR_t();
390  doublereal nau_t = phi0_t();
391  doublereal res_tt = phiR_tt();
392  doublereal nau_tt = phi0_tt();
393  doublereal res_dt = phiR_dt();
394  doublereal nau_dt = phi0_dt();
395 
396  std::printf("nau = %20.12e\t\tres = %20.12e\n", nau, res);
397  std::printf("nau_d = %20.12e\t\tres_d = %20.12e\n", nau_d, res_d);
398  printf("nau_dd = %20.12e\t\tres_dd = %20.12e\n", nau_dd, res_dd);
399  printf("nau_t = %20.12e\t\tres_t = %20.12e\n", nau_t, res_t);
400  printf("nau_tt = %20.12e\t\tres_tt = %20.12e\n", nau_tt, res_tt);
401  printf("nau_dt = %20.12e\t\tres_dt = %20.12e\n", nau_dt, res_dt);
402 }
403 
405 {
406  doublereal T = 500.;
407  doublereal rho = 838.025;
408  doublereal tau = T_c/T;
409  doublereal delta = rho / Rho_c;
410  printf(" T = 500 K, rho = 838.025 kg m-3\n");
411  intCheck(tau, delta);
412 }
413 
415 {
416  doublereal T = 647;
417  doublereal rho = 358.0;
418  doublereal tau = T_c/T;
419  doublereal delta = rho / Rho_c;
420  printf(" T = 647 K, rho = 358.0 kg m-3\n");
421  intCheck(tau, delta);
422 }
423 
424 void WaterPropsIAPWSphi::tdpolycalc(doublereal tau, doublereal delta)
425 {
426  if ((tau != TAUsave) || 1) {
427  TAUsave = tau;
428  TAUsqrt = sqrt(tau);
429  TAUp[0] = 1.0;
430  for (int i = 1; i < 51; i++) {
431  TAUp[i] = TAUp[i-1] * tau;
432  }
433  }
434  if ((delta != DELTAsave) || 1) {
435  DELTAsave = delta;
436  DELTAp[0] = 1.0;
437  for (int i = 1; i <= 15; i++) {
438  DELTAp[i] = DELTAp[i-1] * delta;
439  }
440  }
441 }
442 
443 doublereal WaterPropsIAPWSphi::phi0() const
444 {
445  doublereal tau = TAUsave;
446  doublereal delta = DELTAsave;
447  doublereal retn = log(delta) + ni0[1] + ni0[2]*tau + ni0[3]*log(tau);
448 
449  retn += ni0[4] * log(1.0 - exp(-gammi0[4]*tau));
450  retn += ni0[5] * log(1.0 - exp(-gammi0[5]*tau));
451  retn += ni0[6] * log(1.0 - exp(-gammi0[6]*tau));
452  retn += ni0[7] * log(1.0 - exp(-gammi0[7]*tau));
453  retn += ni0[8] * log(1.0 - exp(-gammi0[8]*tau));
454  return retn;
455 }
456 
457 doublereal WaterPropsIAPWSphi::phiR() const
458 {
459  doublereal tau = TAUsave;
460  doublereal delta = DELTAsave;
461  int i, j;
462 
463  /*
464  * Write out the first seven polynomials in the expression
465  */
466  doublereal T375 = pow(tau, 0.375);
467  doublereal val = (ni[1] * delta / TAUsqrt +
468  ni[2] * delta * TAUsqrt * T375 +
469  ni[3] * delta * tau +
470  ni[4] * DELTAp[2] * TAUsqrt +
471  ni[5] * DELTAp[2] * T375 * T375 +
472  ni[6] * DELTAp[3] * T375 +
473  ni[7] * DELTAp[4] * tau);
474  /*
475  * Next, do polynomial contributions 8 to 51
476  */
477  for (i = 8; i <= 51; i++) {
478  val += (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] * exp(-DELTAp[ciR[i]]));
479  }
480 
481  /*
482  * Next do contributions 52 to 54
483  */
484  for (j = 0; j < 3; j++) {
485  i = 52 + j;
486  doublereal dtmp = delta - epsi[j];
487  doublereal ttmp = tau - gammai[j];
488  val += (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
489  exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
490  }
491 
492  /*
493  * Next do contributions 55 and 56
494  */
495  for (j = 0; j < 2; j++) {
496  i = 55 + j;
497  doublereal deltam1 = delta - 1.0;
498  doublereal dtmp2 = deltam1 * deltam1;
499  doublereal atmp = 0.5 / Bbetai[j];
500  doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
501  doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
502  doublereal ttmp = tau - 1.0;
503 
504  doublereal triagtmp = pow(triag, bi[j]);
505 
506  doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
507  val += (ni[i] * triagtmp * delta * phi);
508  }
509 
510  return val;
511 }
512 
513 doublereal WaterPropsIAPWSphi::phi(doublereal tau, doublereal delta)
514 {
515  tdpolycalc(tau, delta);
516  doublereal nau = phi0();
517  doublereal res = phiR();
518  return nau + res;
519 }
520 
521 doublereal WaterPropsIAPWSphi::phiR_d() const
522 {
523  doublereal tau = TAUsave;
524  doublereal delta = DELTAsave;
525  int i, j;
526 
527  /*
528  * Write out the first seven polynomials in the expression
529  */
530  doublereal T375 = pow(tau, 0.375);
531  doublereal val = (ni[1] / TAUsqrt +
532  ni[2] * TAUsqrt * T375 +
533  ni[3] * tau +
534  ni[4] * 2.0 * delta * TAUsqrt +
535  ni[5] * 2.0 * delta * T375 * T375 +
536  ni[6] * 3.0 * DELTAp[2] * T375 +
537  ni[7] * 4.0 * DELTAp[3] * tau);
538  /*
539  * Next, do polynomial contributions 8 to 51
540  */
541  for (i = 8; i <= 51; i++) {
542  val += ((ni[i] * exp(-DELTAp[ciR[i]]) * DELTAp[diR[i] - 1] *
543  TAUp[tiR[i]]) * (diR[i] - ciR[i]* DELTAp[ciR[i]]));
544  }
545 
546  /*
547  * Next do contributions 52 to 54
548  */
549  for (j = 0; j < 3; j++) {
550  i = 52 + j;
551  doublereal dtmp = delta - epsi[j];
552  doublereal ttmp = tau - gammai[j];
553  doublereal tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
554  exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
555  val += tmp * (diR[i]/delta - 2.0 * alphai[j] * dtmp);
556  }
557 
558  /*
559  * Next do contributions 55 and 56
560  */
561  for (j = 0; j < 2; j++) {
562  i = 55 + j;
563  doublereal deltam1 = delta - 1.0;
564  doublereal dtmp2 = deltam1 * deltam1;
565  doublereal atmp = 0.5 / Bbetai[j];
566  doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
567  doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
568  doublereal ttmp = tau - 1.0;
569 
570  doublereal triagtmp = pow(triag, bi[j]);
571  doublereal triagtmpm1 = pow(triag, bi[j]-1.0);
572  doublereal atmpM1 = atmp - 1.0;
573  doublereal ptmp = pow(dtmp2,atmpM1);
574  doublereal p2tmp = pow(dtmp2, ai[j]-1.0);
575  doublereal dtriagddelta =
576  deltam1 *(Ai[j] * theta * 2.0 / Bbetai[j] * ptmp +
577  2.0*Bi[j]*ai[j]*p2tmp);
578 
579  doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
580  doublereal dphiddelta = -2.0*Ci[j]*deltam1*phi;
581  doublereal dtriagtmpddelta = bi[j] * triagtmpm1 * dtriagddelta;
582 
583  doublereal tmp = ni[i] * (triagtmp * (phi + delta*dphiddelta) +
584  dtriagtmpddelta * delta * phi);
585  val += tmp;
586  }
587 
588  return val;
589 }
590 
591 doublereal WaterPropsIAPWSphi::phi0_d() const
592 {
593  doublereal delta = DELTAsave;
594  return 1.0/delta;
595 }
596 
597 doublereal WaterPropsIAPWSphi::phi_d(doublereal tau, doublereal delta)
598 {
599  tdpolycalc(tau, delta);
600  doublereal nau = phi0_d();
601  doublereal res = phiR_d();
602  return nau + res;
603 }
604 
605 doublereal WaterPropsIAPWSphi::pressureM_rhoRT(doublereal tau, doublereal delta)
606 {
607  tdpolycalc(tau, delta);
608  doublereal res = phiR_d();
609  return 1.0 + delta * res;
610 }
611 
612 doublereal WaterPropsIAPWSphi::phiR_dd() const
613 {
614  doublereal tau = TAUsave;
615  doublereal delta = DELTAsave;
616  int i, j;
617  doublereal atmp;
618 
619  /*
620  * Write out the first seven polynomials in the expression
621  */
622  doublereal T375 = pow(tau, 0.375);
623  doublereal val = (ni[4] * 2.0 * TAUsqrt +
624  ni[5] * 2.0 * T375 * T375 +
625  ni[6] * 6.0 * delta * T375 +
626  ni[7] * 12.0 * DELTAp[2] * tau);
627  /*
628  * Next, do polynomial contributions 8 to 51
629  */
630  for (i = 8; i <= 51; i++) {
631  doublereal dtmp = DELTAp[ciR[i]];
632  doublereal tmp = ni[i] * exp(-dtmp) * TAUp[tiR[i]];
633  if (diR[i] == 1) {
634  atmp = 1.0/delta;
635  } else {
636  atmp = DELTAp[diR[i] - 2];
637  }
638  tmp *= atmp *((diR[i] - ciR[i]*dtmp)*(diR[i]-1.0-ciR[i]*dtmp) -
639  ciR[i]*ciR[i]*dtmp);
640  val += tmp;
641  }
642 
643  /*
644  * Next do contributions 52 to 54
645  */
646  for (j = 0; j < 3; j++) {
647  i = 52 + j;
648  doublereal dtmp = delta - epsi[j];
649  doublereal ttmp = tau - gammai[j];
650  doublereal tmp = (ni[i] * TAUp[tiR[i]] *
651  exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
652  doublereal deltmp = DELTAp[diR[i]];
653  doublereal deltmpM1 = deltmp/delta;
654  doublereal deltmpM2 = deltmpM1 / delta;
655  doublereal d2tmp = dtmp * dtmp;
656 
657  val += tmp * (-2.0*alphai[j]*deltmp +
658  4.0 * alphai[j] * alphai[j] * deltmp * d2tmp -
659  4.0 * diR[i] * alphai[j] * deltmpM1 * dtmp +
660  diR[i] * (diR[i] - 1.0) * deltmpM2);
661  }
662 
663  /*
664  * Next do contributions 55 and 56
665  */
666  for (j = 0; j < 2; j++) {
667  i = 55 + j;
668  doublereal deltam1 = delta - 1.0;
669  doublereal dtmp2 = deltam1 * deltam1;
670  atmp = 0.5 / Bbetai[j];
671  doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
672  doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
673  doublereal ttmp = tau - 1.0;
674 
675  doublereal triagtmp = pow(triag, bi[j]);
676  doublereal triagtmpm1 = pow(triag, bi[j]-1.0);
677  doublereal atmpM1 = atmp - 1.0;
678  doublereal ptmp = pow(dtmp2,atmpM1);
679  doublereal p2tmp = pow(dtmp2, ai[j]-1.0);
680  doublereal dtriagddelta =
681  deltam1 *(Ai[j] * theta * 2.0 / Bbetai[j] * ptmp +
682  2.0*Bi[j]*ai[j]*p2tmp);
683 
684  doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
685  doublereal dphiddelta = -2.0*Ci[j]*deltam1*phi;
686  doublereal dtriagtmpddelta = bi[j] * triagtmpm1 * dtriagddelta;
687 
688 
689  doublereal d2phiddelta2 = 2.0 * Ci[j] * phi * (2.0*Ci[j]*dtmp2 - 1.0);
690 
691  doublereal pptmp = ptmp / dtmp2;
692  doublereal d2triagddelta2 = dtriagddelta / deltam1;
693  d2triagddelta2 +=
694  dtmp2 *(4.0*Bi[j]*ai[j]*(ai[j]-1.0)*pow(dtmp2,ai[j]-2.0) +
695  2.0*Ai[j]*Ai[j]/(Bbetai[j]*Bbetai[j])*ptmp*ptmp +
696  Ai[j]*theta*4.0/Bbetai[j]*(atmp-1.0)*pptmp);
697 
698  doublereal d2triagtmpd2delta =
699  bi[j] * (triagtmpm1 * d2triagddelta2 +
700  (bi[j]-1.0)*triagtmpm1/triag*dtriagddelta*dtriagddelta);
701 
702  doublereal ctmp = (triagtmp * (2.0*dphiddelta + delta*d2phiddelta2) +
703  2.0*dtriagtmpddelta*(phi + delta * dphiddelta) +
704  d2triagtmpd2delta * delta * phi);
705 
706  val += ni[i] * ctmp;
707  }
708 
709  return val;
710 }
711 
712 doublereal WaterPropsIAPWSphi::phi0_dd() const
713 {
714  doublereal delta = DELTAsave;
715  return -1.0/(delta*delta);
716 }
717 
718 doublereal WaterPropsIAPWSphi::phi_dd(doublereal tau, doublereal delta)
719 {
720  tdpolycalc(tau, delta);
721  doublereal nau = phi0_dd();
722  doublereal res = phiR_dd();
723  return nau + res;
724 }
725 
726 doublereal WaterPropsIAPWSphi::dimdpdrho(doublereal tau, doublereal delta)
727 {
728  tdpolycalc(tau, delta);
729  doublereal res1 = phiR_d();
730  doublereal res2 = phiR_dd();
731  return 1.0 + delta * (2.0*res1 + delta*res2);
732 }
733 
734 doublereal WaterPropsIAPWSphi::dimdpdT(doublereal tau, doublereal delta)
735 {
736  tdpolycalc(tau, delta);
737  doublereal res1 = phiR_d();
738  doublereal res2 = phiR_dt();
739  return (1.0 + delta * res1) - tau * delta * (res2);
740 }
741 
742 doublereal WaterPropsIAPWSphi::phi0_t() const
743 {
744  doublereal tau = TAUsave;
745  doublereal retn = ni0[2] + ni0[3]/tau;
746  retn += (ni0[4] * gammi0[4] * (1.0/(1.0 - exp(-gammi0[4]*tau)) - 1.0));
747  retn += (ni0[5] * gammi0[5] * (1.0/(1.0 - exp(-gammi0[5]*tau)) - 1.0));
748  retn += (ni0[6] * gammi0[6] * (1.0/(1.0 - exp(-gammi0[6]*tau)) - 1.0));
749  retn += (ni0[7] * gammi0[7] * (1.0/(1.0 - exp(-gammi0[7]*tau)) - 1.0));
750  retn += (ni0[8] * gammi0[8] * (1.0/(1.0 - exp(-gammi0[8]*tau)) - 1.0));
751  return retn;
752 }
753 
754 doublereal WaterPropsIAPWSphi::phiR_t() const
755 {
756  doublereal tau = TAUsave;
757  doublereal delta = DELTAsave;
758  int i, j;
759  doublereal atmp, tmp;
760 
761  /*
762  * Write out the first seven polynomials in the expression
763  */
764  doublereal T375 = pow(tau, 0.375);
765  doublereal val = ((-0.5) *ni[1] * delta / TAUsqrt / tau +
766  ni[2] * delta * 0.875 / TAUsqrt * T375 +
767  ni[3] * delta +
768  ni[4] * DELTAp[2] * 0.5 / TAUsqrt +
769  ni[5] * DELTAp[2] * 0.75 * T375 * T375 / tau +
770  ni[6] * DELTAp[3] * 0.375 * T375 / tau +
771  ni[7] * DELTAp[4]);
772  /*
773  * Next, do polynomial contributions 8 to 51
774  */
775  for (i = 8; i <= 51; i++) {
776  tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]-1] * exp(-DELTAp[ciR[i]]));
777  val += tiR[i] * tmp;
778  }
779 
780  /*
781  * Next do contributions 52 to 54
782  */
783  for (j = 0; j < 3; j++) {
784  i = 52 + j;
785  doublereal dtmp = delta - epsi[j];
786  doublereal ttmp = tau - gammai[j];
787  tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
788  exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
789  val += tmp *(tiR[i]/tau - 2.0 * betai[j]*ttmp);
790  }
791 
792  /*
793  * Next do contributions 55 and 56
794  */
795  for (j = 0; j < 2; j++) {
796  i = 55 + j;
797  doublereal deltam1 = delta - 1.0;
798  doublereal dtmp2 = deltam1 * deltam1;
799  atmp = 0.5 / Bbetai[j];
800  doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
801  doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
802  doublereal ttmp = tau - 1.0;
803 
804  doublereal triagtmp = pow(triag, bi[j]);
805 
806  doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
807 
808 
809  doublereal dtriagtmpdtau = -2.0*theta * bi[j] * triagtmp / triag;
810 
811  doublereal dphidtau = - 2.0 * Di[j] * ttmp * phi;
812 
813  val += ni[i] * delta * (dtriagtmpdtau * phi + triagtmp * dphidtau);
814  }
815 
816  return val;
817 }
818 
819 doublereal WaterPropsIAPWSphi::phi_t(doublereal tau, doublereal delta)
820 {
821  tdpolycalc(tau, delta);
822  doublereal nau = phi0_t();
823  doublereal res = phiR_t();
824  return nau + res;
825 }
826 
827 doublereal WaterPropsIAPWSphi::phi0_tt() const
828 {
829  doublereal tau = TAUsave;
830  doublereal tmp, itmp;
831  doublereal retn = - ni0[3]/(tau * tau);
832  for (int i = 4; i <= 8; i++) {
833  tmp = exp(-gammi0[i]*tau);
834  itmp = 1.0 - tmp;
835  retn -= (ni0[i] * gammi0[i] * gammi0[i] * tmp / (itmp * itmp));
836  }
837  return retn;
838 }
839 
840 doublereal WaterPropsIAPWSphi::phiR_tt() const
841 {
842  doublereal tau = TAUsave;
843  doublereal delta = DELTAsave;
844  int i, j;
845  doublereal atmp, tmp;
846 
847  /*
848  * Write out the first seven polynomials in the expression
849  */
850  doublereal T375 = pow(tau, 0.375);
851  doublereal val = ((-0.5) * (-1.5) * ni[1] * delta / (TAUsqrt * tau * tau) +
852  ni[2] * delta * 0.875 * (-0.125) * T375 / (TAUsqrt * tau) +
853  ni[4] * DELTAp[2] * 0.5 * (-0.5)/ (TAUsqrt * tau) +
854  ni[5] * DELTAp[2] * 0.75 *(-0.25) * T375 * T375 / (tau * tau) +
855  ni[6] * DELTAp[3] * 0.375 *(-0.625) * T375 / (tau * tau));
856  /*
857  * Next, do polynomial contributions 8 to 51
858  */
859  for (i = 8; i <= 51; i++) {
860  if (tiR[i] > 1) {
861  tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]-2] * exp(-DELTAp[ciR[i]]));
862  val += tiR[i] * (tiR[i] - 1.0) * tmp;
863  }
864  }
865 
866  /*
867  * Next do contributions 52 to 54
868  */
869  for (j = 0; j < 3; j++) {
870  i = 52 + j;
871  doublereal dtmp = delta - epsi[j];
872  doublereal ttmp = tau - gammai[j];
873  tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
874  exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
875  atmp = tiR[i]/tau - 2.0 * betai[j]*ttmp;
876  val += tmp *(atmp * atmp - tiR[i]/(tau*tau) - 2.0*betai[j]);
877  }
878 
879  /*
880  * Next do contributions 55 and 56
881  */
882  for (j = 0; j < 2; j++) {
883  i = 55 + j;
884  doublereal deltam1 = delta - 1.0;
885  doublereal dtmp2 = deltam1 * deltam1;
886  atmp = 0.5 / Bbetai[j];
887  doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
888  doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
889  doublereal ttmp = tau - 1.0;
890 
891  doublereal triagtmp = pow(triag, bi[j]);
892  doublereal triagtmpM1 = triagtmp / triag;
893 
894  doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
895 
896 
897  doublereal dtriagtmpdtau = -2.0*theta * bi[j] * triagtmp / triag;
898 
899  doublereal dphidtau = - 2.0 * Di[j] * ttmp * phi;
900 
901  doublereal d2triagtmpdtau2 =
902  (2 * bi[j] * triagtmpM1 +
903  4 * theta * theta * bi[j] * (bi[j]-1.0) * triagtmpM1 / triag);
904 
905  doublereal d2phidtau2 = 2.0*Di[j]*phi *(2.0*Di[j]*ttmp*ttmp - 1.0);
906 
907  tmp = (d2triagtmpdtau2 * phi +
908  2 * dtriagtmpdtau * dphidtau +
909  triagtmp * d2phidtau2);
910  val += ni[i] * delta * tmp;
911  }
912 
913  return val;
914 }
915 
916 doublereal WaterPropsIAPWSphi::phi_tt(doublereal tau, doublereal delta)
917 {
918  tdpolycalc(tau, delta);
919  doublereal nau = phi0_tt();
920  doublereal res = phiR_tt();
921  return nau + res;
922 }
923 
924 doublereal WaterPropsIAPWSphi::phi0_dt() const
925 {
926  return 0.0;
927 }
928 
929 doublereal WaterPropsIAPWSphi::phiR_dt() const
930 {
931  doublereal tau = TAUsave;
932  doublereal delta = DELTAsave;
933  int i, j;
934  doublereal tmp;
935  /*
936  * Write out the first seven polynomials in the expression
937  */
938  doublereal T375 = pow(tau, 0.375);
939  doublereal val = (ni[1] * (-0.5) / (TAUsqrt * tau) +
940  ni[2] * (0.875) * T375 / TAUsqrt +
941  ni[3] +
942  ni[4] * 2.0 * delta * (0.5) / TAUsqrt +
943  ni[5] * 2.0 * delta * (0.75) * T375 * T375 / tau +
944  ni[6] * 3.0 * DELTAp[2] * 0.375 * T375 / tau +
945  ni[7] * 4.0 * DELTAp[3]);
946  /*
947  * Next, do polynomial contributions 8 to 51
948  */
949  for (i = 8; i <= 51; i++) {
950  tmp = (ni[i] * tiR[i] * exp(-DELTAp[ciR[i]]) * DELTAp[diR[i] - 1] *
951  TAUp[tiR[i] - 1]);
952  val += tmp * (diR[i] - ciR[i] * DELTAp[ciR[i]]);
953  }
954 
955  /*
956  * Next do contributions 52 to 54
957  */
958  for (j = 0; j < 3; j++) {
959  i = 52 + j;
960  doublereal dtmp = delta - epsi[j];
961  doublereal ttmp = tau - gammai[j];
962  tmp = (ni[i] * DELTAp[diR[i]] * TAUp[tiR[i]] *
963  exp(-alphai[j]*dtmp*dtmp - betai[j]*ttmp*ttmp));
964  val += tmp * ((diR[i]/delta - 2.0 * alphai[j] * dtmp) *
965  (tiR[i]/tau - 2.0 * betai[j] * ttmp));
966  }
967 
968  /*
969  * Next do contributions 55 and 56
970  */
971  for (j = 0; j < 2; j++) {
972  i = 55 + j;
973  doublereal deltam1 = delta - 1.0;
974  doublereal dtmp2 = deltam1 * deltam1;
975  doublereal atmp = 0.5 / Bbetai[j];
976  doublereal theta = (1.0 - tau) + Ai[j] * pow(dtmp2, atmp);
977  doublereal triag = theta * theta + Bi[j] * pow(dtmp2, ai[j]);
978  doublereal ttmp = tau - 1.0;
979 
980  doublereal triagtmp = pow(triag, bi[j]);
981  doublereal triagtmpm1 = pow(triag, bi[j]-1.0);
982  doublereal atmpM1 = atmp - 1.0;
983  doublereal ptmp = pow(dtmp2,atmpM1);
984  doublereal p2tmp = pow(dtmp2, ai[j]-1.0);
985  doublereal dtriagddelta =
986  deltam1 *(Ai[j] * theta * 2.0 / Bbetai[j] * ptmp +
987  2.0*Bi[j]*ai[j]*p2tmp);
988 
989  doublereal phi = exp(-Ci[j]*dtmp2 - Di[j]*ttmp*ttmp);
990  doublereal dphiddelta = -2.0*Ci[j]*deltam1*phi;
991  doublereal dtriagtmpddelta = bi[j] * triagtmpm1 * dtriagddelta;
992 
993 
994  doublereal dtriagtmpdtau = -2.0*theta * bi[j] * triagtmp / triag;
995 
996  doublereal dphidtau = - 2.0 * Di[j] * ttmp * phi;
997 
998  doublereal d2phiddeltadtau = 4.0 * Ci[j] * Di[j] * deltam1 * ttmp * phi;
999 
1000  doublereal d2triagtmpddeltadtau =
1001  (-Ai[j] * bi[j] * 2.0 / Bbetai[j] * triagtmpm1 * deltam1 * ptmp
1002  -2.0 * theta * bi[j] * (bi[j] - 1.0) * triagtmpm1 / triag * dtriagddelta);
1003 
1004 
1005  doublereal tmp = ni[i] * (triagtmp * (dphidtau + delta*d2phiddeltadtau) +
1006  delta * dtriagtmpddelta * dphidtau +
1007  dtriagtmpdtau * (phi + delta * dphiddelta) +
1008  d2triagtmpddeltadtau * delta * phi);
1009  val += tmp;
1010  }
1011 
1012  return val;
1013 }
1014 
1015 doublereal WaterPropsIAPWSphi::dfind(doublereal p_red, doublereal tau, doublereal deltaGuess)
1016 {
1017  doublereal dd = deltaGuess;
1018  bool conv = false;
1019  doublereal deldd = dd;
1020  doublereal pcheck = 1.0E-30 + 1.0E-8 * p_red;
1021  for (int n = 0; n < 200; n++) {
1022  /*
1023  * Calculate the internal polynomials, and then calculate the
1024  * phi deriv functions needed by this routine.
1025  */
1026  tdpolycalc(tau, dd);
1027  doublereal q1 = phiR_d();
1028  doublereal q2 = phiR_dd();
1029 
1030  /*
1031  * Calculate the predicted reduced pressure, pred0, based on the
1032  * current tau and dd.
1033  */
1034  doublereal pred0 = dd + dd * dd * q1;
1035  /*
1036  * Calculate the derivative of the predicted reduced pressure
1037  * wrt the reduced density, dd, This is dpddelta
1038  */
1039  doublereal dpddelta = 1.0 + 2.0 * dd * q1 + dd * dd * q2;
1040  /*
1041  * If dpddelta is negative, then we are in the middle of the
1042  * 2 phase region, beyond the stability curve. We need to adjust
1043  * the initial guess outwards and start a new iteration.
1044  */
1045  if (dpddelta <= 0.0) {
1046  if (deltaGuess > 1.0) {
1047  dd = dd * 1.05;
1048  }
1049  if (deltaGuess < 1.0) {
1050  dd = dd * 0.95;
1051  }
1052  continue;
1053  }
1054  /*
1055  * Check for convergence
1056  */
1057  if (fabs(pred0-p_red) < pcheck) {
1058  conv = true;
1059  break;
1060  }
1061 
1062  /*
1063  * Dampen and crop the update
1064  */
1065  doublereal dpdx = dpddelta;
1066  if (n < 10) {
1067  dpdx = dpddelta * 1.1;
1068  }
1069  if (dpdx < 0.001) {
1070  dpdx = 0.001;
1071  }
1072 
1073  /*
1074  * Formulate the update to reduced density using
1075  * Newton's method. Then, crop it to a max value
1076  * of 0.02
1077  */
1078  deldd = - (pred0 - p_red) / dpdx;
1079  if (fabs(deldd) > 0.05) {
1080  deldd = deldd * 0.05 / fabs(deldd);
1081  }
1082  /*
1083  * updated the reduced density value
1084  */
1085  dd = dd + deldd;
1086  if (fabs(deldd/dd) < 1.0E-14) {
1087  conv = true;
1088  break;
1089  }
1090  /*
1091  * Check for negative densities
1092  */
1093  if (dd <= 0.0) {
1094  dd = 1.0E-24;
1095  }
1096  }
1097  /*
1098  * Check for convergence, and return 0.0 if it wasn't achieved.
1099  */
1100  if (! conv) {
1101  dd = 0.0;
1102  }
1103  return dd;
1104 }
1105 
1107 {
1108  doublereal delta = DELTAsave;
1109  doublereal rd = phiR_d();
1110  return 1.0 + phi0() + phiR() + delta * rd;
1111 }
1112 
1114 {
1115  doublereal delta = DELTAsave;
1116  doublereal tau = TAUsave;
1117  doublereal rd = phiR_d();
1118  doublereal nt = phi0_t();
1119  doublereal rt = phiR_t();
1120  return 1.0 + tau * (nt + rt) + delta * rd;
1121 }
1122 
1124 {
1125  doublereal tau = TAUsave;
1126  doublereal nt = phi0_t();
1127  doublereal rt = phiR_t();
1128  doublereal p0 = phi0();
1129  doublereal pR = phiR();
1130  return tau * (nt + rt) - p0 - pR;
1131 }
1132 
1134 {
1135  doublereal tau = TAUsave;
1136  doublereal nt = phi0_t();
1137  doublereal rt = phiR_t();
1138  return tau * (nt + rt);
1139 }
1140 
1141 doublereal WaterPropsIAPWSphi::cv_R() const
1142 {
1143  doublereal tau = TAUsave;
1144  doublereal ntt = phi0_tt();
1145  doublereal rtt = phiR_tt();
1146  return - tau * tau * (ntt + rtt);
1147 }
1148 
1149 doublereal WaterPropsIAPWSphi::cp_R() const
1150 {
1151  doublereal tau = TAUsave;
1152  doublereal delta = DELTAsave;
1153  doublereal cvR = cv_R();
1154  //doublereal nd = phi0_d();
1155  doublereal rd = phiR_d();
1156  doublereal rdd = phiR_dd();
1157  doublereal rdt = phiR_dt();
1158  doublereal num = (1.0 + delta * rd - delta * tau * rdt);
1159  doublereal cpR = cvR + (num * num /
1160  (1.0 + 2.0 * delta * rd + delta * delta * rdd));
1161  return cpR;
1162 }
1163 
1164 } // namespace Cantera
doublereal phi0_dd() const
Calculate d2_phi0_dd(delta), the second derivative of phi0 wrt delta.
doublereal phiR_dt() const
Calculate the mixed derivative d2_phiR/(dtau ddelta)
doublereal phi0_d() const
Calculate d_phi0_d(delta), the first derivative of phi0 wrt delta.
Header for Lowest level of the classes which support a real water model (see class WaterPropsIAPWS an...
doublereal phi_dd(doublereal tau, doublereal delta)
2nd derivative of phi wrt delta
doublereal gibbs_RT() const
Calculate the dimensionless gibbs free energy.
doublereal phi0_dt() const
Calculate the mixed derivative d2_phi0/(dtau ddelta)
doublereal entropy_R() const
Calculate the dimensionless entropy, s/R.
void check1()
Internal check # 1.
void intCheck(doublereal tau, doublereal delta)
Calculates all of the functions at a one point and prints out the result.
const doublereal Rho_c
Value of the Density at the critical point (kg m-3)
static const doublereal P_c
Critical Pressure (Pascals)
doublereal dfind(doublereal p_red, doublereal tau, doublereal deltaGuess)
This function computes the reduced density, given the reduced pressure and the reduced temperature...
doublereal TAUsave
Last tau that was used to calculate polynomials.
doublereal DELTAp[16]
Value of internally calculated polynomials of powers of delta.
doublereal phiR_dd() const
Calculate d2_phiR_dd(delta), the second derivative of phiR wrt delta.
doublereal DELTAsave
Last delta that was used to calculate polynomials.
doublereal pressureM_rhoRT(doublereal tau, doublereal delta)
Calculate the dimensionless pressure at tau and delta;.
doublereal phiR_tt() const
Calculate Equation 6.6 for dphiRdtau, the second derivative residual part of the dimensionless Helmho...
doublereal phi0_t() const
Calculate d_phi0/d(tau)
const doublereal T_c
Critical Temperature value (kelvin)
doublereal dimdpdrho(doublereal tau, doublereal delta)
Dimensionless derivative of p wrt rho at constant T.
doublereal phiR_t() const
Calculate Equation 6.6 for dphiRdtau, the derivative residual part of the dimensionless Helmholtz fre...
doublereal phi_tt(doublereal tau, doublereal delta)
Second derivative of phi wrt tau.
doublereal phiR_d() const
Calculate d_phiR_d(delta), the first derivative of phiR wrt delta.
doublereal dimdpdT(doublereal tau, doublereal delta)
Dimensionless derivative of p wrt T at constant rho.
void check2()
Internal check # 2.
WaterPropsIAPWSphi()
Base constructor.
void tdpolycalc(doublereal tau, doublereal delta)
Calculates internal polynomials in tau and delta.
doublereal phi0() const
Calculate Equation 6.5 for phi0, the ideal gas part of the dimensionless Helmholtz free energy...
doublereal phi_t(doublereal tau, doublereal delta)
First derivative of phi wrt tau.
doublereal enthalpy_RT() const
Calculate the dimensionless enthalpy, h/RT.
doublereal TAUsqrt
sqrt of TAU
doublereal cp_R() const
Calculate the dimensionless constant pressure heat capacity, Cv/R.
doublereal cv_R() const
Calculate the dimensionless constant volume heat capacity, Cv/R.
doublereal phi_d(doublereal tau, doublereal delta)
Calculate derivative of phi wrt delta.
doublereal phi0_tt() const
Calculate d2_phi0/dtau2.
static const doublereal M_water
Molecular Weight of water that is consistent with the paper (kg kmol-1)
doublereal intEnergy_RT() const
Calculate the dimensionless internal energy, u/RT.
doublereal phi(doublereal tau, doublereal delta)
Calculate the Phi function, which is the base function.
doublereal TAUp[52]
Value of internally calculated polynomials of powers of TAU.