20enum stages {MAIN, EQUILIB_CHECK, ELEM_ABUND_CHECK,
21 RECHECK_DELETED, RETURN_A, RETURN_B};
28void VCS_SOLVE::checkDelta1(span<const double> dsLocal,
29 span<const double> delTPhMoles,
size_t kspec)
32 for (
size_t k = 0; k < kspec; k++) {
35 dchange[iph] += dsLocal[k];
38 for (
size_t iphase = 0; iphase <
m_numPhases; iphase++) {
40 if (!
vcs_doubleEqual(dchange[iphase]/denom, delTPhMoles[iphase]/denom)) {
41 throw CanteraError(
"VCS_SOLVE::checkDelta1",
42 "we have found a problem");
69 for (
size_t i = 0; i <
m_nsp; ++i) {
86 bool allMinorZeroedSpecies =
false;
89 bool giveUpOnElemAbund =
false;
90 int finalElemAbundAttempts = 0;
91 bool uptodate_minors =
true;
92 int forceComponentCalc = 1;
98 int basisOptCount = 0;
102 if (printDetails > 0 && print_lvl == 0) {
112 if (print_lvl != 0) {
113 plogf(
"VCS CALCULATION METHOD\n\n ");
114 plogf(
"MultiPhase Object\n");
120 plogf(
"\n ELEMENTAL ABUNDANCES CORRECT");
121 plogf(
" FROM ESTIMATE Type\n\n");
122 for (
size_t i = 0; i <
m_nelem; ++i) {
123 writeline(
' ', 26,
false);
129 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - forced\n");
131 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - where necessary\n");
134 plogf(
"\n USER ESTIMATE OF EQUILIBRIUM\n");
136 plogf(
" Stan. Chem. Pot. in J/kmol\n");
137 plogf(
"\n SPECIES FORMULA VECTOR ");
138 writeline(
' ', 41,
false);
139 plogf(
" STAN_CHEM_POT EQUILIBRIUM_EST. Species_Type\n\n");
140 writeline(
' ', 20,
false);
141 for (
size_t i = 0; i <
m_nelem; ++i) {
146 for (
size_t i = 0; i <
m_nsp; ++i) {
148 for (
size_t j = 0; j <
m_nelem; ++j) {
152 writeline(
' ', std::max(55-
int(
m_nelem)*8, 0),
false);
164 for (
size_t i = 0; i <
m_nsp; ++i) {
166 plogf(
"On Input species %-12s has a negative MF, setting it small\n",
187 if (forceComponentCalc) {
188 solve_tp_component_calc(allMinorZeroedSpecies);
190 forceComponentCalc = 0;
203 solve_tp_inner(iti, it1, uptodate_minors, allMinorZeroedSpecies,
204 forceComponentCalc, stage, printDetails > 0, basisOptCount);
206 }
else if (stage == EQUILIB_CHECK) {
208 solve_tp_equilib_check(allMinorZeroedSpecies, uptodate_minors,
209 giveUpOnElemAbund, iconv, iti, it1,
211 }
else if (stage == ELEM_ABUND_CHECK) {
213 solve_tp_elem_abund_check(iti, stage, lec, giveUpOnElemAbund,
214 finalElemAbundAttempts, iconv);
215 }
else if (stage == RECHECK_DELETED) {
239 }
else if (stage == RETURN_A) {
255 }
else if (stage == RETURN_B) {
262 plogf(
" --- add_all_deleted(): some rxns not converged. RETURNING TO LOOP!\n");
278 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
316 if (print_lvl > 0 || printDetails > 0) {
324 }
else if (iconv == 1) {
325 plogf(
"WARNING: RANGE SPACE ERROR encountered\n");
332void VCS_SOLVE::solve_tp_component_calc(
bool& allMinorZeroedSpecies)
334 double test = -1.0e-10;
358void VCS_SOLVE::solve_tp_inner(
size_t& iti,
size_t& it1,
359 bool& uptodate_minors,
360 bool& allMinorZeroedSpecies,
361 int& forceComponentCalc,
362 int& stage,
bool printDetails,
372 if (!uptodate_minors) {
377 uptodate_minors =
true;
379 uptodate_minors =
false;
385 plogf(
" Iteration = %3d, Iterations since last evaluation of "
386 "optimal basis = %3d",
389 plogf(
" (all species)\n");
391 plogf(
" (only major species)\n");
418 if (iphasePop !=
npos) {
423 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich "
424 "prevented phase %d popping\n");
432 size_t iphaseDelete =
npos;
434 if (iphasePop ==
npos) {
440 plogf(
" --- vcs_RxnStepSizes not called because alternative"
441 "phase creation delta was used instead\n");
443 size_t doPhaseDeleteKspec =
npos;
444 size_t doPhaseDeleteIph =
npos;
463 if (iphaseDelete !=
npos) {
465 for (
size_t k = 0; k <
m_nsp; k++) {
474 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
475 "we shouldn't be here!");
495 plogf(
" --- Main Loop Treatment of each non-component species ");
497 plogf(
"- Full Calculation:\n");
499 plogf(
"- Major Components Calculation:\n");
501 plogf(
" --- Species IC KMoles Tent_KMoles Rxn_Adj\n");
503 for (
size_t irxn = 0; irxn <
m_numRxnRdc; irxn++) {
510 if (iphasePop !=
npos) {
511 if (iph == iphasePop) {
527 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
529 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
538 for (
size_t j = 0; j <
m_nelem; ++j) {
542 if (atomComp > 0.0) {
557 plogf(
" --- Zeroed species changed to major: ");
561 allMinorZeroedSpecies =
false;
564 plogf(
" --- Zeroed species changed to minor: ");
592 plogf(
" --- %-12s%3d% 11.4E %11.4E %11.4E\n",
619 plogf(
" --- Delete minor species in multispec phase: %-12s\n",
630 stage = RECHECK_DELETED;
653 plogf(
" --- %-12s %3d %11.4E %11.4E %11.4E\n",
708 if (sc_irxn[j] != 0.0) {
730 doPhaseDeleteIph = iph;
732 doPhaseDeleteKspec = kspec;
734 plogf(
" --- SS species changed to zeroedss: ");
741 for (
size_t kk = 0; kk <
m_nsp; kk++) {
768 "VCS_SOLVE::solve_tp_inner",
769 "ds[kspec] = {}, dx = {}, kspec = {}\nwe have a problem!",
787 plogf(
" --- %-12.12s%3d %11.4E %11.4E %11.4E\n",
793 if (doPhaseDeleteIph !=
npos) {
795 plogf(
" --- %-12.12s Main Loop Special Case deleting phase with species:\n",
805 plogf(
" c %11.4E %11.4E %11.4E |\n",
811 plogf(
" --- Finished Main Loop\n");
836 if (par <= 1.01 && par > 0.0) {
840 plogf(
" --- Reduction in step size due to component %s going negative = %11.3E\n",
843 for (
size_t i = 0; i <
m_nsp; ++i) {
859 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
863 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
864 "vcs_solve_TP: ERROR on step change wt[{}:{}]: {} < 0.0",
889 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
892 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E\n",
900 if (printDetails && forced) {
901 plogf(
" -----------------------------------------------------\n");
902 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
903 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
904 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
919 writeline(
' ', 26,
false);
920 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
927 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
929 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
932 plogf(
" -----------------------------------------------------\n");
941 plogf(
" --- Summary of the Update ");
943 plogf(
" (all species):");
945 plogf(
" (only major species):");
948 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
949 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
959 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
967 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
973 writeline(
' ', 56,
false);
974 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
978 plogf(
" --- Phase_Name KMoles(after update)\n");
987 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
989 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E\n",
1016 plogf(
" --- Increment counter increased, step is accepted: %4d\n",
1026 bool justDeletedMultiPhase =
false;
1031 plogf(
" --- Setting microscopic phase %d to zero\n", iph);
1033 justDeletedMultiPhase =
true;
1041 if (justDeletedMultiPhase) {
1042 double test = -1.0e-10;
1053 plogf(
" --- Normal element abundance check");
1062 uptodate_minors =
true;
1080 int maxBasisOpt = 200;
1081 if (basisOptCount <= maxBasisOpt) {
1088 bool doSwap =
false;
1111 plogf(
" and share nonzero stoic: %-9.1f\n",
1114 forceComponentCalc = 1;
1126 debuglog(
" --- Optimum basis check suppressed: basis is oscillating\n",
1130 stage = EQUILIB_CHECK;
1140 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1143 for (
size_t irxn = 0; irxn <
m_numRxnRdc; irxn++) {
1148 plogf(
" --- major/minor species is now zeroed out: %s\n",
1155 plogf(
" --- Noncomponent turned from major to minor: ");
1157 plogf(
" --- Component turned into a minor species: ");
1159 plogf(
" --- Zeroed Species turned into a "
1169 plogf(
" --- Noncomponent turned from minor to major: ");
1171 plogf(
" --- Component turned into a major: ");
1173 plogf(
" --- Noncomponent turned from zeroed to major: ");
1188void VCS_SOLVE::solve_tp_equilib_check(
bool& allMinorZeroedSpecies,
1189 bool& uptodate_minors,
1190 bool& giveUpOnElemAbund,
int& solveFail,
1191 size_t& iti,
size_t& it1,
int maxit,
1192 int& stage,
bool& lec)
1194 if (! allMinorZeroedSpecies) {
1196 plogf(
" --- Equilibrium check for major species: ");
1198 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1213 iti = ((it1/4) *4) - it1;
1221 debuglog(
" MAJOR SPECIES CONVERGENCE achieved "
1234 uptodate_minors =
true;
1237 plogf(
" --- Equilibrium check for minor species: ");
1239 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1261 plogf(
" CONVERGENCE achieved\n");
1272 if (!giveUpOnElemAbund) {
1274 plogf(
" --- Check the Full Element Abundances: ");
1284 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1288 stage = ELEM_ABUND_CHECK;
1299 stage = RECHECK_DELETED;
1308void VCS_SOLVE::solve_tp_elem_abund_check(
size_t& iti,
int& stage,
bool& lec,
1309 bool& giveUpOnElemAbund,
1310 int& finalElemAbundAttempts,
1311 int& rangeErrorFound)
1318 rangeErrorFound = 0;
1339 if (finalElemAbundAttempts >= 3) {
1340 giveUpOnElemAbund =
true;
1341 stage = EQUILIB_CHECK;
1343 finalElemAbundAttempts++;
1350 }
else if (ncAfter) {
1354 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1355 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1356 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1357 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition\n");
1359 rangeErrorFound = 1;
1360 giveUpOnElemAbund =
true;
1365 stage = EQUILIB_CHECK;
1372 stage = EQUILIB_CHECK;
1383 if (w_kspec <= 0.0) {
1386 dg_irxn = std::max(dg_irxn, -200.0);
1387 if (dg_irxn >= 23.0) {
1388 double molNum_kspec_new = w_kspec * 1.0e-10;
1395 return molNum_kspec_new - w_kspec;
1414 double a =
clip(w_kspec * s, -1.0+1e-8, 100.0);
1415 double tmp =
clip(-dg_irxn / (1.0 + a), -200.0, 200.0);
1416 double wTrial = w_kspec * exp(tmp);
1417 double molNum_kspec_new = wTrial;
1419 if (wTrial > 100. * w_kspec) {
1421 if (molNumMax < 100. * w_kspec) {
1422 molNumMax = 100. * w_kspec;
1424 if (wTrial > molNumMax) {
1425 molNum_kspec_new = molNumMax;
1427 molNum_kspec_new = wTrial;
1429 }
else if (1.0E10 * wTrial < w_kspec) {
1430 molNum_kspec_new= 1.0E-10 * w_kspec;
1432 molNum_kspec_new = wTrial;
1441 return molNum_kspec_new - w_kspec;
1456 "delete_species() ERROR: called for a component {}", kspec);
1463 double tmp = sc_irxn[j] * delta;
1485 double tmp = sc_irxn[j] * delta;
1508 plogf(
"vcs_zero_species: Couldn't zero the species %d, "
1509 "did delta of %g. orig conc of %g\n",
1529 "Failed to delete a species!");
1545 if (kspec != klast) {
1560 bool stillExists =
false;
1608 for (
size_t k = 0; k <
m_nsp; k++) {
1631 bool successful =
true;
1636 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName);
1651 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
1653 plogf(
" --- delta attempted: %g achieved: %g "
1654 " Zeroing it manually\n", dx, dxTent);
1675 double dxPerm = 0.0, dxPerm2 = 0.0;
1679 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
1692 if (jcomp != kcomp) {
1700 if (fabs(dxPerm2) < fabs(dxPerm)) {
1707 if (dxPerm != 0.0) {
1716 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
1718 plogf(
" --- zeroing it \n");
1742 plogf(
" an active but zeroed species because its phase "
1766 plogf(
" --- Start rechecking deleted species in multispec phases\n");
1790 xtcutoff[iph] = 0.0;
1848 for (
int cits = 0; cits < 3; cits++) {
1883 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1890 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1897 plogf(
" --- add_deleted(): species %s added back in with mol number %g\n",
1900 plogf(
" --- add_deleted(): species %s failed to be added back in\n");
1919 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g\n",
1933 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1942 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1950 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
1951 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
1954 if (s1 > 0.0 || s2 <= 0.0) {
1961 if (fabs(s1 -s2) > 1.0E-200) {
1962 al = s1 / (s1 - s2);
1964 if (al >= 0.95 || al < 0.0) {
1969 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
1987 plogf(
" --- subroutine FORCE adjusted the mole "
1988 "numbers, AL = %10.3f\n", al);
2002 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2010 plogf(
" --- subroutine FORCE: Adj End Slope = %g\n", s2);
2019 size_t jlose =
npos;
2023 for (
size_t i=0; i<77; i++) {
2027 plogf(
" --- Subroutine BASOPT called to ");
2028 if (doJustComponents) {
2029 plogf(
"calculate the number of components\n");
2031 plogf(
"reevaluate the components\n");
2035 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
2036 plogf(
" --- Active | ");
2037 for (
size_t j = 0; j <
m_nelem; j++) {
2041 plogf(
" --- Species | ");
2042 for (
size_t j = 0; j <
m_nelem; j++) {
2046 for (k = 0; k <
m_nsp; k++) {
2048 for (
size_t j = 0; j <
m_nelem; j++) {
2062 vector<int> ipiv(ncTrial);
2069 for (k = 0; k <
m_nsp; k++) {
2079 while (jr < ncTrial) {
2080 bool exhausted =
false;
2089 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"spSize is nonpositive");
2097 for (
size_t i = jr + 1; i <
m_nsp; ++i) {
2099 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"spSize is nonpositive");
2101 bool doSwap =
false;
2105 doSwap =
m_aw[i] > (
m_aw[k] * 1.001);
2111 doSwap =
m_aw[i] > (
m_aw[k] * 1.001);
2161 double maxConcPossKspec = 0.0;
2162 double maxConcPoss = 0.0;
2163 size_t kfound =
npos;
2164 int minNonZeroes = 100000;
2165 int nonZeroesKspec = 0;
2166 for (
size_t kspec = ncTrial; kspec <
m_nsp; kspec++) {
2168 maxConcPossKspec = 1.0E10;
2170 for (
size_t j = 0; j <
m_nelem; ++j) {
2179 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
2180 if (nonZeroesKspec <= minNonZeroes) {
2181 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
2191 minNonZeroes = std::min(minNonZeroes, nonZeroesKspec);
2192 maxConcPoss = std::max(maxConcPoss, maxConcPossKspec);
2196 if (kfound ==
npos) {
2199 for (
size_t kspec = ncTrial; kspec <
m_nsp; kspec++) {
2200 if (
m_aw[kspec] >= 0.0) {
2201 size_t irxn = kspec - ncTrial;
2212 if (
m_aw[k] == test) {
2218 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we shouldn't be here");
2223 for (
size_t i = 0; i <
m_nsp; ++i) {
2227 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
2242 for (
size_t j = 0; j <
m_nelem; ++j) {
2249 for (
size_t j = 0; j < jl; ++j) {
2251 for (
size_t i = 0; i <
m_nelem; ++i) {
2258 for (
size_t j = 0; j < jl; ++j) {
2259 for (
size_t i = 0; i <
m_nelem; ++i) {
2268 for (
size_t ml = 0; ml <
m_nelem; ++ml) {
2273 if (
m_sa[jr] > 1.0e-6) {
2297 plogf(
" as component %3d\n", jr);
2308 plogf(
" as component %3d\n", jr);
2314 if (doJustComponents) {
2345 C.
resize(ncTrial, ncTrial);
2346 for (
size_t j = 0; j < ncTrial; ++j) {
2347 for (
size_t i = 0; i < ncTrial; ++i) {
2353 for (
size_t j = 0; j < ncTrial; ++j) {
2365 for (
size_t j = 0; j <
m_nelem; j++) {
2370 for (
size_t j = 0; j <
m_nelem; j++) {
2375 for (k = 0; k <
m_nsp; k++) {
2377 for (
size_t j = 0; j < ncTrial; ++j) {
2378 for (
size_t i = 0; i < ncTrial; ++i) {
2388 for (
size_t j = 0; j < ncTrial; ++j) {
2398 size_t i = k - ncTrial;
2399 for (
size_t j = 0; j < ncTrial; j++) {
2408 for (
size_t j = 0; j < ncTrial; j++) {
2415 plogf(
" --- Components:");
2416 for (
size_t j = 0; j < ncTrial; j++) {
2419 plogf(
"\n --- Components Moles:");
2420 for (
size_t j = 0; j < ncTrial; j++) {
2422 plogf(
" % -10.3E", 0.0);
2427 plogf(
"\n --- NonComponent| Moles |");
2428 for (
size_t j = 0; j < ncTrial; j++) {
2436 plogf(
"|% -10.3E|", 0.0);
2440 for (
size_t j = 0; j < ncTrial; j++) {
2448 double sumMax = -1.0;
2454 for (
size_t j = 0; j < ncTrial; ++j) {
2457 for (
size_t n = 0; n < ncTrial; n++) {
2460 sum += coeff * numElements;
2464 for (
size_t n = 0; n < ncTrial; n++) {
2467 sum += coeff * numElements;
2470 if (fabs(sum) > sumMax) {
2478 if (fabs(sum) > 1.0E-6) {
2479 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we have a prob");
2483 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
2485 plogf(
" element = %d ", jMax);
2489 for (
size_t i=0; i<77; i++) {
2507 for (
size_t irxn = 0; irxn <
m_numRxnTot; ++irxn) {
2513 for (
size_t j = 0; j < ncTrial; ++j) {
2515 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
2545 for (
size_t j = 0; j <
m_nelem; ++j) {
2548 if (atomComp > 0.0) {
2552 plogf(
" --- %s can not be nonzero because"
2553 " needed element %s is zero\n",
2573 if (stoicC != 0.0) {
2574 double negChangeComp = - stoicC;
2575 if (negChangeComp > 0.0) {
2578 plogf(
" --- %s is prevented from popping into existence because"
2579 " a needed component to be consumed, %s, has a zero mole number\n",
2588 }
else if (negChangeComp < 0.0) {
2591 plogf(
" --- %s is prevented from popping into existence because"
2592 " a needed component %s is in a zeroed-phase that would be "
2593 "popped into existence at the same time\n",
2680 const int ll,
const size_t lbot,
const size_t ltop)
2682 span<double> tPhMoles;
2683 span<double> actCoeff;
2684 span<double> feSpecies;
2685 span<double> molNum;
2698 "Subroutine vcs_dfe called with bad stateCalc value: {}", stateCalc);
2704 plogf(
" --- Subroutine vcs_dfe called for one species: ");
2707 plogf(
" --- Subroutine vcs_dfe called for all species");
2709 }
else if (ll > 0) {
2710 plogf(
" --- Subroutine vcs_dfe called for components and minors");
2712 plogf(
" --- Subroutine vcs_dfe called for components and majors");
2715 plogf(
" using tentative solution");
2725 for (
size_t kspec = 0; kspec <
m_nsp; kspec++) {
2728 tlogMoles[iph] += molNum[kspec];
2733 "VCS_SOLVE::vcs_dfe",
2734 "phase Moles may be off, iph = {}, {} {}",
2735 iph, tlogMoles[iph], tPhMoles[iph]);
2739 if (tPhMoles[iph] > 0.0) {
2740 tlogMoles[iph] = log(tPhMoles[iph]);
2747 for (
size_t iphase = 0; iphase <
m_numPhases; iphase++) {
2756 auto updateSpecies = [&](
size_t kspec) {
2760 "We have an inconsistency!");
2762 "We have an unexpected situation!");
2778 if (tPhMoles[iphase] > 0.0) {
2780 - tlogMoles[iphase];
2785 logTerm = log(actCoeff[kspec] * molNum[kspec]) - tlogMoles[iphase];
2797 for (
size_t kspec = lbot; kspec < ltop; ++kspec) {
2798 feSpecies[kspec] = updateSpecies(kspec);
2802 feSpecies[kspec] = updateSpecies(kspec);
2808 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2811 feSpecies[kspec] = updateSpecies(kspec);
2814 }
else if (ll > 0) {
2816 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2819 feSpecies[kspec] = updateSpecies(kspec);
2832 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2835 dgLocal[irxn] < 0.0) {
2837 tmp += dgLocal[irxn] * dgLocal[irxn];
2849 for (
size_t i = 0; i <
m_nsp; i++) {
2868void VCS_SOLVE::check_tmoles()
const
2871 double m_tPhaseMoles_old_a = 0.0;
2873 for (
size_t k = 0; k <
m_nsp; k++) {
2881 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
2898 "wrong stateCalc value: {}", vcsState);
2907 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
2909 plogf(
" --- Species Status decision is reevaluated\n");
2911 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
2922 plogf(
"%s\n", sString);
2932 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
2945 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
2949 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
2956 throw CanteraError(
"VCS_SOLVE::vcs_evaluate_speciesType",
2970 const int vcsState,
const bool alterZeroedPhases)
2977 span<double> deltaGRxn, feSpecies, molNumSpecies, actCoeffSpecies;
2989 throw CanteraError(
"VCS_SOLVE::vcs_deltag",
"bad vcsState");
2993 plogf(
" --- Subroutine vcs_deltag called for ");
2995 plogf(
"major noncomponents\n");
2996 }
else if (L == 0) {
2997 plogf(
"all noncomponents\n");
2999 plogf(
"minor noncomponents\n");
3005 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
3012 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3018 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3022 }
else if (L == 0) {
3024 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3029 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3031 dtmp_ptr[kspec] < 0.0) {
3036 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3041 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
3048 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3050 dtmp_ptr[kspec] < 0.0) {
3055 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3100 if (alterZeroedPhases &&
false) {
3106 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3109 sum += molNumSpecies[kspec];
3122 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3127 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
3128 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
3136 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3140 deltaGRxn[irxn] = 1.0 - poly;
3154 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
3190 for (
size_t j = 0; j <
m_nelem; ++j) {
3194 for (
size_t i = 0; i <
m_nsp; i++) {
3197 for (
size_t i = 0; i <
m_nsp; i++) {
3209 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
3227void VCS_SOLVE::vcs_setFlagsVolPhases(
const bool upToDate,
const int stateCalc)
Headers for the DenseMatrix object, which deals with dense rectangular matrices and description of th...
Headers for the MultiPhase object that is used to set up multiphase equilibrium problems (see Chemica...
void zero()
Set all of the entries to zero.
span< double > col(size_t j)
Return a writable span over column j.
vector< double > & data()
Return a reference to the data vector.
Base class for exceptions thrown by Cantera classes.
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
void resize(size_t n, size_t m, double v=0.0) override
Resize the matrix.
void uploadMoleFractionsFromPhases()
Update the locally-stored composition within this object to match the current compositions of the pha...
void setPhaseMoles(const size_t n, const double moles)
Set the number of moles of phase with index n.
int Its
Current number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
int T_Basis_Opts
Total number of optimizations of the components basis set done.
int Basis_Opts
number of optimizations of the components basis set done
int T_Its
Total number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
int T_Calls_vcs_TP
Current number of calls to vcs_TP.
vector< double > m_deltaPhaseMoles
Change in the total moles in each phase.
size_t m_numPhases
Number of Phases in the problem.
int m_doEstimateEquil
Setting for whether to do an initial estimate.
vector< double > m_deltaMolNumSpecies
Reaction Adjustments for each species during the current step.
vector< double > m_spSize
total size of the species
vector< double > m_scSize
Absolute size of the stoichiometric coefficients.
int vcs_evalSS_TP(int ipr, int ip1, double Temp, double pres)
Evaluate the standard state free energies at the current temperature and pressure.
vector< double > m_sm
QR matrix work space used in vcs_basopt()
vector< double > m_wtSpecies
Molecular weight of each species.
vector< size_t > m_indexRxnToSpecies
Mapping between the species index for noncomponent species and the full species index.
void vcs_prep(int printLvl)
This routine is mostly concerned with changing the private data to be consistent with what's needed f...
vector< double > m_sa
Gram-Schmidt work space used in vcs_basopt()
double l2normdg(span< const double > dg) const
Calculate the norm of a deltaGibbs free energy vector.
vector< size_t > m_phaseID
Mapping from the species number to the phase number.
vector< string > m_speciesName
Species string name for the kth species.
void vcs_deltag(const int L, const bool doDeleted, const int vcsState, const bool alterZeroedPhases=true)
This subroutine calculates reaction free energy changes for all noncomponent formation reactions.
double m_tolmaj2
Below this, major species aren't refined any more.
vector< double > m_deltaGRxn_new
Delta G(irxn) for the noncomponent species in the mechanism.
Array2D m_np_dLnActCoeffdMolNum
Change in the log of the activity coefficient with respect to the mole number multiplied by the phase...
void vcs_updateMolNumVolPhases(const int stateCalc)
Update all underlying vcs_VolPhase objects.
void vcs_report(int iconv)
Print out a report on the state of the equilibrium problem to standard output.
size_t m_nelem
Number of element constraints in the problem.
vector< double > m_PMVolumeSpecies
Partial molar volumes of the species.
vector< int > m_elementActive
Specifies whether an element constraint is active.
int m_useActCoeffJac
Choice of Hessians.
vector< size_t > m_speciesLocalPhaseIndex
Index that keeps track of the index of the species within the local phase.
void vcs_updateVP(const int stateCalc)
This routine uploads the state of the system into all of the vcs_VolumePhase objects in the current p...
size_t vcs_add_all_deleted()
Provide an estimate for the deleted species in phases that are not zeroed out.
bool vcs_globStepDamp()
This routine optimizes the minimization of the total Gibbs free energy by making sure the slope of th...
void vcs_basopt(const bool doJustComponents, double test)
Choose the optimum species basis for the calculations.
vector< string > m_elementName
Vector of strings containing the element names.
vector< int > m_speciesUnknownType
Specifies the species unknown type.
vector< double > m_TmpPhase
Temporary vector of length NPhase.
vector< size_t > m_speciesMapIndex
Index vector that keeps track of the species vector rearrangement.
Array2D m_phaseParticipation
This is 1 if the phase, iphase, participates in the formation reaction irxn, and zero otherwise.
vector< int > m_actConventionSpecies
specifies the activity convention of the phase containing the species
void vcs_inest()
Create an initial estimate of the solution to the equilibrium problem.
vector< double > m_elemAbundances
Element abundances vector.
vector< double > m_tPhaseMoles_new
total kmols of species in each phase in the tentative soln vector
vector< double > m_actCoeffSpecies_old
Molar-based Activity Coefficients for Species based on old mole numbers.
vector< double > m_SSfeSpecies
Standard state chemical potentials for species K at the current temperature and pressure.
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.
double m_tolmin2
Below this, minor species aren't refined any more.
vector< double > m_lnMnaughtSpecies
specifies the ln(Mnaught) used to calculate the chemical potentials
vector< int > m_elType
Type of the element constraint.
void vcs_elab()
Computes the current elemental abundances vector.
void prob_report(int print_lvl)
Print out the problem specification in all generality as it currently exists in the VCS_SOLVE object.
double vcs_minor_alt_calc(size_t kspec, size_t irxn, bool &do_delete) const
Minor species alternative calculation.
vector< double > m_molNumSpecies_old
Total moles of the species.
size_t m_numRxnMinorZeroed
Number of active species which are currently either treated as minor species.
vector< double > m_aw
work array of mole fractions used in vcs_basopt()
size_t m_numSpeciesRdc
Current number of species in the problems.
int vcs_delete_species(const size_t kspec)
Change a single species from active to inactive status.
vector< double > m_feSpecies_old
Free energy vector from the start of the current iteration.
int m_debug_print_lvl
Debug printing lvl.
void vcs_counters_init(int ifunc)
Initialize the internal counters.
void vcs_reinsert_deleted(size_t kspec)
We make decisions on the initial mole number, and major-minor status here.
vector< double > m_ss
Gram-Schmidt work space used in vcs_basopt()
vector< double > m_chargeSpecies
Charge of each species. Length = number of species.
Array2D m_formulaMatrix
Formula matrix for the problem.
Array2D m_stoichCoeffRxnMatrix
Stoichiometric coefficient matrix for the reaction mechanism expressed in Reduced Canonical Form.
size_t m_numRxnRdc
Current number of non-component species in the problem.
VCS_COUNTERS * m_VCount
Timing and iteration counters for the vcs object.
vector< double > m_deltaGRxn_Deficient
Last deltag[irxn] from the previous step with additions for possible births of zeroed phases.
vector< unique_ptr< vcs_VolPhase > > m_VolPhaseList
Array of Phase Structures. Length = number of phases.
size_t m_numComponents
Number of components calculated for the problem.
void vcs_prob_specifyFully()
Fully specify the problem to be solved.
int vcs_species_type(const size_t kspec) const
Evaluate the species category for the indicated species.
double m_pressurePA
Pressure.
vector< double > m_feSpecies_new
Dimensionless new free energy for all the species in the mechanism at the new tentative T,...
double m_Faraday_dim
dimensionless value of Faraday's constant, F / RT (1/volt)
int vcs_recheck_deleted()
Recheck deleted species in multispecies phases.
double m_tolmin
Tolerance requirements for minor species.
size_t m_nsp
Total number of species in the problems.
vector< double > m_actCoeffSpecies_new
Molar-based Activity Coefficients for Species.
bool vcs_elabcheck(int ibound)
Checks to see if the element abundances are in compliance.
vector< char > m_SSPhase
Boolean indicating whether a species belongs to a single-species phase.
bool vcs_delete_multiphase(const size_t iph)
This routine handles the bookkeeping involved with the deletion of multiphase phases from the problem...
vector< double > m_phasePhi
electric potential of the iph phase
int delta_species(const size_t kspec, double &delta)
Change the concentration of a species by delta moles.
int vcs_zero_species(const size_t kspec)
Zero out the concentration of a species.
vector< double > m_elemAbundancesGoal
Element abundances vector Goals.
size_t vcs_RxnStepSizes(int &forceComponentCalc, size_t &kSpecial)
Calculates formation reaction step sizes.
size_t vcs_popPhaseID()
Decision as to whether a phase pops back into existence.
Array2D m_deltaMolNumPhase
Change in the number of moles of phase, iphase, due to the noncomponent formation reaction,...
vector< int > m_speciesStatus
Major -Minor status vector for the species in the problem.
vector< double > m_deltaGRxn_tmp
Temporary vector of Rxn DeltaG's.
double vcs_tmoles()
Calculates the total number of moles of species in all phases.
void vcs_switch_pos(const bool ifunc, const size_t k1, const size_t k2)
Swaps the indices for all of the global data for two species, k1 and k2.
int m_printLvl
Print level for print routines.
void vcs_dfe(const int stateCalc, const int ll, const size_t lbot, const size_t ltop)
Calculate the dimensionless chemical potentials of all species or of certain groups of species,...
vector< double > m_tPhaseMoles_old
Total kmols of species in each phase.
double vcs_Total_Gibbs(span< const double > w, span< const double > fe, span< const double > tPhMoles)
Calculate the total dimensionless Gibbs free energy.
int vcs_popPhaseRxnStepSizes(const size_t iphasePop)
Calculates the deltas of the reactions due to phases popping into existence.
size_t m_numRxnTot
Total number of non-component species in the problem.
vector< double > m_molNumSpecies_new
Tentative value of the mole number vector.
double m_temperature
Temperature (Kelvin)
double m_tolmaj
Tolerance requirement for major species.
vector< double > m_deltaGRxn_old
Last deltag[irxn] from the previous step.
bool vcs_evaluate_speciesType()
This routine evaluates the species type for all species.
void vcs_TCounters_report()
Create a report on the plog file containing iteration counters.
int vcs_elcorr(span< double > aa, span< double > x)
This subroutine corrects for element abundances.
double m_totalMolNum
Total number of kmoles in all phases.
Phase information and Phase calculations for vcs.
double electricPotential() const
Returns the electric field of the phase.
size_t nSpecies() const
Return the number of species in the phase.
string PhaseName
String name for the phase.
void sendToVCS_ActCoeff(const int stateCalc, span< double > AC)
Fill in an activity coefficients vector within a VCS_SOLVE object.
void updateFromVCS_MoleNumbers(const int stateCalc)
Update the moles within the phase, if necessary.
bool m_singleSpecies
If true, this phase consists of a single species.
int exists() const
Retrieve the kth Species structure for the species belonging to this phase.
size_t spGlobalIndexVCS(const size_t spIndex) const
Return the Global VCS index of the kth species in the phase.
void setMolesFromVCSCheck(const int vcsStateStatus, span< const double > molesSpeciesVCS, span< const double > TPhMoles)
Set the moles within the phase.
void setTotalMoles(const double totalMols)
Sets the total moles in the phase.
void setSpGlobalIndexVCS(const size_t spIndex, const size_t spGlobalIndex)
set the Global VCS index of the kth species in the phase
void setExistence(const int existence)
Set the existence flag in the object.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
void debuglog(const string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
void writelogendl()
Write an end of line character to the screen and flush output.
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
const double Faraday
Faraday constant [C/kmol].
const double GasConstant
Universal Gas Constant [J/kmol/K].
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.
const char * vcs_speciesType_string(int speciesStatus, int length)
Returns a const char string representing the type of the species given by the first argument.
bool vcs_doubleEqual(double d1, double d2)
Simple routine to check whether two doubles are equal up to roundoff error.
void checkArraySize(const char *procedure, size_t available, size_t required)
Wrapper for throwing ArraySizeError.
Contains declarations for string manipulation functions within Cantera.
Header for the object representing each phase within vcs.
#define VCS_SPECIES_INTERFACIALVOLTAGE
Species refers to an electron in the metal.
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
Unknown refers to the voltage level of a phase.
#define VCS_STATECALC_OLD
State Calculation based on the old or base mole numbers.
#define VCS_DELETE_MINORSPECIES_CUTOFF
Cutoff relative mole number value, below which species are deleted from the equilibrium problem.
#define VCS_RELDELETE_SPECIES_CUTOFF
Cutoff relative mole fraction value, below which species are deleted from the equilibrium problem.
#define VCS_SPECIES_COMPONENT
These defines are valid values for spStatus()
#define VCS_SPECIES_MAJOR
Species is a major species.
#define VCS_PHASE_EXIST_NO
Phase doesn't currently exist in the mixture.
#define VCS_PHASE_EXIST_ALWAYS
These defines are valid values for the phase existence flag.
#define VCS_SPECIES_STOICHZERO
Species lies in a multicomponent phase that is active, but species concentration is zero due to stoic...
#define VCS_ELEM_TYPE_ABSPOS
Normal element constraint consisting of positive coefficients for the formula matrix.
#define VCS_STATECALC_NEW
State Calculation based on the new or tentative mole numbers.
#define VCS_SPECIES_TYPE_MOLNUM
Unknown refers to mole number of a single species.
#define VCS_SPECIES_ZEROEDMS
Species lies in a multicomponent phase with concentration zero.
#define VCS_SPECIES_ZEROEDPHASE
Species lies in a multicomponent phase that is zeroed atm.
#define VCS_SPECIES_ACTIVEBUTZERO
Species lies in a multicomponent phase that is active, but species concentration is zero.
#define VCS_SPECIES_ZEROEDSS
Species is a SS phase, that is currently zeroed out.
#define VCS_DELETE_PHASE_CUTOFF
Cutoff relative moles below which a phase is deleted from the equilibrium problem.
#define VCS_SPECIES_DELETED
Species has such a small mole fraction it is deleted even though its phase may possibly exist.
#define VCS_SPECIES_MINOR
Species is a major species.
#define VCS_PHASE_EXIST_YES
Phase is a normal phase that currently exists.
#define VCS_PHASE_EXIST_ZEROEDPHASE
Phase currently is zeroed due to a programmatic issue.
#define plogf
define this Cantera function to replace printf
Header file for the internal object that holds the vcs equilibrium problem (see Class VCS_SOLVE and C...