Cantera  2.4.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 http://www.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 (CanteraError err) {
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("MultiPhase::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 (CanteraError err) {
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("MultiPhase::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",
429  "Temperature less than zero on input");
430  }
431  if (m_mix->pressure() <= 0.0) {
432  throw CanteraError("vcs_MultiPhaseEquil::equilibrate",
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 }
std::vector< size_t > m_phaseID
Mapping from the species number to the phase number.
Definition: vcs_solve.h:1357
ThermoPhase object for the ideal molal equation of state (see Thermodynamic Properties and class Idea...
int Its
Current number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
Definition: vcs_internal.h:44
vector_int m_speciesUnknownType
Specifies the species unknown type.
Definition: vcs_solve.h:1165
int Basis_Opts
number of optimizations of the components basis set done
Definition: vcs_internal.h:50
int vcs(int ipr, int ip1, int maxit)
Solve an equilibrium problem.
Definition: vcs_solve.cpp:487
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...
VCS_COUNTERS * m_VCount
Timing and iteration counters for the vcs object.
Definition: vcs_solve.h:1484
MultiPhase * m_mix
Pointer to the MultiPhase mixture that will be equilibrated.
Declarations for a simple class that implements an Ansi C wall clock timer (see Cantera::clockWC).
doublereal speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
Definition: MultiPhase.cpp:184
doublereal temperature() const
Temperature [K].
Definition: MultiPhase.h:329
doublereal moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:471
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: ThermoPhase.h:461
size_t nSpecies() const
Number of species, summed over all phases.
Definition: MultiPhase.h:124
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...
int m_printLvl
Print level from the VCSnonlinear package.
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
Definition: global.h:269
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:266
STL namespace.
doublereal volume() const
The total mixture volume [m^3].
Definition: MultiPhase.cpp:472
The class provides the wall clock timer in seconds.
Definition: clockWC.h:44
doublereal pressure() const
Pressure [Pa].
Definition: MultiPhase.h:389
std::vector< std::unique_ptr< vcs_VolPhase > > m_VolPhaseList
Array of Phase Structures. Length = number of phases.
Definition: vcs_solve.h:1394
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: ThermoPhase.h:528
void reportCSV(const std::string &reportFile)
Report the equilibrium answer in a comma separated table format.
const doublereal Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
Definition: ct_defs.h:134
virtual void getActivities(doublereal *a) const
Get the array of non-dimensional activities at the current solution temperature, pressure, and solution concentration.
Definition: ThermoPhase.cpp:70
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
Contains const definitions for types of species reference-state thermodynamics managers (see Species ...
Header for the object representing each phase within vcs.
int m_doEstimateEquil
Setting for whether to do an initial estimate.
Definition: vcs_solve.h:1145
A class for multiphase mixtures.
Definition: MultiPhase.h:57
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...
void getMolalities(doublereal *const molal) const
This function will return the molalities of the species.
doublereal moleFraction(const size_t kGlob) const
Returns the mole fraction of global species k.
Definition: MultiPhase.cpp:805
double secondsWC()
Returns the wall clock time in seconds since the last reset.
Definition: clockWC.cpp:32
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:191
Header file for an ideal solid solution model with incompressible thermodynamics (see Thermodynamic P...
doublereal maxTemp() const
Maximum temperature for which all solution phases have valid thermo data.
Definition: MultiPhase.h:254
virtual int activityConvention() const
This method returns the convention used in specification of the activities, of which there are curren...
Definition: ThermoPhase.cpp:55
void setTemperature(const doublereal T)
Set the temperature [K].
Definition: MultiPhase.cpp:707
size_t nSpecies() const
Return the number of species in the phase.
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
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...
void getChemPotentials(doublereal *mu) const
Returns a vector of Chemical potentials.
Definition: MultiPhase.cpp:241
int m_timing_print_lvl
printing level of timing information
Definition: vcs_solve.h:1505
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
Definition: ThermoPhase.h:420
int m_printLvl
Print level for print routines.
Definition: vcs_solve.h:984
double totalMoles() const
Return the total moles in the phase.
void setPressure(doublereal P)
Set the pressure [Pa].
Definition: MultiPhase.h:404
double m_temperature
Temperature (Kelvin)
Definition: vcs_solve.h:1270
Interface class for the vcsnonlinear solver.
Phase information and Phase calculations for vcs.
Definition: vcs_VolPhase.h:81
VCS_SOLVE m_vsolve
The object that contains the problem statement and does all of the equilibration work.
doublereal entropy() const
The entropy of the mixture [J/K].
Definition: MultiPhase.cpp:316
double m_pressurePA
Pressure.
Definition: vcs_solve.h:1273
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:157
doublereal minTemp() const
Minimum temperature for which all solution phases have valid thermo data.
Definition: MultiPhase.h:247
doublereal IntEnergy() const
The internal energy of the mixture [J].
Definition: MultiPhase.cpp:304
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:78
Contains declarations for string manipulation functions within Cantera.
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:546
#define plogf
define this Cantera function to replace printf
Definition: vcs_internal.h:18
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
Unknown refers to the voltage level of a phase.
Definition: vcs_defs.h:289
thermo_t & phase(size_t n)
Return a reference to phase n.
Definition: MultiPhase.cpp:159
doublereal phaseMoles(const size_t n) const
Return the number of moles in phase n.
Definition: MultiPhase.cpp:790
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:8
size_t m_numPhases
Number of Phases in the problem.
Definition: vcs_solve.h:1068
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...
doublereal enthalpy() const
The enthalpy of the mixture [J].
Definition: MultiPhase.cpp:292
std::string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
Definition: MultiPhase.cpp:759