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