22 string flag = string(xy);
25 }
else if (flag ==
"TV") {
27 }
else if (flag ==
"HP") {
29 }
else if (flag ==
"UV") {
31 }
else if (flag ==
"SP") {
33 }
else if (flag ==
"SV") {
35 }
else if (flag ==
"UP") {
38 throw CanteraError(
"_equilflag",
"unknown property pair "+flag);
61 m_jwork1.resize(
m_mm+2);
62 m_jwork2.resize(
m_mm+2);
63 m_startSoln.resize(
m_mm+1);
68 m_orderVectorElements.resize(
m_mm);
70 for (
size_t m = 0; m <
m_mm; m++) {
71 m_orderVectorElements[m] = m;
73 m_orderVectorSpecies.resize(
m_kk);
74 for (
size_t k = 0; k <
m_kk; k++) {
75 m_orderVectorSpecies[k] = k;
80 for (
size_t m = 0; m <
m_mm; m++) {
81 for (
size_t k = 0; k <
m_kk; k++) {
89 if (mneg !=
npos && mneg != m) {
91 "negative atom numbers allowed for only one element");
99 "species {} has {} atoms of element {}, "
100 "but this element is not an electron.",
109 for (
size_t k = 0; k <
m_kk; k++) {
110 for (
size_t m = 0; m <
m_mm; m++) {
119 fill(m_mu_RT.begin(), m_mu_RT.end(), 0.0);
120 for (
size_t k = 0; k <
m_kk; k++) {
121 for (
size_t m = 0; m <
m_mm; m++) {
122 m_mu_RT[k] += lambda_RT[m]*
nAtoms(k,m);
145 for (
size_t m = 0; m <
m_mm; m++) {
147 for (
size_t k = 0; k <
m_kk; k++) {
151 "negative mole fraction for {}: {}",
160 for (
size_t m = 0; m <
m_mm; m++) {
173 e.setInitialMixMoles(loglevel-1);
178 m_component[m] = e.componentIndex(m);
186 writelog(
"setInitialMoles: Estimated Mole Fractions\n");
189 for (
size_t k = 0; k <
m_kk; k++) {
193 writelog(
" Element_Name ElementGoal ElementMF\n");
194 for (
size_t m = 0; m <
m_mm; m++) {
203 span<double> elMolesGoal,
int loglevel)
205 vector<double> b(
m_mm, -999.0);
206 vector<double> mu_RT(
m_kk, 0.0);
207 vector<double> xMF_est(
m_kk, 0.0);
210 for (
size_t n = 0; n < s.
nSpecies(); n++) {
211 xMF_est[n] = std::max(xMF_est[n], 1e-20);
219 bool usedZeroedSpecies =
false;
222 &mp, m_orderVectorSpecies,
223 m_orderVectorElements, formRxnMatrix);
226 size_t k = m_orderVectorSpecies[m];
228 xMF_est[k] = std::max(xMF_est[k], 1e-8);
234 m_orderVectorSpecies, m_orderVectorElements);
237 scale(mu_RT.begin(), mu_RT.end(), mu_RT.begin(),
242 size_t isp = m_component[m];
248 for (
size_t n = 0; n < s.
nSpecies(); n++) {
256 aa(m,n) =
nAtoms(m_component[m], m_orderVectorElements[n]);
258 b[m] = mu_RT[m_component[m]];
268 lambda_RT[m_orderVectorElements[m]] = b[m];
271 lambda_RT[m_orderVectorElements[m]] = 0.0;
275 writelog(
" id CompSpecies ChemPot EstChemPot Diff\n");
277 size_t isp = m_component[m];
279 for (
size_t n = 0; n <
m_mm; n++) {
280 tmp +=
nAtoms(isp, n) * lambda_RT[n];
282 writelogf(
"%3d %16s %10.5g %10.5g %10.5g\n",
283 m, s.
speciesName(isp), mu_RT[isp], tmp, tmp - mu_RT[isp]);
287 for (
size_t m = 0; m <
m_mm; m++) {
299 return equilibrate(s, XY, elMolesGoal, loglevel-1);
303 span<double> elMolesGoal,
int loglevel)
306 bool tempFixed =
true;
315 "Input ThermoPhase is incompatible with initialization");
357 "illegal property pair '{}'", XYstr);
364 throw CanteraError(
"ChemEquil::equilibrate",
"Specified temperature"
365 " ({} K) outside valid range of {} K to {} K\n",
372 double xval = m_p1(s);
373 double yval = m_p2(s);
376 size_t nvar = mm + 1;
378 vector<double> x(nvar, -102.0);
379 vector<double> res_trial(nvar, 0.0);
387 size_t m = m_orderVectorElements[im];
388 if (elMolesGoal[m] > tmp) {
390 tmp = elMolesGoal[m];
395 "Element Abundance Vector is zeroed");
401 vector<double> xmm(
m_kk, 0.0);
402 for (
size_t k = 0; k <
m_kk; k++) {
411 double tmaxPhase = s.
maxTemp();
412 double tminPhase = s.
minTemp();
415 double tmin = std::max(s.
temperature(), tminPhase);
416 if (tmin > tmaxPhase) {
417 tmin = tmaxPhase - 20;
419 double tmax = std::min(tmin + 10., tmaxPhase);
420 if (tmax < tminPhase) {
421 tmax = tminPhase + 20;
424 double slope, phigh, plow, pval, dt;
439 double t0 = 0.5*(tmin + tmax);
443 for (
int it = 0; it < 10; it++) {
462 slope = (phigh - plow)/(tmax - tmin);
463 dt = (xval - pval)/slope;
466 if (fabs(dt) < 50.0) {
469 dt =
clip(dt, -200.0, 200.0);
470 if ((t0 + dt) < tminPhase) {
471 dt = 0.5*((t0) + tminPhase) - t0;
473 if ((t0 + dt) > tmaxPhase) {
474 dt = 0.5*((t0) + tmaxPhase) - t0;
478 if (t0 <= tminPhase || t0 >= tmaxPhase || t0 < 100.0) {
479 throw CanteraError(
"ChemEquil::equilibrate",
"T out of bounds");
511 vector<double> above(nvar);
512 vector<double> below(nvar);
513 for (
size_t m = 0; m < mm; m++) {
523 above[mm] = log(s.
maxTemp() + 25.0);
524 below[mm] = log(s.
minTemp() - 25.0);
526 vector<double> grad(nvar, 0.0);
527 vector<double> oldx(nvar, 0.0);
528 vector<double> oldresid(nvar, 0.0);
533 double f = 0.5*
dot(res_trial.begin(), res_trial.end(), res_trial.begin());
536 double deltax = (xx - xval)/xval;
537 double deltay = (yy - yval)/yval;
538 bool passThis =
true;
539 for (
size_t m = 0; m < nvar; m++) {
560 if (fabs(res_trial[m]) > tval) {
569 adjustEloc(s, elMolesGoal);
575 "Temperature ({} K) outside valid range of {} K "
583 f = 0.5*
dot(res_trial.begin(), res_trial.end(), res_trial.begin());
586 equilJacobian(s, x, elMolesGoal, jac, xval, yval);
589 writelogf(
"Jacobian matrix %d:\n", iter);
590 for (
size_t m = 0; m <=
m_mm; m++) {
592 for (
size_t n = 0; n <=
m_mm; n++) {
600 }
else if (m == m_skip) {
605 writelog(
" = - ({:10.5g})\n", res_trial[m]);
611 scale(res_trial.begin(), res_trial.end(), res_trial.begin(), -1.0);
615 solve(jac, res_trial);
619 "Jacobian is singular. \nTry adding more species, "
620 "changing the elemental composition slightly, \nor removing "
627 for (
size_t m = 0; m < nvar; m++) {
628 double newval = x[m] + res_trial[m];
629 if (newval > above[m]) {
631 std::min(fctr,0.8*(above[m] - x[m])/(newval - x[m])));
632 }
else if (newval < below[m]) {
633 if (m <
m_mm && (m != m_skip)) {
635 if (x[m] < below[m] + 50.) {
636 res_trial[m] = below[m] - x[m];
639 fctr = std::min(fctr, 0.8*(x[m] - below[m])/(x[m] - newval));
643 if (m == mm && fabs(res_trial[mm]) > 0.2) {
644 fctr = std::min(fctr, 0.2/fabs(res_trial[mm]));
647 if (fctr != 1.0 && loglevel > 0) {
649 "Soln Damping because of bounds: %g", fctr);
653 scale(res_trial.begin(), res_trial.end(), res_trial.begin(), fctr);
655 if (!
dampStep(s, oldx, oldf, grad, res_trial,
656 x, f, elMolesGoal , xval, yval)) {
661 "Cannot find an acceptable Newton damping coefficient.");
676 span<double> grad, span<double> step, span<double> x,
677 double& f, span<double> elmols,
double xval,
double yval)
682 for (
size_t m = 0; m <
m_mm; m++) {
684 if (step[m] > 1.25) {
685 damp = std::min(damp, 1.25 /step[m]);
687 if (step[m] < -1.25) {
688 damp = std::min(damp, -1.25 / step[m]);
691 if (step[m] > 0.75) {
692 damp = std::min(damp, 0.75 /step[m]);
694 if (step[m] < -0.75) {
695 damp = std::min(damp, -0.75 / step[m]);
701 for (
size_t m = 0; m < x.size(); m++) {
702 x[m] = oldx[m] + damp * step[m];
705 writelogf(
"Solution Unknowns: damp = %g\n", damp);
707 for (
size_t m = 0; m <
m_mm; m++) {
708 writelogf(
" % -10.5g % -10.5g % -10.5g\n", x[m], oldx[m], step[m]);
715 span<const double> elmFracGoal, span<double> resid,
716 double xval,
double yval,
int loglevel)
722 for (
size_t n = 0; n <
m_mm; n++) {
723 size_t m = m_orderVectorElements[n];
726 resid[m] = x[m] + 1000.0;
732 if (elmFracGoal[m] < 1.0E-10 || elmFrac[m] < 1.0E-10 || m ==
m_eloc) {
733 resid[m] = elmFracGoal[m] - elmFrac[m];
735 resid[m] = log((1.0 + elmFracGoal[m]) / (1.0 + elmFrac[m]));
740 if (loglevel > 0 && !m_doResPerturb) {
741 writelog(
"Residual: ElFracGoal ElFracCurrent Resid\n");
742 for (
size_t n = 0; n <
m_mm; n++) {
743 writelogf(
" % -14.7E % -14.7E % -10.5E\n",
744 elmFracGoal[n], elmFrac[n], resid[n]);
750 resid[
m_mm] = xx/xval - 1.0;
751 resid[m_skip] = yy/yval - 1.0;
753 if (loglevel > 0 && !m_doResPerturb) {
755 writelogf(
" XX : % -14.7E % -14.7E % -10.5E\n", xval, xx, resid[
m_mm]);
756 writelogf(
" YY(%1d): % -14.7E % -14.7E % -10.5E\n", m_skip, yval, yy, resid[m_skip]);
760void ChemEquil::equilJacobian(
ThermoPhase& s, span<double> x, span<const double> elmols,
761 DenseMatrix& jac,
double xval,
double yval,
int loglevel)
763 vector<double>& r0 = m_jwork1;
764 vector<double>& r1 = m_jwork2;
765 size_t len = x.size();
768 double atol = 1.e-10;
772 m_doResPerturb =
false;
773 for (
size_t n = 0; n <
len; n++) {
775 double dx = std::max(atol, fabs(xsave) * 1.0E-7);
784 for (
size_t m = 0; m < x.size(); m++) {
785 jac(m, n) = (r1[m] - r0[m])*rdx;
789 m_doResPerturb =
false;
793 span<const double> Xmol_i_calc, span<double> eMolesCalc,
794 span<double> n_i_calc,
double pressureConst)
796 double n_t_calc = 0.0;
800 vector<double> actCoeff(
m_kk, 1.0);
805 for (
size_t k = 0; k <
m_kk; k++) {
806 double tmp = - (
m_muSS_RT[k] + log(actCoeff[k]));
807 for (
size_t m = 0; m <
m_mm; m++) {
808 tmp +=
nAtoms(k,m) * x[m];
810 tmp = std::min(tmp, 100.0);
814 n_i_calc[k] = n_t * exp(tmp);
816 n_t_calc += n_i_calc[k];
818 for (
size_t m = 0; m <
m_mm; m++) {
820 for (
size_t k = 0; k <
m_kk; k++) {
821 eMolesCalc[m] +=
nAtoms(k,m) * n_i_calc[k];
833 bool modifiedMatrix =
false;
837 vector<double> b(neq, 0.0);
838 vector<double> n_i(
m_kk,0.0);
839 vector<double> n_i_calc(
m_kk,0.0);
840 vector<double> actCoeff(
m_kk, 1.0);
844 double pressureConst = s.
pressure();
845 vector<double> Xmol_i_calc = n_i;
847 vector<double> x_old(
m_mm+1, 0.0);
848 vector<double> resid(
m_mm+1, 0.0);
849 vector<int> lumpSum(
m_mm+1, 0);
855 vector<double> eMolesCalc(
m_mm, 0.0);
856 vector<double> eMolesFix(
m_mm, 0.0);
857 double elMolesTotal = 0.0;
858 for (
size_t m = 0; m <
m_mm; m++) {
859 elMolesTotal += elMoles[m];
860 for (
size_t k = 0; k <
m_kk; k++) {
861 eMolesFix[m] +=
nAtoms(k,m) * n_i[k];
865 for (
size_t m = 0; m <
m_mm; m++) {
866 if (elMoles[m] > 1.0E-70) {
867 x[m] =
clip(x[m], -100.0, 50.0);
869 x[m] =
clip(x[m], -1000.0, 50.0);
874 double nAtomsMax = 1.0;
878 for (
size_t k = 0; k <
m_kk; k++) {
879 double tmp = - (
m_muSS_RT[k] + log(actCoeff[k]));
881 for (
size_t m = 0; m <
m_mm; m++) {
885 nAtomsMax = std::max(nAtomsMax, sum2);
895 writelog(
"estimateEP_Brinkley::\n\n");
898 writelog(
"Initial mole numbers and mu_SS:\n");
899 writelog(
" Name MoleNum mu_SS actCoeff\n");
900 for (
size_t k = 0; k <
m_kk; k++) {
904 writelogf(
"Initial n_t = %10.5g\n", n_t);
905 writelog(
"Comparison of Goal Element Abundance with Initial Guess:\n");
906 writelog(
" eName eCurrent eGoal\n");
907 for (
size_t m = 0; m <
m_mm; m++) {
912 for (
size_t m = 0; m <
m_mm; m++) {
921 for (
size_t m = 0; m <
m_mm; m++) {
927 writelogf(
"START ITERATION %d:\n", iter);
930 double n_t_calc =
calcEmoles(s, x, n_t, Xmol_i_calc, eMolesCalc, n_i_calc,
933 for (
size_t k = 0; k <
m_kk; k++) {
934 Xmol_i_calc[k] = n_i_calc[k]/n_t_calc;
938 writelog(
" Species: Calculated_Moles Calculated_Mole_Fraction\n");
939 for (
size_t k = 0; k <
m_kk; k++) {
943 writelogf(
"%15s: %10.5g\n",
"Total Molar Sum", n_t_calc);
944 writelogf(
"(iter %d) element moles bal: Goal Calculated\n", iter);
945 for (
size_t m = 0; m <
m_mm; m++) {
951 bool normalStep =
true;
954 for (
size_t m = 0; m <
m_mm; m++) {
955 if (elMoles[m] > 0.001 * elMolesTotal) {
956 if (eMolesCalc[m] > 1000. * elMoles[m]) {
960 if (1000 * eMolesCalc[m] < elMoles[m]) {
967 writelogf(
" NOTE: iter(%d) Doing an abnormal step due to row %d\n", iter, iM);
972 for (
size_t im = 0; im <
m_mm; im++) {
973 size_t m = m_orderVectorElements[im];
975 if (im <
m_nComponents && elMoles[m] > 0.001 * elMolesTotal) {
976 if (eMolesCalc[m] > 1000. * elMoles[m]) {
980 if (1000 * eMolesCalc[m] < elMoles[m]) {
986 if (n_t < (elMolesTotal / nAtomsMax)) {
987 if (resid[
m_mm] < 0.0) {
990 }
else if (n_t > elMolesTotal) {
991 resid[
m_mm] = std::min(resid[
m_mm], 0.0);
1016 for (
size_t m = 0; m <
m_mm; m++) {
1020 double nCutoff = 1.0E-9 * n_t_calc;
1022 writelog(
" Lump Sum Elements Calculation: \n");
1024 for (
size_t m = 0; m <
m_mm; m++) {
1026 size_t kMSp2 =
npos;
1027 for (
size_t k = 0; k <
m_kk; k++) {
1028 if (n_i_calc[k] > nCutoff && fabs(
nAtoms(k,m)) > 0.001) {
1031 double factor = fabs(
nAtoms(kMSp,m) /
nAtoms(kMSp2,m));
1032 for (
size_t n = 0; n <
m_mm; n++) {
1033 if (fabs(factor *
nAtoms(kMSp2,n) -
nAtoms(kMSp,n)) > 1.0E-8) {
1050 for (
size_t im = 0; im <
m_mm; im++) {
1051 size_t m = m_orderVectorElements[im];
1053 for (
size_t n = 0; n <
m_mm; n++) {
1055 for (
size_t k = 0; k <
m_kk; k++) {
1059 a1(m,
m_mm) = eMolesCalc[m];
1060 a1(
m_mm, m) = eMolesCalc[m];
1062 for (
size_t n = 0; n <=
m_mm; n++) {
1073 for (
size_t im = 0; im <
m_mm; im++) {
1074 size_t m = m_orderVectorElements[im];
1076 resid[m] = elMoles[m] - eMolesCalc[m];
1095 for (
size_t m = 0; m <
m_mm; m++) {
1096 if (a1(m,m) < 1.0E-50) {
1098 writelogf(
" NOTE: Diagonalizing the analytical Jac row %d\n", m);
1100 for (
size_t n = 0; n <
m_mm; n++) {
1104 if (resid[m] > 0.0) {
1106 }
else if (resid[m] < 0.0) {
1114 resid[
m_mm] = n_t - n_t_calc;
1118 for (
size_t m = 0; m <=
m_mm; m++) {
1120 for (
size_t n = 0; n <=
m_mm; n++) {
1127 sum += pow(resid[
m_mm] /(n_t + 1.0E-15), 2);
1129 writelogf(
"(it %d) Convergence = %g\n", iter, sum);
1142 for (
size_t m = 0; m <=
m_mm; m++) {
1144 for (
size_t n = 0; n <=
m_mm; n++) {
1145 tmp += fabs(a1(m,n));
1147 if (m <
m_mm && tmp < 1.0E-30) {
1149 writelogf(
" NOTE: Diagonalizing row %d\n", m);
1151 for (
size_t n = 0; n <=
m_mm; n++) {
1159 for (
size_t n = 0; n <=
m_mm; n++) {
1167 for (
size_t m = 0; m <=
m_mm; m++) {
1169 for (
size_t n = 0; n <=
m_mm; n++) {
1195 modifiedMatrix =
false;
1196 for (
size_t m = 0; m <
m_mm; m++) {
1197 size_t sameAsRow =
npos;
1198 for (
size_t im = 0; im < m; im++) {
1199 bool theSame =
true;
1200 for (
size_t n = 0; n <
m_mm; n++) {
1201 if (fabs(a1(m,n) - a1(im,n)) > 1.0E-7) {
1210 if (sameAsRow !=
npos || lumpSum[m]) {
1213 writelogf(
"Lump summing row %d, due to rank deficiency analysis\n", m);
1214 }
else if (sameAsRow !=
npos) {
1215 writelogf(
"Identified that rows %d and %d are the same\n", m, sameAsRow);
1218 modifiedMatrix =
true;
1219 for (
size_t n = 0; n <
m_mm; n++) {
1221 a1(m,m) += fabs(a1(m,n));
1229 writelog(
"Row Summed, MODIFIED Matrix:\n");
1230 for (
size_t m = 0; m <=
m_mm; m++) {
1232 for (
size_t n = 0; n <=
m_mm; n++) {
1244 "Jacobian is singular. \nTry adding more species, "
1245 "changing the elemental composition slightly, \nor removing "
1252 for (
size_t m = 0; m <
m_mm; m++) {
1253 if (resid[m] > 1.0) {
1254 beta = std::min(beta, 1.0 / resid[m]);
1256 if (resid[m] < -1.0) {
1257 beta = std::min(beta, -1.0 / resid[m]);
1261 writelogf(
"(it %d) Beta = %g\n", iter, beta);
1265 for (
size_t m = 0; m <
m_mm; m++) {
1266 x[m] += beta * resid[m];
1268 n_t *= exp(beta * resid[
m_mm]);
1271 writelogf(
"(it %d) OLD_SOLUTION NEW SOLUTION (undamped updated)\n", iter);
1272 for (
size_t m = 0; m <
m_mm; m++) {
1273 writelogf(
" %5s %10.5g %10.5g %10.5g\n",
1284 writelogf(
" ChemEquil::estimateEP_Brinkley() SUCCESS: equilibrium found at T = %g, Pres = %g\n",
1287 writelogf(
" ChemEquil::estimateEP_Brinkley() FAILURE: equilibrium not found at T = %g, Pres = %g\n",
1295void ChemEquil::adjustEloc(
ThermoPhase& s, span<double> elMolesGoal)
1300 if (fabs(elMolesGoal[
m_eloc]) > 1.0E-20) {
1304 size_t maxPosEloc =
npos;
1305 size_t maxNegEloc =
npos;
1306 double maxPosVal = -1.0;
1307 double maxNegVal = -1.0;
1309 for (
size_t k = 0; k <
m_kk; k++) {
1321 double sumPos = 0.0;
1322 double sumNeg = 0.0;
1323 for (
size_t k = 0; k <
m_kk; k++) {
1333 if (sumPos >= sumNeg) {
1334 if (sumPos <= 0.0) {
1337 double factor = (elMolesGoal[
m_eloc] + sumNeg) / sumPos;
1338 if (
m_loglevel > 0 && factor < 0.9999999999) {
1339 writelogf(
"adjustEloc: adjusted %s and friends from %g to %g to ensure neutrality condition\n",
1343 for (
size_t k = 0; k <
m_kk; k++) {
1349 double factor = (-elMolesGoal[
m_eloc] + sumPos) / sumNeg;
1350 if (
m_loglevel > 0 && factor < 0.9999999999) {
1351 writelogf(
"adjustEloc: adjusted %s and friends from %g to %g to ensure neutrality condition\n",
1355 for (
size_t k = 0; k <
m_kk; k++) {
Header file for class ThermoPhase, the base class for phases with thermodynamic properties,...
Base class for exceptions thrown by Cantera classes.
virtual string getMessage() const
Method overridden by derived classes to format the error message.
int dampStep(ThermoPhase &s, span< double > oldx, double oldf, span< double > grad, span< double > step, span< double > x, double &f, span< double > elmols, double xval, double yval)
Find an acceptable step size and take it.
int setInitialMoles(ThermoPhase &s, span< double > elMoleGoal, int loglevel=0)
Estimate the initial mole numbers.
void equilResidual(ThermoPhase &s, span< const double > x, span< const double > elmtotal, span< double > resid, double xval, double yval, int loglevel=0)
Evaluates the residual vector F, of length m_mm.
int equilibrate(ThermoPhase &s, const char *XY, int loglevel=0)
Equilibrate a phase, holding the elemental composition fixed at the initial value found within the Th...
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.
ThermoPhase * m_phase
Pointer to the ThermoPhase object used to initialize this object.
double m_elementTotalSum
Current value of the sum of the element abundances given the current element potentials.
void update(const ThermoPhase &s)
Update internally stored state information.
int estimateElementPotentials(ThermoPhase &s, span< double > lambda, span< double > elMolesGoal, int loglevel=0)
Generate a starting estimate for the element potentials.
size_t m_eloc
Index of the element id corresponding to the electric charge of each species.
double calcEmoles(ThermoPhase &s, span< double > x, const double &n_t, span< const double > Xmol_i_calc, span< double > eMolesCalc, span< double > n_i_calc, double pressureConst)
Given a vector of dimensionless element abundances, this routine calculates the moles of the elements...
void initialize(ThermoPhase &s)
Prepare for equilibrium calculations.
EquilOpt options
Options controlling how the calculation is carried out.
vector< double > m_molefractions
Current value of the mole fractions in the single phase. length = m_kk.
vector< double > m_comp
Storage of the element compositions. natom(k,m) = m_comp[k*m_mm+ m];.
double nAtoms(size_t k, size_t m) const
number of atoms of element m in species k.
double m_elemFracCutoff
element fractional cutoff, below which the element will be zeroed.
vector< double > m_muSS_RT
Dimensionless values of the Gibbs free energy for the standard state of each species,...
vector< double > m_elementmolefracs
Current value of the element mole fractions.
size_t m_mm
number of elements in the phase
void setToEquilState(ThermoPhase &s, span< const double > x, double t)
Set mixture to an equilibrium state consistent with specified element potentials and temperature.
int estimateEP_Brinkley(ThermoPhase &s, span< double > lambda, span< double > elMoles)
Do a calculation of the element potentials using the Brinkley method, p.
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
double absElemTol
Abs Tol in element number.
int iterations
Iteration counter.
double relTolerance
Relative tolerance.
int maxIterations
Maximum number of iterations.
Multiphase chemical equilibrium solver.
A class for multiphase mixtures.
void init()
Process phases and build atomic composition array.
size_t nSpecies() const
Number of species, summed over all phases.
void addPhase(shared_ptr< ThermoPhase > p, double moles)
Add a phase to the mixture.
size_t nElements() const
Number of elements.
void getMoleFractions(span< double > x) const
Get the species mole fraction vector.
size_t nSpecies() const
Returns the number of species in the phase.
double temperature() const
Temperature (K).
virtual void setPressure(double p)
Set the internally stored pressure (Pa) at constant temperature and composition.
double atomicWeight(size_t m) const
Atomic weight of element m.
string speciesName(size_t k) const
Name of the species with index k.
virtual size_t stateSize() const
Return size of vector defining internal state of the phase.
double moleFraction(size_t k) const
Return the mole fraction of a single species.
virtual double density() const
Density (kg/m^3).
double nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
virtual void setTemperature(double temp)
Set the internally stored temperature of the phase (K).
size_t nElements() const
Number of elements.
virtual void setMoleFractions(span< const double > x)
Set the mole fractions to the specified values.
virtual void restoreState(span< const double > state)
Restore the state of the phase from a previously saved state vector.
virtual double pressure() const
Return the thermodynamic pressure (Pa).
string elementName(size_t m) const
Name of the element with index m.
virtual void saveState(span< double > state) const
Write to array 'state' the current internal state.
Base class for a phase with thermodynamic properties.
virtual void getGibbs_RT(span< double > grt) const
Get the nondimensional Gibbs functions for the species in their standard states at the current T and ...
virtual double minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid.
virtual double maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
double entropy_mass() const
Specific entropy. Units: J/kg/K.
double intEnergy_mass() const
Specific internal energy. Units: J/kg.
virtual double refPressure() const
Returns the reference pressure in Pa.
virtual void getChemPotentials(span< double > mu) const
Get the species chemical potentials. Units: J/kmol.
virtual void getActivityCoefficients(span< double > ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
double enthalpy_mass() const
Specific enthalpy. Units: J/kg.
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
size_t BasisOptimize(bool &usedZeroedSpecies, bool doFormRxn, MultiPhase *mphase, span< size_t > orderVectorSpecies, span< size_t > orderVectorElements, span< double > formRxnMatrix)
Choose the optimum basis of species for the equilibrium calculations.
void ElemRearrange(size_t nComponents, span< const double > elementAbundances, MultiPhase *mphase, span< size_t > orderVectorSpecies, span< size_t > orderVectorElements)
Handles the potential rearrangement of the constraint equations represented by the Formula Matrix.
virtual void setToEquilState(span< const double > mu_RT)
This method is used by the ChemEquil equilibrium solver.
void writelogf(const char *fmt, const Args &... args)
Write a formatted message to the screen.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
U len(const T &container)
Get the size of a container, cast to a signed integer type.
double 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.
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
const double GasConstant
Universal Gas Constant [J/kmol/K].
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Namespace for the Cantera kernel.
const size_t npos
index returned by functions to indicate "no position"
void solve(DenseMatrix &A, span< double > b, size_t nrhs, size_t ldb)
Solve Ax = b. Array b is overwritten on exit with x.
int _equilflag(const char *xy)
map property strings to integers
Contains declarations for string manipulation functions within Cantera.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...