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