21 m_vsolve(mix, printLvl)
26 int printLvl,
double err,
27 int maxsteps,
int loglevel)
30 if ((XY != TV) && (XY != HV) && (XY != UV) && (XY != SV)) {
31 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TV",
32 "Wrong XY flag: {}", XY);
39 int strt = estimateEquil;
46 int printLvlSub = std::max(0, printLvl - 1);
47 for (
int n = 0; n < maxiter; n++) {
52 iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
56 printLvlSub, err, maxsteps, loglevel);
60 printLvlSub, err, maxsteps, loglevel);
64 printLvlSub, err, maxsteps, loglevel);
84 double Verr = fabs((Vtarget - Vnow)/Vtarget);
91 double dVdP = (V2 - V1) / (P2 - P1);
96 Pnew = Pnow + (Vtarget - Vnow) / dVdP;
97 if (Pnew < 0.2 * Pnow) {
100 if (Pnew > 3.0 * Pnow) {
106 double dVdP = (
m_mix->
volume() - Vnow)/(0.01*Pnow);
107 Pnew = Pnow + 0.5*(Vtarget - Vnow)/dVdP;
108 if (Pnew < 0.5* Pnow) {
111 if (Pnew > 1.7 * Pnow) {
118 "No convergence for V");
122 double Thigh,
int estimateEquil,
int printLvl,
double err,
int maxsteps,
127 if (XY != HP && XY != UP) {
128 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_HP",
131 int strt = estimateEquil;
138 if (Thigh <= 0.0 || Thigh > 1.0E6) {
144 double Hhigh =
Undef;
146 int printLvlSub = std::max(printLvl - 1, 0);
148 for (
int n = 0; n < maxiter; n++) {
153 iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
158 double Tmoles = pmoles[0];
159 double HperMole = Hnow/Tmoles;
161 plogf(
"T = %g, Hnow = %g ,Tmoles = %g, HperMole = %g\n",
162 Tnow, Hnow, Tmoles, HperMole);
168 if (Hnow < Htarget) {
183 cpb = (Hhigh - Hlow)/(Thigh - Tlow);
184 dT = (Htarget - Hnow)/cpb;
185 double dTa = fabs(dT);
186 double dTmax = 0.5*fabs(Thigh - Tlow);
191 double Tnew = sqrt(Tlow*Thigh);
192 dT =
clip(Tnew - Tnow, -200.0, 200.0);
194 double acpb = std::max(fabs(cpb), 1.0E-6);
195 double denom = std::max(fabs(Htarget), acpb);
196 double Herr = Htarget - Hnow;
197 double HConvErr = fabs((Herr)/denom);
199 plogf(
" equilibrate_HP: It = %d, Tcurr = %g Hcurr = %g, Htarget = %g\n",
200 n, Tnow, Hnow, Htarget);
201 plogf(
" H rel error = %g, cp = %g, HConvErr = %g\n",
202 Herr, cpb, HConvErr);
205 if (HConvErr < err) {
207 plogf(
" equilibrate_HP: CONVERGENCE: Hfinal = %g Tfinal = %g, Its = %d \n",
209 plogf(
" H rel error = %g, cp = %g, HConvErr = %g\n",
210 Herr, cpb, HConvErr);
214 double Tnew = Tnow + dT;
220 if (!estimateEquil) {
223 double Tnew = 0.5*(Tnow + Thigh);
224 if (fabs(Tnew - Tnow) < 1.0) {
231 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_HP",
232 "No convergence for T");
236 int estimateEquil,
int printLvl,
double err,
int maxsteps,
int loglevel)
239 int strt = estimateEquil;
246 if (Thigh <= 0.0 || Thigh > 1.0E6) {
250 double cpb = 1.0, dT;
252 double Shigh =
Undef;
254 Tlow = std::min(Tnow, Tlow);
255 Thigh = std::max(Tnow, Thigh);
256 int printLvlSub = std::max(printLvl - 1, 0);
258 for (
int n = 0; n < maxiter; n++) {
263 int iSuccess =
equilibrate_TP(strt, printLvlSub, err, maxsteps, loglevel);
268 double Tmoles = pmoles[0];
269 double SperMole = Snow/Tmoles;
271 plogf(
"T = %g, Snow = %g ,Tmoles = %g, SperMole = %g\n",
272 Tnow, Snow, Tmoles, SperMole);
279 if (Snow < Starget) {
284 if (Slow > Starget && Snow < Slow) {
300 cpb = (Shigh - Slow)/(Thigh - Tlow);
301 dT = (Starget - Snow)/cpb;
302 double Tnew = Tnow + dT;
303 double dTa = fabs(dT);
304 double dTmax = 0.5*fabs(Thigh - Tlow);
305 if (Tnew > Thigh || Tnew < Tlow) {
306 dTmax = 1.5*fabs(Thigh - Tlow);
308 dTmax = std::min(dTmax, 300.);
313 double Tnew = sqrt(Tlow*Thigh);
317 double acpb = std::max(fabs(cpb), 1.0E-6);
318 double denom = std::max(fabs(Starget), acpb);
319 double Serr = Starget - Snow;
320 double SConvErr = fabs((Serr)/denom);
322 plogf(
" equilibrate_SP: It = %d, Tcurr = %g Scurr = %g, Starget = %g\n",
323 n, Tnow, Snow, Starget);
324 plogf(
" S rel error = %g, cp = %g, SConvErr = %g\n",
325 Serr, cpb, SConvErr);
328 if (SConvErr < err) {
330 plogf(
" equilibrate_SP: CONVERGENCE: Sfinal = %g Tfinal = %g, Its = %d \n",
332 plogf(
" S rel error = %g, cp = %g, HConvErr = %g\n",
333 Serr, cpb, SConvErr);
337 double Tnew = Tnow + dT;
343 if (!estimateEquil) {
346 double Tnew = 0.5*(Tnow + Thigh);
347 if (fabs(Tnew - Tnow) < 1.0) {
354 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_SP",
355 "No convergence for T");
359 double err,
int maxsteps,
int loglevel)
363 return equilibrate_TP(estimateEquil, printLvl, err, maxsteps, loglevel);
364 }
else if (XY == HP || XY == UP) {
373 estimateEquil, printLvl, err, maxsteps, loglevel);
374 }
else if (XY == SP) {
379 estimateEquil, printLvl, err, maxsteps, loglevel);
380 }
else if (XY == TV) {
383 estimateEquil, printLvl, err, maxsteps, loglevel);
384 }
else if (XY == HV) {
387 estimateEquil, printLvl, err, maxsteps, loglevel);
388 }
else if (XY == UV) {
391 estimateEquil, printLvl, err, maxsteps, loglevel);
392 }
else if (XY == SV) {
395 printLvl, err, maxsteps, loglevel);
398 "Unsupported Option");
403 int maxsteps,
int loglevel)
405 int maxit = maxsteps;
413 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TP",
414 "Temperature less than zero on input");
417 throw CanteraError(
"vcs_MultiPhaseEquil::equilibrate_TP",
418 "Pressure less than zero on input");
434 plogf(
"\n Results from vcs:\n");
436 plogf(
"\nVCS FAILED TO CONVERGE!\n");
442 plogf(
"----------------------------------------"
443 "---------------------\n");
444 plogf(
" Name Mole_Number(kmol)");
445 plogf(
" Mole_Fraction Chem_Potential (J/kmol)\n");
446 plogf(
"--------------------------------------------------"
452 plogf(
"%15.3e\n", mu[i]);
459 plogf(
" -1.000e+300\n");
461 plogf(
"%15.3e\n", mu[i]);
464 plogf(
"%15.3e\n", mu[i]);
468 plogf(
"------------------------------------------"
469 "-------------------\n");
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.
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.
string speciesName(size_t kGlob) const
Name of species with global index kGlob.
void setPressure(double P)
Set the pressure [Pa].
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].
double maxTemp() const
Maximum temperature for which all solution phases have valid thermo data.
double IntEnergy() const
The internal energy of the mixture [J].
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 solve_TP(int print_lvl, int printDetails, int maxit)
Main routine that solves for equilibrium at constant T and P using a variant of the VCS method.
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)
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...
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.
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