20enum stages {MAIN, EQUILIB_CHECK, ELEM_ABUND_CHECK,
21 RECHECK_DELETED, RETURN_A, RETURN_B};
28void VCS_SOLVE::checkDelta1(
double*
const dsLocal,
29 double*
const 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");
404 vector<size_t> phasePopPhaseIDs(0);
406 if (iphasePop !=
npos) {
411 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich "
412 "prevented phase %d popping\n");
420 size_t iphaseDelete =
npos;
422 if (iphasePop ==
npos) {
428 plogf(
" --- vcs_RxnStepSizes not called because alternative"
429 "phase creation delta was used instead\n");
431 size_t doPhaseDeleteKspec =
npos;
432 size_t doPhaseDeleteIph =
npos;
451 if (iphaseDelete !=
npos) {
453 for (
size_t k = 0; k <
m_nsp; k++) {
462 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
463 "we shouldn't be here!");
483 plogf(
" --- Main Loop Treatment of each non-component species ");
485 plogf(
"- Full Calculation:\n");
487 plogf(
"- Major Components Calculation:\n");
489 plogf(
" --- Species IC KMoles Tent_KMoles Rxn_Adj\n");
491 for (
size_t irxn = 0; irxn <
m_numRxnRdc; irxn++) {
498 if (iphasePop !=
npos) {
499 if (iph == iphasePop) {
515 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
517 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
526 for (
size_t j = 0; j <
m_nelem; ++j) {
530 if (atomComp > 0.0) {
545 plogf(
" --- Zeroed species changed to major: ");
549 allMinorZeroedSpecies =
false;
552 plogf(
" --- Zeroed species changed to minor: ");
580 plogf(
" --- %-12s%3d% 11.4E %11.4E %11.4E\n",
607 plogf(
" --- Delete minor species in multispec phase: %-12s\n",
618 stage = RECHECK_DELETED;
641 plogf(
" --- %-12s %3d %11.4E %11.4E %11.4E\n",
696 if (sc_irxn[j] != 0.0) {
718 doPhaseDeleteIph = iph;
720 doPhaseDeleteKspec = kspec;
722 plogf(
" --- SS species changed to zeroedss: ");
729 for (
size_t kk = 0; kk <
m_nsp; kk++) {
756 "VCS_SOLVE::solve_tp_inner",
757 "ds[kspec] = {}, dx = {}, kspec = {}\nwe have a problem!",
776 plogf(
" --- %-12.12s%3d %11.4E %11.4E %11.4E\n",
782 if (doPhaseDeleteIph !=
npos) {
784 plogf(
" --- %-12.12s Main Loop Special Case deleting phase with species:\n",
794 plogf(
" c %11.4E %11.4E %11.4E |\n",
800 plogf(
" --- Finished Main Loop\n");
825 if (par <= 1.01 && par > 0.0) {
829 plogf(
" --- Reduction in step size due to component %s going negative = %11.3E\n",
832 for (
size_t i = 0; i <
m_nsp; ++i) {
849 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
853 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
854 "vcs_solve_TP: ERROR on step change wt[{}:{}]: {} < 0.0",
879 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
882 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E\n",
890 if (printDetails && forced) {
891 plogf(
" -----------------------------------------------------\n");
892 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
893 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
894 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
909 writeline(
' ', 26,
false);
910 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
917 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
919 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
922 plogf(
" -----------------------------------------------------\n");
931 plogf(
" --- Summary of the Update ");
933 plogf(
" (all species):");
935 plogf(
" (only major species):");
938 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
939 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
949 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
957 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
963 writeline(
' ', 56,
false);
964 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
968 plogf(
" --- Phase_Name KMoles(after update)\n");
977 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
980 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E\n",
1008 plogf(
" --- Increment counter increased, step is accepted: %4d\n",
1018 bool justDeletedMultiPhase =
false;
1023 plogf(
" --- Setting microscopic phase %d to zero\n", iph);
1025 justDeletedMultiPhase =
true;
1033 if (justDeletedMultiPhase) {
1034 double test = -1.0e-10;
1045 plogf(
" --- Normal element abundance check");
1054 uptodate_minors =
true;
1066 bool doSwap =
false;
1089 plogf(
" and share nonzero stoic: %-9.1f\n",
1092 forceComponentCalc = 1;
1098 stage = EQUILIB_CHECK;
1108 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1111 for (
size_t irxn = 0; irxn <
m_numRxnRdc; irxn++) {
1116 plogf(
" --- major/minor species is now zeroed out: %s\n",
1123 plogf(
" --- Noncomponent turned from major to minor: ");
1125 plogf(
" --- Component turned into a minor species: ");
1127 plogf(
" --- Zeroed Species turned into a "
1137 plogf(
" --- Noncomponent turned from minor to major: ");
1139 plogf(
" --- Component turned into a major: ");
1141 plogf(
" --- Noncomponent turned from zeroed to major: ");
1156void VCS_SOLVE::solve_tp_equilib_check(
bool& allMinorZeroedSpecies,
1157 bool& uptodate_minors,
1158 bool& giveUpOnElemAbund,
int& solveFail,
1159 size_t& iti,
size_t& it1,
int maxit,
1160 int& stage,
bool& lec)
1162 if (! allMinorZeroedSpecies) {
1164 plogf(
" --- Equilibrium check for major species: ");
1166 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1181 iti = ((it1/4) *4) - it1;
1189 debuglog(
" MAJOR SPECIES CONVERGENCE achieved "
1202 uptodate_minors =
true;
1205 plogf(
" --- Equilibrium check for minor species: ");
1207 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1229 plogf(
" CONVERGENCE achieved\n");
1240 if (!giveUpOnElemAbund) {
1242 plogf(
" --- Check the Full Element Abundances: ");
1252 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1256 stage = ELEM_ABUND_CHECK;
1267 stage = RECHECK_DELETED;
1276void VCS_SOLVE::solve_tp_elem_abund_check(
size_t& iti,
int& stage,
bool& lec,
1277 bool& giveUpOnElemAbund,
1278 int& finalElemAbundAttempts,
1279 int& rangeErrorFound)
1286 rangeErrorFound = 0;
1307 if (finalElemAbundAttempts >= 3) {
1308 giveUpOnElemAbund =
true;
1309 stage = EQUILIB_CHECK;
1311 finalElemAbundAttempts++;
1318 }
else if (ncAfter) {
1322 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1323 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1324 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1325 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition\n");
1327 rangeErrorFound = 1;
1328 giveUpOnElemAbund =
true;
1333 stage = EQUILIB_CHECK;
1340 stage = EQUILIB_CHECK;
1351 if (w_kspec <= 0.0) {
1354 dg_irxn = std::max(dg_irxn, -200.0);
1355 if (dg_irxn >= 23.0) {
1356 double molNum_kspec_new = w_kspec * 1.0e-10;
1363 return molNum_kspec_new - w_kspec;
1382 double a =
clip(w_kspec * s, -1.0+1e-8, 100.0);
1383 double tmp =
clip(-dg_irxn / (1.0 + a), -200.0, 200.0);
1384 double wTrial = w_kspec * exp(tmp);
1385 double molNum_kspec_new = wTrial;
1387 if (wTrial > 100. * w_kspec) {
1389 if (molNumMax < 100. * w_kspec) {
1390 molNumMax = 100. * w_kspec;
1392 if (wTrial > molNumMax) {
1393 molNum_kspec_new = molNumMax;
1395 molNum_kspec_new = wTrial;
1397 }
else if (1.0E10 * wTrial < w_kspec) {
1398 molNum_kspec_new= 1.0E-10 * w_kspec;
1400 molNum_kspec_new = wTrial;
1409 return molNum_kspec_new - w_kspec;
1424 "delete_species() ERROR: called for a component {}", kspec);
1428 double dx = *delta_ptr;
1432 double tmp = sc_irxn[j] * dx;
1455 double tmp = sc_irxn[j] * dx;
1478 plogf(
"vcs_zero_species: Couldn't zero the species %d, "
1479 "did delta of %g. orig conc of %g\n",
1499 "Failed to delete a species!");
1515 if (kspec != klast) {
1530 bool stillExists =
false;
1579 for (
size_t k = 0; k <
m_nsp; k++) {
1602 bool successful =
true;
1607 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName);
1622 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
1624 plogf(
" --- delta attempted: %g achieved: %g "
1625 " Zeroing it manually\n", dx, dxTent);
1646 double dxPerm = 0.0, dxPerm2 = 0.0;
1650 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
1663 if (jcomp != kcomp) {
1671 if (fabs(dxPerm2) < fabs(dxPerm)) {
1678 if (dxPerm != 0.0) {
1687 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
1689 plogf(
" --- zeroing it \n");
1713 plogf(
" an active but zeroed species because its phase "
1737 plogf(
" --- Start rechecking deleted species in multispec phases\n");
1761 xtcutoff[iph] = 0.0;
1819 for (
int cits = 0; cits < 3; cits++) {
1854 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1861 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1868 plogf(
" --- add_deleted(): species %s added back in with mol number %g\n",
1871 plogf(
" --- add_deleted(): species %s failed to be added back in\n");
1890 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g\n",
1904 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1913 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1921 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
1922 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
1925 if (s1 > 0.0 || s2 <= 0.0) {
1932 if (fabs(s1 -s2) > 1.0E-200) {
1933 al = s1 / (s1 - s2);
1935 if (al >= 0.95 || al < 0.0) {
1940 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
1958 plogf(
" --- subroutine FORCE adjusted the mole "
1959 "numbers, AL = %10.3f\n", al);
1973 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
1981 plogf(
" --- subroutine FORCE: Adj End Slope = %g\n", s2);
1990 size_t jlose =
npos;
1994 for (
size_t i=0; i<77; i++) {
1998 plogf(
" --- Subroutine BASOPT called to ");
1999 if (doJustComponents) {
2000 plogf(
"calculate the number of components\n");
2002 plogf(
"reevaluate the components\n");
2006 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
2007 plogf(
" --- Active | ");
2008 for (
size_t j = 0; j <
m_nelem; j++) {
2012 plogf(
" --- Species | ");
2013 for (
size_t j = 0; j <
m_nelem; j++) {
2017 for (k = 0; k <
m_nsp; k++) {
2019 for (
size_t j = 0; j <
m_nelem; j++) {
2033 vector<int> ipiv(ncTrial);
2040 for (k = 0; k <
m_nsp; k++) {
2050 while (jr < ncTrial) {
2051 bool exhausted =
false;
2060 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"spSize is nonpositive");
2068 for (
size_t i = jr + 1; i <
m_nsp; ++i) {
2070 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"spSize is nonpositive");
2072 bool doSwap =
false;
2076 doSwap =
m_aw[i] > (
m_aw[k] * 1.001);
2082 doSwap =
m_aw[i] > (
m_aw[k] * 1.001);
2132 double maxConcPossKspec = 0.0;
2133 double maxConcPoss = 0.0;
2134 size_t kfound =
npos;
2135 int minNonZeroes = 100000;
2136 int nonZeroesKspec = 0;
2137 for (
size_t kspec = ncTrial; kspec <
m_nsp; kspec++) {
2139 maxConcPossKspec = 1.0E10;
2141 for (
size_t j = 0; j <
m_nelem; ++j) {
2150 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
2151 if (nonZeroesKspec <= minNonZeroes) {
2152 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
2162 minNonZeroes = std::min(minNonZeroes, nonZeroesKspec);
2163 maxConcPoss = std::max(maxConcPoss, maxConcPossKspec);
2167 if (kfound ==
npos) {
2170 for (
size_t kspec = ncTrial; kspec <
m_nsp; kspec++) {
2171 if (
m_aw[kspec] >= 0.0) {
2172 size_t irxn = kspec - ncTrial;
2183 if (
m_aw[k] == test) {
2189 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we shouldn't be here");
2194 for (
size_t i = 0; i <
m_nsp; ++i) {
2198 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
2213 for (
size_t j = 0; j <
m_nelem; ++j) {
2220 for (
size_t j = 0; j < jl; ++j) {
2222 for (
size_t i = 0; i <
m_nelem; ++i) {
2229 for (
size_t j = 0; j < jl; ++j) {
2230 for (
size_t i = 0; i <
m_nelem; ++i) {
2239 for (
size_t ml = 0; ml <
m_nelem; ++ml) {
2244 if (
m_sa[jr] > 1.0e-6) {
2268 plogf(
" as component %3d\n", jr);
2279 plogf(
" as component %3d\n", jr);
2285 if (doJustComponents) {
2316 C.
resize(ncTrial, ncTrial);
2317 for (
size_t j = 0; j < ncTrial; ++j) {
2318 for (
size_t i = 0; i < ncTrial; ++i) {
2324 for (
size_t j = 0; j < ncTrial; ++j) {
2336 for (
size_t j = 0; j <
m_nelem; j++) {
2341 for (
size_t j = 0; j <
m_nelem; j++) {
2346 for (k = 0; k <
m_nsp; k++) {
2348 for (
size_t j = 0; j < ncTrial; ++j) {
2349 for (
size_t i = 0; i < ncTrial; ++i) {
2359 for (
size_t j = 0; j < ncTrial; ++j) {
2369 size_t i = k - ncTrial;
2370 for (
size_t j = 0; j < ncTrial; j++) {
2379 for (
size_t j = 0; j < ncTrial; j++) {
2386 plogf(
" --- Components:");
2387 for (
size_t j = 0; j < ncTrial; j++) {
2390 plogf(
"\n --- Components Moles:");
2391 for (
size_t j = 0; j < ncTrial; j++) {
2393 plogf(
" % -10.3E", 0.0);
2398 plogf(
"\n --- NonComponent| Moles |");
2399 for (
size_t j = 0; j < ncTrial; j++) {
2407 plogf(
"|% -10.3E|", 0.0);
2411 for (
size_t j = 0; j < ncTrial; j++) {
2419 double sumMax = -1.0;
2425 for (
size_t j = 0; j < ncTrial; ++j) {
2428 for (
size_t n = 0; n < ncTrial; n++) {
2431 sum += coeff * numElements;
2435 for (
size_t n = 0; n < ncTrial; n++) {
2438 sum += coeff * numElements;
2441 if (fabs(sum) > sumMax) {
2449 if (fabs(sum) > 1.0E-6) {
2450 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we have a prob");
2454 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
2456 plogf(
" element = %d ", jMax);
2460 for (
size_t i=0; i<77; i++) {
2478 for (
size_t irxn = 0; irxn <
m_numRxnTot; ++irxn) {
2484 for (
size_t j = 0; j < ncTrial; ++j) {
2486 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
2516 for (
size_t j = 0; j <
m_nelem; ++j) {
2519 if (atomComp > 0.0) {
2523 plogf(
" --- %s can not be nonzero because"
2524 " needed element %s is zero\n",
2544 if (stoicC != 0.0) {
2545 double negChangeComp = - stoicC;
2546 if (negChangeComp > 0.0) {
2549 plogf(
" --- %s is prevented from popping into existence because"
2550 " a needed component to be consumed, %s, has a zero mole number\n",
2559 }
else if (negChangeComp < 0.0) {
2562 plogf(
" --- %s is prevented from popping into existence because"
2563 " a needed component %s is in a zeroed-phase that would be "
2564 "popped into existence at the same time\n",
2651 const int ll,
const size_t lbot,
const size_t ltop)
2653 double* tPhMoles_ptr=0;
2654 double* actCoeff_ptr=0;
2655 double* feSpecies=0;
2669 "Subroutine vcs_dfe called with bad stateCalc value: {}", stateCalc);
2675 plogf(
" --- Subroutine vcs_dfe called for one species: ");
2678 plogf(
" --- Subroutine vcs_dfe called for all species");
2680 }
else if (ll > 0) {
2681 plogf(
" --- Subroutine vcs_dfe called for components and minors");
2683 plogf(
" --- Subroutine vcs_dfe called for components and majors");
2686 plogf(
" using tentative solution");
2695 for (
size_t kspec = 0; kspec <
m_nsp; kspec++) {
2698 tlogMoles[iph] += molNum[kspec];
2703 "VCS_SOLVE::vcs_dfe",
2704 "phase Moles may be off, iph = {}, {} {}",
2705 iph, tlogMoles[iph], tPhMoles_ptr[iph]);
2709 if (tPhMoles_ptr[iph] > 0.0) {
2710 tlogMoles[iph] = log(tPhMoles_ptr[iph]);
2717 for (
size_t iphase = 0; iphase <
m_numPhases; iphase++) {
2726 auto updateSpecies = [&](
size_t kspec) {
2730 "We have an inconsistency!");
2732 "We have an unexpected situation!");
2748 if (tPhMoles_ptr[iphase] > 0.0) {
2750 - tlogMoles[iphase];
2755 logTerm = log(actCoeff_ptr[kspec] * molNum[kspec]) - tlogMoles[iphase];
2767 for (
size_t kspec = lbot; kspec < ltop; ++kspec) {
2768 feSpecies[kspec] = updateSpecies(kspec);
2772 feSpecies[kspec] = updateSpecies(kspec);
2778 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2781 feSpecies[kspec] = updateSpecies(kspec);
2784 }
else if (ll > 0) {
2786 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2789 feSpecies[kspec] = updateSpecies(kspec);
2801 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2804 dgLocal[irxn] < 0.0) {
2806 tmp += dgLocal[irxn] * dgLocal[irxn];
2818 for (
size_t i = 0; i <
m_nsp; i++) {
2837void VCS_SOLVE::check_tmoles()
const
2840 double m_tPhaseMoles_old_a = 0.0;
2842 for (
size_t k = 0; k <
m_nsp; k++) {
2850 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
2869 "wrong stateCalc value: {}", vcsState);
2878 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
2880 plogf(
" --- Species Status decision is reevaluated\n");
2882 for (
size_t kspec = 0; kspec <
m_nsp; ++kspec) {
2893 plogf(
"%s\n", sString);
2903 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
2916 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
2920 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
2927 throw CanteraError(
"VCS_SOLVE::vcs_evaluate_speciesType",
2941 const int vcsState,
const bool alterZeroedPhases)
2950 double* molNumSpecies;
2951 double* actCoeffSpecies;
2963 throw CanteraError(
"VCS_SOLVE::vcs_deltag",
"bad vcsState");
2967 plogf(
" --- Subroutine vcs_deltag called for ");
2969 plogf(
"major noncomponents\n");
2970 }
else if (L == 0) {
2971 plogf(
"all noncomponents\n");
2973 plogf(
"minor noncomponents\n");
2979 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
2986 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
2992 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
2996 }
else if (L == 0) {
2998 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3003 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3005 dtmp_ptr[kspec] < 0.0) {
3010 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3015 for (
size_t irxn = 0; irxn <
m_numRxnRdc; ++irxn) {
3022 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3024 dtmp_ptr[kspec] < 0.0) {
3029 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3074 if (alterZeroedPhases &&
false) {
3080 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3083 sum += molNumSpecies[kspec];
3096 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3101 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
3102 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
3110 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3114 deltaGRxn[irxn] = 1.0 - poly;
3128 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
3164 for (
size_t j = 0; j <
m_nelem; ++j) {
3168 for (
size_t i = 0; i <
m_nsp; i++) {
3171 for (
size_t i = 0; i <
m_nsp; i++) {
3183 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
3201void 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.
double * ptrColumn(size_t j)
Return a pointer to the top of column j, columns are contiguous in memory.
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.
size_t vcs_popPhaseID(vector< size_t > &phasePopPhaseIDs)
Decision as to whether a phase pops back into existence.
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()
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.
int vcs_elcorr(double aa[], double x[])
This subroutine corrects for element abundances.
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.
double vcs_minor_alt_calc(size_t kspec, size_t irxn, bool *do_delete) const
Minor species alternative calculation.
vector< double > m_SSfeSpecies
Standard state chemical potentials for species K at the current temperature and pressure.
double l2normdg(double dg[]) const
Calculate the norm of a deltaGibbs free energy vector.
int delta_species(const size_t kspec, double *const delta_ptr)
Change the concentration of a species by delta moles.
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.
vector< double > m_molNumSpecies_old
Total moles of the species.
double vcs_Total_Gibbs(double *w, double *fe, double *tPhMoles)
Calculate the total dimensionless Gibbs free energy.
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 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.
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.
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.
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 setMolesFromVCSCheck(const int vcsStateStatus, const double *molesSpeciesVCS, const double *const TPhMoles)
Set the moles within the phase.
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 setTotalMoles(const double totalMols)
Sets the total moles in the phase.
void sendToVCS_ActCoeff(const int stateCalc, double *const AC)
Fill in an activity coefficients vector within a VCS_SOLVE object.
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"
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 solve(DenseMatrix &A, double *b, size_t nrhs, size_t ldb)
Solve Ax = b. Array b is overwritten on exit with x.
Contains declarations for string manipulation functions within Cantera.
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...