Cantera 2.6.0

MixtureFugacityTP.cpp
Go to the documentation of this file.
1/**
2 * @file MixtureFugacityTP.cpp
3 * Methods file for a derived class of ThermoPhase that handles
4 * non-ideal mixtures based on the fugacity models (see \ref thermoprops and
5 * class \link Cantera::MixtureFugacityTP MixtureFugacityTP\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
11#include "cantera/thermo/MixtureFugacityTP.h"
12#include "cantera/base/stringUtils.h"
13#include "cantera/base/ctml.h"
14
15 using namespace std;
16
17 namespace Cantera
18{
19
20 MixtureFugacityTP::MixtureFugacityTP() :
21 iState_(FLUID_GAS),
22 forcedState_(FLUID_UNDEFINED)
23{
24}
25
26 int MixtureFugacityTP::standardStateConvention() const
27{
28 return cSS_CONVENTION_TEMPERATURE;
29}
30
31 void MixtureFugacityTP::setForcedSolutionBranch(int solnBranch)
32{
33 forcedState_ = solnBranch;
34}
35
36 int MixtureFugacityTP::forcedSolutionBranch() const
37{
38 return forcedState_;
39}
40
41 int MixtureFugacityTP::reportSolnBranchActual() const
42{
43 return iState_;
44}
45
46// ---- Molar Thermodynamic Properties ---------------------------
47 double MixtureFugacityTP::enthalpy_mole() const
48{
49 double h_ideal = RT() * mean_X(m_h0_RT);
50 double h_nonideal = hresid();
51 return h_ideal + h_nonideal;
52}
53
54
55 double MixtureFugacityTP::entropy_mole() const
56{
57 double s_ideal = GasConstant * (mean_X(m_s0_R) - sum_xlogx()
58 - std::log(pressure()/refPressure()));
59 double s_nonideal = sresid();
60 return s_ideal + s_nonideal;
61}
62
63// ---- Partial Molar Properties of the Solution -----------------
64
65 void MixtureFugacityTP::getChemPotentials_RT(doublereal* muRT) const
66{
67 getChemPotentials(muRT);
68 for (size_t k = 0; k < m_kk; k++) {
69 muRT[k] *= 1.0 / RT();
70 }
71}
72
73// ----- Thermodynamic Values for the Species Standard States States ----
74
75 void MixtureFugacityTP::getStandardChemPotentials(doublereal* g) const
76{
77 copy(m_g0_RT.begin(), m_g0_RT.end(), g);
78 double tmp = log(pressure() / refPressure());
79 for (size_t k = 0; k < m_kk; k++) {
80 g[k] = RT() * (g[k] + tmp);
81 }
82}
83
84 void MixtureFugacityTP::getEnthalpy_RT(doublereal* hrt) const
85{
86 getEnthalpy_RT_ref(hrt);
87}
88
89 void MixtureFugacityTP::getEntropy_R(doublereal* sr) const
90{
91 copy(m_s0_R.begin(), m_s0_R.end(), sr);
92 double tmp = log(pressure() / refPressure());
93 for (size_t k = 0; k < m_kk; k++) {
94 sr[k] -= tmp;
95 }
96}
97
98 void MixtureFugacityTP::getGibbs_RT(doublereal* grt) const
99{
100 copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
101 double tmp = log(pressure() / refPressure());
102 for (size_t k = 0; k < m_kk; k++) {
103 grt[k] += tmp;
104 }
105}
106
107 void MixtureFugacityTP::getPureGibbs(doublereal* g) const
108{
109 scale(m_g0_RT.begin(), m_g0_RT.end(), g, RT());
110 double tmp = log(pressure() / refPressure()) * RT();
111 for (size_t k = 0; k < m_kk; k++) {
112 g[k] += tmp;
113 }
114}
115
116 void MixtureFugacityTP::getIntEnergy_RT(doublereal* urt) const
117{
118 copy(m_h0_RT.begin(), m_h0_RT.end(), urt);
119 for (size_t i = 0; i < m_kk; i++) {
120 urt[i] -= 1.0;
121 }
122}
123
124 void MixtureFugacityTP::getCp_R(doublereal* cpr) const
125{
126 copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
127}
128
129 void MixtureFugacityTP::getStandardVolumes(doublereal* vol) const
130{
131 for (size_t i = 0; i < m_kk; i++) {
132 vol[i] = RT() / pressure();
133 }
134}
135
136// ----- Thermodynamic Values for the Species Reference States ----
137
138 void MixtureFugacityTP::getEnthalpy_RT_ref(doublereal* hrt) const
139{
140 copy(m_h0_RT.begin(), m_h0_RT.end(), hrt);
141}
142
143 void MixtureFugacityTP::getGibbs_RT_ref(doublereal* grt) const
144{
145 copy(m_g0_RT.begin(), m_g0_RT.end(), grt);
146}
147
148 void MixtureFugacityTP::getGibbs_ref(doublereal* g) const
149{
150 const vector_fp& gibbsrt = gibbs_RT_ref();
151 scale(gibbsrt.begin(), gibbsrt.end(), g, RT());
152}
153
154 const vector_fp& MixtureFugacityTP::gibbs_RT_ref() const
155{
156 return m_g0_RT;
157}
158
159 void MixtureFugacityTP::getEntropy_R_ref(doublereal* er) const
160{
161 copy(m_s0_R.begin(), m_s0_R.end(), er);
162}
163
164 void MixtureFugacityTP::getCp_R_ref(doublereal* cpr) const
165{
166 copy(m_cp0_R.begin(), m_cp0_R.end(), cpr);
167}
168
169 void MixtureFugacityTP::getStandardVolumes_ref(doublereal* vol) const
170{
171 for (size_t i = 0; i < m_kk; i++) {
172 vol[i]= RT() / refPressure();
173 }
174}
175
176 void MixtureFugacityTP::setStateFromXML(const XML_Node& state)
177{
178 int doTP = 0;
179 string comp = getChildValue(state,"moleFractions");
180 if (comp != "") {
181 // not overloaded in current object -> phase state is not calculated.
182 setMoleFractionsByName(comp);
183 doTP = 1;
184 } else {
185 comp = getChildValue(state,"massFractions");
186 if (comp != "") {
187 // not overloaded in current object -> phase state is not calculated.
188 setMassFractionsByName(comp);
189 doTP = 1;
190 }
191 }
192 double t = temperature();
193 if (state.hasChild("temperature")) {
194 t = getFloat(state, "temperature", "temperature");
195 doTP = 1;
196 }
197 if (state.hasChild("pressure")) {
198 double p = getFloat(state, "pressure", "pressure");
199 setState_TP(t, p);
200 } else if (state.hasChild("density")) {
201 double rho = getFloat(state, "density", "density");
202 setState_TR(t, rho);
203 } else if (doTP) {
204 double rho = density();
205 setState_TR(t, rho);
206 }
207}
208
209 bool MixtureFugacityTP::addSpecies(shared_ptr<Species> spec)
210{
211 bool added = ThermoPhase::addSpecies(spec);
212 if (added) {
213 if (m_kk == 1) {
214 moleFractions_.push_back(1.0);
215 } else {
216 moleFractions_.push_back(0.0);
217 }
218 m_h0_RT.push_back(0.0);
219 m_cp0_R.push_back(0.0);
220 m_g0_RT.push_back(0.0);
221 m_s0_R.push_back(0.0);
222 m_tmpV.push_back(0.0);
223 }
224 return added;
225}
226
227 void MixtureFugacityTP::setTemperature(const doublereal temp)
228{
229 Phase::setTemperature(temp);
230 _updateReferenceStateThermo();
231 // depends on mole fraction and temperature
232 updateMixingExpressions();
233 iState_ = phaseState(true);
234}
235
236 void MixtureFugacityTP::setPressure(doublereal p)
237{
238 // A pretty tricky algorithm is needed here, due to problems involving
239 // standard states of real fluids. For those cases you need to combine the T
240 // and P specification for the standard state, or else you may venture into
241 // the forbidden zone, especially when nearing the triple point. Therefore,
242 // we need to do the standard state thermo calc with the (t, pres) combo.
243
244 double t = temperature();
245 double rhoNow = density();
246 if (forcedState_ == FLUID_UNDEFINED) {
247 double rho = densityCalc(t, p, iState_, rhoNow);
248 if (rho > 0.0) {
249 setDensity(rho);
250 iState_ = phaseState(true);
251 } else {
252 if (rho < -1.5) {
253 rho = densityCalc(t, p, FLUID_UNDEFINED , rhoNow);
254 if (rho > 0.0) {
255 setDensity(rho);
256 iState_ = phaseState(true);
257 } else {
258 throw CanteraError("MixtureFugacityTP::setPressure",
259 "neg rho");
260 }
261 } else {
262 throw CanteraError("MixtureFugacityTP::setPressure",
263 "neg rho");
264 }
265 }
266 } else if (forcedState_ == FLUID_GAS) {
267 // Normal density calculation
268 if (iState_ < FLUID_LIQUID_0) {
269 double rho = densityCalc(t, p, iState_, rhoNow);
270 if (rho > 0.0) {
271 setDensity(rho);
272 iState_ = phaseState(true);
273 if (iState_ >= FLUID_LIQUID_0) {
274 throw CanteraError("MixtureFugacityTP::setPressure",
275 "wrong state");
276 }
277 } else {
278 throw CanteraError("MixtureFugacityTP::setPressure",
279 "neg rho");
280 }
281 }
282 } else if (forcedState_ > FLUID_LIQUID_0) {
283 if (iState_ >= FLUID_LIQUID_0) {
284 double rho = densityCalc(t, p, iState_, rhoNow);
285 if (rho > 0.0) {
286 setDensity(rho);
287 iState_ = phaseState(true);
288 if (iState_ == FLUID_GAS) {
289 throw CanteraError("MixtureFugacityTP::setPressure",
290 "wrong state");
291 }
292 } else {
293 throw CanteraError("MixtureFugacityTP::setPressure",
294 "neg rho");
295 }
296 }
297 }
298}
299
300 void MixtureFugacityTP::compositionChanged()
301{
302 Phase::compositionChanged();
303 getMoleFractions(moleFractions_.data());
304 updateMixingExpressions();
305}
306
307 void MixtureFugacityTP::getActivityConcentrations(doublereal* c) const
308{
309 getActivityCoefficients(c);
310 double p_RT = pressure() / RT();
311 for (size_t k = 0; k < m_kk; k++) {
312 c[k] *= moleFraction(k)*p_RT;
313 }
314}
315
316doublereal MixtureFugacityTP::z() const
317{
318 return pressure() * meanMolecularWeight() / (density() * RT());
319}
320
321doublereal MixtureFugacityTP::sresid() const
322{
323 throw NotImplementedError("MixtureFugacityTP::sresid");
324}
325
326doublereal MixtureFugacityTP::hresid() const
327{
328 throw NotImplementedError("MixtureFugacityTP::hresid");
329}
330
331doublereal MixtureFugacityTP::psatEst(doublereal TKelvin) const
332{
333 doublereal pcrit = critPressure();
334 doublereal tt = critTemperature() / TKelvin;
335 if (tt < 1.0) {
336 return pcrit;
337 }
338 doublereal lpr = -0.8734*tt*tt - 3.4522*tt + 4.2918;
339 return pcrit*exp(lpr);
340}
341
342doublereal MixtureFugacityTP::liquidVolEst(doublereal TKelvin, doublereal& pres) const
343{
344 throw NotImplementedError("MixtureFugacityTP::liquidVolEst");
345}
346
347doublereal MixtureFugacityTP::densityCalc(doublereal TKelvin, doublereal presPa,
348 int phase, doublereal rhoguess)
349{
350 doublereal tcrit = critTemperature();
351 doublereal mmw = meanMolecularWeight();
352 if (rhoguess == -1.0) {
353 if (phase != -1) {
354 if (TKelvin > tcrit) {
355 rhoguess = presPa * mmw / (GasConstant * TKelvin);
356 } else {
357 if (phase == FLUID_GAS || phase == FLUID_SUPERCRIT) {
358 rhoguess = presPa * mmw / (GasConstant * TKelvin);
359 } else if (phase >= FLUID_LIQUID_0) {
360 double lqvol = liquidVolEst(TKelvin, presPa);
361 rhoguess = mmw / lqvol;
362 }
363 }
364 } else {
365 // Assume the Gas phase initial guess, if nothing is specified to
366 // the routine
367 rhoguess = presPa * mmw / (GasConstant * TKelvin);
368 }
369 }
370
371 double molarVolBase = mmw / rhoguess;
372 double molarVolLast = molarVolBase;
373 double vc = mmw / critDensity();
374
375 // molar volume of the spinodal at the current temperature and mole
376 // fractions. this will be updated as we go.
377 double molarVolSpinodal = vc;
378 bool conv = false;
379
380 // We start on one side of the vc and stick with that side
381 bool gasSide = molarVolBase > vc;
382 if (gasSide) {
383 molarVolLast = (GasConstant * TKelvin)/presPa;
384 } else {
385 molarVolLast = liquidVolEst(TKelvin, presPa);
386 }
387
388 // OK, now we do a small solve to calculate the molar volume given the T,P
389 // value. The algorithm is taken from dfind()
390 for (int n = 0; n < 200; n++) {
391 // Calculate the predicted reduced pressure, pred0, based on the current
392 // tau and dd. Calculate the derivative of the predicted pressure wrt
393 // the molar volume. This routine also returns the pressure, presBase
394 double presBase;
395 double dpdVBase = dpdVCalc(TKelvin, molarVolBase, presBase);
396
397 // If dpdV is positive, then we are in the middle of the 2 phase region
398 // and beyond the spinodal stability curve. We need to adjust the
399 // initial guess outwards and start a new iteration.
400 if (dpdVBase >= 0.0) {
401 if (TKelvin > tcrit) {
402 throw CanteraError("MixtureFugacityTP::densityCalc",
403 "T > tcrit unexpectedly");
404 }
405
406 // TODO Spawn a calculation for the value of the spinodal point that
407 // is very accurate. Answer the question as to whether a
408 // solution is possible on the current side of the vapor dome.
409 if (gasSide) {
410 if (molarVolBase >= vc) {
411 molarVolSpinodal = molarVolBase;
412 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
413 } else {
414 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
415 }
416 } else {
417 if (molarVolBase <= vc) {
418 molarVolSpinodal = molarVolBase;
419 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
420 } else {
421 molarVolBase = 0.5 * (molarVolLast + molarVolSpinodal);
422 }
423 }
424 continue;
425 }
426
427 // Check for convergence
428 if (fabs(presBase-presPa) < 1.0E-30 + 1.0E-8 * presPa) {
429 conv = true;
430 break;
431 }
432
433 // Dampen and crop the update
434 doublereal dpdV = dpdVBase;
435 if (n < 10) {
436 dpdV = dpdVBase * 1.5;
437 }
438
439 // Formulate the update to the molar volume by Newton's method. Then,
440 // crop it to a max value of 0.1 times the current volume
441 double delMV = - (presBase - presPa) / dpdV;
442 if ((!gasSide || delMV < 0.0) && fabs(delMV) > 0.2 * molarVolBase) {
443 delMV = delMV / fabs(delMV) * 0.2 * molarVolBase;
444 }
445 // Only go 1/10 the way towards the spinodal at any one time.
446 if (TKelvin < tcrit) {
447 if (gasSide) {
448 if (delMV < 0.0 && -delMV > 0.5 * (molarVolBase - molarVolSpinodal)) {
449 delMV = - 0.5 * (molarVolBase - molarVolSpinodal);
450 }
451 } else {
452 if (delMV > 0.0 && delMV > 0.5 * (molarVolSpinodal - molarVolBase)) {
453 delMV = 0.5 * (molarVolSpinodal - molarVolBase);
454 }
455 }
456 }
457 // updated the molar volume value
458 molarVolLast = molarVolBase;
459 molarVolBase += delMV;
460
461 if (fabs(delMV/molarVolBase) < 1.0E-14) {
462 conv = true;
463 break;
464 }
465
466 // Check for negative molar volumes
467 if (molarVolBase <= 0.0) {
468 molarVolBase = std::min(1.0E-30, fabs(delMV*1.0E-4));
469 }
470 }
471
472 // Check for convergence, and return 0.0 if it wasn't achieved.
473 double densBase = 0.0;
474 if (! conv) {
475 molarVolBase = 0.0;
476 throw CanteraError("MixtureFugacityTP::densityCalc",
477 "Process did not converge");
478 } else {
479 densBase = mmw / molarVolBase;
480 }
481 return densBase;
482}
483
484 void MixtureFugacityTP::updateMixingExpressions()
485{
486}
487
488 int MixtureFugacityTP::corr0(doublereal TKelvin, doublereal pres, doublereal& densLiqGuess,
489 doublereal& densGasGuess, doublereal& liqGRT, doublereal& gasGRT)
490{
491 int retn = 0;
492 doublereal densLiq = densityCalc(TKelvin, pres, FLUID_LIQUID_0, densLiqGuess);
493 if (densLiq <= 0.0) {
494 retn = -1;
495 } else {
496 densLiqGuess = densLiq;
497 setState_TR(TKelvin, densLiq);
498 liqGRT = gibbs_mole() / RT();
499 }
500
501 doublereal densGas = densityCalc(TKelvin, pres, FLUID_GAS, densGasGuess);
502 if (densGas <= 0.0) {
503 if (retn == -1) {
504 throw CanteraError("MixtureFugacityTP::corr0",
505 "Error occurred trying to find gas density at (T,P) = {} {}",
506 TKelvin, pres);
507 }
508 retn = -2;
509 } else {
510 densGasGuess = densGas;
511 setState_TR(TKelvin, densGas);
512 gasGRT = gibbs_mole() / RT();
513 }
514 return retn;
515}
516
517 int MixtureFugacityTP::phaseState(bool checkState) const
518{
519 int state = iState_;
520 if (checkState) {
521 double t = temperature();
522 double tcrit = critTemperature();
523 double rhocrit = critDensity();
524 if (t >= tcrit) {
525 return FLUID_SUPERCRIT;
526 }
527 double tmid = tcrit - 100.;
528 if (tmid < 0.0) {
529 tmid = tcrit / 2.0;
530 }
531 double pp = psatEst(tmid);
532 double mmw = meanMolecularWeight();
533 double molVolLiqTmid = liquidVolEst(tmid, pp);
534 double molVolGasTmid = GasConstant * tmid / pp;
535 double densLiqTmid = mmw / molVolLiqTmid;
536 double densGasTmid = mmw / molVolGasTmid;
537 double densMidTmid = 0.5 * (densLiqTmid + densGasTmid);
538 doublereal rhoMid = rhocrit + (t - tcrit) * (rhocrit - densMidTmid) / (tcrit - tmid);
539
540 double rho = density();
541 int iStateGuess = FLUID_LIQUID_0;
542 if (rho < rhoMid) {
543 iStateGuess = FLUID_GAS;
544 }
545 double molarVol = mmw / rho;
546 double presCalc;
547
548 double dpdv = dpdVCalc(t, molarVol, presCalc);
549 if (dpdv < 0.0) {
550 state = iStateGuess;
551 } else {
552 state = FLUID_UNSTABLE;
553 }
554 }
555 return state;
556}
557
558doublereal MixtureFugacityTP::densSpinodalLiquid() const
559{
560 throw NotImplementedError("MixtureFugacityTP::densSpinodalLiquid");
561}
562
563doublereal MixtureFugacityTP::densSpinodalGas() const
564{
565 throw NotImplementedError("MixtureFugacityTP::densSpinodalGas");
566}
567
568doublereal MixtureFugacityTP::satPressure(doublereal TKelvin)
569{
570 doublereal molarVolGas;
571 doublereal molarVolLiquid;
572 return calculatePsat(TKelvin, molarVolGas, molarVolLiquid);
573}
574
575doublereal MixtureFugacityTP::calculatePsat(doublereal TKelvin, doublereal& molarVolGas,
576 doublereal& molarVolLiquid)
577{
578 // The algorithm for this routine has undergone quite a bit of work. It
579 // probably needs more work. However, it seems now to be fairly robust. The
580 // key requirement is to find an initial pressure where both the liquid and
581 // the gas exist. This is not as easy as it sounds, and it gets exceedingly
582 // hard as the critical temperature is approached from below. Once we have
583 // this initial state, then we seek to equilibrate the Gibbs free energies
584 // of the gas and liquid and use the formula
585 //
586 // dp = VdG
587 //
588 // to create an update condition for deltaP using
589 //
590 // - (Gliq - Ggas) = (Vliq - Vgas) (deltaP)
591 //
592 // @todo Suggestions for the future would be to switch it to an algorithm
593 // that uses the gas molar volume and the liquid molar volumes as the
594 // fundamental unknowns.
595
596 // we need this because this is a non-const routine that is public
597 setTemperature(TKelvin);
598 double densSave = density();
599 double tempSave = temperature();
600 double pres;
601 doublereal mw = meanMolecularWeight();
602 if (TKelvin < critTemperature()) {
603 pres = psatEst(TKelvin);
604 // trial value = Psat from correlation
605 doublereal volLiquid = liquidVolEst(TKelvin, pres);
606 double RhoLiquidGood = mw / volLiquid;
607 double RhoGasGood = pres * mw / (GasConstant * TKelvin);
608 doublereal delGRT = 1.0E6;
609 doublereal liqGRT, gasGRT;
610
611 // First part of the calculation involves finding a pressure at which
612 // the gas and the liquid state coexists.
613 doublereal presLiquid = 0.;
614 doublereal presGas;
615 doublereal presBase = pres;
616 bool foundLiquid = false;
617 bool foundGas = false;
618
619 doublereal densLiquid = densityCalc(TKelvin, presBase, FLUID_LIQUID_0, RhoLiquidGood);
620 if (densLiquid > 0.0) {
621 foundLiquid = true;
622 presLiquid = pres;
623 RhoLiquidGood = densLiquid;
624 }
625 if (!foundLiquid) {
626 for (int i = 0; i < 50; i++) {
627 pres = 1.1 * pres;
628 densLiquid = densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood);
629 if (densLiquid > 0.0) {
630 foundLiquid = true;
631 presLiquid = pres;
632 RhoLiquidGood = densLiquid;
633 break;
634 }
635 }
636 }
637
638 pres = presBase;
639 doublereal densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
640 if (densGas <= 0.0) {
641 foundGas = false;
642 } else {
643 foundGas = true;
644 presGas = pres;
645 RhoGasGood = densGas;
646 }
647 if (!foundGas) {
648 for (int i = 0; i < 50; i++) {
649 pres = 0.9 * pres;
650 densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
651 if (densGas > 0.0) {
652 foundGas = true;
653 presGas = pres;
654 RhoGasGood = densGas;
655 break;
656 }
657 }
658 }
659
660 if (foundGas && foundLiquid && presGas != presLiquid) {
661 pres = 0.5 * (presLiquid + presGas);
662 bool goodLiq;
663 bool goodGas;
664 for (int i = 0; i < 50; i++) {
665 densLiquid = densityCalc(TKelvin, pres, FLUID_LIQUID_0, RhoLiquidGood);
666 if (densLiquid <= 0.0) {
667 goodLiq = false;
668 } else {
669 goodLiq = true;
670 RhoLiquidGood = densLiquid;
671 presLiquid = pres;
672 }
673 densGas = densityCalc(TKelvin, pres, FLUID_GAS, RhoGasGood);
674 if (densGas <= 0.0) {
675 goodGas = false;
676 } else {
677 goodGas = true;
678 RhoGasGood = densGas;
679 presGas = pres;
680 }
681 if (goodGas && goodLiq) {
682 break;
683 }
684 if (!goodLiq && !goodGas) {
685 pres = 0.5 * (pres + presLiquid);
686 }
687 if (goodLiq || goodGas) {
688 pres = 0.5 * (presLiquid + presGas);
689 }
690 }
691 }
692 if (!foundGas || !foundLiquid) {
693 warn_user("MixtureFugacityTP::calculatePsat",
694 "could not find a starting pressure; exiting.");
695 return 0.0;
696 }
697 if (presGas != presLiquid) {
698 warn_user("MixtureFugacityTP::calculatePsat",
699 "could not find a starting pressure; exiting");
700 return 0.0;
701 }
702
703 pres = presGas;
704 double presLast = pres;
705 double RhoGas = RhoGasGood;
706 double RhoLiquid = RhoLiquidGood;
707
708 // Now that we have found a good pressure we can proceed with the algorithm.
709 for (int i = 0; i < 20; i++) {
710 int stab = corr0(TKelvin, pres, RhoLiquid, RhoGas, liqGRT, gasGRT);
711 if (stab == 0) {
712 presLast = pres;
713 delGRT = liqGRT - gasGRT;
714 doublereal delV = mw * (1.0/RhoLiquid - 1.0/RhoGas);
715 doublereal dp = - delGRT * GasConstant * TKelvin / delV;
716
717 if (fabs(dp) > 0.1 * pres) {
718 if (dp > 0.0) {
719 dp = 0.1 * pres;
720 } else {
721 dp = -0.1 * pres;
722 }
723 }
724 pres += dp;
725 } else if (stab == -1) {
726 delGRT = 1.0E6;
727 if (presLast > pres) {
728 pres = 0.5 * (presLast + pres);
729 } else {
730 // we are stuck here - try this
731 pres = 1.1 * pres;
732 }
733 } else if (stab == -2) {
734 if (presLast < pres) {
735 pres = 0.5 * (presLast + pres);
736 } else {
737 // we are stuck here - try this
738 pres = 0.9 * pres;
739 }
740 }
741 molarVolGas = mw / RhoGas;
742 molarVolLiquid = mw / RhoLiquid;
743
744 if (fabs(delGRT) < 1.0E-8) {
745 // converged
746 break;
747 }
748 }
749
750 molarVolGas = mw / RhoGas;
751 molarVolLiquid = mw / RhoLiquid;
752 // Put the fluid in the desired end condition
753 setState_TR(tempSave, densSave);
754 return pres;
755 } else {
756 pres = critPressure();
757 setState_TP(TKelvin, pres);
758 molarVolGas = mw / density();
759 molarVolLiquid = molarVolGas;
760 setState_TR(tempSave, densSave);
761 }
762 return pres;
763}
764
765doublereal MixtureFugacityTP::dpdVCalc(doublereal TKelvin, doublereal molarVol, doublereal& presCalc) const
766{
767 throw NotImplementedError("MixtureFugacityTP::dpdVCalc");
768}
769
770 void MixtureFugacityTP::_updateReferenceStateThermo() const
771{
772 double Tnow = temperature();
773
774 // If the temperature has changed since the last time these
775 // properties were computed, recompute them.
776 if (m_tlast != Tnow) {
777 m_spthermo.update(Tnow, &m_cp0_R[0], &m_h0_RT[0], &m_s0_R[0]);
778 m_tlast = Tnow;
779
780 // update the species Gibbs functions
781 for (size_t k = 0; k < m_kk; k++) {
782 m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
783 }
784 doublereal pref = refPressure();
785 if (pref <= 0.0) {
786 throw CanteraError("MixtureFugacityTP::_updateReferenceStateThermo",
787 "negative reference pressure");
788 }
789 }
790}
791
792 double MixtureFugacityTP::critTemperature() const
793{
794 double pc, tc, vc;
795 calcCriticalConditions(pc, tc, vc);
796 return tc;
797}
798
799 double MixtureFugacityTP::critPressure() const
800{
801 double pc, tc, vc;
802 calcCriticalConditions(pc, tc, vc);
803 return pc;
804}
805
806 double MixtureFugacityTP::critVolume() const
807{
808 double pc, tc, vc;
809 calcCriticalConditions(pc, tc, vc);
810 return vc;
811}
812
813 double MixtureFugacityTP::critCompressibility() const
814{
815 double pc, tc, vc;
816 calcCriticalConditions(pc, tc, vc);
817 return pc*vc/tc/GasConstant;
818}
819
820 double MixtureFugacityTP::critDensity() const
821{
822 double pc, tc, vc;
823 calcCriticalConditions(pc, tc, vc);
824 double mmw = meanMolecularWeight();
825 return mmw / vc;
826}
827
828 void MixtureFugacityTP::calcCriticalConditions(double& pc, double& tc, double& vc) const
829{
830 throw NotImplementedError("MixtureFugacityTP::calcCriticalConditions");
831}
832
833 int MixtureFugacityTP::solveCubic(double T, double pres, double a, double b,
834 double aAlpha, double Vroot[3], double an,
835 double bn, double cn, double dn, double tc, double vc) const
836{
837 fill_n(Vroot, 3, 0.0);
838 if (T <= 0.0) {
839 throw CanteraError("MixtureFugacityTP::solveCubic",
840 "negative temperature T = {}", T);
841 }
842
843 // Derive the center of the cubic, x_N
844 double xN = - bn /(3 * an);
845
846 // Derive the value of delta**2. This is a key quantity that determines the number of turning points
847 double delta2 = (bn * bn - 3 * an * cn) / (9 * an * an);
848 double delta = 0.0;
849
850 // Calculate a couple of ratios
851 // Cubic equation in z : z^3 - (1-B) z^2 + (A -2B -3B^2)z - (AB- B^2- B^3) = 0
852 double ratio1 = 3.0 * an * cn / (bn * bn);
853 double ratio2 = pres * b / (GasConstant * T); // B
854 if (fabs(ratio1) < 1.0E-7) {
855 double ratio3 = aAlpha / (GasConstant * T) * pres / (GasConstant * T); // A
856 if (fabs(ratio2) < 1.0E-5 && fabs(ratio3) < 1.0E-5) {
857 // A and B terms in cubic equation for z are almost zero, then z is near to 1
858 double zz = 1.0;
859 for (int i = 0; i < 10; i++) {
860 double znew = zz / (zz - ratio2) - ratio3 / (zz + ratio1);
861 double deltaz = znew - zz;
862 zz = znew;
863 if (fabs(deltaz) < 1.0E-14) {
864 break;
865 }
866 }
867 double v = zz * GasConstant * T / pres;
868 Vroot[0] = v;
869 return 1;
870 }
871 }
872
873 int nSolnValues = -1; // Represents number of solutions to the cubic equation
874 double h2 = 4. * an * an * delta2 * delta2 * delta2; // h^2
875 if (delta2 > 0.0) {
876 delta = sqrt(delta2);
877 }
878
879 double h = 2.0 * an * delta * delta2;
880 double yN = 2.0 * bn * bn * bn / (27.0 * an * an) - bn * cn / (3.0 * an) + dn; // y_N term
881 double disc = yN * yN - h2; // discriminant
882
883 //check if y = h
884 if (fabs(fabs(h) - fabs(yN)) < 1.0E-10) {
885 if (disc > 1e-10) {
886 throw CanteraError("MixtureFugacityTP::solveCubic",
887 "value of yN and h are too high, unrealistic roots may be obtained");
888 }
889 disc = 0.0;
890 }
891
892 if (disc < -1e-14) {
893 // disc<0 then we have three distinct roots.
894 nSolnValues = 3;
895 } else if (fabs(disc) < 1e-14) {
896 // disc=0 then we have two distinct roots (third one is repeated root)
897 nSolnValues = 2;
898 // We are here as p goes to zero.
899 } else if (disc > 1e-14) {
900 // disc> 0 then we have one real root.
901 nSolnValues = 1;
902 }
903
904 double tmp;
905 // One real root -> have to determine whether gas or liquid is the root
906 if (disc > 0.0) {
907 double tmpD = sqrt(disc);
908 double tmp1 = (- yN + tmpD) / (2.0 * an);
909 double sgn1 = 1.0;
910 if (tmp1 < 0.0) {
911 sgn1 = -1.0;
912 tmp1 = -tmp1;
913 }
914 double tmp2 = (- yN - tmpD) / (2.0 * an);
915 double sgn2 = 1.0;
916 if (tmp2 < 0.0) {
917 sgn2 = -1.0;
918 tmp2 = -tmp2;
919 }
920 double p1 = pow(tmp1, 1./3.);
921 double p2 = pow(tmp2, 1./3.);
922 double alpha = xN + sgn1 * p1 + sgn2 * p2;
923 Vroot[0] = alpha;
924 Vroot[1] = 0.0;
925 Vroot[2] = 0.0;
926 } else if (disc < 0.0) {
927 // Three real roots alpha, beta, gamma are obtained.
928 double val = acos(-yN / h);
929 double theta = val / 3.0;
930 double twoThirdPi = 2. * Pi / 3.;
931 double alpha = xN + 2. * delta * cos(theta);
932 double beta = xN + 2. * delta * cos(theta + twoThirdPi);
933 double gamma = xN + 2. * delta * cos(theta + 2.0 * twoThirdPi);
934 Vroot[0] = beta;
935 Vroot[1] = gamma;
936 Vroot[2] = alpha;
937
938 for (int i = 0; i < 3; i++) {
939 tmp = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
940 if (fabs(tmp) > 1.0E-4) {
941 for (int j = 0; j < 3; j++) {
942 if (j != i && fabs(Vroot[i] - Vroot[j]) < 1.0E-4 * (fabs(Vroot[i]) + fabs(Vroot[j]))) {
943 writelog("MixtureFugacityTP::solveCubic(T ={}, p ={}):"
944 " WARNING roots have merged: {}, {}\n",
945 T, pres, Vroot[i], Vroot[j]);
946 }
947 }
948 }
949 }
950 } else if (disc == 0.0) {
951 //Three equal roots are obtained, that is, alpha = beta = gamma
952 if (yN < 1e-18 && h < 1e-18) {
953 // yN = 0.0 and h = 0 (that is, disc = 0)
954 Vroot[0] = xN;
955 Vroot[1] = xN;
956 Vroot[2] = xN;
957 } else {
958 // h and yN need to figure out whether delta^3 is positive or negative
959 if (yN > 0.0) {
960 tmp = pow(yN/(2*an), 1./3.);
961 // In this case, tmp and delta must be equal.
962 if (fabs(tmp - delta) > 1.0E-9) {
963 throw CanteraError("MixtureFugacityTP::solveCubic",
964 "Inconsistency in solver: solver is ill-conditioned.");
965 }
966 Vroot[1] = xN + delta;
967 Vroot[0] = xN - 2.0*delta; // liquid phase root
968 } else {
969 tmp = pow(yN/(2*an), 1./3.);
970 // In this case, tmp and delta must be equal.
971 if (fabs(tmp - delta) > 1.0E-9) {
972 throw CanteraError("MixtureFugacityTP::solveCubic",
973 "Inconsistency in solver: solver is ill-conditioned.");
974 }
975 delta = -delta;
976 Vroot[0] = xN + delta;
977 Vroot[1] = xN - 2.0*delta; // gas phase root
978 }
979 }
980 }
981
982 // Find an accurate root, since there might be a heavy amount of roundoff error due to bad conditioning in this solver.
983 double res, dresdV = 0.0;
984 for (int i = 0; i < nSolnValues; i++) {
985 for (int n = 0; n < 20; n++) {
986 res = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
987 if (fabs(res) < 1.0E-14) { // accurate root is obtained
988 break;
989 }
990 dresdV = 3.0 * an * Vroot[i] * Vroot[i] + 2.0 * bn * Vroot[i] + cn; // derivative of the residual
991 double del = - res / dresdV;
992 Vroot[i] += del;
993 if (fabs(del) / (fabs(Vroot[i]) + fabs(del)) < 1.0E-14) {
994 break;
995 }
996 double res2 = an * Vroot[i] * Vroot[i] * Vroot[i] + bn * Vroot[i] * Vroot[i] + cn * Vroot[i] + dn;
997 if (fabs(res2) < fabs(res)) {
998 continue;
999 } else {
1000 Vroot[i] -= del; // Go back to previous value of Vroot.
1001 Vroot[i] += 0.1 * del; // under-relax by 0.1
1002 }
1003 }
1004 if ((fabs(res) > 1.0E-14) && (fabs(res) > 1.0E-14 * fabs(dresdV) * fabs(Vroot[i]))) {
1005 writelog("MixtureFugacityTP::solveCubic(T = {}, p = {}): "
1006 "WARNING root didn't converge V = {}", T, pres, Vroot[i]);
1007 writelogendl();
1008 }
1009 }
1010
1011 if (nSolnValues == 1) {
1012 // Determine the phase of the single root.
1013 // nSolnValues = 1 represents the gas phase by default.
1014 if (T > tc) {
1015 if (Vroot[0] < vc) {
1016 // Supercritical phase
1017 nSolnValues = -1;
1018 }
1019 } else {
1020 if (Vroot[0] < xN) {
1021 //Liquid phase
1022 nSolnValues = -1;
1023 }
1024 }
1025 } else {
1026 // Determine if we have two distinct roots or three equal roots
1027 // nSolnValues = 2 represents 2 equal roots by default.
1028 if (nSolnValues == 2 && delta > 1e-14) {
1029 //If delta > 0, we have two distinct roots (and one repeated root)
1030 nSolnValues = -2;
1031 }
1032 }
1033 return nSolnValues;
1034}
1035
1036}
MixtureFugacityTP.h
Header file for a derived class of ThermoPhase that handles non-ideal mixtures based on the fugacity ...
FLUID_UNSTABLE
#define FLUID_UNSTABLE
Various states of the Fugacity object.
Definition: MixtureFugacityTP.h:22
Cantera::CanteraError
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Cantera::MixtureFugacityTP::setStateFromXML
virtual void setStateFromXML(const XML_Node &state)
Set the initial state of the phase to the conditions specified in the state XML element.
Definition: MixtureFugacityTP.cpp:176
Cantera::MixtureFugacityTP::iState_
int iState_
Current state of the fluid.
Definition: MixtureFugacityTP.h:564
Cantera::MixtureFugacityTP::m_g0_RT
vector_fp m_g0_RT
Temporary storage for dimensionless reference state Gibbs energies.
Definition: MixtureFugacityTP.h:576
Cantera::MixtureFugacityTP::reportSolnBranchActual
virtual int reportSolnBranchActual() const
Report the solution branch which the solution is actually on.
Definition: MixtureFugacityTP.cpp:41
Cantera::MixtureFugacityTP::m_cp0_R
vector_fp m_cp0_R
Temporary storage for dimensionless reference state heat capacities.
Definition: MixtureFugacityTP.h:573
Cantera::MixtureFugacityTP::entropy_mole
virtual double entropy_mole() const
Molar entropy. Units: J/kmol/K.
Definition: MixtureFugacityTP.cpp:55
Cantera::MixtureFugacityTP::addSpecies
virtual bool addSpecies(shared_ptr< Species > spec)
Definition: MixtureFugacityTP.cpp:209
Cantera::MixtureFugacityTP::getGibbs_RT_ref
virtual void getGibbs_RT_ref(doublereal *grt) const
Returns the vector of nondimensional Gibbs Free Energies of the reference state at the current temper...
Definition: MixtureFugacityTP.cpp:143
Cantera::MixtureFugacityTP::enthalpy_mole
virtual double enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
Definition: MixtureFugacityTP.cpp:47
Cantera::MixtureFugacityTP::getGibbs_RT
virtual void getGibbs_RT(doublereal *grt) const
Get the nondimensional Gibbs functions for the species at their standard states of solution at the cu...
Definition: MixtureFugacityTP.cpp:98
Cantera::MixtureFugacityTP::hresid
virtual doublereal hresid() const
Calculate the deviation terms for the total enthalpy of the mixture from the ideal gas mixture.
Definition: MixtureFugacityTP.cpp:326
Cantera::MixtureFugacityTP::critCompressibility
virtual double critCompressibility() const
Critical compressibility (unitless).
Definition: MixtureFugacityTP.cpp:813
Cantera::MixtureFugacityTP::z
doublereal z() const
Calculate the value of z.
Definition: MixtureFugacityTP.cpp:316
Cantera::MixtureFugacityTP::m_h0_RT
vector_fp m_h0_RT
Temporary storage for dimensionless reference state enthalpies.
Definition: MixtureFugacityTP.h:570
Cantera::MixtureFugacityTP::satPressure
virtual doublereal satPressure(doublereal TKelvin)
Calculate the saturation pressure at the current mixture content for the given temperature.
Definition: MixtureFugacityTP.cpp:568
Cantera::MixtureFugacityTP::_updateReferenceStateThermo
virtual void _updateReferenceStateThermo() const
Updates the reference state thermodynamic functions at the current T of the solution.
Definition: MixtureFugacityTP.cpp:770
Cantera::MixtureFugacityTP::getStandardVolumes
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of each species in their standard states at the current T and P of the solution...
Definition: MixtureFugacityTP.cpp:129
Cantera::MixtureFugacityTP::m_s0_R
vector_fp m_s0_R
Temporary storage for dimensionless reference state entropies.
Definition: MixtureFugacityTP.h:579
Cantera::MixtureFugacityTP::solveCubic
int solveCubic(double T, double pres, double a, double b, double aAlpha, double Vroot[3], double an, double bn, double cn, double dn, double tc, double vc) const
Solve the cubic equation of state.
Definition: MixtureFugacityTP.cpp:833
Cantera::MixtureFugacityTP::dpdVCalc
virtual doublereal dpdVCalc(doublereal TKelvin, doublereal molarVol, doublereal &presCalc) const
Calculate the pressure and the pressure derivative given the temperature and the molar volume.
Definition: MixtureFugacityTP.cpp:765
Cantera::MixtureFugacityTP::sresid
virtual doublereal sresid() const
Calculate the deviation terms for the total entropy of the mixture from the ideal gas mixture.
Definition: MixtureFugacityTP.cpp:321
Cantera::MixtureFugacityTP::getCp_R
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the standard state of the species at ...
Definition: MixtureFugacityTP.cpp:124
Cantera::MixtureFugacityTP::critVolume
virtual double critVolume() const
Critical volume (m3/kmol).
Definition: MixtureFugacityTP.cpp:806
Cantera::MixtureFugacityTP::getEntropy_R
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Enthalpy functions for the standard state species at the current T an...
Definition: MixtureFugacityTP.cpp:89
Cantera::MixtureFugacityTP::setPressure
virtual void setPressure(doublereal p)
Set the internally stored pressure (Pa) at constant temperature and composition.
Definition: MixtureFugacityTP.cpp:236
Cantera::MixtureFugacityTP::densityCalc
virtual doublereal densityCalc(doublereal TKelvin, doublereal pressure, int phaseRequested, doublereal rhoguess)
Calculates the density given the temperature and the pressure and a guess at the density.
Definition: MixtureFugacityTP.cpp:347
Cantera::MixtureFugacityTP::psatEst
virtual doublereal psatEst(doublereal TKelvin) const
Estimate for the saturation pressure.
Definition: MixtureFugacityTP.cpp:331
Cantera::MixtureFugacityTP::liquidVolEst
virtual doublereal liquidVolEst(doublereal TKelvin, doublereal &pres) const
Estimate for the molar volume of the liquid.
Definition: MixtureFugacityTP.cpp:342
Cantera::MixtureFugacityTP::gibbs_RT_ref
const vector_fp & gibbs_RT_ref() const
Returns the vector of nondimensional Gibbs free energies of the reference state at the current temper...
Definition: MixtureFugacityTP.cpp:154
Cantera::MixtureFugacityTP::standardStateConvention
virtual int standardStateConvention() const
This method returns the convention used in specification of the standard state, of which there are cu...
Definition: MixtureFugacityTP.cpp:26
Cantera::MixtureFugacityTP::getEntropy_R_ref
virtual void getEntropy_R_ref(doublereal *er) const
Returns the vector of nondimensional entropies of the reference state at the current temperature of t...
Definition: MixtureFugacityTP.cpp:159
Cantera::MixtureFugacityTP::densSpinodalGas
virtual doublereal densSpinodalGas() const
Return the value of the density at the gas spinodal point (on the gas side) for the current temperatu...
Definition: MixtureFugacityTP.cpp:563
Cantera::MixtureFugacityTP::critDensity
virtual double critDensity() const
Critical density (kg/m3).
Definition: MixtureFugacityTP.cpp:820
Cantera::MixtureFugacityTP::getIntEnergy_RT
virtual void getIntEnergy_RT(doublereal *urt) const
Returns the vector of nondimensional internal Energies of the standard state at the current temperatu...
Definition: MixtureFugacityTP.cpp:116
Cantera::MixtureFugacityTP::setTemperature
virtual void setTemperature(const doublereal temp)
Set the temperature of the phase.
Definition: MixtureFugacityTP.cpp:227
Cantera::MixtureFugacityTP::getCp_R_ref
virtual void getCp_R_ref(doublereal *cprt) const
Returns the vector of nondimensional constant pressure heat capacities of the reference state at the ...
Definition: MixtureFugacityTP.cpp:164
Cantera::MixtureFugacityTP::moleFractions_
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
Definition: MixtureFugacityTP.h:555
Cantera::MixtureFugacityTP::calculatePsat
doublereal calculatePsat(doublereal TKelvin, doublereal &molarVolGas, doublereal &molarVolLiquid)
Calculate the saturation pressure at the current mixture content for the given temperature.
Definition: MixtureFugacityTP.cpp:575
Cantera::MixtureFugacityTP::getStandardChemPotentials
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity.
Definition: MixtureFugacityTP.cpp:75
Cantera::MixtureFugacityTP::getStandardVolumes_ref
virtual void getStandardVolumes_ref(doublereal *vol) const
Get the molar volumes of the species reference states at the current T and P_ref of the solution.
Definition: MixtureFugacityTP.cpp:169
Cantera::MixtureFugacityTP::forcedState_
int forcedState_
Force the system to be on a particular side of the spinodal curve.
Definition: MixtureFugacityTP.h:567
Cantera::MixtureFugacityTP::forcedSolutionBranch
virtual int forcedSolutionBranch() const
Report the solution branch which the solution is restricted to.
Definition: MixtureFugacityTP.cpp:36
Cantera::MixtureFugacityTP::compositionChanged
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
Definition: MixtureFugacityTP.cpp:300
Cantera::MixtureFugacityTP::critTemperature
virtual double critTemperature() const
Critical temperature (K).
Definition: MixtureFugacityTP.cpp:792
Cantera::MixtureFugacityTP::getChemPotentials_RT
virtual void getChemPotentials_RT(doublereal *mu) const
Get the array of non-dimensional species chemical potentials These are partial molar Gibbs free energ...
Definition: MixtureFugacityTP.cpp:65
Cantera::MixtureFugacityTP::getActivityConcentrations
virtual void getActivityConcentrations(double *c) const
This method returns an array of generalized concentrations.
Definition: MixtureFugacityTP.cpp:307
Cantera::MixtureFugacityTP::setForcedSolutionBranch
virtual void setForcedSolutionBranch(int solnBranch)
Set the solution branch to force the ThermoPhase to exist on one branch or another.
Definition: MixtureFugacityTP.cpp:31
Cantera::MixtureFugacityTP::corr0
int corr0(doublereal TKelvin, doublereal pres, doublereal &densLiq, doublereal &densGas, doublereal &liqGRT, doublereal &gasGRT)
Utility routine in the calculation of the saturation pressure.
Definition: MixtureFugacityTP.cpp:488
Cantera::MixtureFugacityTP::densSpinodalLiquid
virtual doublereal densSpinodalLiquid() const
Return the value of the density at the liquid spinodal point (on the liquid side) for the current tem...
Definition: MixtureFugacityTP.cpp:558
Cantera::MixtureFugacityTP::MixtureFugacityTP
MixtureFugacityTP()
Constructor.
Definition: MixtureFugacityTP.cpp:20
Cantera::MixtureFugacityTP::getGibbs_ref
virtual void getGibbs_ref(doublereal *g) const
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
Definition: MixtureFugacityTP.cpp:148
Cantera::MixtureFugacityTP::getEnthalpy_RT
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Definition: MixtureFugacityTP.cpp:84
Cantera::MixtureFugacityTP::getPureGibbs
virtual void getPureGibbs(doublereal *gpure) const
Get the pure Gibbs free energies of each species.
Definition: MixtureFugacityTP.cpp:107
Cantera::MixtureFugacityTP::m_tmpV
vector_fp m_tmpV
Temporary storage - length = m_kk.
Definition: MixtureFugacityTP.h:302
Cantera::MixtureFugacityTP::critPressure
virtual double critPressure() const
Critical pressure (Pa).
Definition: MixtureFugacityTP.cpp:799
Cantera::MixtureFugacityTP::phaseState
int phaseState(bool checkState=false) const
Returns the Phase State flag for the current state of the object.
Definition: MixtureFugacityTP.cpp:517
Cantera::MixtureFugacityTP::getEnthalpy_RT_ref
virtual void getEnthalpy_RT_ref(doublereal *hrt) const
Definition: MixtureFugacityTP.cpp:138
Cantera::MultiSpeciesThermo::update
virtual void update(doublereal T, doublereal *cp_R, doublereal *h_RT, doublereal *s_R) const
Compute the reference-state properties for all species.
Definition: MultiSpeciesThermo.cpp:90
Cantera::NotImplementedError
An error indicating that an unimplemented function has been called.
Definition: ctexceptions.h:187
Cantera::Phase::mean_X
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
Definition: Phase.cpp:717
Cantera::Phase::setMoleFractionsByName
void setMoleFractionsByName(const compositionMap &xMap)
Set the species mole fractions by name.
Definition: Phase.cpp:380
Cantera::Phase::m_kk
size_t m_kk
Number of species in the phase.
Definition: Phase.h:943
Cantera::Phase::setDensity
virtual void setDensity(const double density_)
Set the internally stored density (kg/m^3) of the phase.
Definition: Phase.cpp:687
Cantera::Phase::meanMolecularWeight
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:751
Cantera::Phase::getMoleFractions
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
Definition: Phase.cpp:543
Cantera::Phase::moleFraction
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:548
Cantera::Phase::setState_TR
void setState_TR(doublereal t, doublereal rho)
Set the internally stored temperature (K) and density (kg/m^3)
Definition: Phase.cpp:462
Cantera::Phase::density
virtual double density() const
Density (kg/m^3).
Definition: Phase.h:679
Cantera::Phase::compositionChanged
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
Definition: Phase.cpp:999
Cantera::Phase::temperature
doublereal temperature() const
Temperature (K).
Definition: Phase.h:654
Cantera::Phase::setTemperature
virtual void setTemperature(double temp)
Set the internally stored temperature of the phase (K).
Definition: Phase.h:719
Cantera::Phase::setMassFractionsByName
void setMassFractionsByName(const compositionMap &yMap)
Set the species mass fractions by name.
Definition: Phase.cpp:416
Cantera::Phase::pressure
virtual double pressure() const
Return the thermodynamic pressure (Pa).
Definition: Phase.h:672
Cantera::Phase::sum_xlogx
doublereal sum_xlogx() const
Evaluate .
Definition: Phase.cpp:727
Cantera::ThermoPhase::gibbs_mole
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
Definition: ThermoPhase.h:254
Cantera::ThermoPhase::addSpecies
virtual bool addSpecies(shared_ptr< Species > spec)
Definition: ThermoPhase.cpp:1140
Cantera::ThermoPhase::setState_TP
virtual void setState_TP(doublereal t, doublereal p)
Set the temperature (K) and pressure (Pa)
Definition: ThermoPhase.cpp:138
Cantera::ThermoPhase::RT
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:782
Cantera::ThermoPhase::m_tlast
doublereal m_tlast
last value of the temperature processed by reference state
Definition: ThermoPhase.h:1928
Cantera::ThermoPhase::getChemPotentials
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: ThermoPhase.h:495
Cantera::ThermoPhase::getActivityCoefficients
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
Definition: ThermoPhase.h:454
Cantera::ThermoPhase::refPressure
virtual doublereal refPressure() const
Returns the reference pressure in Pa.
Definition: ThermoPhase.h:150
Cantera::ThermoPhase::m_spthermo
MultiSpeciesThermo m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
Definition: ThermoPhase.h:1894
Cantera::XML_Node
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
Cantera::XML_Node::hasChild
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:529
ctml.h
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
Cantera::Pi
const double Pi
Pi.
Definition: ct_defs.h:52
Cantera::writelog
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition: global.h:164
Cantera
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:557
Cantera::getFloat
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:166
Cantera::getChildValue
std::string getChildValue(const XML_Node &parent, const std::string &nameString)
This function reads a child node with the name, nameString, and returns its XML value as the return s...
Definition: ctml.cpp:133
Cantera::vector_fp
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:184
Cantera::warn_user
void warn_user(const std::string &method, const std::string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition: global.h:245
Cantera::GasConstant
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:113
Cantera::cSS_CONVENTION_TEMPERATURE
const int cSS_CONVENTION_TEMPERATURE
Definition: ThermoPhase.h:37
Cantera::scale
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
Definition: utilities.h:100
Cantera::writelogendl
void writelogendl()
Write an end of line character to the screen and flush output.
Definition: global.cpp:42
stringUtils.h
Contains declarations for string manipulation functions within Cantera.