Cantera 2.6.0
vcs_MultiPhaseEquil.cpp
Go to the documentation of this file.
1/**
2 * @file vcs_MultiPhaseEquil.cpp
3 * Driver routine for the VCSnonideal equilibrium solver package
4 */
5
6// This file is part of Cantera. See License.txt in the top-level directory or
7// at https://cantera.org/license.txt for license and copyright information.
8
17
18#include <cstdio>
19
20using namespace std;
21
22namespace Cantera
23{
25 m_mix(mix),
26 m_printLvl(printLvl),
27 m_vsolve(mix, printLvl)
28{
29}
30
31int vcs_MultiPhaseEquil::equilibrate_TV(int XY, doublereal xtarget,
32 int estimateEquil,
33 int printLvl, doublereal err,
34 int maxsteps, int loglevel)
35{
36 doublereal Vtarget = m_mix->volume();
37 if ((XY != TV) && (XY != HV) && (XY != UV) && (XY != SV)) {
38 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_TV",
39 "Wrong XY flag: {}", XY);
40 }
41 int maxiter = 100;
42 int iSuccess = 0;
43 if (XY == TV) {
44 m_mix->setTemperature(xtarget);
45 }
46 int strt = estimateEquil;
47 double P1 = 0.0;
48 double V1 = 0.0;
49 double V2 = 0.0;
50 double P2 = 0.0;
51 doublereal Tlow = 0.5 * m_mix->minTemp();
52 doublereal Thigh = 2.0 * m_mix->maxTemp();
53 int printLvlSub = std::max(0, printLvl - 1);
54 for (int n = 0; n < maxiter; n++) {
55 double Pnow = m_mix->pressure();
56
57 switch (XY) {
58 case TV:
59 iSuccess = equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
60 break;
61 case HV:
62 iSuccess = equilibrate_HP(xtarget, HP, Tlow, Thigh, strt,
63 printLvlSub, err, maxsteps, loglevel);
64 break;
65 case UV:
66 iSuccess = equilibrate_HP(xtarget, UP, Tlow, Thigh, strt,
67 printLvlSub, err, maxsteps, loglevel);
68 break;
69 case SV:
70 iSuccess = equilibrate_SP(xtarget, Tlow, Thigh, strt,
71 printLvlSub, err, maxsteps, loglevel);
72 break;
73 default:
74 break;
75 }
76 strt = false;
77 double Vnow = m_mix->volume();
78 if (n == 0) {
79 V2 = Vnow;
80 P2 = Pnow;
81 } else if (n == 1) {
82 V1 = Vnow;
83 P1 = Pnow;
84 } else {
85 P2 = P1;
86 V2 = V1;
87 P1 = Pnow;
88 V1 = Vnow;
89 }
90
91 double Verr = fabs((Vtarget - Vnow)/Vtarget);
92 if (Verr < err) {
93 return iSuccess;
94 }
95 double Pnew;
96 // find dV/dP
97 if (n > 1) {
98 double dVdP = (V2 - V1) / (P2 - P1);
99 if (dVdP == 0.0) {
100 throw CanteraError("vcs_MultiPhase::equilibrate_TV",
101 "dVdP == 0.0");
102 } else {
103 Pnew = Pnow + (Vtarget - Vnow) / dVdP;
104 if (Pnew < 0.2 * Pnow) {
105 Pnew = 0.2 * Pnow;
106 }
107 if (Pnew > 3.0 * Pnow) {
108 Pnew = 3.0 * Pnow;
109 }
110 }
111 } else {
112 m_mix->setPressure(Pnow*1.01);
113 double dVdP = (m_mix->volume() - Vnow)/(0.01*Pnow);
114 Pnew = Pnow + 0.5*(Vtarget - Vnow)/dVdP;
115 if (Pnew < 0.5* Pnow) {
116 Pnew = 0.5 * Pnow;
117 }
118 if (Pnew > 1.7 * Pnow) {
119 Pnew = 1.7 * Pnow;
120 }
121 }
122 m_mix->setPressure(Pnew);
123 }
124 throw CanteraError("vcs_MultiPhase::equilibrate_TV",
125 "No convergence for V");
126}
127
129 int XY, double Tlow, double Thigh,
130 int estimateEquil,
131 int printLvl, doublereal err,
132 int maxsteps, int loglevel)
133{
134 int maxiter = 100;
135 int iSuccess;
136 if (XY != HP && XY != UP) {
137 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_HP",
138 "Wrong XP", XY);
139 }
140 int strt = estimateEquil;
141
142 // Lower bound on T. This will change as we progress in the calculation
143 if (Tlow <= 0.0) {
144 Tlow = 0.5 * m_mix->minTemp();
145 }
146 // Upper bound on T. This will change as we progress in the calculation
147 if (Thigh <= 0.0 || Thigh > 1.0E6) {
148 Thigh = 2.0 * m_mix->maxTemp();
149 }
150
151 doublereal cpb = 1.0;
152 doublereal Hlow = Undef;
153 doublereal Hhigh = Undef;
154 doublereal Tnow = m_mix->temperature();
155 int printLvlSub = std::max(printLvl - 1, 0);
156
157 for (int n = 0; n < maxiter; n++) {
158 // start with a loose error tolerance, but tighten it as we get
159 // close to the final temperature
160 try {
161 Tnow = m_mix->temperature();
162 iSuccess = equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
163 strt = 0;
164 double Hnow = (XY == UP) ? m_mix->IntEnergy() : m_mix->enthalpy();
165 double pmoles[10];
166 pmoles[0] = m_mix->phaseMoles(0);
167 double Tmoles = pmoles[0];
168 double HperMole = Hnow/Tmoles;
169 if (printLvl > 0) {
170 plogf("T = %g, Hnow = %g ,Tmoles = %g, HperMole = %g\n",
171 Tnow, Hnow, Tmoles, HperMole);
172 }
173
174 // the equilibrium enthalpy monotonically increases with T;
175 // if the current value is below the target, then we know the
176 // current temperature is too low. Set the lower bounds.
177 if (Hnow < Htarget) {
178 if (Tnow > Tlow) {
179 Tlow = Tnow;
180 Hlow = Hnow;
181 }
182 } else {
183 // the current enthalpy is greater than the target; therefore
184 // the current temperature is too high. Set the high bounds.
185 if (Tnow < Thigh) {
186 Thigh = Tnow;
187 Hhigh = Hnow;
188 }
189 }
190 double dT;
191 if (Hlow != Undef && Hhigh != Undef) {
192 cpb = (Hhigh - Hlow)/(Thigh - Tlow);
193 dT = (Htarget - Hnow)/cpb;
194 double dTa = fabs(dT);
195 double dTmax = 0.5*fabs(Thigh - Tlow);
196 if (dTa > dTmax) {
197 dT *= dTmax/dTa;
198 }
199 } else {
200 double Tnew = sqrt(Tlow*Thigh);
201 dT = clip(Tnew - Tnow, -200.0, 200.0);
202 }
203 double acpb = std::max(fabs(cpb), 1.0E-6);
204 double denom = std::max(fabs(Htarget), acpb);
205 double Herr = Htarget - Hnow;
206 double HConvErr = fabs((Herr)/denom);
207 if (printLvl > 0) {
208 plogf(" equilibrate_HP: It = %d, Tcurr = %g Hcurr = %g, Htarget = %g\n",
209 n, Tnow, Hnow, Htarget);
210 plogf(" H rel error = %g, cp = %g, HConvErr = %g\n",
211 Herr, cpb, HConvErr);
212 }
213
214 if (HConvErr < err) { // || dTa < 1.0e-4) {
215 if (printLvl > 0) {
216 plogf(" equilibrate_HP: CONVERGENCE: Hfinal = %g Tfinal = %g, Its = %d \n",
217 Hnow, Tnow, n);
218 plogf(" H rel error = %g, cp = %g, HConvErr = %g\n",
219 Herr, cpb, HConvErr);
220 }
221 return iSuccess;
222 }
223 double Tnew = Tnow + dT;
224 if (Tnew < 0.0) {
225 Tnew = 0.5*Tnow;
226 }
227 m_mix->setTemperature(Tnew);
228 } catch (const CanteraError&) {
229 if (!estimateEquil) {
230 strt = -1;
231 } else {
232 double Tnew = 0.5*(Tnow + Thigh);
233 if (fabs(Tnew - Tnow) < 1.0) {
234 Tnew = Tnow + 1.0;
235 }
236 m_mix->setTemperature(Tnew);
237 }
238 }
239 }
240 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_HP",
241 "No convergence for T");
242}
243
245 double Tlow, double Thigh,
246 int estimateEquil,
247 int printLvl, doublereal err,
248 int maxsteps, int loglevel)
249{
250 int maxiter = 100;
251 int strt = estimateEquil;
252
253 // Lower bound on T. This will change as we progress in the calculation
254 if (Tlow <= 0.0) {
255 Tlow = 0.5 * m_mix->minTemp();
256 }
257 // Upper bound on T. This will change as we progress in the calculation
258 if (Thigh <= 0.0 || Thigh > 1.0E6) {
259 Thigh = 2.0 * m_mix->maxTemp();
260 }
261
262 doublereal cpb = 1.0, dT;
263 doublereal Slow = Undef;
264 doublereal Shigh = Undef;
265 doublereal Tnow = m_mix->temperature();
266 Tlow = std::min(Tnow, Tlow);
267 Thigh = std::max(Tnow, Thigh);
268 int printLvlSub = std::max(printLvl - 1, 0);
269
270 for (int n = 0; n < maxiter; n++) {
271 // start with a loose error tolerance, but tighten it as we get
272 // close to the final temperature
273 try {
274 Tnow = m_mix->temperature();
275 int iSuccess = equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
276 strt = 0;
277 double Snow = m_mix->entropy();
278 double pmoles[10];
279 pmoles[0] = m_mix->phaseMoles(0);
280 double Tmoles = pmoles[0];
281 double SperMole = Snow/Tmoles;
282 if (printLvl > 0) {
283 plogf("T = %g, Snow = %g ,Tmoles = %g, SperMole = %g\n",
284 Tnow, Snow, Tmoles, SperMole);
285 }
286
287 // the equilibrium entropy monotonically increases with T;
288 // if the current value is below the target, then we know the
289 // current temperature is too low. Set the lower bounds to the
290 // current condition.
291 if (Snow < Starget) {
292 if (Tnow > Tlow) {
293 Tlow = Tnow;
294 Slow = Snow;
295 } else {
296 if (Slow > Starget && Snow < Slow) {
297 Thigh = Tlow;
298 Shigh = Slow;
299 Tlow = Tnow;
300 Slow = Snow;
301 }
302 }
303 } else {
304 // the current enthalpy is greater than the target; therefore
305 // the current temperature is too high. Set the high bounds.
306 if (Tnow < Thigh) {
307 Thigh = Tnow;
308 Shigh = Snow;
309 }
310 }
311 if (Slow != Undef && Shigh != Undef) {
312 cpb = (Shigh - Slow)/(Thigh - Tlow);
313 dT = (Starget - Snow)/cpb;
314 double Tnew = Tnow + dT;
315 double dTa = fabs(dT);
316 double dTmax = 0.5*fabs(Thigh - Tlow);
317 if (Tnew > Thigh || Tnew < Tlow) {
318 dTmax = 1.5*fabs(Thigh - Tlow);
319 }
320 dTmax = std::min(dTmax, 300.);
321 if (dTa > dTmax) {
322 dT *= dTmax/dTa;
323 }
324 } else {
325 double Tnew = sqrt(Tlow*Thigh);
326 dT = Tnew - Tnow;
327 }
328
329 double acpb = std::max(fabs(cpb), 1.0E-6);
330 double denom = std::max(fabs(Starget), acpb);
331 double Serr = Starget - Snow;
332 double SConvErr = fabs((Serr)/denom);
333 if (printLvl > 0) {
334 plogf(" equilibrate_SP: It = %d, Tcurr = %g Scurr = %g, Starget = %g\n",
335 n, Tnow, Snow, Starget);
336 plogf(" S rel error = %g, cp = %g, SConvErr = %g\n",
337 Serr, cpb, SConvErr);
338 }
339
340 if (SConvErr < err) { // || dTa < 1.0e-4) {
341 if (printLvl > 0) {
342 plogf(" equilibrate_SP: CONVERGENCE: Sfinal = %g Tfinal = %g, Its = %d \n",
343 Snow, Tnow, n);
344 plogf(" S rel error = %g, cp = %g, HConvErr = %g\n",
345 Serr, cpb, SConvErr);
346 }
347 return iSuccess;
348 }
349 double Tnew = Tnow + dT;
350 if (Tnew < 0.0) {
351 Tnew = 0.5*Tnow;
352 }
353 m_mix->setTemperature(Tnew);
354 } catch (const CanteraError&) {
355 if (!estimateEquil) {
356 strt = -1;
357 } else {
358 double Tnew = 0.5*(Tnow + Thigh);
359 if (fabs(Tnew - Tnow) < 1.0) {
360 Tnew = Tnow + 1.0;
361 }
362 m_mix->setTemperature(Tnew);
363 }
364 }
365 }
366 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_SP",
367 "No convergence for T");
368}
369
370int vcs_MultiPhaseEquil::equilibrate(int XY, int estimateEquil,
371 int printLvl, doublereal err,
372 int maxsteps, int loglevel)
373{
374 doublereal xtarget;
375 if (XY == TP) {
376 return equilibrate_TP(estimateEquil, printLvl, err, maxsteps, loglevel);
377 } else if (XY == HP || XY == UP) {
378 if (XY == HP) {
379 xtarget = m_mix->enthalpy();
380 } else {
381 xtarget = m_mix->IntEnergy();
382 }
383 double Tlow = 0.5 * m_mix->minTemp();
384 double Thigh = 2.0 * m_mix->maxTemp();
385 return equilibrate_HP(xtarget, XY, Tlow, Thigh,
386 estimateEquil, printLvl, err, maxsteps, loglevel);
387 } else if (XY == SP) {
388 xtarget = m_mix->entropy();
389 double Tlow = 0.5 * m_mix->minTemp();
390 double Thigh = 2.0 * m_mix->maxTemp();
391 return equilibrate_SP(xtarget, Tlow, Thigh,
392 estimateEquil, printLvl, err, maxsteps, loglevel);
393 } else if (XY == TV) {
394 xtarget = m_mix->temperature();
395 return equilibrate_TV(XY, xtarget,
396 estimateEquil, printLvl, err, maxsteps, loglevel);
397 } else if (XY == HV) {
398 xtarget = m_mix->enthalpy();
399 return equilibrate_TV(XY, xtarget,
400 estimateEquil, printLvl, err, maxsteps, loglevel);
401 } else if (XY == UV) {
402 xtarget = m_mix->IntEnergy();
403 return equilibrate_TV(XY, xtarget,
404 estimateEquil, printLvl, err, maxsteps, loglevel);
405 } else if (XY == SV) {
406 xtarget = m_mix->entropy();
407 return equilibrate_TV(XY, xtarget, estimateEquil,
408 printLvl, err, maxsteps, loglevel);
409 } else {
410 throw CanteraError("vcs_MultiPhaseEquil::equilibrate",
411 "Unsupported Option");
412 }
413}
414
416 int printLvl, doublereal err,
417 int maxsteps, int loglevel)
418{
419 int maxit = maxsteps;
420 clockWC tickTock;
421 m_printLvl = printLvl;
422 m_vsolve.m_printLvl = printLvl;
423 m_vsolve.m_doEstimateEquil = estimateEquil;
424
425 // Check obvious bounds on the temperature and pressure NOTE, we may want to
426 // do more here with the real bounds given by the ThermoPhase objects.
427 if (m_mix->temperature() <= 0.0) {
428 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_TP",
429 "Temperature less than zero on input");
430 }
431 if (m_mix->pressure() <= 0.0) {
432 throw CanteraError("vcs_MultiPhaseEquil::equilibrate_TP",
433 "Pressure less than zero on input");
434 }
435
436 //! Call the thermo Program
437 int ip1 = m_printLvl;
438 int ipr = std::max(0, m_printLvl-1);
439 if (m_printLvl >= 3) {
440 ip1 = m_printLvl - 2;
441 } else {
442 ip1 = 0;
443 }
444 int iSuccess = m_vsolve.vcs(ipr, ip1, maxit);
445
446 double te = tickTock.secondsWC();
447 if (printLvl > 0) {
448 vector_fp mu(m_mix->nSpecies());
449 m_mix->getChemPotentials(mu.data());
450 plogf("\n Results from vcs:\n");
451 if (iSuccess != 0) {
452 plogf("\nVCS FAILED TO CONVERGE!\n");
453 }
454 plogf("\n");
455 plogf("Temperature = %g Kelvin\n", m_vsolve.m_temperature);
456 plogf("Pressure = %g Pa\n", m_vsolve.m_pressurePA);
457 plogf("\n");
458 plogf("----------------------------------------"
459 "---------------------\n");
460 plogf(" Name Mole_Number(kmol)");
461 plogf(" Mole_Fraction Chem_Potential (J/kmol)\n");
462 plogf("--------------------------------------------------"
463 "-----------\n");
464 for (size_t i = 0; i < m_mix->nSpecies(); i++) {
465 plogf("%-12s", m_mix->speciesName(i));
467 plogf(" %15.3e %15.3e ", 0.0, m_mix->moleFraction(i));
468 plogf("%15.3e\n", mu[i]);
469 } else {
470 plogf(" %15.3e %15.3e ", m_mix->speciesMoles(i), m_mix->moleFraction(i));
471 if (m_mix->speciesMoles(i) <= 0.0) {
472 size_t iph = m_vsolve.m_phaseID[i];
473 vcs_VolPhase* VPhase = m_vsolve.m_VolPhaseList[iph].get();
474 if (VPhase->nSpecies() > 1) {
475 plogf(" -1.000e+300\n");
476 } else {
477 plogf("%15.3e\n", mu[i]);
478 }
479 } else {
480 plogf("%15.3e\n", mu[i]);
481 }
482 }
483 }
484 plogf("------------------------------------------"
485 "-------------------\n");
486 if (printLvl > 2 && m_vsolve.m_timing_print_lvl > 0) {
487 plogf("Total time = %12.6e seconds\n", te);
488 }
489 }
490 return iSuccess;
491}
492
493void vcs_MultiPhaseEquil::reportCSV(const std::string& reportFile)
494{
495 size_t nphase = m_vsolve.m_numPhases;
496
497 FILE* FP = fopen(reportFile.c_str(), "w");
498 if (!FP) {
499 throw CanteraError("vcs_MultiPhaseEquil::reportCSV",
500 "Failure to open file");
501 }
502 vector_fp VolPM;
503 vector_fp activity;
504 vector_fp ac;
505 vector_fp mu;
506 vector_fp mu0;
507 vector_fp molalities;
508
509 double vol = 0.0;
510 for (size_t iphase = 0; iphase < nphase; iphase++) {
511 ThermoPhase& tref = m_mix->phase(iphase);
512 size_t nSpecies = tref.nSpecies();
513 VolPM.resize(nSpecies, 0.0);
514 tref.getPartialMolarVolumes(&VolPM[0]);
515 vcs_VolPhase* volP = m_vsolve.m_VolPhaseList[iphase].get();
516
517 double TMolesPhase = volP->totalMoles();
518 double VolPhaseVolumes = 0.0;
519 for (size_t k = 0; k < nSpecies; k++) {
520 VolPhaseVolumes += VolPM[k] * tref.moleFraction(k);
521 }
522 VolPhaseVolumes *= TMolesPhase;
523 vol += VolPhaseVolumes;
524 }
525
526 fprintf(FP,"--------------------- VCS_MULTIPHASE_EQUIL FINAL REPORT"
527 " -----------------------------\n");
528 fprintf(FP,"Temperature = %11.5g kelvin\n", m_mix->temperature());
529 fprintf(FP,"Pressure = %11.5g Pascal\n", m_mix->pressure());
530 fprintf(FP,"Total Volume = %11.5g m**3\n", vol);
531 fprintf(FP,"Number Basis optimizations = %d\n", m_vsolve.m_VCount->Basis_Opts);
532 fprintf(FP,"Number VCS iterations = %d\n", m_vsolve.m_VCount->Its);
533
534 for (size_t iphase = 0; iphase < nphase; iphase++) {
535 ThermoPhase& tref = m_mix->phase(iphase);
536 string phaseName = tref.name();
537 vcs_VolPhase* volP = m_vsolve.m_VolPhaseList[iphase].get();
538 double TMolesPhase = volP->totalMoles();
539 size_t nSpecies = tref.nSpecies();
540 activity.resize(nSpecies, 0.0);
541 ac.resize(nSpecies, 0.0);
542 mu0.resize(nSpecies, 0.0);
543 mu.resize(nSpecies, 0.0);
544 VolPM.resize(nSpecies, 0.0);
545 molalities.resize(nSpecies, 0.0);
546 int actConvention = tref.activityConvention();
547 tref.getActivities(&activity[0]);
548 tref.getActivityCoefficients(&ac[0]);
549 tref.getStandardChemPotentials(&mu0[0]);
550 tref.getPartialMolarVolumes(&VolPM[0]);
551 tref.getChemPotentials(&mu[0]);
552 double VolPhaseVolumes = 0.0;
553 for (size_t k = 0; k < nSpecies; k++) {
554 VolPhaseVolumes += VolPM[k] * tref.moleFraction(k);
555 }
556 VolPhaseVolumes *= TMolesPhase;
557 vol += VolPhaseVolumes;
558
559 if (actConvention == 1) {
560 MolalityVPSSTP* mTP = static_cast<MolalityVPSSTP*>(&tref);
561 mTP->getMolalities(&molalities[0]);
562 tref.getChemPotentials(&mu[0]);
563
564 if (iphase == 0) {
565 fprintf(FP," Name, Phase, PhaseMoles, Mole_Fract, "
566 "Molalities, ActCoeff, Activity,"
567 "ChemPot_SS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
568
569 fprintf(FP," , , (kmol), , "
570 " , , ,"
571 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
572 }
573 for (size_t k = 0; k < nSpecies; k++) {
574 std::string sName = tref.speciesName(k);
575 fprintf(FP,"%12s, %11s, %11.3e, %11.3e, %11.3e, %11.3e, %11.3e,"
576 "%11.3e, %11.3e, %11.3e, %11.3e, %11.3e\n",
577 sName.c_str(),
578 phaseName.c_str(), TMolesPhase,
579 tref.moleFraction(k), molalities[k], ac[k], activity[k],
580 mu0[k]*1.0E-6, mu[k]*1.0E-6,
581 tref.moleFraction(k) * TMolesPhase,
582 VolPM[k], VolPhaseVolumes);
583 }
584 } else {
585 if (iphase == 0) {
586 fprintf(FP," Name, Phase, PhaseMoles, Mole_Fract, "
587 "Molalities, ActCoeff, Activity,"
588 " ChemPotSS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
589
590 fprintf(FP," , , (kmol), , "
591 " , , ,"
592 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
593 }
594 for (size_t k = 0; k < nSpecies; k++) {
595 molalities[k] = 0.0;
596 }
597 for (size_t k = 0; k < nSpecies; k++) {
598 std::string sName = tref.speciesName(k);
599 fprintf(FP,"%12s, %11s, %11.3e, %11.3e, %11.3e, %11.3e, %11.3e, "
600 "%11.3e, %11.3e,% 11.3e, %11.3e, %11.3e\n",
601 sName.c_str(),
602 phaseName.c_str(), TMolesPhase,
603 tref.moleFraction(k), molalities[k], ac[k],
604 activity[k], mu0[k]*1.0E-6, mu[k]*1.0E-6,
605 tref.moleFraction(k) * TMolesPhase,
606 VolPM[k], VolPhaseVolumes);
607 }
608 }
609 }
610 fclose(FP);
611}
612
613}
ThermoPhase object for the ideal molal equation of state (see Thermodynamic Properties and class Idea...
Header file for an ideal solid solution model with incompressible thermodynamics (see Thermodynamic P...
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
void getMolalities(doublereal *const molal) const
This function will return the molalities of the species.
A class for multiphase mixtures.
Definition: MultiPhase.h:60
doublereal maxTemp() const
Maximum temperature for which all solution phases have valid thermo data.
Definition: MultiPhase.h:256
doublereal minTemp() const
Minimum temperature for which all solution phases have valid thermo data.
Definition: MultiPhase.h:249
size_t nSpecies() const
Number of species, summed over all phases.
Definition: MultiPhase.h:126
doublereal pressure() const
Pressure [Pa].
Definition: MultiPhase.h:391
doublereal enthalpy() const
The enthalpy of the mixture [J].
Definition: MultiPhase.cpp:294
doublereal speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
Definition: MultiPhase.cpp:186
doublereal IntEnergy() const
The internal energy of the mixture [J].
Definition: MultiPhase.cpp:306
doublereal moleFraction(const size_t kGlob) const
Returns the mole fraction of global species k.
Definition: MultiPhase.cpp:806
doublereal phaseMoles(const size_t n) const
Return the number of moles in phase n.
Definition: MultiPhase.cpp:791
std::string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
Definition: MultiPhase.cpp:761
void setPressure(doublereal P)
Set the pressure [Pa].
Definition: MultiPhase.h:406
doublereal entropy() const
The entropy of the mixture [J/K].
Definition: MultiPhase.cpp:318
doublereal volume() const
The total mixture volume [m^3].
Definition: MultiPhase.cpp:474
doublereal temperature() const
Temperature [K].
Definition: MultiPhase.h:331
void getChemPotentials(doublereal *mu) const
Returns a vector of Chemical potentials.
Definition: MultiPhase.cpp:243
ThermoPhase & phase(size_t n)
Return a reference to phase n.
Definition: MultiPhase.cpp:161
void setTemperature(const doublereal T)
Set the temperature [K].
Definition: MultiPhase.cpp:709
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:70
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:273
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:200
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:548
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:102
virtual void getActivities(doublereal *a) const
Get the array of non-dimensional activities at the current solution temperature, pressure,...
Definition: ThermoPhase.cpp:77
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: ThermoPhase.h:495
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
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: ThermoPhase.h:562
virtual int activityConvention() const
This method returns the convention used in specification of the activities, of which there are curren...
Definition: ThermoPhase.cpp:56
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
Definition: ThermoPhase.h:580
int Its
Current number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
Definition: vcs_internal.h:41
int Basis_Opts
number of optimizations of the components basis set done
Definition: vcs_internal.h:47
size_t m_numPhases
Number of Phases in the problem.
Definition: vcs_solve.h:1069
int m_doEstimateEquil
Setting for whether to do an initial estimate.
Definition: vcs_solve.h:1146
vector_int m_speciesUnknownType
Specifies the species unknown type.
Definition: vcs_solve.h:1166
int m_timing_print_lvl
printing level of timing information
Definition: vcs_solve.h:1506
std::vector< size_t > m_phaseID
Mapping from the species number to the phase number.
Definition: vcs_solve.h:1358
VCS_COUNTERS * m_VCount
Timing and iteration counters for the vcs object.
Definition: vcs_solve.h:1485
int vcs(int ipr, int ip1, int maxit)
Solve an equilibrium problem.
Definition: vcs_solve.cpp:492
double m_pressurePA
Pressure.
Definition: vcs_solve.h:1274
std::vector< std::unique_ptr< vcs_VolPhase > > m_VolPhaseList
Array of Phase Structures. Length = number of phases.
Definition: vcs_solve.h:1395
int m_printLvl
Print level for print routines.
Definition: vcs_solve.h:985
double m_temperature
Temperature (Kelvin)
Definition: vcs_solve.h:1271
The class provides the wall clock timer in seconds.
Definition: clockWC.h:45
double secondsWC()
Returns the wall clock time in seconds since the last reset.
Definition: clockWC.cpp:32
VCS_SOLVE m_vsolve
The object that contains the problem statement and does all of the equilibration work.
int equilibrate_HP(doublereal Htarget, int XY, double Tlow, double Thigh, int estimateEquil=0, int printLvl=0, doublereal err=1.0E-6, int maxsteps=VCS_MAXSTEPS, int loglevel=-99)
Equilibrate the solution using the current element abundances stored in the MultiPhase object using e...
void reportCSV(const std::string &reportFile)
Report the equilibrium answer in a comma separated table format.
vcs_MultiPhaseEquil(MultiPhase *mix, int printLvl)
Constructor for the multiphase equilibrium solver.
int equilibrate_TP(int estimateEquil=0, int printLvl=0, doublereal err=1.0e-6, int maxsteps=VCS_MAXSTEPS, int loglevel=-99)
Equilibrate the solution using the current element abundances stored in the MultiPhase object using c...
int equilibrate_SP(doublereal Starget, double Tlow, double Thigh, int estimateEquil=0, int printLvl=0, doublereal err=1.0E-6, int maxsteps=VCS_MAXSTEPS, int loglevel=-99)
Equilibrate the solution using the current element abundances stored in the MultiPhase object using c...
int equilibrate(int XY, int estimateEquil=0, int printLvl=0, doublereal err=1.0e-6, int maxsteps=VCS_MAXSTEPS, int loglevel=-99)
Equilibrate the solution using the current element abundances stored in the MultiPhase object.
int m_printLvl
Print level from the VCSnonlinear package.
int equilibrate_TV(int XY, doublereal xtarget, int estimateEquil=0, int printLvl=0, doublereal err=1.0E-6, int maxsteps=VCS_MAXSTEPS, int logLevel=-99)
Equilibrate the solution using the current element abundances stored in the MultiPhase object using c...
MultiPhase * m_mix
Pointer to the MultiPhase mixture that will be equilibrated.
Phase information and Phase calculations for vcs.
Definition: vcs_VolPhase.h:78
size_t nSpecies() const
Return the number of species in the phase.
double totalMoles() const
Return the total moles in the phase.
Declarations for a simple class that implements an Ansi C wall clock timer (see Cantera::clockWC).
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
const double Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
Definition: ct_defs.h:161
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
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
Definition: global.h:356
Contains const definitions for types of species reference-state thermodynamics managers (see Species ...
Contains declarations for string manipulation functions within Cantera.
Interface class for the vcsnonlinear solver.
Header for the object representing each phase within vcs.
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
Unknown refers to the voltage level of a phase.
Definition: vcs_defs.h:293
#define plogf
define this Cantera function to replace printf
Definition: vcs_internal.h:18