Cantera  2.5.1
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 
12 #include "cantera/base/clockWC.h"
17 
18 #include <cstdio>
19 
20 using namespace std;
21 
22 namespace Cantera
23 {
24 vcs_MultiPhaseEquil::vcs_MultiPhaseEquil(MultiPhase* mix, int printLvl) :
25  m_mix(mix),
26  m_printLvl(printLvl),
27  m_vsolve(mix, printLvl)
28 {
29 }
30 
31 int 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 
128 int vcs_MultiPhaseEquil::equilibrate_HP(doublereal Htarget,
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 
244 int vcs_MultiPhaseEquil::equilibrate_SP(doublereal Starget,
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 
370 int 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 
493 void 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:58
doublereal maxTemp() const
Maximum temperature for which all solution phases have valid thermo data.
Definition: MultiPhase.h:254
doublereal minTemp() const
Minimum temperature for which all solution phases have valid thermo data.
Definition: MultiPhase.h:247
size_t nSpecies() const
Number of species, summed over all phases.
Definition: MultiPhase.h:124
doublereal pressure() const
Pressure [Pa].
Definition: MultiPhase.h:389
doublereal enthalpy() const
The enthalpy of the mixture [J].
Definition: MultiPhase.cpp:292
doublereal speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
Definition: MultiPhase.cpp:184
doublereal IntEnergy() const
The internal energy of the mixture [J].
Definition: MultiPhase.cpp:304
doublereal moleFraction(const size_t kGlob) const
Returns the mole fraction of global species k.
Definition: MultiPhase.cpp:805
doublereal phaseMoles(const size_t n) const
Return the number of moles in phase n.
Definition: MultiPhase.cpp:790
std::string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
Definition: MultiPhase.cpp:759
void setPressure(doublereal P)
Set the pressure [Pa].
Definition: MultiPhase.h:404
doublereal entropy() const
The entropy of the mixture [J/K].
Definition: MultiPhase.cpp:316
doublereal volume() const
The total mixture volume [m^3].
Definition: MultiPhase.cpp:472
doublereal temperature() const
Temperature [K].
Definition: MultiPhase.h:329
void getChemPotentials(doublereal *mu) const
Returns a vector of Chemical potentials.
Definition: MultiPhase.cpp:241
thermo_t & phase(size_t n)
Return a reference to phase n.
Definition: MultiPhase.cpp:159
void setTemperature(const doublereal T)
Set the temperature [K].
Definition: MultiPhase.cpp:707
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:84
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:285
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:229
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:577
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:75
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: ThermoPhase.h:489
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
Definition: ThermoPhase.h:448
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: ThermoPhase.h:556
virtual int activityConvention() const
This method returns the convention used in specification of the activities, of which there are curren...
Definition: ThermoPhase.cpp:54
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:574
int Its
Current number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
Definition: vcs_internal.h:44
int Basis_Opts
number of optimizations of the components basis set done
Definition: vcs_internal.h:50
size_t m_numPhases
Number of Phases in the problem.
Definition: vcs_solve.h:1068
int m_doEstimateEquil
Setting for whether to do an initial estimate.
Definition: vcs_solve.h:1145
vector_int m_speciesUnknownType
Specifies the species unknown type.
Definition: vcs_solve.h:1165
int m_timing_print_lvl
printing level of timing information
Definition: vcs_solve.h:1505
std::vector< size_t > m_phaseID
Mapping from the species number to the phase number.
Definition: vcs_solve.h:1357
VCS_COUNTERS * m_VCount
Timing and iteration counters for the vcs object.
Definition: vcs_solve.h:1484
int vcs(int ipr, int ip1, int maxit)
Solve an equilibrium problem.
Definition: vcs_solve.cpp:487
double m_pressurePA
Pressure.
Definition: vcs_solve.h:1273
std::vector< std::unique_ptr< vcs_VolPhase > > m_VolPhaseList
Array of Phase Structures. Length = number of phases.
Definition: vcs_solve.h:1394
int m_printLvl
Print level for print routines.
Definition: vcs_solve.h:984
double m_temperature
Temperature (Kelvin)
Definition: vcs_solve.h:1270
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.
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:82
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).
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
Definition: global.h:300
const double Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
Definition: ct_defs.h:157
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:180
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
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:289
#define plogf
define this Cantera function to replace printf
Definition: vcs_internal.h:18