21 enum stages {MAIN, EQUILIB_CHECK, ELEM_ABUND_CHECK,
22 RECHECK_DELETED, RETURN_A, RETURN_B};
28 void VCS_SOLVE::checkDelta1(
double*
const dsLocal,
29 double*
const delTPhMoles,
size_t kspec)
32 for (
size_t k = 0; k < kspec; k++) {
34 size_t iph = m_phaseID[k];
35 dchange[iph] += dsLocal[k];
38 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
39 double denom = max(m_totalMolNum, 1.0E-4);
40 if (!
vcs_doubleEqual(dchange[iphase]/denom, delTPhMoles[iphase]/denom)) {
41 throw CanteraError(
"VCS_SOLVE::checkDelta1",
42 "we have found a problem");
47 int VCS_SOLVE::vcs_solve_TP(
int print_lvl,
int printDetails,
int maxit)
50 bool allMinorZeroedSpecies =
false;
53 int rangeErrorFound = 0;
54 bool giveUpOnElemAbund =
false;
55 int finalElemAbundAttempts = 0;
56 bool uptodate_minors =
true;
57 int forceComponentCalc = 1;
61 m_debug_print_lvl = printDetails;
62 if (printDetails > 0 && print_lvl == 0) {
70 m_sm.assign(m_nelem * m_nelem, 0.0);
71 m_ss.assign(m_nelem, 0.0);
72 m_sa.assign(m_nelem, 0.0);
73 m_aw.assign(m_nsp, 0.0);
74 m_wx.assign(m_nelem, 0.0);
76 int solveFail =
false;
83 plogf(
"VCS CALCULATION METHOD\n\n ");
84 plogf(
"MultiPhase Object\n");
85 plogf(
"\n\n%5d SPECIES\n%5d ELEMENTS\n", m_nsp, m_nelem);
86 plogf(
"%5d COMPONENTS\n", m_numComponents);
87 plogf(
"%5d PHASES\n", m_numPhases);
88 plogf(
" PRESSURE%22.8g %3s\n", m_pressurePA,
"Pa ");
89 plogf(
" TEMPERATURE%19.3f K\n", m_temperature);
92 plogf(
" PHASE1 INERTS%17.3f\n", TPhInertMoles[0]);
94 if (m_numPhases > 1) {
95 plogf(
" PHASE2 INERTS%17.3f\n", TPhInertMoles[1]);
97 plogf(
"\n ELEMENTAL ABUNDANCES CORRECT");
98 plogf(
" FROM ESTIMATE Type\n\n");
99 for (
size_t i = 0; i < m_nelem; ++i) {
100 writeline(
' ', 26,
false);
101 plogf(
"%-2.2s", m_elementName[i]);
102 plogf(
"%20.12E%20.12E %3d\n", m_elemAbundancesGoal[i], m_elemAbundances[i],
105 if (m_doEstimateEquil < 0) {
106 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - forced\n");
107 }
else if (m_doEstimateEquil > 0) {
108 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - where necessary\n");
110 if (m_doEstimateEquil == 0) {
111 plogf(
"\n USER ESTIMATE OF EQUILIBRIUM\n");
113 plogf(
" Stan. Chem. Pot. in J/kmol\n");
114 plogf(
"\n SPECIES FORMULA VECTOR ");
115 writeline(
' ', 41,
false);
116 plogf(
" STAN_CHEM_POT EQUILIBRIUM_EST. Species_Type\n\n");
117 writeline(
' ', 20,
false);
118 for (
size_t i = 0; i < m_nelem; ++i) {
119 plogf(
"%-4.4s ", m_elementName[i]);
123 for (
size_t i = 0; i < m_nsp; ++i) {
124 plogf(
" %-18.18s", m_speciesName[i]);
125 for (
size_t j = 0; j < m_nelem; ++j) {
126 plogf(
"% -7.3g ", m_formulaMatrix(i,j));
128 plogf(
" %3d ", m_phaseID[i]);
129 writeline(
' ', std::max(55-
int(m_nelem)*8, 0),
false);
130 plogf(
"%12.5E %12.5E", RT * m_SSfeSpecies[i], m_molNumSpecies_old[i]);
141 for (
size_t i = 0; i < m_nsp; ++i) {
142 if (m_molNumSpecies_old[i] < 0.0) {
143 plogf(
"On Input species %-12s has a negative MF, setting it small\n",
145 size_t iph = m_phaseID[i];
148 m_molNumSpecies_old[i] = tmp;
164 if (forceComponentCalc) {
165 int retn = solve_tp_component_calc(allMinorZeroedSpecies);
170 forceComponentCalc = 0;
176 if (m_VCount->Its > maxit) {
179 solve_tp_inner(iti, it1, uptodate_minors, allMinorZeroedSpecies,
180 forceComponentCalc, stage, printDetails > 0, ANOTE);
182 }
else if (stage == EQUILIB_CHECK) {
184 solve_tp_equilib_check(allMinorZeroedSpecies, uptodate_minors,
185 giveUpOnElemAbund, solveFail, iti, it1,
187 }
else if (stage == ELEM_ABUND_CHECK) {
189 solve_tp_elem_abund_check(iti, stage, lec, giveUpOnElemAbund,
190 finalElemAbundAttempts, rangeErrorFound);
191 }
else if (stage == RECHECK_DELETED) {
201 size_t npb = vcs_recheck_deleted();
215 }
else if (stage == RETURN_A) {
217 size_t npb = vcs_recheck_deleted();
231 }
else if (stage == RETURN_B) {
234 size_t npb = vcs_add_all_deleted();
237 if (m_debug_print_lvl >= 1) {
238 plogf(
" --- add_all_deleted(): some rxns not converged. RETURNING TO LOOP!\n");
253 m_molNumSpecies_new.assign(m_molNumSpecies_new.size(), 0.0);
254 for (
size_t kspec = 0; kspec < m_nsp; ++kspec) {
255 if (m_SSPhase[kspec]) {
256 m_molNumSpecies_new[kspec] = 1.0;
258 size_t iph = m_phaseID[kspec];
259 if (m_tPhaseMoles_old[iph] != 0.0) {
260 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] / m_tPhaseMoles_old[iph];
266 size_t i = m_speciesLocalPhaseIndex[kspec];
267 m_molNumSpecies_new[kspec] = m_VolPhaseList[iph]->molefraction(i);
272 if (rangeErrorFound) {
278 m_VCount->Time_vcs_TP = tsecond;
279 m_VCount->T_Time_vcs_TP += m_VCount->Time_vcs_TP;
280 m_VCount->T_Calls_vcs_TP++;
281 m_VCount->T_Its += m_VCount->Its;
282 m_VCount->T_Basis_Opts += m_VCount->Basis_Opts;
283 m_VCount->T_Time_basopt += m_VCount->Time_basopt;
289 int VCS_SOLVE::solve_tp_component_calc(
bool& allMinorZeroedSpecies)
291 double test = -1.0e-10;
292 bool usedZeroedSpecies;
293 int retn = vcs_basopt(
false, &m_aw[0], &m_sa[0], &m_sm[0], &m_ss[0],
294 test, &usedZeroedSpecies);
304 allMinorZeroedSpecies = vcs_evaluate_speciesType();
307 if (! vcs_elabcheck(0)) {
308 debuglog(
" --- Element Abundance check failed\n", m_debug_print_lvl >= 2);
309 vcs_elcorr(&m_sm[0], &m_wx[0]);
316 debuglog(
" --- Element Abundance check passed\n", m_debug_print_lvl >= 2);
321 void VCS_SOLVE::solve_tp_inner(
size_t& iti,
size_t& it1,
322 bool& uptodate_minors,
323 bool& allMinorZeroedSpecies,
324 int& forceComponentCalc,
325 int& stage,
bool printDetails,
char* ANOTE)
334 if (!uptodate_minors) {
339 uptodate_minors =
true;
341 uptodate_minors =
false;
347 plogf(
" Iteration = %3d, Iterations since last evaluation of "
348 "optimal basis = %3d",
349 m_VCount->Its, it1 - 1);
351 plogf(
" (all species)\n");
353 plogf(
" (only major species)\n");
364 m_feSpecies_new = m_feSpecies_old;
365 m_actCoeffSpecies_new = m_actCoeffSpecies_old;
366 m_deltaGRxn_new = m_deltaGRxn_old;
367 m_deltaGRxn_Deficient = m_deltaGRxn_old;
368 m_tPhaseMoles_new = m_tPhaseMoles_old;
373 m_deltaMolNumSpecies.assign(m_deltaMolNumSpecies.size(), 0.0);
379 std::vector<size_t> phasePopPhaseIDs(0);
380 size_t iphasePop = vcs_popPhaseID(phasePopPhaseIDs);
381 if (iphasePop !=
npos) {
382 int soldel = vcs_popPhaseRxnStepSizes(iphasePop);
385 if (m_debug_print_lvl >= 2) {
386 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich "
387 "prevented phase %d popping\n");
395 size_t iphaseDelete =
npos;
397 if (iphasePop ==
npos) {
401 iphaseDelete = vcs_RxnStepSizes(forceComponentCalc, kspec);
402 }
else if (m_debug_print_lvl >= 2) {
403 plogf(
" --- vcs_RxnStepSizes not called because alternative"
404 "phase creation delta was used instead\n");
406 size_t doPhaseDeleteKspec =
npos;
407 size_t doPhaseDeleteIph =
npos;
410 m_deltaPhaseMoles.assign(m_deltaPhaseMoles.size(), 0.0);
426 if (iphaseDelete !=
npos) {
427 debuglog(
" --- Main Loop Treatment -> Circumvented due to Phase Deletion\n", m_debug_print_lvl >= 2);
428 for (
size_t k = 0; k < m_nsp; k++) {
429 m_molNumSpecies_new[k] = m_molNumSpecies_old[k] + m_deltaMolNumSpecies[k];
430 size_t iph = m_phaseID[k];
431 m_tPhaseMoles_new[iph] += m_deltaMolNumSpecies[k];
433 if (kspec >= m_numComponents) {
434 if (m_SSPhase[kspec] == 1) {
437 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
438 "we shouldn't be here!");
440 ++m_numRxnMinorZeroed;
441 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
457 if (m_debug_print_lvl >= 2) {
458 plogf(
" --- Main Loop Treatment of each non-component species ");
460 plogf(
"- Full Calculation:\n");
462 plogf(
"- Major Components Calculation:\n");
464 plogf(
" --- Species IC ");
465 plogf(
" KMoles Tent_KMoles Rxn_Adj | Comment \n");
467 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
468 size_t kspec = m_indexRxnToSpecies[irxn];
469 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
470 size_t iph = m_phaseID[kspec];
471 vcs_VolPhase* Vphase = m_VolPhaseList[iph].get();
475 if (iphasePop !=
npos) {
476 if (iph == iphasePop) {
477 dx = m_deltaMolNumSpecies[kspec];
478 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
479 sprintf(ANOTE,
"Phase pop");
482 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
487 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
488 m_deltaMolNumSpecies[kspec] = dx;
491 bool resurrect = (m_deltaMolNumSpecies[kspec] > 0.0);
492 if (m_debug_print_lvl >= 3) {
493 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
494 m_speciesName[kspec], m_speciesStatus[kspec]);
495 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
496 irxn, m_deltaGRxn_new[irxn], m_molNumSpecies_new[kspec],
497 m_molNumSpecies_old[kspec], m_deltaMolNumSpecies[kspec]);
499 if (m_deltaGRxn_new[irxn] >= 0.0 || !resurrect) {
500 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
501 m_deltaMolNumSpecies[kspec] = 0.0;
503 sprintf(ANOTE,
"Species stays zeroed: DG = %11.4E", m_deltaGRxn_new[irxn]);
504 if (m_deltaGRxn_new[irxn] < 0.0) {
506 sprintf(ANOTE,
"Species stays zeroed even though dg neg due to "
507 "STOICH/PHASEPOP constraint: DG = %11.4E",
508 m_deltaGRxn_new[irxn]);
510 sprintf(ANOTE,
"Species stays zeroed even though dg neg: DG = %11.4E, ds zeroed",
511 m_deltaGRxn_new[irxn]);
515 for (
size_t j = 0; j < m_nelem; ++j) {
516 int elType = m_elType[j];
518 double atomComp = m_formulaMatrix(kspec,j);
519 if (atomComp > 0.0) {
520 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
522 sprintf(ANOTE,
"Species stays zeroed even though dG "
523 "neg, because of %s elemAbund",
524 m_elementName[j].c_str());
536 if (m_debug_print_lvl >= 2) {
537 plogf(
" --- Zeroed species changed to major: ");
538 plogf(
"%-12s\n", m_speciesName[kspec]);
541 allMinorZeroedSpecies =
false;
543 if (m_debug_print_lvl >= 2) {
544 plogf(
" --- Zeroed species changed to minor: ");
545 plogf(
"%-12s\n", m_speciesName[kspec]);
549 if (m_deltaMolNumSpecies[kspec] > 0.0) {
550 dx = m_deltaMolNumSpecies[kspec] * 0.01;
551 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
554 dx = m_molNumSpecies_new[kspec] - m_molNumSpecies_old[kspec];
556 m_deltaMolNumSpecies[kspec] = dx;
557 sprintf(ANOTE,
"Born:IC=-1 to IC=1:DG=%11.4E", m_deltaGRxn_new[irxn]);
559 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
560 m_deltaMolNumSpecies[kspec] = 0.0;
569 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
570 m_deltaMolNumSpecies[kspec] = 0.0;
572 sprintf(ANOTE,
"minor species not considered");
573 if (m_debug_print_lvl >= 2) {
574 plogf(
" --- %-12s%3d% 11.4E %11.4E %11.4E | %s\n",
575 m_speciesName[kspec], m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
576 m_deltaMolNumSpecies[kspec], ANOTE);
594 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
595 m_deltaMolNumSpecies[kspec] = dx;
596 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
600 if (m_debug_print_lvl >= 2) {
601 plogf(
" --- Delete minor species in multispec phase: %-12s\n",
602 m_speciesName[kspec]);
604 m_deltaMolNumSpecies[kspec] = 0.0;
610 size_t lnospec = vcs_delete_species(kspec);
612 stage = RECHECK_DELETED;
626 sprintf(ANOTE,
"Normal Major Calc");
631 if (fabs(m_deltaGRxn_new[irxn]) <= m_tolmaj2) {
632 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
633 m_deltaMolNumSpecies[kspec] = 0.0;
635 sprintf(ANOTE,
"major species is converged");
636 if (m_debug_print_lvl >= 2) {
637 plogf(
" --- %-12s %3d %11.4E %11.4E %11.4E | %s\n",
638 m_speciesName[kspec], m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
639 m_deltaMolNumSpecies[kspec], ANOTE);
651 if ((m_deltaGRxn_new[irxn] * m_deltaMolNumSpecies[kspec]) <= 0.0) {
652 dx = m_deltaMolNumSpecies[kspec];
655 m_deltaMolNumSpecies[kspec] = 0.0;
656 sprintf(ANOTE,
"dx set to 0, DG flipped sign due to "
657 "changed initial point");
661 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
667 if (m_molNumSpecies_new[kspec] <= 0.0) {
668 sprintf(ANOTE,
"initial nonpos kmoles= %11.3E",
669 m_molNumSpecies_new[kspec]);
677 if (!m_SSPhase[kspec]) {
682 dx = -0.9 * m_molNumSpecies_old[kspec];
683 m_deltaMolNumSpecies[kspec] = dx;
684 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
689 dx = -m_molNumSpecies_old[kspec];
695 for (
size_t j = 0; j < m_numComponents; ++j) {
696 if (sc_irxn[j] != 0.0) {
697 m_wx[j] = m_molNumSpecies_old[j] + sc_irxn[j] * dx;
698 if (m_wx[j] <= m_molNumSpecies_old[j] * 0.01 - 1.0E-150) {
699 dx = std::max(dx, m_molNumSpecies_old[j] * -0.99 / sc_irxn[j]);
702 m_wx[j] = m_molNumSpecies_old[j];
705 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
706 if (m_molNumSpecies_new[kspec] > 0.0) {
707 m_deltaMolNumSpecies[kspec] = dx;
709 "zeroing SS phase created a neg component species "
710 "-> reducing step size instead");
714 iph = m_phaseID[kspec];
715 Vphase = m_VolPhaseList[iph].get();
716 sprintf(ANOTE,
"zeroing out SS phase: ");
722 m_molNumSpecies_new[kspec] = 0.0;
723 doPhaseDeleteIph = iph;
725 doPhaseDeleteKspec = kspec;
726 if (m_debug_print_lvl >= 2 && m_speciesStatus[kspec] >= 0) {
727 plogf(
" --- SS species changed to zeroedss: ");
728 plogf(
"%-12s\n", m_speciesName[kspec]);
731 ++m_numRxnMinorZeroed;
732 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
734 for (
size_t kk = 0; kk < m_nsp; kk++) {
735 m_deltaMolNumSpecies[kk] = 0.0;
736 m_molNumSpecies_new[kk] = m_molNumSpecies_old[kk];
738 m_deltaMolNumSpecies[kspec] = dx;
739 m_molNumSpecies_new[kspec] = 0.0;
741 for (
size_t k = 0; k < m_numComponents; ++k) {
742 m_deltaMolNumSpecies[k] = 0.0;
744 for (iph = 0; iph < m_numPhases; iph++) {
745 m_deltaPhaseMoles[iph] = 0.0;
753 if (dx != 0.0 && (m_speciesUnknownType[kspec] !=
760 1.0E-14*(fabs(m_deltaMolNumSpecies[kspec]) + fabs(dx) + 1.0E-32),
761 "VCS_SOLVE::solve_tp_inner",
762 "ds[kspec] = {}, dx = {}, kspec = {}\nwe have a problem!",
763 m_deltaMolNumSpecies[kspec], dx, kspec);
764 for (
size_t k = 0; k < m_numComponents; ++k) {
765 m_deltaMolNumSpecies[k] += sc_irxn[k] * dx;
770 for (iph = 0; iph < m_numPhases; iph++) {
771 m_deltaPhaseMoles[iph] += dx * m_deltaMolNumPhase(iph,irxn);
775 checkDelta1(&m_deltaMolNumSpecies[0],
776 &m_deltaPhaseMoles[0], kspec+1);
779 if (m_debug_print_lvl >= 2) {
780 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
781 plogf(
" --- %-12.12s%3d %11.4E %11.4E %11.4E | %s\n",
782 m_speciesName[kspec], m_speciesStatus[kspec],
783 m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
784 m_deltaMolNumSpecies[kspec], ANOTE);
787 if (doPhaseDeleteIph !=
npos) {
788 if (m_debug_print_lvl >= 2) {
789 plogf(
" --- %-12.12s Main Loop Special Case deleting phase with species:\n",
790 m_speciesName[doPhaseDeleteKspec]);
795 if (m_debug_print_lvl >= 2) {
796 for (
size_t k = 0; k < m_numComponents; k++) {
798 plogf(
"%-12.12s", m_speciesName[k]);
799 plogf(
" c %11.4E %11.4E %11.4E |\n",
800 m_molNumSpecies_old[k],
801 m_molNumSpecies_old[k]+m_deltaMolNumSpecies[k], m_deltaMolNumSpecies[k]);
805 plogf(
" --- Finished Main Loop\n");
814 for (
size_t k = 0; k < m_numComponents; ++k) {
815 if (m_molNumSpecies_old[k] > 0.0) {
816 double xx = -m_deltaMolNumSpecies[k] / m_molNumSpecies_old[k];
821 }
else if (m_deltaMolNumSpecies[k] < 0.0) {
824 size_t iph = m_phaseID[k];
825 m_deltaPhaseMoles[iph] -= m_deltaMolNumSpecies[k];
826 m_deltaMolNumSpecies[k] = 0.0;
830 if (par <= 1.01 && par > 0.0) {
833 if (m_debug_print_lvl >= 2) {
834 plogf(
" --- Reduction in step size due to component %s going negative = %11.3E\n",
835 m_speciesName[ll], par);
837 for (
size_t i = 0; i < m_nsp; ++i) {
838 m_deltaMolNumSpecies[i] *= par;
840 for (
size_t iph = 0; iph < m_numPhases; iph++) {
841 m_deltaPhaseMoles[iph] *= par;
846 checkDelta1(&m_deltaMolNumSpecies[0],
847 &m_deltaPhaseMoles[0], m_nsp);
854 for (
size_t kspec = 0; kspec < m_nsp; ++kspec) {
855 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
856 if (m_molNumSpecies_new[kspec] < 0.0 && (m_speciesUnknownType[kspec]
858 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
859 "vcs_solve_TP: ERROR on step change wt[{}:{}]: {} < 0.0",
860 kspec, m_speciesName[kspec], m_molNumSpecies_new[kspec]);
865 for (
size_t iph = 0; iph < m_numPhases; iph++) {
866 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + m_deltaPhaseMoles[iph];
884 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
885 vcs_Total_Gibbs(&m_molNumSpecies_old[0], &m_feSpecies_old[0],
886 &m_tPhaseMoles_old[0]));
887 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E\n",
888 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
889 &m_tPhaseMoles_new[0]));
892 bool forced = vcs_globStepDamp();
895 if (printDetails && forced) {
896 plogf(
" -----------------------------------------------------\n");
897 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
898 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
899 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
900 for (
size_t i = 0; i < m_numComponents; ++i) {
901 plogf(
" --- %-12.12s", m_speciesName[i]);
902 plogf(
" %14.6E %14.6E %14.6E\n", m_molNumSpecies_old[i],
903 m_molNumSpecies_old[i] + m_deltaMolNumSpecies[i], m_molNumSpecies_new[i]);
905 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
906 size_t irxn = kspec - m_numComponents;
907 plogf(
" --- %-12.12s", m_speciesName[kspec]);
908 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n", m_speciesStatus[kspec],
909 m_molNumSpecies_old[kspec],
910 m_molNumSpecies_old[kspec]+m_deltaMolNumSpecies[kspec],
911 m_molNumSpecies_new[kspec], m_deltaGRxn_old[irxn],
912 m_deltaGRxn_tmp[irxn], m_deltaGRxn_new[irxn]);
914 writeline(
' ', 26,
false);
915 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
916 l2normdg(&m_deltaGRxn_old[0]),
917 l2normdg(&m_deltaGRxn_new[0]));
918 plogf(
" Total kmoles of gas = %15.7E\n", m_tPhaseMoles_old[0]);
919 if ((m_numPhases > 1) && (!m_VolPhaseList[1]->m_singleSpecies)) {
920 plogf(
" Total kmoles of liquid = %15.7E\n", m_tPhaseMoles_old[1]);
922 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
924 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
925 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
926 &m_tPhaseMoles_new[0]));
927 plogf(
" -----------------------------------------------------\n");
936 plogf(
" --- Summary of the Update ");
938 plogf(
" (all species):");
940 plogf(
" (only major species):");
943 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
944 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
945 for (
size_t i = 0; i < m_numComponents; ++i) {
946 plogf(
" --- %-12.12s", m_speciesName[i]);
948 plogf(
"%14.6E%14.6E%14.6E%14.6E\n", m_molNumSpecies_old[i],
949 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i]);
951 for (
size_t i = m_numComponents; i < m_numSpeciesRdc; ++i) {
952 size_t l1 = i - m_numComponents;
953 plogf(
" --- %-12.12s", m_speciesName[i]);
954 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
955 m_speciesStatus[i], m_molNumSpecies_old[i],
956 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i],
957 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
959 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
960 size_t l1 = kspec - m_numComponents;
961 plogf(
" --- %-12.12s", m_speciesName[kspec]);
962 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
963 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
964 m_molNumSpecies_new[kspec], m_feSpecies_old[kspec], m_feSpecies_new[kspec],
965 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
968 writeline(
' ', 56,
false);
969 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
970 l2normdg(&m_deltaGRxn_old[0]),
971 l2normdg(&m_deltaGRxn_new[0]));
973 plogf(
" --- Phase_Name KMoles(after update)\n");
976 for (
size_t iph = 0; iph < m_numPhases; iph++) {
977 vcs_VolPhase* Vphase = m_VolPhaseList[iph].get();
978 plogf(
" --- %18s = %15.7E\n", Vphase->PhaseName, m_tPhaseMoles_new[iph]);
982 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
983 vcs_Total_Gibbs(&m_molNumSpecies_old[0], &m_feSpecies_old[0],
984 &m_tPhaseMoles_old[0]));
985 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E\n",
986 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
987 &m_tPhaseMoles_new[0]));
988 debuglog(
" --- Troublesome solve\n", m_VCount->Its > 550);
1001 m_tPhaseMoles_old = m_tPhaseMoles_new;
1002 m_molNumSpecies_old = m_molNumSpecies_new;
1003 m_actCoeffSpecies_old = m_actCoeffSpecies_new;
1004 m_deltaGRxn_old = m_deltaGRxn_new;
1005 m_feSpecies_old = m_feSpecies_new;
1012 if (m_debug_print_lvl >= 2) {
1013 plogf(
" --- Increment counter increased, step is accepted: %4d\n",
1023 bool justDeletedMultiPhase =
false;
1024 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1025 if (!m_VolPhaseList[iph]->m_singleSpecies && m_tPhaseMoles_old[iph] != 0.0 &&
1027 if (m_debug_print_lvl >= 1) {
1028 plogf(
" --- Setting microscopic phase %d to zero\n", iph);
1030 justDeletedMultiPhase =
true;
1031 vcs_delete_multiphase(iph);
1038 if (justDeletedMultiPhase) {
1039 bool usedZeroedSpecies;
1040 double test = -1.0e-10;
1041 int retn = vcs_basopt(
false, &m_aw[0], &m_sa[0], &m_sm[0], &m_ss[0],
1042 test, &usedZeroedSpecies);
1044 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
1045 "BASOPT returned with an error condition");
1055 if (m_debug_print_lvl >= 2) {
1056 plogf(
" --- Normal element abundance check");
1059 if (! vcs_elabcheck(0)) {
1060 debuglog(
" - failed -> redoing element abundances.\n", m_debug_print_lvl >= 2);
1061 vcs_elcorr(&m_sm[0], &m_wx[0]);
1065 uptodate_minors =
true;
1067 debuglog(
" - passed\n", m_debug_print_lvl >= 2);
1071 for (
size_t i = 0; i < m_numRxnRdc; ++i) {
1072 size_t k = m_indexRxnToSpecies[i];
1076 for (
size_t j = 0; j < m_numComponents; ++j) {
1077 bool doSwap =
false;
1079 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1080 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1081 if (!m_SSPhase[k] && doSwap) {
1082 doSwap = m_molNumSpecies_old[k] > (m_molNumSpecies_old[j] * 1.01);
1086 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1087 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1089 doSwap = m_molNumSpecies_old[k] > (m_molNumSpecies_old[j] * 1.01);
1092 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1093 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1096 if (doSwap && m_stoichCoeffRxnMatrix(j,i) != 0.0) {
1097 if (m_debug_print_lvl >= 2) {
1098 plogf(
" --- Get a new basis because %s", m_speciesName[k]);
1099 plogf(
" is better than comp %s", m_speciesName[j]);
1100 plogf(
" and share nonzero stoic: %-9.1f\n",
1101 m_stoichCoeffRxnMatrix(j,i));
1103 forceComponentCalc = 1;
1108 debuglog(
" --- Check for an optimum basis passed\n", m_debug_print_lvl >= 2);
1109 stage = EQUILIB_CHECK;
1118 if (m_debug_print_lvl >= 2) {
1119 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1121 m_numRxnMinorZeroed = 0;
1122 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
1123 size_t kspec = m_indexRxnToSpecies[irxn];
1124 int speciesType = vcs_species_type(kspec);
1127 plogf(
" --- major/minor species is now zeroed out: %s\n",
1128 m_speciesName[kspec]);
1130 ++m_numRxnMinorZeroed;
1134 plogf(
" --- Noncomponent turned from major to minor: ");
1135 }
else if (kspec < m_numComponents) {
1136 plogf(
" --- Component turned into a minor species: ");
1138 plogf(
" --- Zeroed Species turned into a "
1141 plogf(
"%s\n", m_speciesName[kspec]);
1143 ++m_numRxnMinorZeroed;
1146 if (m_debug_print_lvl >= 2) {
1148 plogf(
" --- Noncomponent turned from minor to major: ");
1149 }
else if (kspec < m_numComponents) {
1150 plogf(
" --- Component turned into a major: ");
1152 plogf(
" --- Noncomponent turned from zeroed to major: ");
1154 plogf(
"%s\n", m_speciesName[kspec]);
1159 m_speciesStatus[kspec] = speciesType;
1164 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
1167 void VCS_SOLVE::solve_tp_equilib_check(
bool& allMinorZeroedSpecies,
1168 bool& uptodate_minors,
1169 bool& giveUpOnElemAbund,
int& solveFail,
1170 size_t& iti,
size_t& it1,
int maxit,
1171 int& stage,
bool& lec)
1173 if (! allMinorZeroedSpecies) {
1174 if (m_debug_print_lvl >= 2) {
1175 plogf(
" --- Equilibrium check for major species: ");
1177 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1178 size_t kspec = irxn + m_numComponents;
1179 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MAJOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmaj)) {
1180 if (m_VCount->Its >= maxit) {
1187 if (m_debug_print_lvl >= 2) {
1188 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]]);
1192 iti = ((it1/4) *4) - it1;
1198 debuglog(
" MAJOR SPECIES CONVERGENCE achieved", m_debug_print_lvl >= 2);
1200 debuglog(
" MAJOR SPECIES CONVERGENCE achieved "
1201 "(because there are no major species)\n", m_debug_print_lvl >= 2);
1206 if (m_numRxnMinorZeroed != 0) {
1213 uptodate_minors =
true;
1215 if (m_debug_print_lvl >= 2) {
1216 plogf(
" --- Equilibrium check for minor species: ");
1218 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1219 size_t kspec = irxn + m_numComponents;
1220 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MINOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmin)) {
1221 if (m_VCount->Its >= maxit) {
1228 if (m_debug_print_lvl >= 2) {
1229 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]]);
1239 if (m_debug_print_lvl >= 2) {
1240 plogf(
" CONVERGENCE achieved\n");
1251 if (!giveUpOnElemAbund) {
1252 if (m_debug_print_lvl >= 2) {
1253 plogf(
" --- Check the Full Element Abundances: ");
1258 if (! vcs_elabcheck(1)) {
1259 if (m_debug_print_lvl >= 2) {
1260 if (! vcs_elabcheck(0)) {
1263 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1267 stage = ELEM_ABUND_CHECK;
1270 if (m_debug_print_lvl >= 2) {
1277 if (m_numSpeciesRdc != m_nsp) {
1278 stage = RECHECK_DELETED;
1287 void VCS_SOLVE::solve_tp_elem_abund_check(
size_t& iti,
int& stage,
bool& lec,
1288 bool& giveUpOnElemAbund,
1289 int& finalElemAbundAttempts,
1290 int& rangeErrorFound)
1297 rangeErrorFound = 0;
1298 if (! vcs_elabcheck(1)) {
1299 bool ncBefore = vcs_elabcheck(0);
1300 vcs_elcorr(&m_sm[0], &m_wx[0]);
1301 bool ncAfter = vcs_elabcheck(0);
1302 bool neAfter = vcs_elabcheck(1);
1318 if (finalElemAbundAttempts >= 3) {
1319 giveUpOnElemAbund =
true;
1320 stage = EQUILIB_CHECK;
1322 finalElemAbundAttempts++;
1329 }
else if (ncAfter) {
1332 if (m_debug_print_lvl >= 2) {
1333 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1334 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1335 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1336 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition\n");
1338 rangeErrorFound = 1;
1339 giveUpOnElemAbund =
true;
1344 stage = EQUILIB_CHECK;
1351 stage = EQUILIB_CHECK;
1354 double VCS_SOLVE::vcs_minor_alt_calc(
size_t kspec,
size_t irxn,
bool* do_delete,
1357 double w_kspec = m_molNumSpecies_old[kspec];
1358 double dg_irxn = m_deltaGRxn_old[irxn];
1359 size_t iph = m_phaseID[kspec];
1363 if (w_kspec <= 0.0) {
1366 dg_irxn = std::max(dg_irxn, -200.0);
1368 sprintf(ANOTE,
"minor species alternative calc");
1370 if (dg_irxn >= 23.0) {
1371 double molNum_kspec_new = w_kspec * 1.0e-10;
1378 return molNum_kspec_new - w_kspec;
1380 if (fabs(dg_irxn) <= m_tolmin2) {
1386 double s = m_np_dLnActCoeffdMolNum(kspec,kspec) / m_tPhaseMoles_old[iph];
1397 double a =
clip(w_kspec * s, -1.0+1e-8, 100.0);
1398 double tmp =
clip(-dg_irxn / (1.0 + a), -200.0, 200.0);
1399 double wTrial = w_kspec * exp(tmp);
1400 double molNum_kspec_new = wTrial;
1402 if (wTrial > 100. * w_kspec) {
1403 double molNumMax = 0.0001 * m_tPhaseMoles_old[iph];
1404 if (molNumMax < 100. * w_kspec) {
1405 molNumMax = 100. * w_kspec;
1407 if (wTrial > molNumMax) {
1408 molNum_kspec_new = molNumMax;
1410 molNum_kspec_new = wTrial;
1412 }
else if (1.0E10 * wTrial < w_kspec) {
1413 molNum_kspec_new= 1.0E-10 * w_kspec;
1415 molNum_kspec_new = wTrial;
1424 return molNum_kspec_new - w_kspec;
1429 double dx = m_deltaGRxn_old[irxn]/ m_Faraday_dim;
1431 sprintf(ANOTE,
"voltage species alternative calc");
1437 int VCS_SOLVE::delta_species(
const size_t kspec,
double*
const delta_ptr)
1439 size_t irxn = kspec - m_numComponents;
1441 AssertThrowMsg(kspec >= m_numComponents,
"VCS_SOLVE::delta_species",
1442 "delete_species() ERROR: called for a component {}", kspec);
1446 double dx = *delta_ptr;
1447 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
1448 for (
size_t j = 0; j < m_numComponents; ++j) {
1449 if (m_molNumSpecies_old[j] > 0.0) {
1450 double tmp = sc_irxn[j] * dx;
1451 if (-tmp > m_molNumSpecies_old[j]) {
1453 dx = std::min(dx, - m_molNumSpecies_old[j] / sc_irxn[j]);
1459 if (m_molNumSpecies_old[j] <= 0.0 && sc_irxn[j] < 0.0) {
1467 m_molNumSpecies_old[kspec] += dx;
1468 size_t iph = m_phaseID[kspec];
1469 m_tPhaseMoles_old[iph] += dx;
1472 for (
size_t j = 0; j < m_numComponents; ++j) {
1473 double tmp = sc_irxn[j] * dx;
1476 m_molNumSpecies_old[j] += tmp;
1477 m_tPhaseMoles_old[iph] += tmp;
1479 m_molNumSpecies_old[j] = std::max(m_molNumSpecies_old[j], 0.0);
1486 int VCS_SOLVE::vcs_zero_species(
const size_t kspec)
1492 double dx = -m_molNumSpecies_old[kspec];
1494 retn = delta_species(kspec, &dx);
1495 if (!retn && m_debug_print_lvl >= 1) {
1496 plogf(
"vcs_zero_species: Couldn't zero the species %d, "
1497 "did delta of %g. orig conc of %g\n",
1498 kspec, dx, m_molNumSpecies_old[kspec] + dx);
1505 int VCS_SOLVE::vcs_delete_species(
const size_t kspec)
1507 const size_t klast = m_numSpeciesRdc - 1;
1508 const size_t iph = m_phaseID[kspec];
1509 vcs_VolPhase*
const Vphase = m_VolPhaseList[iph].get();
1510 const size_t irxn = kspec - m_numComponents;
1514 const int retn = vcs_zero_species(kspec);
1517 "Failed to delete a species!");
1523 --m_numRxnMinorZeroed;
1526 m_deltaGRxn_new[irxn] = 0.0;
1527 m_deltaGRxn_old[irxn] = 0.0;
1528 m_feSpecies_new[kspec] = 0.0;
1529 m_feSpecies_old[kspec] = 0.0;
1530 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
1533 if (kspec != klast) {
1534 vcs_switch_pos(
true, klast, kspec);
1539 &m_tPhaseMoles_old[0]);
1548 bool stillExists =
false;
1549 for (
size_t k = 0; k < m_numSpeciesRdc; k++) {
1551 m_phaseID[k] == iph && m_molNumSpecies_old[k] > 0.0) {
1557 vcs_delete_multiphase(iph);
1563 return (m_numRxnRdc == 0);
1566 void VCS_SOLVE::vcs_reinsert_deleted(
size_t kspec)
1568 size_t iph = m_phaseID[kspec];
1569 if (m_debug_print_lvl >= 2) {
1570 plogf(
" --- Add back a deleted species: %-12s\n", m_speciesName[kspec]);
1577 delta_species(kspec, &dx);
1580 if (m_SSPhase[kspec]) {
1582 --m_numRxnMinorZeroed;
1587 &m_molNumSpecies_old[0],
1588 &m_tPhaseMoles_old[0]);
1594 if (! m_SSPhase[kspec]) {
1597 for (
size_t k = 0; k < m_nsp; k++) {
1609 ++m_numRxnMinorZeroed;
1611 if (kspec != (m_numSpeciesRdc - 1)) {
1613 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
1617 bool VCS_SOLVE::vcs_delete_multiphase(
const size_t iph)
1620 bool successful =
true;
1624 if (m_debug_print_lvl >= 2) {
1625 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName);
1629 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1630 if (m_phaseID[kspec] == iph) {
1633 double dx = - m_molNumSpecies_old[kspec];
1636 int retn = delta_species(kspec, &dxTent);
1639 if (m_debug_print_lvl >= 2) {
1640 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
1641 iph, Vphase->
PhaseName, m_speciesName[kspec]);
1642 plogf(
" --- delta attempted: %g achieved: %g "
1643 " Zeroing it manually\n", dx, dxTent);
1645 m_molNumSpecies_old[kspec] = 0.0;
1646 m_molNumSpecies_new[kspec] = 0.0;
1647 m_deltaMolNumSpecies[kspec] = 0.0;
1652 m_molNumSpecies_old[kspec] = 0.0;
1653 m_molNumSpecies_new[kspec] = 0.0;
1654 m_deltaMolNumSpecies[kspec] = 0.0;
1664 double dxPerm = 0.0, dxPerm2 = 0.0;
1665 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
1666 if (m_phaseID[kcomp] == iph) {
1667 if (m_debug_print_lvl >= 2) {
1668 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
1669 kcomp, m_speciesName[kcomp], m_molNumSpecies_old[kcomp]);
1671 if (m_molNumSpecies_old[kcomp] != 0.0) {
1672 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1673 size_t irxn = kspec - m_numComponents;
1674 if (m_phaseID[kspec] != iph) {
1675 if (m_stoichCoeffRxnMatrix(kcomp,irxn) != 0.0) {
1676 double dxWant = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(kcomp,irxn);
1677 if (dxWant + m_molNumSpecies_old[kspec] < 0.0) {
1678 dxPerm = -m_molNumSpecies_old[kspec];
1680 for (
size_t jcomp = 0; kcomp < m_numComponents; ++kcomp) {
1681 if (jcomp != kcomp) {
1682 if (m_phaseID[jcomp] == iph) {
1685 double dj = dxWant * m_stoichCoeffRxnMatrix(jcomp,irxn);
1686 if (dj + m_molNumSpecies_old[kcomp] < 0.0) {
1687 dxPerm2 = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(jcomp,irxn);
1689 if (fabs(dxPerm2) < fabs(dxPerm)) {
1696 if (dxPerm != 0.0) {
1697 delta_species(kspec, &dxPerm);
1703 if (m_molNumSpecies_old[kcomp] != 0.0) {
1704 if (m_debug_print_lvl >= 2) {
1705 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
1706 kcomp, m_speciesName[kcomp], m_molNumSpecies_old[kcomp]);
1707 plogf(
" --- zeroing it \n");
1709 m_molNumSpecies_old[kcomp] = 0.0;
1720 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
1721 if (m_phaseID[kspec] == iph) {
1722 m_molNumSpecies_old[kspec] = 0.0;
1723 m_molNumSpecies_new[kspec] = 0.0;
1724 m_deltaMolNumSpecies[kspec] = 0.0;
1729 if (m_debug_print_lvl >= 2) {
1730 plogf(
" --- Make %s", m_speciesName[kspec]);
1731 plogf(
" an active but zeroed species because its phase "
1734 if (kspec != (m_numSpeciesRdc - 1)) {
1736 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
1742 m_tPhaseMoles_old[iph] = 0.0;
1743 m_tPhaseMoles_new[iph] = 0.0;
1744 m_deltaPhaseMoles[iph] = 0.0;
1751 int VCS_SOLVE::vcs_recheck_deleted()
1754 if (m_debug_print_lvl >= 2) {
1755 plogf(
" --- Start rechecking deleted species in multispec phases\n");
1757 if (m_numSpeciesRdc == m_nsp) {
1764 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
1765 size_t iph = m_phaseID[kspec];
1766 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_old[kspec])
1767 - m_lnMnaughtSpecies[kspec]
1768 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
1775 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1776 if (m_tPhaseMoles_old[iph] > 0.0) {
1779 xtcutoff[iph] = 0.0;
1805 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1806 size_t kspec = m_indexRxnToSpecies[irxn];
1807 size_t iph = m_phaseID[kspec];
1808 if (m_tPhaseMoles_old[iph] == 0.0) {
1809 if (m_deltaGRxn_new[irxn] < 0.0) {
1810 vcs_reinsert_deleted(kspec);
1813 m_molNumSpecies_old[kspec] = 0.0;
1815 }
else if (m_tPhaseMoles_old[iph] > 0.0) {
1816 if (m_deltaGRxn_new[irxn] < xtcutoff[iph]) {
1817 vcs_reinsert_deleted(kspec);
1825 size_t VCS_SOLVE::vcs_add_all_deleted()
1827 if (m_numSpeciesRdc == m_nsp) {
1836 m_molNumSpecies_new = m_molNumSpecies_old;
1837 for (
int cits = 0; cits < 3; cits++) {
1838 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
1839 size_t iph = m_phaseID[kspec];
1841 if (m_molNumSpecies_new[kspec] == 0.0) {
1847 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_new[kspec]) - m_lnMnaughtSpecies[kspec]
1848 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
1854 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1855 size_t kspec = m_indexRxnToSpecies[irxn];
1856 size_t iph = m_phaseID[kspec];
1857 if (m_tPhaseMoles_old[iph] > 0.0) {
1858 double maxDG = std::min(m_deltaGRxn_new[irxn], 690.0);
1859 double dx = m_tPhaseMoles_old[iph] * exp(- maxDG);
1860 m_molNumSpecies_new[kspec] = dx;
1864 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1865 size_t kspec = m_indexRxnToSpecies[irxn];
1866 size_t iph = m_phaseID[kspec];
1867 if (m_tPhaseMoles_old[iph] > 0.0) {
1868 double dx = m_molNumSpecies_new[kspec];
1869 size_t retn = delta_species(kspec, &dx);
1871 if (m_debug_print_lvl) {
1872 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1873 m_speciesName[kspec], kspec, dx);
1877 retn = delta_species(kspec, &dx);
1878 if (retn == 0 && m_debug_print_lvl) {
1879 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1880 m_speciesName[kspec], kspec, dx);
1884 if (m_debug_print_lvl >= 2) {
1886 plogf(
" --- add_deleted(): species %s added back in with mol number %g\n",
1887 m_speciesName[kspec], dx);
1889 plogf(
" --- add_deleted(): species %s failed to be added back in\n");
1899 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1900 size_t kspec = m_indexRxnToSpecies[irxn];
1901 size_t iph = m_phaseID[kspec];
1902 if (m_tPhaseMoles_old[iph] > 0.0 && fabs(m_deltaGRxn_old[irxn]) > m_tolmin) {
1903 if (((m_molNumSpecies_old[kspec] * exp(-m_deltaGRxn_old[irxn])) >
1907 if (m_debug_print_lvl >= 2) {
1908 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g\n",
1909 m_speciesName[kspec], m_molNumSpecies_old[kspec],
1910 m_deltaGRxn_old[irxn]);
1918 bool VCS_SOLVE::vcs_globStepDamp()
1920 double* dptr = &m_deltaGRxn_new[0];
1924 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1925 size_t kspec = irxn + m_numComponents;
1927 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
1933 dptr = &m_deltaGRxn_old[0];
1934 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1935 size_t kspec = irxn + m_numComponents;
1937 s1 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
1941 if (m_debug_print_lvl >= 2) {
1942 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
1943 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
1947 if (m_debug_print_lvl >= 2) {
1948 plogf(
" --- subroutine FORCE produced no adjustments,");
1950 plogf(
" s1 positive but really small\n");
1952 plogf(
" failed s1 test\n");
1959 debuglog(
" --- subroutine FORCE produced no adjustments, s2 < 0\n", m_debug_print_lvl >= 2);
1965 if (fabs(s1 -s2) > 1.0E-200) {
1966 al = s1 / (s1 - s2);
1968 if (al >= 0.95 || al < 0.0) {
1969 if (m_debug_print_lvl >= 2) {
1970 plogf(
" --- subroutine FORCE produced no adjustments (al = %g)\n", al);
1974 if (m_debug_print_lvl >= 2) {
1975 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
1979 if (m_debug_print_lvl >= 2) {
1980 m_deltaGRxn_tmp = m_deltaGRxn_new;
1983 dptr = &m_molNumSpecies_new[0];
1984 for (
size_t kspec = 0; kspec < m_numSpeciesRdc; ++kspec) {
1985 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] +
1986 al * m_deltaMolNumSpecies[kspec];
1988 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1989 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + al * m_deltaPhaseMoles[iph];
1993 if (m_debug_print_lvl >= 2) {
1994 plogf(
" --- subroutine FORCE adjusted the mole "
1995 "numbers, AL = %10.3f\n", al);
2008 dptr = &m_deltaGRxn_new[0];
2010 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2011 size_t kspec = irxn + m_numComponents;
2013 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2017 if (m_debug_print_lvl >= 2) {
2018 plogf(
" --- subroutine FORCE: Adj End Slope = %g\n", s2);
2023 int VCS_SOLVE::vcs_basopt(
const bool doJustComponents,
double aw[],
double sa[],
double sm[],
2024 double ss[],
double test,
bool*
const usedZeroedSpecies)
2028 size_t jlose =
npos;
2031 if (m_debug_print_lvl >= 2) {
2033 for (
size_t i=0; i<77; i++) {
2037 plogf(
" --- Subroutine BASOPT called to ");
2038 if (doJustComponents) {
2039 plogf(
"calculate the number of components\n");
2041 plogf(
"reevaluate the components\n");
2043 if (m_debug_print_lvl >= 2) {
2045 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
2046 plogf(
" --- Active | ");
2047 for (
size_t j = 0; j < m_nelem; j++) {
2048 plogf(
" %1d ", m_elementActive[j]);
2051 plogf(
" --- Species | ");
2052 for (
size_t j = 0; j < m_nelem; j++) {
2053 writelog(
" {:>8.8s}", m_elementName[j]);
2056 for (k = 0; k < m_nsp; k++) {
2057 writelog(
" --- {:>11.11s} | ", m_speciesName[k]);
2058 for (
size_t j = 0; j < m_nelem; j++) {
2059 plogf(
" %8.2g", m_formulaMatrix(k,j));
2070 size_t ncTrial = std::min(m_nelem, m_nsp);
2071 m_numComponents = ncTrial;
2072 *usedZeroedSpecies =
false;
2076 std::copy(m_molNumSpecies_old.begin(),
2077 m_molNumSpecies_old.begin() + m_nsp, aw);
2080 for (k = 0; k < m_nsp; k++) {
2090 while (jr < ncTrial) {
2098 k = vcs_basisOptMax(aw, jr, m_nsp);
2138 *usedZeroedSpecies =
true;
2139 double maxConcPossKspec = 0.0;
2140 double maxConcPoss = 0.0;
2141 size_t kfound =
npos;
2142 int minNonZeroes = 100000;
2143 int nonZeroesKspec = 0;
2144 for (
size_t kspec = ncTrial; kspec < m_nsp; kspec++) {
2146 maxConcPossKspec = 1.0E10;
2148 for (
size_t j = 0; j < m_nelem; ++j) {
2150 double nu = m_formulaMatrix(kspec,j);
2153 maxConcPossKspec = std::min(m_elemAbundancesGoal[j] / nu, maxConcPossKspec);
2157 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
2158 if (nonZeroesKspec <= minNonZeroes) {
2159 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
2164 if (m_SSfeSpecies[kspec] <= m_SSfeSpecies[kfound]) {
2169 minNonZeroes = std::min(minNonZeroes, nonZeroesKspec);
2170 maxConcPoss = std::max(maxConcPoss, maxConcPossKspec);
2174 if (kfound ==
npos) {
2177 for (
size_t kspec = ncTrial; kspec < m_nsp; kspec++) {
2178 if (aw[kspec] >= 0.0) {
2179 size_t irxn = kspec - ncTrial;
2180 if (m_deltaGRxn_new[irxn] < gmin) {
2181 gmin = m_deltaGRxn_new[irxn];
2190 if (aw[k] == test) {
2191 m_numComponents = jr;
2192 ncTrial = m_numComponents;
2193 size_t numPreDeleted = m_numRxnTot - m_numRxnRdc;
2194 if (numPreDeleted != (m_nsp - m_numSpeciesRdc)) {
2195 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we shouldn't be here");
2197 m_numRxnTot = m_nsp - ncTrial;
2198 m_numRxnRdc = m_numRxnTot - numPreDeleted;
2199 m_numSpeciesRdc = m_nsp - numPreDeleted;
2200 for (
size_t i = 0; i < m_nsp; ++i) {
2201 m_indexRxnToSpecies[i] = ncTrial + i;
2203 if (m_debug_print_lvl >= 2) {
2204 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
2219 for (
size_t j = 0; j < m_nelem; ++j) {
2220 sm[j + jr*m_nelem] = m_formulaMatrix(k,j);
2226 for (
size_t j = 0; j < jl; ++j) {
2228 for (
size_t i = 0; i < m_nelem; ++i) {
2229 ss[j] += sm[i + jr*m_nelem] * sm[i + j*m_nelem];
2235 for (
size_t j = 0; j < jl; ++j) {
2236 for (
size_t i = 0; i < m_nelem; ++i) {
2237 sm[i + jr*m_nelem] -= ss[j] * sm[i + j*m_nelem];
2245 for (
size_t ml = 0; ml < m_nelem; ++ml) {
2246 sa[jr] += pow(sm[ml + jr*m_nelem], 2);
2250 if (sa[jr] > 1.0e-6) {
2257 if (m_debug_print_lvl >= 2) {
2258 plogf(
" --- %-12.12s", m_speciesName[k]);
2260 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[k]);
2262 plogf(
"(%9.2g)", m_molNumSpecies_old[k]);
2264 plogf(
" replaces %-12.12s", m_speciesName[jr]);
2266 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[jr]);
2268 plogf(
"(%9.2g)", m_molNumSpecies_old[jr]);
2270 plogf(
" as component %3d\n", jr);
2272 vcs_switch_pos(
false, jr, k);
2273 std::swap(aw[jr], aw[k]);
2274 }
else if (m_debug_print_lvl >= 2) {
2275 plogf(
" --- %-12.12s", m_speciesName[k]);
2277 plogf(
"(Volts = %9.2g) remains ", m_molNumSpecies_old[k]);
2279 plogf(
"(%9.2g) remains ", m_molNumSpecies_old[k]);
2281 plogf(
" as component %3d\n", jr);
2290 if (doJustComponents) {
2320 C.
resize(ncTrial, ncTrial);
2321 for (
size_t j = 0; j < ncTrial; ++j) {
2322 for (
size_t i = 0; i < ncTrial; ++i) {
2323 C(i, j) = m_formulaMatrix(j,i);
2326 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2327 k = m_indexRxnToSpecies[i];
2328 for (
size_t j = 0; j < ncTrial; ++j) {
2329 m_stoichCoeffRxnMatrix(j,i) = - m_formulaMatrix(k,j);
2334 solve(C, m_stoichCoeffRxnMatrix.
ptrColumn(0), m_numRxnTot, m_nelem);
2340 for (
size_t j = 0; j < m_nelem; j++) {
2341 if (!m_elementActive[j] && !strcmp(m_elementName[j].c_str(),
"E")) {
2345 for (
size_t j = 0; j < m_nelem; j++) {
2346 if (m_elementActive[j] && !strncmp((m_elementName[j]).c_str(),
"cn_", 3)) {
2350 for (k = 0; k < m_nsp; k++) {
2352 for (
size_t j = 0; j < ncTrial; ++j) {
2353 for (
size_t i = 0; i < ncTrial; ++i) {
2355 C(i, j) = m_formulaMatrix(j,juse);
2357 C(i, j) = m_formulaMatrix(j,i);
2361 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2362 k = m_indexRxnToSpecies[i];
2363 for (
size_t j = 0; j < ncTrial; ++j) {
2365 aw[j] = - m_formulaMatrix(k,juse);
2367 aw[j] = - m_formulaMatrix(k,j);
2372 solve(C, aw, 1, m_nelem);
2373 size_t i = k - ncTrial;
2374 for (
size_t j = 0; j < ncTrial; j++) {
2375 m_stoichCoeffRxnMatrix(j,i) = aw[j];
2381 for (
size_t i = 0; i < m_numRxnTot; i++) {
2383 for (
size_t j = 0; j < ncTrial; j++) {
2384 szTmp += fabs(m_stoichCoeffRxnMatrix(j,i));
2386 m_scSize[i] = szTmp;
2389 if (m_debug_print_lvl >= 2) {
2390 plogf(
" --- Components:");
2391 for (
size_t j = 0; j < ncTrial; j++) {
2394 plogf(
"\n --- Components Moles:");
2395 for (
size_t j = 0; j < ncTrial; j++) {
2397 plogf(
" % -10.3E", 0.0);
2399 plogf(
" % -10.3E", m_molNumSpecies_old[j]);
2402 plogf(
"\n --- NonComponent| Moles |");
2403 for (
size_t j = 0; j < ncTrial; j++) {
2404 plogf(
" %10.10s", m_speciesName[j]);
2407 for (
size_t i = 0; i < m_numRxnTot; i++) {
2408 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
2409 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]]);
2411 plogf(
"|% -10.3E|", 0.0);
2413 plogf(
"|% -10.3E|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
2415 for (
size_t j = 0; j < ncTrial; j++) {
2416 plogf(
" %+7.3f", m_stoichCoeffRxnMatrix(j,i));
2423 double sumMax = -1.0;
2426 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2427 k = m_indexRxnToSpecies[i];
2429 for (
size_t j = 0; j < ncTrial; ++j) {
2431 sum = m_formulaMatrix(k,juse);
2432 for (
size_t n = 0; n < ncTrial; n++) {
2433 double numElements = m_formulaMatrix(n,juse);
2434 double coeff = m_stoichCoeffRxnMatrix(n,i);
2435 sum += coeff * numElements;
2438 sum = m_formulaMatrix(k,j);
2439 for (
size_t n = 0; n < ncTrial; n++) {
2440 double numElements = m_formulaMatrix(n,j);
2441 double coeff = m_stoichCoeffRxnMatrix(n,i);
2442 sum += coeff * numElements;
2445 if (fabs(sum) > sumMax) {
2453 if (fabs(sum) > 1.0E-6) {
2454 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we have a prob");
2458 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
2459 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[iMax]]);
2460 plogf(
" element = %d ", jMax);
2461 plogf(
"%-5.5s", m_elementName[jMax]);
2464 for (
size_t i=0; i<77; i++) {
2476 m_deltaMolNumPhase.zero();
2477 m_phaseParticipation.zero();
2482 for (
size_t irxn = 0; irxn < m_numRxnTot; ++irxn) {
2483 double* scrxn_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
2484 size_t kspec = m_indexRxnToSpecies[irxn];
2485 size_t iph = m_phaseID[kspec];
2486 m_deltaMolNumPhase(iph,irxn) = 1.0;
2487 m_phaseParticipation(iph,irxn)++;
2488 for (
size_t j = 0; j < ncTrial; ++j) {
2490 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
2493 m_deltaMolNumPhase(iph,irxn) += scrxn_ptr[j];
2494 m_phaseParticipation(iph,irxn)++;
2502 m_VCount->Time_basopt += tsecond;
2503 m_VCount->Basis_Opts++;
2507 size_t VCS_SOLVE::vcs_basisOptMax(
const double*
const molNum,
const size_t j,
2524 double big = molNum[j] * m_spSize[j] * 1.01;
2525 if (m_spSize[j] <= 0.0) {
2527 "spSize is nonpositive");
2529 for (
size_t i = j + 1; i < n; ++i) {
2530 if (m_spSize[i] <= 0.0) {
2532 "spSize is nonpositive");
2534 bool doSwap =
false;
2536 doSwap = (molNum[i] * m_spSize[i]) > big;
2537 if (!m_SSPhase[i] && doSwap) {
2538 doSwap = molNum[i] > (molNum[largest] * 1.001);
2542 doSwap = (molNum[i] * m_spSize[i]) > big;
2544 doSwap = molNum[i] > (molNum[largest] * 1.001);
2547 doSwap = (molNum[i] * m_spSize[i]) > big;
2552 big = molNum[i] * m_spSize[i] * 1.01;
2558 int VCS_SOLVE::vcs_species_type(
const size_t kspec)
const
2565 size_t iph = m_phaseID[kspec];
2566 int irxn = int(kspec) - int(m_numComponents);
2567 int phaseExist = m_VolPhaseList[iph]->exists();
2570 if (m_molNumSpecies_old[kspec] <= 0.0) {
2571 if (m_tPhaseMoles_old[iph] <= 0.0 && !m_SSPhase[kspec]) {
2577 for (
size_t j = 0; j < m_nelem; ++j) {
2579 double atomComp = m_formulaMatrix(kspec,j);
2580 if (atomComp > 0.0) {
2581 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
2583 if (m_debug_print_lvl >= 2) {
2584 plogf(
" --- %s can not be nonzero because"
2585 " needed element %s is zero\n",
2586 m_speciesName[kspec], m_elementName[j]);
2588 if (m_SSPhase[kspec]) {
2603 for (
size_t j = 0; j < m_numComponents; ++j) {
2604 double stoicC = m_stoichCoeffRxnMatrix(j,irxn);
2605 if (stoicC != 0.0) {
2606 double negChangeComp = - stoicC;
2607 if (negChangeComp > 0.0) {
2608 if (m_molNumSpecies_old[j] < 1.0E-60) {
2609 if (m_debug_print_lvl >= 2) {
2610 plogf(
" --- %s is prevented from popping into existence because"
2611 " a needed component to be consumed, %s, has a zero mole number\n",
2612 m_speciesName[kspec], m_speciesName[j]);
2614 if (m_SSPhase[kspec]) {
2620 }
else if (negChangeComp < 0.0) {
2621 if (m_VolPhaseList[m_phaseID[j]]->exists() <= 0) {
2622 if (m_debug_print_lvl >= 2) {
2623 plogf(
" --- %s is prevented from popping into existence because"
2624 " a needed component %s is in a zeroed-phase that would be "
2625 "popped into existence at the same time\n",
2626 m_speciesName[kspec], m_speciesName[j]);
2628 if (m_SSPhase[kspec]) {
2639 if (irxn >= 0 && m_deltaGRxn_old[irxn] >= 0.0) {
2641 if (m_SSPhase[kspec]) {
2655 if (m_tPhaseMoles_old[iph] > 0.0) {
2656 if (m_SSPhase[kspec]) {
2667 if (m_tPhaseMoles_old[iph] <= 0.0) {
2668 if (m_SSPhase[kspec]) {
2680 if (m_SSPhase[kspec]) {
2689 if (m_molNumSpecies_old[kspec] > (m_tPhaseMoles_old[iph] * 0.001)) {
2701 double szAdj = m_scSize[irxn] * std::sqrt((
double)m_numRxnTot);
2702 for (
size_t k = 0; k < m_numComponents; ++k) {
2703 if (!m_SSPhase[k] && m_stoichCoeffRxnMatrix(k,irxn) != 0.0 && m_molNumSpecies_old[kspec] * szAdj >= m_molNumSpecies_old[k] * 0.01) {
2711 void VCS_SOLVE::vcs_dfe(
const int stateCalc,
2712 const int ll,
const size_t lbot,
const size_t ltop)
2714 double* tPhMoles_ptr=0;
2715 double* actCoeff_ptr=0;
2716 double* feSpecies=0;
2719 feSpecies = &m_feSpecies_old[0];
2720 tPhMoles_ptr = &m_tPhaseMoles_old[0];
2721 actCoeff_ptr = &m_actCoeffSpecies_old[0];
2722 molNum = &m_molNumSpecies_old[0];
2724 feSpecies = &m_feSpecies_new[0];
2725 tPhMoles_ptr = &m_tPhaseMoles_new[0];
2726 actCoeff_ptr = &m_actCoeffSpecies_new[0];
2727 molNum = &m_molNumSpecies_new[0];
2730 "Subroutine vcs_dfe called with bad stateCalc value: {}", stateCalc);
2733 if (m_debug_print_lvl >= 2) {
2736 plogf(
" --- Subroutine vcs_dfe called for one species: ");
2737 plogf(
"%-12.12s", m_speciesName[lbot]);
2739 plogf(
" --- Subroutine vcs_dfe called for all species");
2741 }
else if (ll > 0) {
2742 plogf(
" --- Subroutine vcs_dfe called for components and minors");
2744 plogf(
" --- Subroutine vcs_dfe called for components and majors");
2747 plogf(
" using tentative solution");
2752 double* tlogMoles = &m_TmpPhase[0];
2756 double* tPhInertMoles = &TPhInertMoles[0];
2757 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2758 tlogMoles[iph] = tPhInertMoles[iph];
2761 for (
size_t kspec = 0; kspec < m_nsp; kspec++) {
2763 size_t iph = m_phaseID[kspec];
2764 tlogMoles[iph] += molNum[kspec];
2767 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2769 "VCS_SOLVE::vcs_dfe",
2770 "phase Moles may be off, iph = {}, {} {}",
2771 iph, tlogMoles[iph], tPhMoles_ptr[iph]);
2773 m_TmpPhase.assign(m_TmpPhase.size(), 0.0);
2774 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2775 if (tPhMoles_ptr[iph] > 0.0) {
2776 tlogMoles[iph] = log(tPhMoles_ptr[iph]);
2783 l2 = m_numComponents;
2792 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
2807 for (
size_t kspec = l1; kspec < l2; ++kspec) {
2808 size_t iphase = m_phaseID[kspec];
2810 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
2811 "We have an inconsistency!");
2812 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
2813 "We have an unexpected situation!");
2814 feSpecies[kspec] = m_SSfeSpecies[kspec]
2815 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2817 if (m_SSPhase[kspec]) {
2818 feSpecies[kspec] = m_SSfeSpecies[kspec]
2819 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2822 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2823 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2826 size_t iph = m_phaseID[kspec];
2827 if (tPhMoles_ptr[iph] > 0.0) {
2828 feSpecies[kspec] = m_SSfeSpecies[kspec]
2830 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2831 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2833 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2834 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2837 feSpecies[kspec] = m_SSfeSpecies[kspec]
2838 + log(actCoeff_ptr[kspec] * molNum[kspec])
2839 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2840 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2848 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2849 size_t kspec = m_indexRxnToSpecies[irxn];
2851 size_t iphase = m_phaseID[kspec];
2853 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
2854 "We have an inconsistency!");
2855 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
2856 "We have an unexpected situation!");
2857 feSpecies[kspec] = m_SSfeSpecies[kspec]
2858 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2860 if (m_SSPhase[kspec]) {
2861 feSpecies[kspec] = m_SSfeSpecies[kspec]
2862 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2865 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2866 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2869 size_t iph = m_phaseID[kspec];
2870 if (tPhMoles_ptr[iph] > 0.0) {
2871 feSpecies[kspec] = m_SSfeSpecies[kspec]
2873 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2874 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2876 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2877 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2880 feSpecies[kspec] = m_SSfeSpecies[kspec]
2881 + log(actCoeff_ptr[kspec] * molNum[kspec])
2882 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2883 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2889 }
else if (ll > 0) {
2891 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2892 size_t kspec = m_indexRxnToSpecies[irxn];
2894 size_t iphase = m_phaseID[kspec];
2896 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
2897 "We have an inconsistency!");
2898 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
2899 "We have an unexpected situation!");
2900 feSpecies[kspec] = m_SSfeSpecies[kspec]
2901 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2903 if (m_SSPhase[kspec]) {
2904 feSpecies[kspec] = m_SSfeSpecies[kspec]
2905 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2908 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2909 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2912 size_t iph = m_phaseID[kspec];
2913 if (tPhMoles_ptr[iph] > 0.0) {
2914 feSpecies[kspec] = m_SSfeSpecies[kspec]
2916 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2917 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2919 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2920 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2923 feSpecies[kspec] = m_SSfeSpecies[kspec]
2924 + log(actCoeff_ptr[kspec] * molNum[kspec])
2925 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2926 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2935 double VCS_SOLVE::l2normdg(
double dgLocal[])
const
2937 if (m_numRxnRdc <= 0) {
2941 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2942 size_t kspec = irxn + m_numComponents;
2944 dgLocal[irxn] < 0.0) {
2946 tmp += dgLocal[irxn] * dgLocal[irxn];
2950 return std::sqrt(tmp / m_numRxnRdc);
2953 double VCS_SOLVE::vcs_tmoles()
2955 for (
size_t i = 0; i < m_numPhases; i++) {
2956 m_tPhaseMoles_old[i] = TPhInertMoles[i];
2958 for (
size_t i = 0; i < m_nsp; i++) {
2960 m_tPhaseMoles_old[m_phaseID[i]] += m_molNumSpecies_old[i];
2964 for (
size_t i = 0; i < m_numPhases; i++) {
2965 sum += m_tPhaseMoles_old[i];
2967 if (m_tPhaseMoles_old[i] == 0.0) {
2973 m_totalMolNum = sum;
2974 return m_totalMolNum;
2977 void VCS_SOLVE::check_tmoles()
const
2980 for (
size_t i = 0; i < m_numPhases; i++) {
2981 double m_tPhaseMoles_old_a = TPhInertMoles[i];
2983 for (
size_t k = 0; k < m_nsp; k++) {
2985 m_tPhaseMoles_old_a += m_molNumSpecies_old[k];
2988 sum += m_tPhaseMoles_old_a;
2990 double denom = m_tPhaseMoles_old[i]+ m_tPhaseMoles_old_a + 1.0E-19;
2991 if (!
vcs_doubleEqual(m_tPhaseMoles_old[i]/denom, m_tPhaseMoles_old_a/denom)) {
2992 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
2993 i, m_tPhaseMoles_old[i], m_tPhaseMoles_old_a);
2998 void VCS_SOLVE::vcs_updateVP(
const int vcsState)
3000 for (
size_t i = 0; i < m_numPhases; i++) {
3004 &m_molNumSpecies_old[0],
3005 &m_tPhaseMoles_old[0]);
3008 &m_molNumSpecies_new[0],
3009 &m_tPhaseMoles_new[0]);
3012 "wrong stateCalc value: {}", vcsState);
3017 bool VCS_SOLVE::vcs_evaluate_speciesType()
3019 m_numRxnMinorZeroed = 0;
3020 if (m_debug_print_lvl >= 2) {
3021 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
3022 }
else if (m_debug_print_lvl >= 5) {
3023 plogf(
" --- Species Status decision is reevaluated\n");
3025 for (
size_t kspec = 0; kspec < m_nsp; ++kspec) {
3026 m_speciesStatus[kspec] = vcs_species_type(kspec);
3027 if (m_debug_print_lvl >= 5) {
3028 plogf(
" --- %-16s: ", m_speciesName[kspec]);
3029 if (kspec < m_numComponents) {
3034 plogf(
" %10.3g ", m_molNumSpecies_old[kspec]);
3036 plogf(
"%s\n", sString);
3037 }
else if (m_debug_print_lvl >= 2) {
3039 switch (m_speciesStatus[kspec]) {
3043 plogf(
" --- Major Species : %-s\n", m_speciesName[kspec]);
3046 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
3047 m_speciesName[kspec]);
3050 plogf(
" --- Zeroed-MS Phase Species: %-s\n", m_speciesName[kspec]);
3053 plogf(
" --- Zeroed-SS Phase Species: %-s\n", m_speciesName[kspec]);
3056 plogf(
" --- Deleted-Small Species : %-s\n", m_speciesName[kspec]);
3059 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
3060 m_speciesName[kspec]);
3063 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
3064 m_speciesName[kspec]);
3067 plogf(
" --- InterfaceVoltage Species: %-s\n", m_speciesName[kspec]);
3070 throw CanteraError(
"VCS_SOLVE::vcs_evaluate_speciesType",
3071 "Unknown type: {}", m_speciesStatus[kspec]);
3076 ++m_numRxnMinorZeroed;
3079 debuglog(
" ---\n", m_debug_print_lvl >= 2);
3080 return (m_numRxnMinorZeroed >= m_numRxnRdc);
3083 void VCS_SOLVE::vcs_deltag(
const int L,
const bool doDeleted,
3084 const int vcsState,
const bool alterZeroedPhases)
3086 size_t irxnl = m_numRxnRdc;
3088 irxnl = m_numRxnTot;
3093 double* molNumSpecies;
3094 double* actCoeffSpecies;
3096 deltaGRxn = &m_deltaGRxn_new[0];
3097 feSpecies = &m_feSpecies_new[0];
3098 molNumSpecies = &m_molNumSpecies_new[0];
3099 actCoeffSpecies = &m_actCoeffSpecies_new[0];
3101 deltaGRxn = &m_deltaGRxn_old[0];
3102 feSpecies = &m_feSpecies_old[0];
3103 molNumSpecies = &m_molNumSpecies_old[0];
3104 actCoeffSpecies = &m_actCoeffSpecies_old[0];
3106 throw CanteraError(
"VCS_SOLVE::vcs_deltag",
"bad vcsState");
3109 if (m_debug_print_lvl >= 2) {
3110 plogf(
" --- Subroutine vcs_deltag called for ");
3112 plogf(
"major noncomponents\n");
3113 }
else if (L == 0) {
3114 plogf(
"all noncomponents\n");
3116 plogf(
"minor noncomponents\n");
3122 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3123 size_t kspec = irxn + m_numComponents;
3126 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3127 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3128 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3129 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3135 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3139 }
else if (L == 0) {
3141 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3143 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3144 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3145 for (
size_t kspec = 0; kspec < m_numComponents; ++kspec) {
3146 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3148 dtmp_ptr[kspec] < 0.0) {
3153 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3158 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3159 size_t kspec = irxn + m_numComponents;
3162 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3163 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3164 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3165 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3167 dtmp_ptr[kspec] < 0.0) {
3172 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3217 if (alterZeroedPhases &&
false) {
3218 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3223 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3226 sum += molNumSpecies[kspec];
3239 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3242 if (kspec >= m_numComponents) {
3243 size_t irxn = kspec - m_numComponents;
3244 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
3245 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
3253 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3255 if (kspec >= m_numComponents) {
3256 size_t irxn = kspec - m_numComponents;
3257 deltaGRxn[irxn] = 1.0 - poly;
3265 void VCS_SOLVE::vcs_printDeltaG(
const int stateCalc)
3267 double* deltaGRxn = &m_deltaGRxn_old[0];
3268 double* feSpecies = &m_feSpecies_old[0];
3269 double* molNumSpecies = &m_molNumSpecies_old[0];
3270 const double* tPhMoles_ptr = &m_tPhaseMoles_old[0];
3271 const double* actCoeff_ptr = &m_actCoeffSpecies_old[0];
3273 deltaGRxn = &m_deltaGRxn_new[0];
3274 feSpecies = &m_feSpecies_new[0];
3275 molNumSpecies = &m_molNumSpecies_new[0];
3276 actCoeff_ptr = &m_actCoeffSpecies_new[0];
3277 tPhMoles_ptr = &m_tPhaseMoles_new[0];
3280 bool zeroedPhase =
false;
3281 if (m_debug_print_lvl >= 2) {
3282 plogf(
" --- DELTA_G TABLE Components:");
3283 for (
size_t j = 0; j < m_numComponents; j++) {
3286 plogf(
"\n --- Components Moles:");
3287 for (
size_t j = 0; j < m_numComponents; j++) {
3288 plogf(
"%10.3g", m_molNumSpecies_old[j]);
3290 plogf(
"\n --- NonComponent| Moles | ");
3291 for (
size_t j = 0; j < m_numComponents; j++) {
3292 plogf(
"%-10.10s", m_speciesName[j]);
3295 for (
size_t i = 0; i < m_numRxnTot; i++) {
3296 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
3297 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]]);
3301 plogf(
"|%10.3g|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
3303 for (
size_t j = 0; j < m_numComponents; j++) {
3304 plogf(
" %6.2f", m_stoichCoeffRxnMatrix(j,i));
3309 for (
int i=0; i<77; i++) {
3315 writelog(
" --- DeltaG Table (J/kmol) Name PhID MoleNum MolFR "
3316 " ElectrChemStar ElectrChem DeltaGStar DeltaG(Pred) Stability\n");
3318 writeline(
'-', 132);
3320 for (
size_t kspec = 0; kspec < m_nsp; kspec++) {
3322 if (kspec >= m_numComponents) {
3323 irxn = kspec - m_numComponents;
3325 double mfValue = 1.0;
3326 size_t iphase = m_phaseID[kspec];
3327 const vcs_VolPhase* Vphase = m_VolPhaseList[iphase].get();
3333 zeroedPhase =
false;
3335 if (tPhMoles_ptr[iphase] > 0.0) {
3339 mfValue = molNumSpecies[kspec] / tPhMoles_ptr[iphase];
3342 size_t klocal = m_speciesLocalPhaseIndex[kspec];
3343 mfValue = Vphase->moleFraction(klocal);
3350 double feFull = feSpecies[kspec];
3353 feFull += log(actCoeff_ptr[kspec]) + log(mfValue);
3355 writelogf(
"%-24.24s", m_speciesName[kspec]);
3360 writelogf(
" % -12.4e", molNumSpecies[kspec]);
3363 writelogf(
" % -12.4e", feSpecies[kspec] * RT);
3366 writelogf(
" % -12.4e", deltaGRxn[irxn] * RT);
3367 writelogf(
" % -12.4e", (deltaGRxn[irxn] + feFull - feSpecies[kspec]) * RT);
3369 if (deltaGRxn[irxn] < 0.0) {
3370 if (molNumSpecies[kspec] > 0.0) {
3375 }
else if (deltaGRxn[irxn] > 0.0) {
3376 if (molNumSpecies[kspec] > 0.0) {
3388 writeline(
'-', 132);
3391 void VCS_SOLVE::vcs_switch_pos(
const bool ifunc,
const size_t k1,
const size_t k2)
3396 if (k1 >= m_nsp || k2 >= m_nsp) {
3397 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
3402 vcs_VolPhase* pv1 = m_VolPhaseList[m_phaseID[k1]].get();
3403 vcs_VolPhase* pv2 = m_VolPhaseList[m_phaseID[k2]].get();
3404 size_t kp1 = m_speciesLocalPhaseIndex[k1];
3405 size_t kp2 = m_speciesLocalPhaseIndex[k2];
3412 std::swap(m_speciesName[k1], m_speciesName[k2]);
3413 std::swap(m_molNumSpecies_old[k1], m_molNumSpecies_old[k2]);
3414 std::swap(m_speciesUnknownType[k1], m_speciesUnknownType[k2]);
3415 std::swap(m_molNumSpecies_new[k1], m_molNumSpecies_new[k2]);
3416 std::swap(m_SSfeSpecies[k1], m_SSfeSpecies[k2]);
3417 std::swap(m_spSize[k1], m_spSize[k2]);
3418 std::swap(m_deltaMolNumSpecies[k1], m_deltaMolNumSpecies[k2]);
3419 std::swap(m_feSpecies_old[k1], m_feSpecies_old[k2]);
3420 std::swap(m_feSpecies_new[k1], m_feSpecies_new[k2]);
3421 std::swap(m_SSPhase[k1], m_SSPhase[k2]);
3422 std::swap(m_phaseID[k1], m_phaseID[k2]);
3423 std::swap(m_speciesMapIndex[k1], m_speciesMapIndex[k2]);
3424 std::swap(m_speciesLocalPhaseIndex[k1], m_speciesLocalPhaseIndex[k2]);
3425 std::swap(m_actConventionSpecies[k1], m_actConventionSpecies[k2]);
3426 std::swap(m_lnMnaughtSpecies[k1], m_lnMnaughtSpecies[k2]);
3427 std::swap(m_actCoeffSpecies_new[k1], m_actCoeffSpecies_new[k2]);
3428 std::swap(m_actCoeffSpecies_old[k1], m_actCoeffSpecies_old[k2]);
3429 std::swap(m_wtSpecies[k1], m_wtSpecies[k2]);
3430 std::swap(m_chargeSpecies[k1], m_chargeSpecies[k2]);
3431 std::swap(m_speciesThermoList[k1], m_speciesThermoList[k2]);
3432 std::swap(m_PMVolumeSpecies[k1], m_PMVolumeSpecies[k2]);
3434 for (
size_t j = 0; j < m_nelem; ++j) {
3435 std::swap(m_formulaMatrix(k1,j), m_formulaMatrix(k2,j));
3437 if (m_useActCoeffJac && k1 != k2) {
3438 for (
size_t i = 0; i < m_nsp; i++) {
3439 std::swap(m_np_dLnActCoeffdMolNum(k1,i), m_np_dLnActCoeffdMolNum(k2,i));
3441 for (
size_t i = 0; i < m_nsp; i++) {
3442 std::swap(m_np_dLnActCoeffdMolNum(i,k1), m_np_dLnActCoeffdMolNum(i,k2));
3445 std::swap(m_speciesStatus[k1], m_speciesStatus[k2]);
3450 size_t i1 = k1 - m_numComponents;
3451 size_t i2 = k2 - m_numComponents;
3452 if (i1 > m_numRxnTot || i2 >= m_numRxnTot) {
3453 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
3456 for (
size_t j = 0; j < m_numComponents; ++j) {
3457 std::swap(m_stoichCoeffRxnMatrix(j,i1), m_stoichCoeffRxnMatrix(j,i2));
3459 std::swap(m_scSize[i1], m_scSize[i2]);
3460 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3461 std::swap(m_deltaMolNumPhase(iph,i1), m_deltaMolNumPhase(iph,i2));
3462 std::swap(m_phaseParticipation(iph,i1),
3463 m_phaseParticipation(iph,i2));
3465 std::swap(m_deltaGRxn_new[i1], m_deltaGRxn_new[i2]);
3466 std::swap(m_deltaGRxn_old[i1], m_deltaGRxn_old[i2]);
3467 std::swap(m_deltaGRxn_tmp[i1], m_deltaGRxn_tmp[i2]);
3471 void VCS_SOLVE::vcs_setFlagsVolPhases(
const bool upToDate,
const int stateCalc)
3474 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3475 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
3478 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3479 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
3484 void VCS_SOLVE::vcs_setFlagsVolPhase(
const size_t iph,
const bool upToDate,
3485 const int stateCalc)
3488 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
3490 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
3494 void VCS_SOLVE::vcs_updateMolNumVolPhases(
const int stateCalc)
3496 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3497 m_VolPhaseList[iph]->updateFromVCS_MoleNumbers(stateCalc);
Headers for the DenseMatrix object, which deals with dense rectangular matrices and description of th...
doublereal * 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, doublereal v=0.0)
Resize the matrix.
The class provides the wall clock timer in seconds.
double secondsWC()
Returns the wall clock time in seconds since the last reset.
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.
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
int indicating whether the phase exists or not
size_t spGlobalIndexVCS(const size_t spIndex) const
Return the Global VCS index of the kth species in the phase.
std::string PhaseName
String name for 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.
Declarations for a simple class that implements an Ansi C wall clock timer (see Cantera::clockWC).
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.
const size_t npos
index returned by functions to indicate "no position"
std::vector< int > vector_int
Vector of ints.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
const double GasConstant
Universal Gas Constant [J/kmol/K].
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
void writelogf(const char *fmt, const Args &... args)
Write a formatted message to the screen.
Namespace for the Cantera kernel.
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.
int solve(DenseMatrix &A, double *b, size_t nrhs, size_t ldb)
Solve Ax = b. Array b is overwritten on exit with x.
Contains declarations for string manipulation functions within Cantera.
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
Species is a component which can be nonzero.
#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
Always exists because it contains inerts which can't exist in any other phase.
#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 E...