24 vcs_MultiPhaseEquil::vcs_MultiPhaseEquil(
MultiPhase* mix,
int printLvl) :
27 m_vsolve(mix, printLvl)
33 int printLvl, doublereal err,
34 int maxsteps,
int loglevel)
37 if ((XY != TV) && (XY != HV) && (XY != UV) && (XY != SV)) {
38 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TV",
39 "Wrong XY flag: {}", XY);
46 int strt = estimateEquil;
53 int printLvlSub = std::max(0, printLvl - 1);
54 for (
int n = 0; n < maxiter; n++) {
59 iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
63 printLvlSub, err, maxsteps, loglevel);
67 printLvlSub, err, maxsteps, loglevel);
71 printLvlSub, err, maxsteps, loglevel);
91 double Verr = fabs((Vtarget - Vnow)/Vtarget);
98 double dVdP = (V2 - V1) / (P2 - P1);
103 Pnew = Pnow + (Vtarget - Vnow) / dVdP;
104 if (Pnew < 0.2 * Pnow) {
107 if (Pnew > 3.0 * Pnow) {
113 double dVdP = (
m_mix->
volume() - Vnow)/(0.01*Pnow);
114 Pnew = Pnow + 0.5*(Vtarget - Vnow)/dVdP;
115 if (Pnew < 0.5* Pnow) {
118 if (Pnew > 1.7 * Pnow) {
125 "No convergence for V");
129 int XY,
double Tlow,
double Thigh,
131 int printLvl, doublereal err,
132 int maxsteps,
int loglevel)
136 if (XY != HP && XY != UP) {
137 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_HP",
140 int strt = estimateEquil;
147 if (Thigh <= 0.0 || Thigh > 1.0E6) {
151 doublereal cpb = 1.0;
152 doublereal Hlow =
Undef;
153 doublereal Hhigh =
Undef;
155 int printLvlSub = std::max(printLvl - 1, 0);
157 for (
int n = 0; n < maxiter; n++) {
162 iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
167 double Tmoles = pmoles[0];
168 double HperMole = Hnow/Tmoles;
170 plogf(
"T = %g, Hnow = %g ,Tmoles = %g, HperMole = %g\n",
171 Tnow, Hnow, Tmoles, HperMole);
177 if (Hnow < Htarget) {
192 cpb = (Hhigh - Hlow)/(Thigh - Tlow);
193 dT = (Htarget - Hnow)/cpb;
194 double dTa = fabs(dT);
195 double dTmax = 0.5*fabs(Thigh - Tlow);
200 double Tnew = sqrt(Tlow*Thigh);
201 dT =
clip(Tnew - Tnow, -200.0, 200.0);
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);
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);
214 if (HConvErr < err) {
216 plogf(
" equilibrate_HP: CONVERGENCE: Hfinal = %g Tfinal = %g, Its = %d \n",
218 plogf(
" H rel error = %g, cp = %g, HConvErr = %g\n",
219 Herr, cpb, HConvErr);
223 double Tnew = Tnow + dT;
229 if (!estimateEquil) {
232 double Tnew = 0.5*(Tnow + Thigh);
233 if (fabs(Tnew - Tnow) < 1.0) {
240 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_HP",
241 "No convergence for T");
245 double Tlow,
double Thigh,
247 int printLvl, doublereal err,
248 int maxsteps,
int loglevel)
251 int strt = estimateEquil;
258 if (Thigh <= 0.0 || Thigh > 1.0E6) {
262 doublereal cpb = 1.0, dT;
263 doublereal Slow =
Undef;
264 doublereal Shigh =
Undef;
266 Tlow = std::min(Tnow, Tlow);
267 Thigh = std::max(Tnow, Thigh);
268 int printLvlSub = std::max(printLvl - 1, 0);
270 for (
int n = 0; n < maxiter; n++) {
275 int iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
280 double Tmoles = pmoles[0];
281 double SperMole = Snow/Tmoles;
283 plogf(
"T = %g, Snow = %g ,Tmoles = %g, SperMole = %g\n",
284 Tnow, Snow, Tmoles, SperMole);
291 if (Snow < Starget) {
296 if (Slow > Starget && Snow < Slow) {
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);
320 dTmax = std::min(dTmax, 300.);
325 double Tnew = sqrt(Tlow*Thigh);
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);
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);
340 if (SConvErr < err) {
342 plogf(
" equilibrate_SP: CONVERGENCE: Sfinal = %g Tfinal = %g, Its = %d \n",
344 plogf(
" S rel error = %g, cp = %g, HConvErr = %g\n",
345 Serr, cpb, SConvErr);
349 double Tnew = Tnow + dT;
355 if (!estimateEquil) {
358 double Tnew = 0.5*(Tnow + Thigh);
359 if (fabs(Tnew - Tnow) < 1.0) {
366 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_SP",
367 "No convergence for T");
371 int printLvl, doublereal err,
372 int maxsteps,
int loglevel)
376 return equilibrate_TP(estimateEquil, printLvl, err, maxsteps, loglevel);
377 }
else if (XY == HP || XY == UP) {
386 estimateEquil, printLvl, err, maxsteps, loglevel);
387 }
else if (XY == SP) {
392 estimateEquil, printLvl, err, maxsteps, loglevel);
393 }
else if (XY == TV) {
396 estimateEquil, printLvl, err, maxsteps, loglevel);
397 }
else if (XY == HV) {
400 estimateEquil, printLvl, err, maxsteps, loglevel);
401 }
else if (XY == UV) {
404 estimateEquil, printLvl, err, maxsteps, loglevel);
405 }
else if (XY == SV) {
408 printLvl, err, maxsteps, loglevel);
411 "Unsupported Option");
416 int printLvl, doublereal err,
417 int maxsteps,
int loglevel)
419 int maxit = maxsteps;
428 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TP",
429 "Temperature less than zero on input");
432 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TP",
433 "Pressure less than zero on input");
450 plogf(
"\n Results from vcs:\n");
452 plogf(
"\nVCS FAILED TO CONVERGE!\n");
458 plogf(
"----------------------------------------"
459 "---------------------\n");
460 plogf(
" Name Mole_Number(kmol)");
461 plogf(
" Mole_Fraction Chem_Potential (J/kmol)\n");
462 plogf(
"--------------------------------------------------"
468 plogf(
"%15.3e\n", mu[i]);
475 plogf(
" -1.000e+300\n");
477 plogf(
"%15.3e\n", mu[i]);
480 plogf(
"%15.3e\n", mu[i]);
484 plogf(
"------------------------------------------"
485 "-------------------\n");
487 plogf(
"Total time = %12.6e seconds\n", te);
497 FILE* FP = fopen(reportFile.c_str(),
"w");
500 "Failure to open file");
510 for (
size_t iphase = 0; iphase < nphase; iphase++) {
513 VolPM.resize(nSpecies, 0.0);
518 double VolPhaseVolumes = 0.0;
519 for (
size_t k = 0; k < nSpecies; k++) {
522 VolPhaseVolumes *= TMolesPhase;
523 vol += VolPhaseVolumes;
526 fprintf(FP,
"--------------------- VCS_MULTIPHASE_EQUIL FINAL REPORT"
527 " -----------------------------\n");
530 fprintf(FP,
"Total Volume = %11.5g m**3\n", vol);
534 for (
size_t iphase = 0; iphase < nphase; iphase++) {
536 string phaseName = tref.
name();
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);
552 double VolPhaseVolumes = 0.0;
553 for (
size_t k = 0; k < nSpecies; k++) {
556 VolPhaseVolumes *= TMolesPhase;
557 vol += VolPhaseVolumes;
559 if (actConvention == 1) {
565 fprintf(FP,
" Name, Phase, PhaseMoles, Mole_Fract, "
566 "Molalities, ActCoeff, Activity,"
567 "ChemPot_SS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
569 fprintf(FP,
" , , (kmol), , "
571 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
573 for (
size_t k = 0; k < nSpecies; 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",
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,
582 VolPM[k], VolPhaseVolumes);
586 fprintf(FP,
" Name, Phase, PhaseMoles, Mole_Fract, "
587 "Molalities, ActCoeff, Activity,"
588 " ChemPotSS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
590 fprintf(FP,
" , , (kmol), , "
592 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
594 for (
size_t k = 0; k < nSpecies; k++) {
597 for (
size_t k = 0; k < nSpecies; 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",
602 phaseName.c_str(), TMolesPhase,
604 activity[k], mu0[k]*1.0E-6, mu[k]*1.0E-6,
606 VolPM[k], VolPhaseVolumes);