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;
96 if (printDetails > 0 && print_lvl == 0) {
106 if (print_lvl != 0) {
107 plogf(
"VCS CALCULATION METHOD\n\n ");
108 plogf(
"MultiPhase Object\n");
114 plogf(
"\n ELEMENTAL ABUNDANCES CORRECT");
115 plogf(
" FROM ESTIMATE Type\n\n");
116 for (
size_t i = 0; i <
m_nelem; ++i) {
117 writeline(
' ', 26,
false);
123 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - forced\n");
125 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - where necessary\n");
128 plogf(
"\n USER ESTIMATE OF EQUILIBRIUM\n");
130 plogf(
" Stan. Chem. Pot. in J/kmol\n");
131 plogf(
"\n SPECIES FORMULA VECTOR ");
132 writeline(
' ', 41,
false);
133 plogf(
" STAN_CHEM_POT EQUILIBRIUM_EST. Species_Type\n\n");
134 writeline(
' ', 20,
false);
135 for (
size_t i = 0; i <
m_nelem; ++i) {
140 for (
size_t i = 0; i <
m_nsp; ++i) {
142 for (
size_t j = 0; j <
m_nelem; ++j) {
146 writeline(
' ', std::max(55-
int(
m_nelem)*8, 0),
false);
158 for (
size_t i = 0; i <
m_nsp; ++i) {
160 plogf(
"On Input species %-12s has a negative MF, setting it small\n",
181 if (forceComponentCalc) {
182 solve_tp_component_calc(allMinorZeroedSpecies);
184 forceComponentCalc = 0;
193 solve_tp_inner(iti, it1, uptodate_minors, allMinorZeroedSpecies,
194 forceComponentCalc, stage, printDetails > 0);
196 }
else if (stage == EQUILIB_CHECK) {
198 solve_tp_equilib_check(allMinorZeroedSpecies, uptodate_minors,
199 giveUpOnElemAbund, iconv, iti, it1,
201 }
else if (stage == ELEM_ABUND_CHECK) {
203 solve_tp_elem_abund_check(iti, stage, lec, giveUpOnElemAbund,
204 finalElemAbundAttempts, iconv);
205 }
else if (stage == RECHECK_DELETED) {
229 }
else if (stage == RETURN_A) {
245 }
else if (stage == RETURN_B) {
252 plogf(
" --- add_all_deleted(): some rxns not converged. RETURNING TO LOOP!\n");
268 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
306 if (print_lvl > 0 || printDetails > 0) {
313 }
else if (iconv == 1) {
314 plogf(
"WARNING: RANGE SPACE ERROR encountered\n");
320void VCS_SOLVE::solve_tp_component_calc(
bool& allMinorZeroedSpecies)
322 double test = -1.0e-10;
346void VCS_SOLVE::solve_tp_inner(
size_t& iti,
size_t& it1,
347 bool& uptodate_minors,
348 bool& allMinorZeroedSpecies,
349 int& forceComponentCalc,
350 int& stage,
bool printDetails)
359 if (!uptodate_minors) {
364 uptodate_minors =
true;
366 uptodate_minors =
false;
372 plogf(
" Iteration = %3d, Iterations since last evaluation of "
373 "optimal basis = %3d",
376 plogf(
" (all species)\n");
378 plogf(
" (only major species)\n");
405 if (iphasePop !=
npos) {
410 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich "
411 "prevented phase %d popping\n");
419 size_t iphaseDelete =
npos;
421 if (iphasePop ==
npos) {
427 plogf(
" --- vcs_RxnStepSizes not called because alternative"
428 "phase creation delta was used instead\n");
430 size_t doPhaseDeleteKspec =
npos;
431 size_t doPhaseDeleteIph =
npos;
450 if (iphaseDelete !=
npos) {
452 for (
size_t k = 0; k <
m_nsp; k++) {
461 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
462 "we shouldn't be here!");
482 plogf(
" --- Main Loop Treatment of each non-component species ");
484 plogf(
"- Full Calculation:\n");
486 plogf(
"- Major Components Calculation:\n");
488 plogf(
" --- Species IC KMoles Tent_KMoles Rxn_Adj\n");
490 for (
size_t irxn = 0; irxn <
m_numRxnRdc; irxn++) {
497 if (iphasePop !=
npos) {
498 if (iph == iphasePop) {
514 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
516 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
525 for (
size_t j = 0; j <
m_nelem; ++j) {
529 if (atomComp > 0.0) {
544 plogf(
" --- Zeroed species changed to major: ");
548 allMinorZeroedSpecies =
false;
551 plogf(
" --- Zeroed species changed to minor: ");
579 plogf(
" --- %-12s%3d% 11.4E %11.4E %11.4E\n",
606 plogf(
" --- Delete minor species in multispec phase: %-12s\n",
617 stage = RECHECK_DELETED;
640 plogf(
" --- %-12s %3d %11.4E %11.4E %11.4E\n",
695 if (sc_irxn[j] != 0.0) {
717 doPhaseDeleteIph = iph;
719 doPhaseDeleteKspec = kspec;
721 plogf(
" --- SS species changed to zeroedss: ");
728 for (
size_t kk = 0; kk <
m_nsp; kk++) {
755 "VCS_SOLVE::solve_tp_inner",
756 "ds[kspec] = {}, dx = {}, kspec = {}\nwe have a problem!",
774 plogf(
" --- %-12.12s%3d %11.4E %11.4E %11.4E\n",
780 if (doPhaseDeleteIph !=
npos) {
782 plogf(
" --- %-12.12s Main Loop Special Case deleting phase with species:\n",
792 plogf(
" c %11.4E %11.4E %11.4E |\n",
798 plogf(
" --- Finished Main Loop\n");
823 if (par <= 1.01 && par > 0.0) {
827 plogf(
" --- Reduction in step size due to component %s going negative = %11.3E\n",
830 for (
size_t i = 0; i <
m_nsp; ++i) {
846 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
850 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
851 "vcs_solve_TP: ERROR on step change wt[{}:{}]: {} < 0.0",
876 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
879 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E\n",
887 if (printDetails && forced) {
888 plogf(
" -----------------------------------------------------\n");
889 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
890 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
891 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
906 writeline(
' ', 26,
false);
907 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
914 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
916 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
919 plogf(
" -----------------------------------------------------\n");
928 plogf(
" --- Summary of the Update ");
930 plogf(
" (all species):");
932 plogf(
" (only major species):");
935 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
936 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
946 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
954 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
960 writeline(
' ', 56,
false);
961 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
965 plogf(
" --- Phase_Name KMoles(after update)\n");
974 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
976 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E\n",
1003 plogf(
" --- Increment counter increased, step is accepted: %4d\n",
1013 bool justDeletedMultiPhase =
false;
1018 plogf(
" --- Setting microscopic phase %d to zero\n", iph);
1020 justDeletedMultiPhase =
true;
1028 if (justDeletedMultiPhase) {
1029 double test = -1.0e-10;
1040 plogf(
" --- Normal element abundance check");
1049 uptodate_minors =
true;
1061 bool doSwap =
false;
1084 plogf(
" and share nonzero stoic: %-9.1f\n",
1087 forceComponentCalc = 1;
1093 stage = EQUILIB_CHECK;
1103 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1106 for (
size_t irxn = 0; irxn <
m_numRxnRdc; irxn++) {
1111 plogf(
" --- major/minor species is now zeroed out: %s\n",
1118 plogf(
" --- Noncomponent turned from major to minor: ");
1120 plogf(
" --- Component turned into a minor species: ");
1122 plogf(
" --- Zeroed Species turned into a "
1132 plogf(
" --- Noncomponent turned from minor to major: ");
1134 plogf(
" --- Component turned into a major: ");
1136 plogf(
" --- Noncomponent turned from zeroed to major: ");
1151void VCS_SOLVE::solve_tp_equilib_check(
bool& allMinorZeroedSpecies,
1152 bool& uptodate_minors,
1153 bool& giveUpOnElemAbund,
int& solveFail,
1154 size_t& iti,
size_t& it1,
int maxit,
1155 int& stage,
bool& lec)
1157 if (! allMinorZeroedSpecies) {
1159 plogf(
" --- Equilibrium check for major species: ");
1161 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1176 iti = ((it1/4) *4) - it1;
1184 debuglog(
" MAJOR SPECIES CONVERGENCE achieved "
1197 uptodate_minors =
true;
1200 plogf(
" --- Equilibrium check for minor species: ");
1202 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1224 plogf(
" CONVERGENCE achieved\n");
1235 if (!giveUpOnElemAbund) {
1237 plogf(
" --- Check the Full Element Abundances: ");
1247 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1251 stage = ELEM_ABUND_CHECK;
1262 stage = RECHECK_DELETED;
1271void VCS_SOLVE::solve_tp_elem_abund_check(
size_t& iti,
int& stage,
bool& lec,
1272 bool& giveUpOnElemAbund,
1273 int& finalElemAbundAttempts,
1274 int& rangeErrorFound)
1281 rangeErrorFound = 0;
1302 if (finalElemAbundAttempts >= 3) {
1303 giveUpOnElemAbund =
true;
1304 stage = EQUILIB_CHECK;
1306 finalElemAbundAttempts++;
1313 }
else if (ncAfter) {
1317 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1318 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1319 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1320 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition\n");
1322 rangeErrorFound = 1;
1323 giveUpOnElemAbund =
true;
1328 stage = EQUILIB_CHECK;
1335 stage = EQUILIB_CHECK;
1346 if (w_kspec <= 0.0) {
1349 dg_irxn = std::max(dg_irxn, -200.0);
1350 if (dg_irxn >= 23.0) {
1351 double molNum_kspec_new = w_kspec * 1.0e-10;
1358 return molNum_kspec_new - w_kspec;
1377 double a =
clip(w_kspec * s, -1.0+1e-8, 100.0);
1378 double tmp =
clip(-dg_irxn / (1.0 + a), -200.0, 200.0);
1379 double wTrial = w_kspec * exp(tmp);
1380 double molNum_kspec_new = wTrial;
1382 if (wTrial > 100. * w_kspec) {
1384 if (molNumMax < 100. * w_kspec) {
1385 molNumMax = 100. * w_kspec;
1387 if (wTrial > molNumMax) {
1388 molNum_kspec_new = molNumMax;
1390 molNum_kspec_new = wTrial;
1392 }
else if (1.0E10 * wTrial < w_kspec) {
1393 molNum_kspec_new= 1.0E-10 * w_kspec;
1395 molNum_kspec_new = wTrial;
1404 return molNum_kspec_new - w_kspec;
1419 "delete_species() ERROR: called for a component {}", kspec);
1426 double tmp = sc_irxn[j] * delta;
1448 double tmp = sc_irxn[j] * delta;
1471 plogf(
"vcs_zero_species: Couldn't zero the species %d, "
1472 "did delta of %g. orig conc of %g\n",
1492 "Failed to delete a species!");
1508 if (kspec != klast) {
1523 bool stillExists =
false;
1571 for (
size_t k = 0; k <
m_nsp; k++) {
1594 bool successful =
true;
1599 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName);
1614 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
1616 plogf(
" --- delta attempted: %g achieved: %g "
1617 " Zeroing it manually\n", dx, dxTent);
1638 double dxPerm = 0.0, dxPerm2 = 0.0;
1642 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
1655 if (jcomp != kcomp) {
1663 if (fabs(dxPerm2) < fabs(dxPerm)) {
1670 if (dxPerm != 0.0) {
1679 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
1681 plogf(
" --- zeroing it \n");
1705 plogf(
" an active but zeroed species because its phase "
1729 plogf(
" --- Start rechecking deleted species in multispec phases\n");
1753 xtcutoff[iph] = 0.0;
1811 for (
int cits = 0; cits < 3; cits++) {
1846 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1853 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1860 plogf(
" --- add_deleted(): species %s added back in with mol number %g\n",
1863 plogf(
" --- add_deleted(): species %s failed to be added back in\n");
1882 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g\n",
1896 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1905 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1913 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
1914 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
1917 if (s1 > 0.0 || s2 <= 0.0) {
1924 if (fabs(s1 -s2) > 1.0E-200) {
1925 al = s1 / (s1 - s2);
1927 if (al >= 0.95 || al < 0.0) {
1932 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
1950 plogf(
" --- subroutine FORCE adjusted the mole "
1951 "numbers, AL = %10.3f\n", al);
1965 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1973 plogf(
" --- subroutine FORCE: Adj End Slope = %g\n", s2);
1982 size_t jlose =
npos;
1986 for (
size_t i=0; i<77; i++) {
1990 plogf(
" --- Subroutine BASOPT called to ");
1991 if (doJustComponents) {
1992 plogf(
"calculate the number of components\n");
1994 plogf(
"reevaluate the components\n");
1998 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
1999 plogf(
" --- Active | ");
2000 for (
size_t j = 0; j <
m_nelem; j++) {
2004 plogf(
" --- Species | ");
2005 for (
size_t j = 0; j <
m_nelem; j++) {
2009 for (k = 0; k <
m_nsp; k++) {
2011 for (
size_t j = 0; j <
m_nelem; j++) {
2025 vector<int> ipiv(ncTrial);
2032 for (k = 0; k <
m_nsp; k++) {
2042 while (jr < ncTrial) {
2043 bool exhausted =
false;
2052 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"spSize is nonpositive");
2060 for (
size_t i = jr + 1; i <
m_nsp; ++i) {
2062 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"spSize is nonpositive");
2064 bool doSwap =
false;
2068 doSwap =
m_aw[i] > (
m_aw[k] * 1.001);
2074 doSwap =
m_aw[i] > (
m_aw[k] * 1.001);
2124 double maxConcPossKspec = 0.0;
2125 double maxConcPoss = 0.0;
2126 size_t kfound =
npos;
2127 int minNonZeroes = 100000;
2128 int nonZeroesKspec = 0;
2129 for (
size_t kspec = ncTrial; kspec <
m_nsp; kspec++) {
2131 maxConcPossKspec = 1.0E10;
2133 for (
size_t j = 0; j <
m_nelem; ++j) {
2142 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
2143 if (nonZeroesKspec <= minNonZeroes) {
2144 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
2154 minNonZeroes = std::min(minNonZeroes, nonZeroesKspec);
2155 maxConcPoss = std::max(maxConcPoss, maxConcPossKspec);
2159 if (kfound ==
npos) {
2162 for (
size_t kspec = ncTrial; kspec <
m_nsp; kspec++) {
2163 if (
m_aw[kspec] >= 0.0) {
2164 size_t irxn = kspec - ncTrial;
2175 if (
m_aw[k] == test) {
2181 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we shouldn't be here");
2186 for (
size_t i = 0; i <
m_nsp; ++i) {
2190 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
2205 for (
size_t j = 0; j <
m_nelem; ++j) {
2212 for (
size_t j = 0; j < jl; ++j) {
2214 for (
size_t i = 0; i <
m_nelem; ++i) {
2221 for (
size_t j = 0; j < jl; ++j) {
2222 for (
size_t i = 0; i <
m_nelem; ++i) {
2231 for (
size_t ml = 0; ml <
m_nelem; ++ml) {
2236 if (
m_sa[jr] > 1.0e-6) {
2260 plogf(
" as component %3d\n", jr);
2271 plogf(
" as component %3d\n", jr);
2277 if (doJustComponents) {
2308 C.
resize(ncTrial, ncTrial);
2309 for (
size_t j = 0; j < ncTrial; ++j) {
2310 for (
size_t i = 0; i < ncTrial; ++i) {
2316 for (
size_t j = 0; j < ncTrial; ++j) {
2328 for (
size_t j = 0; j <
m_nelem; j++) {
2333 for (
size_t j = 0; j <
m_nelem; j++) {
2338 for (k = 0; k <
m_nsp; k++) {
2340 for (
size_t j = 0; j < ncTrial; ++j) {
2341 for (
size_t i = 0; i < ncTrial; ++i) {
2351 for (
size_t j = 0; j < ncTrial; ++j) {
2361 size_t i = k - ncTrial;
2362 for (
size_t j = 0; j < ncTrial; j++) {
2371 for (
size_t j = 0; j < ncTrial; j++) {
2378 plogf(
" --- Components:");
2379 for (
size_t j = 0; j < ncTrial; j++) {
2382 plogf(
"\n --- Components Moles:");
2383 for (
size_t j = 0; j < ncTrial; j++) {
2385 plogf(
" % -10.3E", 0.0);
2390 plogf(
"\n --- NonComponent| Moles |");
2391 for (
size_t j = 0; j < ncTrial; j++) {
2399 plogf(
"|% -10.3E|", 0.0);
2403 for (
size_t j = 0; j < ncTrial; j++) {
2411 double sumMax = -1.0;
2417 for (
size_t j = 0; j < ncTrial; ++j) {
2420 for (
size_t n = 0; n < ncTrial; n++) {
2423 sum += coeff * numElements;
2427 for (
size_t n = 0; n < ncTrial; n++) {
2430 sum += coeff * numElements;
2433 if (fabs(sum) > sumMax) {
2441 if (fabs(sum) > 1.0E-6) {
2442 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we have a prob");
2446 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
2448 plogf(
" element = %d ", jMax);
2452 for (
size_t i=0; i<77; i++) {
2470 for (
size_t irxn = 0; irxn <
m_numRxnTot; ++irxn) {
2476 for (
size_t j = 0; j < ncTrial; ++j) {
2478 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
2508 for (
size_t j = 0; j <
m_nelem; ++j) {
2511 if (atomComp > 0.0) {
2515 plogf(
" --- %s can not be nonzero because"
2516 " needed element %s is zero\n",
2536 if (stoicC != 0.0) {
2537 double negChangeComp = - stoicC;
2538 if (negChangeComp > 0.0) {
2541 plogf(
" --- %s is prevented from popping into existence because"
2542 " a needed component to be consumed, %s, has a zero mole number\n",
2551 }
else if (negChangeComp < 0.0) {
2554 plogf(
" --- %s is prevented from popping into existence because"
2555 " a needed component %s is in a zeroed-phase that would be "
2556 "popped into existence at the same time\n",
2643 const int ll,
const size_t lbot,
const size_t ltop)
2645 span<double> tPhMoles;
2646 span<double> actCoeff;
2647 span<double> feSpecies;
2648 span<double> molNum;
2661 "Subroutine vcs_dfe called with bad stateCalc value: {}", stateCalc);
2667 plogf(
" --- Subroutine vcs_dfe called for one species: ");
2670 plogf(
" --- Subroutine vcs_dfe called for all species");
2672 }
else if (ll > 0) {
2673 plogf(
" --- Subroutine vcs_dfe called for components and minors");
2675 plogf(
" --- Subroutine vcs_dfe called for components and majors");
2678 plogf(
" using tentative solution");
2688 for (
size_t kspec = 0; kspec <
m_nsp; kspec++) {
2691 tlogMoles[iph] += molNum[kspec];
2696 "VCS_SOLVE::vcs_dfe",
2697 "phase Moles may be off, iph = {}, {} {}",
2698 iph, tlogMoles[iph], tPhMoles[iph]);
2702 if (tPhMoles[iph] > 0.0) {
2703 tlogMoles[iph] = log(tPhMoles[iph]);
2710 for (
size_t iphase = 0; iphase <
m_numPhases; iphase++) {
2719 auto updateSpecies = [&](
size_t kspec) {
2723 "We have an inconsistency!");
2725 "We have an unexpected situation!");
2741 if (tPhMoles[iphase] > 0.0) {
2743 - tlogMoles[iphase];
2748 logTerm = log(actCoeff[kspec] * molNum[kspec]) - tlogMoles[iphase];
2760 for (
size_t kspec = lbot; kspec < ltop; ++kspec) {
2761 feSpecies[kspec] = updateSpecies(kspec);
2765 feSpecies[kspec] = updateSpecies(kspec);
2771 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2774 feSpecies[kspec] = updateSpecies(kspec);
2777 }
else if (ll > 0) {
2779 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2782 feSpecies[kspec] = updateSpecies(kspec);
2795 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2798 dgLocal[irxn] < 0.0) {
2800 tmp += dgLocal[irxn] * dgLocal[irxn];
2812 for (
size_t i = 0; i <
m_nsp; i++) {
2831void VCS_SOLVE::check_tmoles()
const
2834 double m_tPhaseMoles_old_a = 0.0;
2836 for (
size_t k = 0; k <
m_nsp; k++) {
2844 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
2861 "wrong stateCalc value: {}", vcsState);
2870 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
2872 plogf(
" --- Species Status decision is reevaluated\n");
2874 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
2885 plogf(
"%s\n", sString);
2895 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
2908 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
2912 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
2919 throw CanteraError(
"VCS_SOLVE::vcs_evaluate_speciesType",
2933 const int vcsState,
const bool alterZeroedPhases)
2940 span<double> deltaGRxn, feSpecies, molNumSpecies, actCoeffSpecies;
2952 throw CanteraError(
"VCS_SOLVE::vcs_deltag",
"bad vcsState");
2956 plogf(
" --- Subroutine vcs_deltag called for ");
2958 plogf(
"major noncomponents\n");
2959 }
else if (L == 0) {
2960 plogf(
"all noncomponents\n");
2962 plogf(
"minor noncomponents\n");
2968 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2975 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
2981 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
2985 }
else if (L == 0) {
2987 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
2992 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
2994 dtmp_ptr[kspec] < 0.0) {
2999 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3004 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
3011 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3013 dtmp_ptr[kspec] < 0.0) {
3018 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3063 if (alterZeroedPhases &&
false) {
3069 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3072 sum += molNumSpecies[kspec];
3085 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3090 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
3091 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
3099 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3103 deltaGRxn[irxn] = 1.0 - poly;
3117 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
3153 for (
size_t j = 0; j <
m_nelem; ++j) {
3157 for (
size_t i = 0; i <
m_nsp; i++) {
3160 for (
size_t i = 0; i <
m_nsp; i++) {
3172 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
3190void 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...