25 m_vsolve(mix, printLvl)
30 int printLvl,
double err,
31 int maxsteps,
int loglevel)
34 if ((XY != TV) && (XY != HV) && (XY != UV) && (XY != SV)) {
35 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TV",
36 "Wrong XY flag: {}", XY);
43 int strt = estimateEquil;
50 int printLvlSub = std::max(0, printLvl - 1);
51 for (
int n = 0; n < maxiter; n++) {
56 iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
60 printLvlSub, err, maxsteps, loglevel);
64 printLvlSub, err, maxsteps, loglevel);
68 printLvlSub, err, maxsteps, loglevel);
88 double Verr = fabs((Vtarget - Vnow)/Vtarget);
95 double dVdP = (V2 - V1) / (P2 - P1);
100 Pnew = Pnow + (Vtarget - Vnow) / dVdP;
101 if (Pnew < 0.2 * Pnow) {
104 if (Pnew > 3.0 * Pnow) {
110 double dVdP = (
m_mix->
volume() - Vnow)/(0.01*Pnow);
111 Pnew = Pnow + 0.5*(Vtarget - Vnow)/dVdP;
112 if (Pnew < 0.5* Pnow) {
115 if (Pnew > 1.7 * Pnow) {
122 "No convergence for V");
126 double Thigh,
int estimateEquil,
int printLvl,
double err,
int maxsteps,
131 if (XY != HP && XY != UP) {
132 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_HP",
135 int strt = estimateEquil;
142 if (Thigh <= 0.0 || Thigh > 1.0E6) {
148 double Hhigh =
Undef;
150 int printLvlSub = std::max(printLvl - 1, 0);
152 for (
int n = 0; n < maxiter; n++) {
157 iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
162 double Tmoles = pmoles[0];
163 double HperMole = Hnow/Tmoles;
165 plogf(
"T = %g, Hnow = %g ,Tmoles = %g, HperMole = %g\n",
166 Tnow, Hnow, Tmoles, HperMole);
172 if (Hnow < Htarget) {
187 cpb = (Hhigh - Hlow)/(Thigh - Tlow);
188 dT = (Htarget - Hnow)/cpb;
189 double dTa = fabs(dT);
190 double dTmax = 0.5*fabs(Thigh - Tlow);
195 double Tnew = sqrt(Tlow*Thigh);
196 dT =
clip(Tnew - Tnow, -200.0, 200.0);
198 double acpb = std::max(fabs(cpb), 1.0E-6);
199 double denom = std::max(fabs(Htarget), acpb);
200 double Herr = Htarget - Hnow;
201 double HConvErr = fabs((Herr)/denom);
203 plogf(
" equilibrate_HP: It = %d, Tcurr = %g Hcurr = %g, Htarget = %g\n",
204 n, Tnow, Hnow, Htarget);
205 plogf(
" H rel error = %g, cp = %g, HConvErr = %g\n",
206 Herr, cpb, HConvErr);
209 if (HConvErr < err) {
211 plogf(
" equilibrate_HP: CONVERGENCE: Hfinal = %g Tfinal = %g, Its = %d \n",
213 plogf(
" H rel error = %g, cp = %g, HConvErr = %g\n",
214 Herr, cpb, HConvErr);
218 double Tnew = Tnow + dT;
224 if (!estimateEquil) {
227 double Tnew = 0.5*(Tnow + Thigh);
228 if (fabs(Tnew - Tnow) < 1.0) {
235 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_HP",
236 "No convergence for T");
240 int estimateEquil,
int printLvl,
double err,
int maxsteps,
int loglevel)
243 int strt = estimateEquil;
250 if (Thigh <= 0.0 || Thigh > 1.0E6) {
254 double cpb = 1.0, dT;
256 double Shigh =
Undef;
258 Tlow = std::min(Tnow, Tlow);
259 Thigh = std::max(Tnow, Thigh);
260 int printLvlSub = std::max(printLvl - 1, 0);
262 for (
int n = 0; n < maxiter; n++) {
267 int iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
272 double Tmoles = pmoles[0];
273 double SperMole = Snow/Tmoles;
275 plogf(
"T = %g, Snow = %g ,Tmoles = %g, SperMole = %g\n",
276 Tnow, Snow, Tmoles, SperMole);
283 if (Snow < Starget) {
288 if (Slow > Starget && Snow < Slow) {
304 cpb = (Shigh - Slow)/(Thigh - Tlow);
305 dT = (Starget - Snow)/cpb;
306 double Tnew = Tnow + dT;
307 double dTa = fabs(dT);
308 double dTmax = 0.5*fabs(Thigh - Tlow);
309 if (Tnew > Thigh || Tnew < Tlow) {
310 dTmax = 1.5*fabs(Thigh - Tlow);
312 dTmax = std::min(dTmax, 300.);
317 double Tnew = sqrt(Tlow*Thigh);
321 double acpb = std::max(fabs(cpb), 1.0E-6);
322 double denom = std::max(fabs(Starget), acpb);
323 double Serr = Starget - Snow;
324 double SConvErr = fabs((Serr)/denom);
326 plogf(
" equilibrate_SP: It = %d, Tcurr = %g Scurr = %g, Starget = %g\n",
327 n, Tnow, Snow, Starget);
328 plogf(
" S rel error = %g, cp = %g, SConvErr = %g\n",
329 Serr, cpb, SConvErr);
332 if (SConvErr < err) {
334 plogf(
" equilibrate_SP: CONVERGENCE: Sfinal = %g Tfinal = %g, Its = %d \n",
336 plogf(
" S rel error = %g, cp = %g, HConvErr = %g\n",
337 Serr, cpb, SConvErr);
341 double Tnew = Tnow + dT;
347 if (!estimateEquil) {
350 double Tnew = 0.5*(Tnow + Thigh);
351 if (fabs(Tnew - Tnow) < 1.0) {
358 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_SP",
359 "No convergence for T");
363 double err,
int maxsteps,
int loglevel)
367 return equilibrate_TP(estimateEquil, printLvl, err, maxsteps, loglevel);
368 }
else if (XY == HP || XY == UP) {
377 estimateEquil, printLvl, err, maxsteps, loglevel);
378 }
else if (XY == SP) {
383 estimateEquil, printLvl, err, maxsteps, loglevel);
384 }
else if (XY == TV) {
387 estimateEquil, printLvl, err, maxsteps, loglevel);
388 }
else if (XY == HV) {
391 estimateEquil, printLvl, err, maxsteps, loglevel);
392 }
else if (XY == UV) {
395 estimateEquil, printLvl, err, maxsteps, loglevel);
396 }
else if (XY == SV) {
399 printLvl, err, maxsteps, loglevel);
402 "Unsupported Option");
407 int maxsteps,
int loglevel)
409 int maxit = maxsteps;
418 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TP",
419 "Temperature less than zero on input");
422 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TP",
423 "Pressure less than zero on input");
440 plogf(
"\n Results from vcs:\n");
442 plogf(
"\nVCS FAILED TO CONVERGE!\n");
448 plogf(
"----------------------------------------"
449 "---------------------\n");
450 plogf(
" Name Mole_Number(kmol)");
451 plogf(
" Mole_Fraction Chem_Potential (J/kmol)\n");
452 plogf(
"--------------------------------------------------"
458 plogf(
"%15.3e\n", mu[i]);
465 plogf(
" -1.000e+300\n");
467 plogf(
"%15.3e\n", mu[i]);
470 plogf(
"%15.3e\n", mu[i]);
474 plogf(
"------------------------------------------"
475 "-------------------\n");
477 plogf(
"Total time = %12.6e seconds\n", te);
487 FILE* FP = fopen(reportFile.c_str(),
"w");
490 "Failure to open file");
492 vector<double> VolPM;
493 vector<double> activity;
497 vector<double> molalities;
500 for (
size_t iphase = 0; iphase < nphase; iphase++) {
503 VolPM.resize(nSpecies, 0.0);
508 double VolPhaseVolumes = 0.0;
509 for (
size_t k = 0; k < nSpecies; k++) {
512 VolPhaseVolumes *= TMolesPhase;
513 vol += VolPhaseVolumes;
516 fprintf(FP,
"--------------------- VCS_MULTIPHASE_EQUIL FINAL REPORT"
517 " -----------------------------\n");
520 fprintf(FP,
"Total Volume = %11.5g m**3\n", vol);
524 for (
size_t iphase = 0; iphase < nphase; iphase++) {
526 string phaseName = tref.
name();
530 activity.resize(nSpecies, 0.0);
531 ac.resize(nSpecies, 0.0);
532 mu0.resize(nSpecies, 0.0);
533 mu.resize(nSpecies, 0.0);
534 VolPM.resize(nSpecies, 0.0);
535 molalities.resize(nSpecies, 0.0);
542 double VolPhaseVolumes = 0.0;
543 for (
size_t k = 0; k < nSpecies; k++) {
546 VolPhaseVolumes *= TMolesPhase;
547 vol += VolPhaseVolumes;
549 if (actConvention == 1) {
555 fprintf(FP,
" Name, Phase, PhaseMoles, Mole_Fract, "
556 "Molalities, ActCoeff, Activity,"
557 "ChemPot_SS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
559 fprintf(FP,
" , , (kmol), , "
561 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
563 for (
size_t k = 0; k < nSpecies; k++) {
565 fprintf(FP,
"%12s, %11s, %11.3e, %11.3e, %11.3e, %11.3e, %11.3e,"
566 "%11.3e, %11.3e, %11.3e, %11.3e, %11.3e\n",
568 phaseName.c_str(), TMolesPhase,
569 tref.
moleFraction(k), molalities[k], ac[k], activity[k],
570 mu0[k]*1.0E-6, mu[k]*1.0E-6,
572 VolPM[k], VolPhaseVolumes);
576 fprintf(FP,
" Name, Phase, PhaseMoles, Mole_Fract, "
577 "Molalities, ActCoeff, Activity,"
578 " ChemPotSS0, ChemPot, mole_num, PMVol, Phase_Volume\n");
580 fprintf(FP,
" , , (kmol), , "
582 " (J/kmol), (J/kmol), (kmol), (m**3/kmol), (m**3)\n");
584 for (
size_t k = 0; k < nSpecies; k++) {
587 for (
size_t k = 0; k < nSpecies; k++) {
589 fprintf(FP,
"%12s, %11s, %11.3e, %11.3e, %11.3e, %11.3e, %11.3e, "
590 "%11.3e, %11.3e,% 11.3e, %11.3e, %11.3e\n",
592 phaseName.c_str(), TMolesPhase,
594 activity[k], mu0[k]*1.0E-6, mu[k]*1.0E-6,
596 VolPM[k], VolPhaseVolumes);
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.
MolalityVPSSTP is a derived class of ThermoPhase that handles variable pressure standard state method...
void getMolalities(double *const molal) const
This function will return the molalities of the species.
A class for multiphase mixtures.
double speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
size_t nSpecies() const
Number of species, summed over all phases.
double enthalpy() const
The enthalpy of the mixture [J].
double pressure() const
Pressure [Pa].
double minTemp() const
Minimum temperature for which all solution phases have valid thermo data.
double entropy() const
The entropy of the mixture [J/K].
double temperature() const
Temperature [K].
void getChemPotentials(double *mu) const
Returns a vector of Chemical potentials.
double moleFraction(const size_t kGlob) const
Returns the mole fraction of global species k.
void setPressure(double P)
Set the pressure [Pa].
string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
double phaseMoles(const size_t n) const
Return the number of moles in phase n.
double volume() const
The total mixture volume [m^3].
void setTemperature(const double T)
Set the temperature [K].
ThermoPhase & phase(size_t n)
Return a reference to phase n.
double maxTemp() const
Maximum temperature for which all solution phases have valid thermo data.
double IntEnergy() const
The internal energy of the mixture [J].
size_t nSpecies() const
Returns the number of species in the phase.
string speciesName(size_t k) const
Name of the species with index k.
double moleFraction(size_t k) const
Return the mole fraction of a single species.
string name() const
Return the name of the phase.
Base class for a phase with thermodynamic properties.
virtual void getActivityCoefficients(double *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
virtual int activityConvention() const
This method returns the convention used in specification of the activities, of which there are curren...
virtual void getActivities(double *a) const
Get the array of non-dimensional activities at the current solution temperature, pressure,...
virtual void getStandardChemPotentials(double *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
virtual void getChemPotentials(double *mu) const
Get the species chemical potentials. Units: J/kmol.
virtual void getPartialMolarVolumes(double *vbar) const
Return an array of partial molar volumes for the species in the mixture.
int Its
Current number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
int Basis_Opts
number of optimizations of the components basis set done
size_t m_numPhases
Number of Phases in the problem.
int m_doEstimateEquil
Setting for whether to do an initial estimate.
vector< size_t > m_phaseID
Mapping from the species number to the phase number.
vector< int > m_speciesUnknownType
Specifies the species unknown type.
int m_timing_print_lvl
printing level of timing information
VCS_COUNTERS * m_VCount
Timing and iteration counters for the vcs object.
int vcs(int ipr, int ip1, int maxit)
Solve an equilibrium problem.
vector< unique_ptr< vcs_VolPhase > > m_VolPhaseList
Array of Phase Structures. Length = number of phases.
double m_pressurePA
Pressure.
int m_printLvl
Print level for print routines.
double m_temperature
Temperature (Kelvin)
The class provides the wall clock timer in seconds.
double secondsWC()
Returns the wall clock time in seconds since the last reset.
VCS_SOLVE m_vsolve
The object that contains the problem statement and does all of the equilibration work.
int equilibrate_SP(double Starget, double Tlow, double Thigh, int estimateEquil=0, int printLvl=0, double 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 reportCSV(const 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, double 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, double 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 equilibrate_TV(int XY, double xtarget, int estimateEquil=0, int printLvl=0, double 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 m_printLvl
Print level from the VCSnonlinear package.
int equilibrate_HP(double Htarget, int XY, double Tlow, double Thigh, int estimateEquil=0, int printLvl=0, double 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...
MultiPhase * m_mix
Pointer to the MultiPhase mixture that will be equilibrated.
Phase information and Phase calculations for vcs.
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.
Namespace for the Cantera kernel.
const double Undef
Fairly random number to be used to initialize variables against to see if they are subsequently defin...
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.
#define plogf
define this Cantera function to replace printf