23 string flag = string(xy);
26 }
else if (flag ==
"TV") {
28 }
else if (flag ==
"HP") {
30 }
else if (flag ==
"UV") {
32 }
else if (flag ==
"SP") {
34 }
else if (flag ==
"SV") {
36 }
else if (flag ==
"UP") {
39 throw CanteraError(
"_equilflag",
"unknown property pair "+flag);
44 ChemEquil::ChemEquil() : m_skip(
npos), m_elementTotalSum(1.0),
46 m_elemFracCutoff(1.0E-100),
52 m_elementTotalSum(1.0),
54 m_elemFracCutoff(1.0E-100),
60 ChemEquil::~ChemEquil()
77 m_jwork1.resize(
m_mm+2);
78 m_jwork2.resize(
m_mm+2);
79 m_startSoln.resize(
m_mm+1);
84 m_orderVectorElements.resize(
m_mm);
86 for (
size_t m = 0; m <
m_mm; m++) {
87 m_orderVectorElements[m] = m;
89 m_orderVectorSpecies.resize(
m_kk);
90 for (
size_t k = 0; k <
m_kk; k++) {
91 m_orderVectorSpecies[k] = k;
96 for (
size_t m = 0; m <
m_mm; m++) {
97 for (
size_t k = 0; k <
m_kk; k++) {
101 if (s.
nAtoms(k,m) < 0.0) {
105 if (mneg !=
npos && mneg != m) {
107 "negative atom numbers allowed for only one element");
115 "species {} has {} atoms of element {}, "
116 "but this element is not an electron.",
125 for (
size_t k = 0; k <
m_kk; k++) {
126 for (
size_t m = 0; m <
m_mm; m++) {
133 const vector_fp& lambda_RT, doublereal t)
136 fill(m_mu_RT.begin(), m_mu_RT.end(), 0.0);
137 for (
size_t k = 0; k <
m_kk; k++) {
138 for (
size_t m = 0; m <
m_mm; m++) {
139 m_mu_RT[k] += lambda_RT[m]*
nAtoms(k,m);
162 for (
size_t m = 0; m <
m_mm; m++) {
164 for (
size_t k = 0; k <
m_kk; k++) {
168 "negative mole fraction for {}: {}",
177 for (
size_t m = 0; m <
m_mm; m++) {
189 e.setInitialMixMoles(loglevel-1);
194 m_component[m] = e.componentIndex(m);
202 writelog(
"setInitialMoles: Estimated Mole Fractions\n");
205 for (
size_t k = 0; k <
m_kk; k++) {
209 writelog(
" Element_Name ElementGoal ElementMF\n");
210 for (
size_t m = 0; m <
m_mm; m++) {
226 for (
size_t n = 0; n < s.
nSpecies(); n++) {
227 xMF_est[n] = std::max(xMF_est[n], 1e-20);
235 int usedZeroedSpecies = 0;
238 &mp, m_orderVectorSpecies,
239 m_orderVectorElements, formRxnMatrix);
242 size_t k = m_orderVectorSpecies[m];
244 xMF_est[k] = std::max(xMF_est[k], 1e-8);
250 m_orderVectorSpecies, m_orderVectorElements);
253 scale(mu_RT.begin(), mu_RT.end(), mu_RT.begin(),
258 size_t isp = m_component[m];
264 for (
size_t n = 0; n < s.
nSpecies(); n++) {
272 aa(m,n) =
nAtoms(m_component[m], m_orderVectorElements[n]);
274 b[m] = mu_RT[m_component[m]];
282 lambda_RT[m_orderVectorElements[m]] = b[m];
285 lambda_RT[m_orderVectorElements[m]] = 0.0;
289 writelog(
" id CompSpecies ChemPot EstChemPot Diff\n");
291 size_t isp = m_component[m];
293 for (
size_t n = 0; n <
m_mm; n++) {
294 tmp +=
nAtoms(isp, n) * lambda_RT[n];
296 writelogf(
"%3d %16s %10.5g %10.5g %10.5g\n",
297 m, s.
speciesName(isp), mu_RT[isp], tmp, tmp - mu_RT[isp]);
301 for (
size_t m = 0; m <
m_mm; m++) {
313 return equilibrate(s, XY, elMolesGoal, loglevel-1);
320 bool tempFixed =
true;
329 "Input ThermoPhase is incompatible with initialization");
371 "illegal property pair '{}'", XYstr);
378 throw CanteraError(
"ChemEquil::equilibrate",
"Specified temperature"
379 " ({} K) outside valid range of {} K to {} K\n",
386 double xval = m_p1(s);
387 double yval = m_p2(s);
390 size_t nvar = mm + 1;
401 size_t m = m_orderVectorElements[im];
402 if (elMolesGoal[m] > tmp) {
404 tmp = elMolesGoal[m];
409 "Element Abundance Vector is zeroed");
416 for (
size_t k = 0; k <
m_kk; k++) {
425 doublereal tmaxPhase = s.
maxTemp();
426 doublereal tminPhase = s.
minTemp();
429 doublereal tmin = std::max(s.
temperature(), tminPhase);
430 if (tmin > tmaxPhase) {
431 tmin = tmaxPhase - 20;
433 doublereal tmax = std::min(tmin + 10., tmaxPhase);
434 if (tmax < tminPhase) {
435 tmax = tminPhase + 20;
438 doublereal slope, phigh, plow, pval, dt;
453 doublereal t0 = 0.5*(tmin + tmax);
457 for (
int it = 0; it < 10; it++) {
476 slope = (phigh - plow)/(tmax - tmin);
477 dt = (xval - pval)/slope;
480 if (fabs(dt) < 50.0) {
483 dt =
clip(dt, -200.0, 200.0);
484 if ((t0 + dt) < tminPhase) {
485 dt = 0.5*((t0) + tminPhase) - t0;
487 if ((t0 + dt) > tmaxPhase) {
488 dt = 0.5*((t0) + tmaxPhase) - t0;
492 if (t0 <= tminPhase || t0 >= tmaxPhase || t0 < 100.0) {
493 throw CanteraError(
"ChemEquil::equilibrate",
"T out of bounds");
527 for (
size_t m = 0; m < mm; m++) {
537 above[mm] = log(s.
maxTemp() + 25.0);
538 below[mm] = log(s.
minTemp() - 25.0);
547 double f = 0.5*
dot(res_trial.begin(), res_trial.end(), res_trial.begin());
550 double deltax = (xx - xval)/xval;
551 double deltay = (yy - yval)/yval;
552 bool passThis =
true;
553 for (
size_t m = 0; m < nvar; m++) {
574 if (fabs(res_trial[m]) > tval) {
583 adjustEloc(s, elMolesGoal);
589 "Temperature ({} K) outside valid range of {} K "
597 f = 0.5*
dot(res_trial.begin(), res_trial.end(), res_trial.begin());
600 equilJacobian(s, x, elMolesGoal, jac, xval, yval);
603 writelogf(
"Jacobian matrix %d:\n", iter);
604 for (
size_t m = 0; m <=
m_mm; m++) {
606 for (
size_t n = 0; n <=
m_mm; n++) {
614 }
else if (m == m_skip) {
619 writelog(
" = - ({:10.5g})\n", res_trial[m]);
625 scale(res_trial.begin(), res_trial.end(), res_trial.begin(), -1.0);
633 "Jacobian is singular. \nTry adding more species, "
634 "changing the elemental composition slightly, \nor removing "
641 for (
size_t m = 0; m < nvar; m++) {
642 double newval = x[m] + res_trial[m];
643 if (newval > above[m]) {
645 std::min(fctr,0.8*(above[m] - x[m])/(newval - x[m])));
646 }
else if (newval < below[m]) {
647 if (m <
m_mm && (m != m_skip)) {
649 if (x[m] < below[m] + 50.) {
650 res_trial[m] = below[m] - x[m];
653 fctr = std::min(fctr, 0.8*(x[m] - below[m])/(x[m] - newval));
657 if (m == mm && fabs(res_trial[mm]) > 0.2) {
658 fctr = std::min(fctr, 0.2/fabs(res_trial[mm]));
661 if (fctr != 1.0 && loglevel > 0) {
663 "Soln Damping because of bounds: %g", fctr);
667 scale(res_trial.begin(), res_trial.end(), res_trial.begin(), fctr);
669 if (!
dampStep(s, oldx, oldf, grad, res_trial,
670 x, f, elMolesGoal , xval, yval)) {
675 "Cannot find an acceptable Newton damping coefficient.");
691 double& f,
vector_fp& elmols,
double xval,
double yval)
696 for (
size_t m = 0; m <
m_mm; m++) {
698 if (step[m] > 1.25) {
699 damp = std::min(damp, 1.25 /step[m]);
701 if (step[m] < -1.25) {
702 damp = std::min(damp, -1.25 / step[m]);
705 if (step[m] > 0.75) {
706 damp = std::min(damp, 0.75 /step[m]);
708 if (step[m] < -0.75) {
709 damp = std::min(damp, -0.75 / step[m]);
715 for (
size_t m = 0; m < x.size(); m++) {
716 x[m] = oldx[m] + damp * step[m];
719 writelogf(
"Solution Unknowns: damp = %g\n", damp);
721 for (
size_t m = 0; m <
m_mm; m++) {
722 writelogf(
" % -10.5g % -10.5g % -10.5g\n", x[m], oldx[m], step[m]);
730 doublereal xval, doublereal yval,
int loglevel)
736 for (
size_t n = 0; n <
m_mm; n++) {
737 size_t m = m_orderVectorElements[n];
740 resid[m] = x[m] + 1000.0;
746 if (elmFracGoal[m] < 1.0E-10 || elmFrac[m] < 1.0E-10 || m ==
m_eloc) {
747 resid[m] = elmFracGoal[m] - elmFrac[m];
749 resid[m] = log((1.0 + elmFracGoal[m]) / (1.0 + elmFrac[m]));
754 if (loglevel > 0 && !m_doResPerturb) {
755 writelog(
"Residual: ElFracGoal ElFracCurrent Resid\n");
756 for (
size_t n = 0; n <
m_mm; n++) {
757 writelogf(
" % -14.7E % -14.7E % -10.5E\n",
758 elmFracGoal[n], elmFrac[n], resid[n]);
764 resid[
m_mm] = xx/xval - 1.0;
765 resid[m_skip] = yy/yval - 1.0;
767 if (loglevel > 0 && !m_doResPerturb) {
769 writelogf(
" XX : % -14.7E % -14.7E % -10.5E\n", xval, xx, resid[
m_mm]);
770 writelogf(
" YY(%1d): % -14.7E % -14.7E % -10.5E\n", m_skip, yval, yy, resid[m_skip]);
776 doublereal xval, doublereal yval,
int loglevel)
780 size_t len = x.size();
783 doublereal atol = 1.e-10;
787 m_doResPerturb =
false;
788 for (
size_t n = 0; n < len; n++) {
790 double dx = std::max(atol, fabs(xsave) * 1.0E-7);
799 for (
size_t m = 0; m < x.size(); m++) {
800 jac(m, n) = (r1[m] - r0[m])*rdx;
804 m_doResPerturb =
false;
810 double pressureConst)
812 double n_t_calc = 0.0;
821 for (
size_t k = 0; k <
m_kk; k++) {
822 double tmp = - (
m_muSS_RT[k] + log(actCoeff[k]));
823 for (
size_t m = 0; m <
m_mm; m++) {
824 tmp +=
nAtoms(k,m) * x[m];
826 tmp = std::min(tmp, 100.0);
830 n_i_calc[k] = n_t * exp(tmp);
832 n_t_calc += n_i_calc[k];
834 for (
size_t m = 0; m <
m_mm; m++) {
836 for (
size_t k = 0; k <
m_kk; k++) {
837 eMolesCalc[m] +=
nAtoms(k,m) * n_i_calc[k];
850 bool modifiedMatrix =
false;
861 double pressureConst = s.
pressure();
874 double elMolesTotal = 0.0;
875 for (
size_t m = 0; m <
m_mm; m++) {
876 elMolesTotal += elMoles[m];
877 for (
size_t k = 0; k <
m_kk; k++) {
878 eMolesFix[m] +=
nAtoms(k,m) * n_i[k];
882 for (
size_t m = 0; m <
m_mm; m++) {
883 if (elMoles[m] > 1.0E-70) {
884 x[m] =
clip(x[m], -100.0, 50.0);
886 x[m] =
clip(x[m], -1000.0, 50.0);
891 double nAtomsMax = 1.0;
895 for (
size_t k = 0; k <
m_kk; k++) {
896 double tmp = - (
m_muSS_RT[k] + log(actCoeff[k]));
898 for (
size_t m = 0; m <
m_mm; m++) {
902 nAtomsMax = std::max(nAtomsMax, sum2);
912 writelog(
"estimateEP_Brinkley::\n\n");
915 writelog(
"Initial mole numbers and mu_SS:\n");
916 writelog(
" Name MoleNum mu_SS actCoeff\n");
917 for (
size_t k = 0; k <
m_kk; k++) {
921 writelogf(
"Initial n_t = %10.5g\n", n_t);
922 writelog(
"Comparison of Goal Element Abundance with Initial Guess:\n");
923 writelog(
" eName eCurrent eGoal\n");
924 for (
size_t m = 0; m <
m_mm; m++) {
929 for (
size_t m = 0; m <
m_mm; m++) {
938 for (
size_t m = 0; m <
m_mm; m++) {
944 writelogf(
"START ITERATION %d:\n", iter);
947 double n_t_calc =
calcEmoles(s, x, n_t, Xmol_i_calc, eMolesCalc, n_i_calc,
950 for (
size_t k = 0; k <
m_kk; k++) {
951 Xmol_i_calc[k] = n_i_calc[k]/n_t_calc;
955 writelog(
" Species: Calculated_Moles Calculated_Mole_Fraction\n");
956 for (
size_t k = 0; k <
m_kk; k++) {
960 writelogf(
"%15s: %10.5g\n",
"Total Molar Sum", n_t_calc);
961 writelogf(
"(iter %d) element moles bal: Goal Calculated\n", iter);
962 for (
size_t m = 0; m <
m_mm; m++) {
968 bool normalStep =
true;
971 for (
size_t m = 0; m <
m_mm; m++) {
972 if (elMoles[m] > 0.001 * elMolesTotal) {
973 if (eMolesCalc[m] > 1000. * elMoles[m]) {
977 if (1000 * eMolesCalc[m] < elMoles[m]) {
984 writelogf(
" NOTE: iter(%d) Doing an abnormal step due to row %d\n", iter, iM);
989 for (
size_t im = 0; im <
m_mm; im++) {
990 size_t m = m_orderVectorElements[im];
992 if (im <
m_nComponents && elMoles[m] > 0.001 * elMolesTotal) {
993 if (eMolesCalc[m] > 1000. * elMoles[m]) {
997 if (1000 * eMolesCalc[m] < elMoles[m]) {
1003 if (n_t < (elMolesTotal / nAtomsMax)) {
1004 if (resid[
m_mm] < 0.0) {
1007 }
else if (n_t > elMolesTotal) {
1008 resid[
m_mm] = std::min(resid[
m_mm], 0.0);
1033 for (
size_t m = 0; m <
m_mm; m++) {
1037 double nCutoff = 1.0E-9 * n_t_calc;
1039 writelog(
" Lump Sum Elements Calculation: \n");
1041 for (
size_t m = 0; m <
m_mm; m++) {
1043 size_t kMSp2 =
npos;
1044 int nSpeciesWithElem = 0;
1045 for (
size_t k = 0; k <
m_kk; k++) {
1046 if (n_i_calc[k] > nCutoff && fabs(
nAtoms(k,m)) > 0.001) {
1050 double factor = fabs(
nAtoms(kMSp,m) /
nAtoms(kMSp2,m));
1051 for (
size_t n = 0; n <
m_mm; n++) {
1052 if (fabs(factor *
nAtoms(kMSp2,n) -
nAtoms(kMSp,n)) > 1.0E-8) {
1069 for (
size_t im = 0; im <
m_mm; im++) {
1070 size_t m = m_orderVectorElements[im];
1072 for (
size_t n = 0; n <
m_mm; n++) {
1074 for (
size_t k = 0; k <
m_kk; k++) {
1078 a1(m,
m_mm) = eMolesCalc[m];
1079 a1(
m_mm, m) = eMolesCalc[m];
1081 for (
size_t n = 0; n <=
m_mm; n++) {
1092 for (
size_t im = 0; im <
m_mm; im++) {
1093 size_t m = m_orderVectorElements[im];
1095 resid[m] = elMoles[m] - eMolesCalc[m];
1114 for (
size_t m = 0; m <
m_mm; m++) {
1115 if (a1(m,m) < 1.0E-50) {
1117 writelogf(
" NOTE: Diagonalizing the analytical Jac row %d\n", m);
1119 for (
size_t n = 0; n <
m_mm; n++) {
1123 if (resid[m] > 0.0) {
1125 }
else if (resid[m] < 0.0) {
1133 resid[
m_mm] = n_t - n_t_calc;
1137 for (
size_t m = 0; m <=
m_mm; m++) {
1139 for (
size_t n = 0; n <=
m_mm; n++) {
1146 sum += pow(resid[
m_mm] /(n_t + 1.0E-15), 2);
1148 writelogf(
"(it %d) Convergence = %g\n", iter, sum);
1161 for (
size_t m = 0; m <=
m_mm; m++) {
1163 for (
size_t n = 0; n <=
m_mm; n++) {
1164 tmp += fabs(a1(m,n));
1166 if (m <
m_mm && tmp < 1.0E-30) {
1168 writelogf(
" NOTE: Diagonalizing row %d\n", m);
1170 for (
size_t n = 0; n <=
m_mm; n++) {
1178 for (
size_t n = 0; n <=
m_mm; n++) {
1186 for (
size_t m = 0; m <=
m_mm; m++) {
1188 for (
size_t n = 0; n <=
m_mm; n++) {
1214 modifiedMatrix =
false;
1215 for (
size_t m = 0; m <
m_mm; m++) {
1216 size_t sameAsRow =
npos;
1217 for (
size_t im = 0; im < m; im++) {
1218 bool theSame =
true;
1219 for (
size_t n = 0; n <
m_mm; n++) {
1220 if (fabs(a1(m,n) - a1(im,n)) > 1.0E-7) {
1229 if (sameAsRow !=
npos || lumpSum[m]) {
1232 writelogf(
"Lump summing row %d, due to rank deficiency analysis\n", m);
1233 }
else if (sameAsRow !=
npos) {
1234 writelogf(
"Identified that rows %d and %d are the same\n", m, sameAsRow);
1237 modifiedMatrix =
true;
1238 for (
size_t n = 0; n <
m_mm; n++) {
1240 a1(m,m) += fabs(a1(m,n));
1248 writelog(
"Row Summed, MODIFIED Matrix:\n");
1249 for (
size_t m = 0; m <=
m_mm; m++) {
1251 for (
size_t n = 0; n <=
m_mm; n++) {
1263 "Jacobian is singular. \nTry adding more species, "
1264 "changing the elemental composition slightly, \nor removing "
1271 for (
size_t m = 0; m <
m_mm; m++) {
1272 if (resid[m] > 1.0) {
1273 beta = std::min(beta, 1.0 / resid[m]);
1275 if (resid[m] < -1.0) {
1276 beta = std::min(beta, -1.0 / resid[m]);
1280 writelogf(
"(it %d) Beta = %g\n", iter, beta);
1284 for (
size_t m = 0; m <
m_mm; m++) {
1285 x[m] += beta * resid[m];
1287 n_t *= exp(beta * resid[
m_mm]);
1290 writelogf(
"(it %d) OLD_SOLUTION NEW SOLUTION (undamped updated)\n", iter);
1291 for (
size_t m = 0; m <
m_mm; m++) {
1292 writelogf(
" %5s %10.5g %10.5g %10.5g\n",
1303 writelogf(
" ChemEquil::estimateEP_Brinkley() SUCCESS: equilibrium found at T = %g, Pres = %g\n",
1306 writelogf(
" ChemEquil::estimateEP_Brinkley() FAILURE: equilibrium not found at T = %g, Pres = %g\n",
1319 if (fabs(elMolesGoal[
m_eloc]) > 1.0E-20) {
1323 size_t maxPosEloc =
npos;
1324 size_t maxNegEloc =
npos;
1325 double maxPosVal = -1.0;
1326 double maxNegVal = -1.0;
1328 for (
size_t k = 0; k <
m_kk; k++) {
1340 double sumPos = 0.0;
1341 double sumNeg = 0.0;
1342 for (
size_t k = 0; k <
m_kk; k++) {
1352 if (sumPos >= sumNeg) {
1353 if (sumPos <= 0.0) {
1356 double factor = (elMolesGoal[
m_eloc] + sumNeg) / sumPos;
1357 if (
m_loglevel > 0 && factor < 0.9999999999) {
1358 writelogf(
"adjustEloc: adjusted %s and friends from %g to %g to ensure neutrality condition\n",
1362 for (
size_t k = 0; k <
m_kk; k++) {
1368 double factor = (-elMolesGoal[
m_eloc] + sumPos) / sumNeg;
1369 if (
m_loglevel > 0 && factor < 0.9999999999) {
1370 writelogf(
"adjustEloc: adjusted %s and friends from %g to %g to ensure neutrality condition\n",
1374 for (
size_t k = 0; k <
m_kk; k++) {
vector_fp & data()
Return a reference to the data vector.
Base class for exceptions thrown by Cantera classes.
virtual std::string getMessage() const
Method overridden by derived classes to format the error message.
int equilibrate(thermo_t &s, const char *XY, int loglevel=0)
vector_fp m_muSS_RT
Dimensionless values of the Gibbs free energy for the standard state of each species,...
void equilResidual(thermo_t &s, const vector_fp &x, const vector_fp &elmtotal, vector_fp &resid, double xval, double yval, int loglevel=0)
Evaluates the residual vector F, of length m_mm.
void update(const thermo_t &s)
Update internally stored state information.
thermo_t * m_phase
Pointer to the ThermoPhase object used to initialize this object.
size_t m_kk
number of species in the phase
int m_loglevel
Verbosity of printed output.
size_t m_nComponents
This is equal to the rank of the stoichiometric coefficient matrix when it is computed.
size_t m_eloc
Index of the element id corresponding to the electric charge of each species.
int dampStep(thermo_t &s, vector_fp &oldx, double oldf, vector_fp &grad, vector_fp &step, vector_fp &x, double &f, vector_fp &elmols, double xval, double yval)
Find an acceptable step size and take it.
EquilOpt options
Options controlling how the calculation is carried out.
vector_fp m_molefractions
Current value of the mole fractions in the single phase. length = m_kk.
int setInitialMoles(thermo_t &s, vector_fp &elMoleGoal, int loglevel=0)
Estimate the initial mole numbers.
double calcEmoles(thermo_t &s, vector_fp &x, const double &n_t, const vector_fp &Xmol_i_calc, vector_fp &eMolesCalc, vector_fp &n_i_calc, double pressureConst)
Given a vector of dimensionless element abundances, this routine calculates the moles of the elements...
vector_fp m_comp
Storage of the element compositions. natom(k,m) = m_comp[k*m_mm+ m];.
void setToEquilState(thermo_t &s, const vector_fp &x, doublereal t)
vector_fp m_elementmolefracs
Current value of the element mole fractions.
int estimateEP_Brinkley(thermo_t &s, vector_fp &lambda, vector_fp &elMoles)
doublereal nAtoms(size_t k, size_t m) const
number of atoms of element m in species k.
int estimateElementPotentials(thermo_t &s, vector_fp &lambda, vector_fp &elMolesGoal, int loglevel=0)
Generate a starting estimate for the element potentials.
double m_elemFracCutoff
element fractional cutoff, below which the element will be zeroed.
doublereal m_elementTotalSum
Current value of the sum of the element abundances given the current element potentials.
void initialize(thermo_t &s)
size_t m_mm
number of elements in the phase
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
int iterations
Iteration counter.
doublereal relTolerance
Relative tolerance.
doublereal absElemTol
Abs Tol in element number.
int maxIterations
Maximum number of iterations.
A class for multiphase mixtures.
void init()
Process phases and build atomic composition array.
void addPhase(ThermoPhase *p, doublereal moles)
Add a phase to the mixture.
virtual void setMoleFractions(const double *const x)
Set the mole fractions to the specified values.
size_t nSpecies() const
Returns the number of species in the phase.
void saveState(vector_fp &state) const
Save the current internal state of the phase.
doublereal atomicWeight(size_t m) const
Atomic weight of element m.
virtual void setPressure(double p)
Set the internally stored pressure (Pa) at constant temperature and composition.
std::string speciesName(size_t k) const
Name of the species with index k.
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
double moleFraction(size_t k) const
Return the mole fraction of a single species.
doublereal nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
virtual double density() const
Density (kg/m^3).
doublereal temperature() const
Temperature (K).
size_t nElements() const
Number of elements.
void restoreState(const vector_fp &state)
Restore a state saved on a previous call to saveState.
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
virtual double pressure() const
Return the thermodynamic pressure (Pa).
std::string elementName(size_t m) const
Name of the element with index m.
Base class for a phase with thermodynamic properties.
doublereal entropy_mass() const
Specific entropy. Units: J/kg/K.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
virtual doublereal refPressure() const
Returns the reference pressure in Pa.
virtual doublereal maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
doublereal intEnergy_mass() const
Specific internal energy. Units: J/kg.
doublereal enthalpy_mass() const
Specific enthalpy. Units: J/kg.
virtual void getGibbs_RT(doublereal *grt) const
Get the nondimensional Gibbs functions for the species in their standard states at the current T and ...
virtual doublereal minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid.
size_t BasisOptimize(int *usedZeroedSpecies, bool doFormRxn, MultiPhase *mphase, std::vector< size_t > &orderVectorSpecies, std::vector< size_t > &orderVectorElements, vector_fp &formRxnMatrix)
Choose the optimum basis of species for the equilibrium calculations.
void ElemRearrange(size_t nComponents, const vector_fp &elementAbundances, MultiPhase *mphase, std::vector< size_t > &orderVectorSpecies, std::vector< size_t > &orderVectorElements)
Handles the potential rearrangement of the constraint equations represented by the Formula Matrix.
virtual void setToEquilState(const doublereal *mu_RT)
This method is used by the ChemEquil equilibrium solver.
const size_t npos
index returned by functions to indicate "no position"
const double OneAtm
One atmosphere [Pa].
std::vector< int > vector_int
Vector of ints.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
const double GasConstant
Universal Gas Constant [J/kmol/K].
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
void writelogf(const char *fmt, const Args &... args)
Write a formatted message to the screen.
Namespace for the Cantera kernel.
doublereal dot(InputIter x_begin, InputIter x_end, InputIter2 y_begin)
Function that calculates a templated inner product.
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
int _equilflag(const char *xy)
map property strings to integers
int solve(DenseMatrix &A, double *b, size_t nrhs, size_t ldb)
Solve Ax = b. Array b is overwritten on exit with x.
Contains declarations for string manipulation functions within Cantera.