21 enum stages {MAIN, EQUILIB_CHECK, ELEM_ABUND_CHECK,
22 RECHECK_DELETED, RETURN_A, RETURN_B};
24 const int anote_size = 128;
30 void VCS_SOLVE::checkDelta1(
double*
const dsLocal,
31 double*
const delTPhMoles,
size_t kspec)
33 vector<double> dchange(m_numPhases, 0.0);
34 for (
size_t k = 0; k < kspec; k++) {
36 size_t iph = m_phaseID[k];
37 dchange[iph] += dsLocal[k];
40 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
41 double denom = max(m_totalMolNum, 1.0E-4);
42 if (!
vcs_doubleEqual(dchange[iphase]/denom, delTPhMoles[iphase]/denom)) {
43 throw CanteraError(
"VCS_SOLVE::checkDelta1",
44 "we have found a problem");
49 int VCS_SOLVE::vcs_solve_TP(
int print_lvl,
int printDetails,
int maxit)
52 bool allMinorZeroedSpecies =
false;
55 int rangeErrorFound = 0;
56 bool giveUpOnElemAbund =
false;
57 int finalElemAbundAttempts = 0;
58 bool uptodate_minors =
true;
59 int forceComponentCalc = 1;
61 char ANOTE[anote_size];
63 m_debug_print_lvl = printDetails;
64 if (printDetails > 0 && print_lvl == 0) {
72 m_sm.assign(m_nelem * m_nelem, 0.0);
73 m_ss.assign(m_nelem, 0.0);
74 m_sa.assign(m_nelem, 0.0);
75 m_aw.assign(m_nsp, 0.0);
76 m_wx.assign(m_nelem, 0.0);
78 int solveFail =
false;
85 plogf(
"VCS CALCULATION METHOD\n\n ");
86 plogf(
"MultiPhase Object\n");
87 plogf(
"\n\n%5d SPECIES\n%5d ELEMENTS\n", m_nsp, m_nelem);
88 plogf(
"%5d COMPONENTS\n", m_numComponents);
89 plogf(
"%5d PHASES\n", m_numPhases);
90 plogf(
" PRESSURE%22.8g %3s\n", m_pressurePA,
"Pa ");
91 plogf(
" TEMPERATURE%19.3f K\n", m_temperature);
94 plogf(
" PHASE1 INERTS%17.3f\n", TPhInertMoles[0]);
96 if (m_numPhases > 1) {
97 plogf(
" PHASE2 INERTS%17.3f\n", TPhInertMoles[1]);
99 plogf(
"\n ELEMENTAL ABUNDANCES CORRECT");
100 plogf(
" FROM ESTIMATE Type\n\n");
101 for (
size_t i = 0; i < m_nelem; ++i) {
102 writeline(
' ', 26,
false);
103 plogf(
"%-2.2s", m_elementName[i]);
104 plogf(
"%20.12E%20.12E %3d\n", m_elemAbundancesGoal[i], m_elemAbundances[i],
107 if (m_doEstimateEquil < 0) {
108 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - forced\n");
109 }
else if (m_doEstimateEquil > 0) {
110 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - where necessary\n");
112 if (m_doEstimateEquil == 0) {
113 plogf(
"\n USER ESTIMATE OF EQUILIBRIUM\n");
115 plogf(
" Stan. Chem. Pot. in J/kmol\n");
116 plogf(
"\n SPECIES FORMULA VECTOR ");
117 writeline(
' ', 41,
false);
118 plogf(
" STAN_CHEM_POT EQUILIBRIUM_EST. Species_Type\n\n");
119 writeline(
' ', 20,
false);
120 for (
size_t i = 0; i < m_nelem; ++i) {
121 plogf(
"%-4.4s ", m_elementName[i]);
125 for (
size_t i = 0; i < m_nsp; ++i) {
126 plogf(
" %-18.18s", m_speciesName[i]);
127 for (
size_t j = 0; j < m_nelem; ++j) {
128 plogf(
"% -7.3g ", m_formulaMatrix(i,j));
130 plogf(
" %3d ", m_phaseID[i]);
131 writeline(
' ', std::max(55-
int(m_nelem)*8, 0),
false);
132 plogf(
"%12.5E %12.5E", RT * m_SSfeSpecies[i], m_molNumSpecies_old[i]);
143 for (
size_t i = 0; i < m_nsp; ++i) {
144 if (m_molNumSpecies_old[i] < 0.0) {
145 plogf(
"On Input species %-12s has a negative MF, setting it small\n",
147 size_t iph = m_phaseID[i];
150 m_molNumSpecies_old[i] = tmp;
166 if (forceComponentCalc) {
167 int retn = solve_tp_component_calc(allMinorZeroedSpecies);
172 forceComponentCalc = 0;
178 if (m_VCount->Its > maxit) {
181 solve_tp_inner(iti, it1, uptodate_minors, allMinorZeroedSpecies,
182 forceComponentCalc, stage, printDetails > 0, ANOTE);
184 }
else if (stage == EQUILIB_CHECK) {
186 solve_tp_equilib_check(allMinorZeroedSpecies, uptodate_minors,
187 giveUpOnElemAbund, solveFail, iti, it1,
189 }
else if (stage == ELEM_ABUND_CHECK) {
191 solve_tp_elem_abund_check(iti, stage, lec, giveUpOnElemAbund,
192 finalElemAbundAttempts, rangeErrorFound);
193 }
else if (stage == RECHECK_DELETED) {
203 size_t npb = vcs_recheck_deleted();
217 }
else if (stage == RETURN_A) {
219 size_t npb = vcs_recheck_deleted();
233 }
else if (stage == RETURN_B) {
236 size_t npb = vcs_add_all_deleted();
239 if (m_debug_print_lvl >= 1) {
240 plogf(
" --- add_all_deleted(): some rxns not converged. RETURNING TO LOOP!\n");
255 m_molNumSpecies_new.assign(m_molNumSpecies_new.size(), 0.0);
256 for (
size_t kspec = 0; kspec < m_nsp; ++kspec) {
257 if (m_SSPhase[kspec]) {
258 m_molNumSpecies_new[kspec] = 1.0;
260 size_t iph = m_phaseID[kspec];
261 if (m_tPhaseMoles_old[iph] != 0.0) {
262 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] / m_tPhaseMoles_old[iph];
268 size_t i = m_speciesLocalPhaseIndex[kspec];
269 m_molNumSpecies_new[kspec] = m_VolPhaseList[iph]->molefraction(i);
274 if (rangeErrorFound) {
280 m_VCount->Time_vcs_TP = tsecond;
281 m_VCount->T_Time_vcs_TP += m_VCount->Time_vcs_TP;
282 m_VCount->T_Calls_vcs_TP++;
283 m_VCount->T_Its += m_VCount->Its;
284 m_VCount->T_Basis_Opts += m_VCount->Basis_Opts;
285 m_VCount->T_Time_basopt += m_VCount->Time_basopt;
291 int VCS_SOLVE::solve_tp_component_calc(
bool& allMinorZeroedSpecies)
293 double test = -1.0e-10;
294 bool usedZeroedSpecies;
295 int retn = vcs_basopt(
false, &m_aw[0], &m_sa[0], &m_sm[0], &m_ss[0],
296 test, &usedZeroedSpecies);
306 allMinorZeroedSpecies = vcs_evaluate_speciesType();
309 if (! vcs_elabcheck(0)) {
310 debuglog(
" --- Element Abundance check failed\n", m_debug_print_lvl >= 2);
311 vcs_elcorr(&m_sm[0], &m_wx[0]);
318 debuglog(
" --- Element Abundance check passed\n", m_debug_print_lvl >= 2);
323 void VCS_SOLVE::solve_tp_inner(
size_t& iti,
size_t& it1,
324 bool& uptodate_minors,
325 bool& allMinorZeroedSpecies,
326 int& forceComponentCalc,
327 int& stage,
bool printDetails,
char* ANOTE)
336 if (!uptodate_minors) {
341 uptodate_minors =
true;
343 uptodate_minors =
false;
349 plogf(
" Iteration = %3d, Iterations since last evaluation of "
350 "optimal basis = %3d",
351 m_VCount->Its, it1 - 1);
353 plogf(
" (all species)\n");
355 plogf(
" (only major species)\n");
366 m_feSpecies_new = m_feSpecies_old;
367 m_actCoeffSpecies_new = m_actCoeffSpecies_old;
368 m_deltaGRxn_new = m_deltaGRxn_old;
369 m_deltaGRxn_Deficient = m_deltaGRxn_old;
370 m_tPhaseMoles_new = m_tPhaseMoles_old;
375 m_deltaMolNumSpecies.assign(m_deltaMolNumSpecies.size(), 0.0);
381 vector<size_t> phasePopPhaseIDs(0);
382 size_t iphasePop = vcs_popPhaseID(phasePopPhaseIDs);
383 if (iphasePop !=
npos) {
384 int soldel = vcs_popPhaseRxnStepSizes(iphasePop);
387 if (m_debug_print_lvl >= 2) {
388 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich "
389 "prevented phase %d popping\n");
397 size_t iphaseDelete =
npos;
399 if (iphasePop ==
npos) {
403 iphaseDelete = vcs_RxnStepSizes(forceComponentCalc, kspec);
404 }
else if (m_debug_print_lvl >= 2) {
405 plogf(
" --- vcs_RxnStepSizes not called because alternative"
406 "phase creation delta was used instead\n");
408 size_t doPhaseDeleteKspec =
npos;
409 size_t doPhaseDeleteIph =
npos;
412 m_deltaPhaseMoles.assign(m_deltaPhaseMoles.size(), 0.0);
428 if (iphaseDelete !=
npos) {
429 debuglog(
" --- Main Loop Treatment -> Circumvented due to Phase Deletion\n", m_debug_print_lvl >= 2);
430 for (
size_t k = 0; k < m_nsp; k++) {
431 m_molNumSpecies_new[k] = m_molNumSpecies_old[k] + m_deltaMolNumSpecies[k];
432 size_t iph = m_phaseID[k];
433 m_tPhaseMoles_new[iph] += m_deltaMolNumSpecies[k];
435 if (kspec >= m_numComponents) {
436 if (m_SSPhase[kspec] == 1) {
439 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
440 "we shouldn't be here!");
442 ++m_numRxnMinorZeroed;
443 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
459 if (m_debug_print_lvl >= 2) {
460 plogf(
" --- Main Loop Treatment of each non-component species ");
462 plogf(
"- Full Calculation:\n");
464 plogf(
"- Major Components Calculation:\n");
466 plogf(
" --- Species IC ");
467 plogf(
" KMoles Tent_KMoles Rxn_Adj | Comment \n");
469 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
470 size_t kspec = m_indexRxnToSpecies[irxn];
471 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
472 size_t iph = m_phaseID[kspec];
473 vcs_VolPhase* Vphase = m_VolPhaseList[iph].get();
477 if (iphasePop !=
npos) {
478 if (iph == iphasePop) {
479 dx = m_deltaMolNumSpecies[kspec];
480 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
481 snprintf(ANOTE, anote_size,
"Phase pop");
484 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
489 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
490 m_deltaMolNumSpecies[kspec] = dx;
493 bool resurrect = (m_deltaMolNumSpecies[kspec] > 0.0);
494 if (m_debug_print_lvl >= 3) {
495 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
496 m_speciesName[kspec], m_speciesStatus[kspec]);
497 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
498 irxn, m_deltaGRxn_new[irxn], m_molNumSpecies_new[kspec],
499 m_molNumSpecies_old[kspec], m_deltaMolNumSpecies[kspec]);
501 if (m_deltaGRxn_new[irxn] >= 0.0 || !resurrect) {
502 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
503 m_deltaMolNumSpecies[kspec] = 0.0;
505 snprintf(ANOTE, anote_size,
"Species stays zeroed: DG = %11.4E",
506 m_deltaGRxn_new[irxn]);
507 if (m_deltaGRxn_new[irxn] < 0.0) {
509 snprintf(ANOTE, anote_size,
510 "Species stays zeroed even though dg neg due to "
511 "STOICH/PHASEPOP constraint: DG = %11.4E",
512 m_deltaGRxn_new[irxn]);
514 snprintf(ANOTE, anote_size,
"Species stays zeroed even"
515 " though dg neg: DG = %11.4E, ds zeroed",
516 m_deltaGRxn_new[irxn]);
520 for (
size_t j = 0; j < m_nelem; ++j) {
521 int elType = m_elType[j];
523 double atomComp = m_formulaMatrix(kspec,j);
524 if (atomComp > 0.0) {
525 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
527 snprintf(ANOTE, anote_size,
"Species stays zeroed"
528 " even though dG neg, because of %s elemAbund",
529 m_elementName[j].c_str());
541 if (m_debug_print_lvl >= 2) {
542 plogf(
" --- Zeroed species changed to major: ");
543 plogf(
"%-12s\n", m_speciesName[kspec]);
546 allMinorZeroedSpecies =
false;
548 if (m_debug_print_lvl >= 2) {
549 plogf(
" --- Zeroed species changed to minor: ");
550 plogf(
"%-12s\n", m_speciesName[kspec]);
554 if (m_deltaMolNumSpecies[kspec] > 0.0) {
555 dx = m_deltaMolNumSpecies[kspec] * 0.01;
556 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
559 dx = m_molNumSpecies_new[kspec] - m_molNumSpecies_old[kspec];
561 m_deltaMolNumSpecies[kspec] = dx;
562 snprintf(ANOTE, anote_size,
"Born:IC=-1 to IC=1:DG=%11.4E",
563 m_deltaGRxn_new[irxn]);
565 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
566 m_deltaMolNumSpecies[kspec] = 0.0;
575 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
576 m_deltaMolNumSpecies[kspec] = 0.0;
578 snprintf(ANOTE, anote_size,
"minor species not considered");
579 if (m_debug_print_lvl >= 2) {
580 plogf(
" --- %-12s%3d% 11.4E %11.4E %11.4E | %s\n",
581 m_speciesName[kspec], m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
582 m_deltaMolNumSpecies[kspec], ANOTE);
600 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
601 m_deltaMolNumSpecies[kspec] = dx;
602 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
606 if (m_debug_print_lvl >= 2) {
607 plogf(
" --- Delete minor species in multispec phase: %-12s\n",
608 m_speciesName[kspec]);
610 m_deltaMolNumSpecies[kspec] = 0.0;
616 size_t lnospec = vcs_delete_species(kspec);
618 stage = RECHECK_DELETED;
632 snprintf(ANOTE, anote_size,
"Normal Major Calc");
637 if (fabs(m_deltaGRxn_new[irxn]) <= m_tolmaj2) {
638 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
639 m_deltaMolNumSpecies[kspec] = 0.0;
641 snprintf(ANOTE, anote_size,
"major species is converged");
642 if (m_debug_print_lvl >= 2) {
643 plogf(
" --- %-12s %3d %11.4E %11.4E %11.4E | %s\n",
644 m_speciesName[kspec], m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
645 m_deltaMolNumSpecies[kspec], ANOTE);
657 if ((m_deltaGRxn_new[irxn] * m_deltaMolNumSpecies[kspec]) <= 0.0) {
658 dx = m_deltaMolNumSpecies[kspec];
661 m_deltaMolNumSpecies[kspec] = 0.0;
662 snprintf(ANOTE, anote_size,
"dx set to 0, DG flipped sign due to "
663 "changed initial point");
667 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
673 if (m_molNumSpecies_new[kspec] <= 0.0) {
674 snprintf(ANOTE, anote_size,
"initial nonpos kmoles= %11.3E",
675 m_molNumSpecies_new[kspec]);
683 if (!m_SSPhase[kspec]) {
688 dx = -0.9 * m_molNumSpecies_old[kspec];
689 m_deltaMolNumSpecies[kspec] = dx;
690 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
695 dx = -m_molNumSpecies_old[kspec];
701 for (
size_t j = 0; j < m_numComponents; ++j) {
702 if (sc_irxn[j] != 0.0) {
703 m_wx[j] = m_molNumSpecies_old[j] + sc_irxn[j] * dx;
704 if (m_wx[j] <= m_molNumSpecies_old[j] * 0.01 - 1.0E-150) {
705 dx = std::max(dx, m_molNumSpecies_old[j] * -0.99 / sc_irxn[j]);
708 m_wx[j] = m_molNumSpecies_old[j];
711 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
712 if (m_molNumSpecies_new[kspec] > 0.0) {
713 m_deltaMolNumSpecies[kspec] = dx;
714 snprintf(ANOTE, anote_size,
715 "zeroing SS phase created a neg component species "
716 "-> reducing step size instead");
720 iph = m_phaseID[kspec];
721 Vphase = m_VolPhaseList[iph].get();
722 snprintf(ANOTE, anote_size,
"zeroing out SS phase: ");
728 m_molNumSpecies_new[kspec] = 0.0;
729 doPhaseDeleteIph = iph;
731 doPhaseDeleteKspec = kspec;
732 if (m_debug_print_lvl >= 2 && m_speciesStatus[kspec] >= 0) {
733 plogf(
" --- SS species changed to zeroedss: ");
734 plogf(
"%-12s\n", m_speciesName[kspec]);
737 ++m_numRxnMinorZeroed;
738 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
740 for (
size_t kk = 0; kk < m_nsp; kk++) {
741 m_deltaMolNumSpecies[kk] = 0.0;
742 m_molNumSpecies_new[kk] = m_molNumSpecies_old[kk];
744 m_deltaMolNumSpecies[kspec] = dx;
745 m_molNumSpecies_new[kspec] = 0.0;
747 for (
size_t k = 0; k < m_numComponents; ++k) {
748 m_deltaMolNumSpecies[k] = 0.0;
750 for (iph = 0; iph < m_numPhases; iph++) {
751 m_deltaPhaseMoles[iph] = 0.0;
759 if (dx != 0.0 && (m_speciesUnknownType[kspec] !=
766 1.0E-14*(fabs(m_deltaMolNumSpecies[kspec]) + fabs(dx) + 1.0E-32),
767 "VCS_SOLVE::solve_tp_inner",
768 "ds[kspec] = {}, dx = {}, kspec = {}\nwe have a problem!",
769 m_deltaMolNumSpecies[kspec], dx, kspec);
770 for (
size_t k = 0; k < m_numComponents; ++k) {
771 m_deltaMolNumSpecies[k] += sc_irxn[k] * dx;
776 for (iph = 0; iph < m_numPhases; iph++) {
777 m_deltaPhaseMoles[iph] += dx * m_deltaMolNumPhase(iph,irxn);
781 checkDelta1(&m_deltaMolNumSpecies[0],
782 &m_deltaPhaseMoles[0], kspec+1);
785 if (m_debug_print_lvl >= 2) {
786 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
787 plogf(
" --- %-12.12s%3d %11.4E %11.4E %11.4E | %s\n",
788 m_speciesName[kspec], m_speciesStatus[kspec],
789 m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
790 m_deltaMolNumSpecies[kspec], ANOTE);
793 if (doPhaseDeleteIph !=
npos) {
794 if (m_debug_print_lvl >= 2) {
795 plogf(
" --- %-12.12s Main Loop Special Case deleting phase with species:\n",
796 m_speciesName[doPhaseDeleteKspec]);
801 if (m_debug_print_lvl >= 2) {
802 for (
size_t k = 0; k < m_numComponents; k++) {
804 plogf(
"%-12.12s", m_speciesName[k]);
805 plogf(
" c %11.4E %11.4E %11.4E |\n",
806 m_molNumSpecies_old[k],
807 m_molNumSpecies_old[k]+m_deltaMolNumSpecies[k], m_deltaMolNumSpecies[k]);
811 plogf(
" --- Finished Main Loop\n");
820 for (
size_t k = 0; k < m_numComponents; ++k) {
821 if (m_molNumSpecies_old[k] > 0.0) {
822 double xx = -m_deltaMolNumSpecies[k] / m_molNumSpecies_old[k];
827 }
else if (m_deltaMolNumSpecies[k] < 0.0) {
830 size_t iph = m_phaseID[k];
831 m_deltaPhaseMoles[iph] -= m_deltaMolNumSpecies[k];
832 m_deltaMolNumSpecies[k] = 0.0;
836 if (par <= 1.01 && par > 0.0) {
839 if (m_debug_print_lvl >= 2) {
840 plogf(
" --- Reduction in step size due to component %s going negative = %11.3E\n",
841 m_speciesName[ll], par);
843 for (
size_t i = 0; i < m_nsp; ++i) {
844 m_deltaMolNumSpecies[i] *= par;
846 for (
size_t iph = 0; iph < m_numPhases; iph++) {
847 m_deltaPhaseMoles[iph] *= par;
852 checkDelta1(&m_deltaMolNumSpecies[0],
853 &m_deltaPhaseMoles[0], m_nsp);
860 for (
size_t kspec = 0; kspec < m_nsp; ++kspec) {
861 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
862 if (m_molNumSpecies_new[kspec] < 0.0 && (m_speciesUnknownType[kspec]
864 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
865 "vcs_solve_TP: ERROR on step change wt[{}:{}]: {} < 0.0",
866 kspec, m_speciesName[kspec], m_molNumSpecies_new[kspec]);
871 for (
size_t iph = 0; iph < m_numPhases; iph++) {
872 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + m_deltaPhaseMoles[iph];
890 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
891 vcs_Total_Gibbs(&m_molNumSpecies_old[0], &m_feSpecies_old[0],
892 &m_tPhaseMoles_old[0]));
893 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E\n",
894 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
895 &m_tPhaseMoles_new[0]));
898 bool forced = vcs_globStepDamp();
901 if (printDetails && forced) {
902 plogf(
" -----------------------------------------------------\n");
903 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
904 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
905 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
906 for (
size_t i = 0; i < m_numComponents; ++i) {
907 plogf(
" --- %-12.12s", m_speciesName[i]);
908 plogf(
" %14.6E %14.6E %14.6E\n", m_molNumSpecies_old[i],
909 m_molNumSpecies_old[i] + m_deltaMolNumSpecies[i], m_molNumSpecies_new[i]);
911 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
912 size_t irxn = kspec - m_numComponents;
913 plogf(
" --- %-12.12s", m_speciesName[kspec]);
914 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n", m_speciesStatus[kspec],
915 m_molNumSpecies_old[kspec],
916 m_molNumSpecies_old[kspec]+m_deltaMolNumSpecies[kspec],
917 m_molNumSpecies_new[kspec], m_deltaGRxn_old[irxn],
918 m_deltaGRxn_tmp[irxn], m_deltaGRxn_new[irxn]);
920 writeline(
' ', 26,
false);
921 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
922 l2normdg(&m_deltaGRxn_old[0]),
923 l2normdg(&m_deltaGRxn_new[0]));
924 plogf(
" Total kmoles of gas = %15.7E\n", m_tPhaseMoles_old[0]);
925 if ((m_numPhases > 1) && (!m_VolPhaseList[1]->m_singleSpecies)) {
926 plogf(
" Total kmoles of liquid = %15.7E\n", m_tPhaseMoles_old[1]);
928 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
930 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
931 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
932 &m_tPhaseMoles_new[0]));
933 plogf(
" -----------------------------------------------------\n");
942 plogf(
" --- Summary of the Update ");
944 plogf(
" (all species):");
946 plogf(
" (only major species):");
949 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
950 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
951 for (
size_t i = 0; i < m_numComponents; ++i) {
952 plogf(
" --- %-12.12s", m_speciesName[i]);
954 plogf(
"%14.6E%14.6E%14.6E%14.6E\n", m_molNumSpecies_old[i],
955 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i]);
957 for (
size_t i = m_numComponents; i < m_numSpeciesRdc; ++i) {
958 size_t l1 = i - m_numComponents;
959 plogf(
" --- %-12.12s", m_speciesName[i]);
960 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
961 m_speciesStatus[i], m_molNumSpecies_old[i],
962 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i],
963 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
965 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
966 size_t l1 = kspec - m_numComponents;
967 plogf(
" --- %-12.12s", m_speciesName[kspec]);
968 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
969 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
970 m_molNumSpecies_new[kspec], m_feSpecies_old[kspec], m_feSpecies_new[kspec],
971 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
974 writeline(
' ', 56,
false);
975 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
976 l2normdg(&m_deltaGRxn_old[0]),
977 l2normdg(&m_deltaGRxn_new[0]));
979 plogf(
" --- Phase_Name KMoles(after update)\n");
982 for (
size_t iph = 0; iph < m_numPhases; iph++) {
983 vcs_VolPhase* Vphase = m_VolPhaseList[iph].get();
984 plogf(
" --- %18s = %15.7E\n", Vphase->PhaseName, m_tPhaseMoles_new[iph]);
988 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
989 vcs_Total_Gibbs(&m_molNumSpecies_old[0], &m_feSpecies_old[0],
990 &m_tPhaseMoles_old[0]));
991 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E\n",
992 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
993 &m_tPhaseMoles_new[0]));
994 debuglog(
" --- Troublesome solve\n", m_VCount->Its > 550);
1007 m_tPhaseMoles_old = m_tPhaseMoles_new;
1008 m_molNumSpecies_old = m_molNumSpecies_new;
1009 m_actCoeffSpecies_old = m_actCoeffSpecies_new;
1010 m_deltaGRxn_old = m_deltaGRxn_new;
1011 m_feSpecies_old = m_feSpecies_new;
1018 if (m_debug_print_lvl >= 2) {
1019 plogf(
" --- Increment counter increased, step is accepted: %4d\n",
1029 bool justDeletedMultiPhase =
false;
1030 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1031 if (!m_VolPhaseList[iph]->m_singleSpecies && m_tPhaseMoles_old[iph] != 0.0 &&
1033 if (m_debug_print_lvl >= 1) {
1034 plogf(
" --- Setting microscopic phase %d to zero\n", iph);
1036 justDeletedMultiPhase =
true;
1037 vcs_delete_multiphase(iph);
1044 if (justDeletedMultiPhase) {
1045 bool usedZeroedSpecies;
1046 double test = -1.0e-10;
1047 int retn = vcs_basopt(
false, &m_aw[0], &m_sa[0], &m_sm[0], &m_ss[0],
1048 test, &usedZeroedSpecies);
1050 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
1051 "BASOPT returned with an error condition");
1061 if (m_debug_print_lvl >= 2) {
1062 plogf(
" --- Normal element abundance check");
1065 if (! vcs_elabcheck(0)) {
1066 debuglog(
" - failed -> redoing element abundances.\n", m_debug_print_lvl >= 2);
1067 vcs_elcorr(&m_sm[0], &m_wx[0]);
1071 uptodate_minors =
true;
1073 debuglog(
" - passed\n", m_debug_print_lvl >= 2);
1077 for (
size_t i = 0; i < m_numRxnRdc; ++i) {
1078 size_t k = m_indexRxnToSpecies[i];
1082 for (
size_t j = 0; j < m_numComponents; ++j) {
1083 bool doSwap =
false;
1085 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1086 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1087 if (!m_SSPhase[k] && doSwap) {
1088 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);
1095 doSwap = m_molNumSpecies_old[k] > (m_molNumSpecies_old[j] * 1.01);
1098 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1099 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1102 if (doSwap && m_stoichCoeffRxnMatrix(j,i) != 0.0) {
1103 if (m_debug_print_lvl >= 2) {
1104 plogf(
" --- Get a new basis because %s", m_speciesName[k]);
1105 plogf(
" is better than comp %s", m_speciesName[j]);
1106 plogf(
" and share nonzero stoic: %-9.1f\n",
1107 m_stoichCoeffRxnMatrix(j,i));
1109 forceComponentCalc = 1;
1114 debuglog(
" --- Check for an optimum basis passed\n", m_debug_print_lvl >= 2);
1115 stage = EQUILIB_CHECK;
1124 if (m_debug_print_lvl >= 2) {
1125 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1127 m_numRxnMinorZeroed = 0;
1128 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
1129 size_t kspec = m_indexRxnToSpecies[irxn];
1130 int speciesType = vcs_species_type(kspec);
1133 plogf(
" --- major/minor species is now zeroed out: %s\n",
1134 m_speciesName[kspec]);
1136 ++m_numRxnMinorZeroed;
1140 plogf(
" --- Noncomponent turned from major to minor: ");
1141 }
else if (kspec < m_numComponents) {
1142 plogf(
" --- Component turned into a minor species: ");
1144 plogf(
" --- Zeroed Species turned into a "
1147 plogf(
"%s\n", m_speciesName[kspec]);
1149 ++m_numRxnMinorZeroed;
1152 if (m_debug_print_lvl >= 2) {
1154 plogf(
" --- Noncomponent turned from minor to major: ");
1155 }
else if (kspec < m_numComponents) {
1156 plogf(
" --- Component turned into a major: ");
1158 plogf(
" --- Noncomponent turned from zeroed to major: ");
1160 plogf(
"%s\n", m_speciesName[kspec]);
1165 m_speciesStatus[kspec] = speciesType;
1170 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
1173 void VCS_SOLVE::solve_tp_equilib_check(
bool& allMinorZeroedSpecies,
1174 bool& uptodate_minors,
1175 bool& giveUpOnElemAbund,
int& solveFail,
1176 size_t& iti,
size_t& it1,
int maxit,
1177 int& stage,
bool& lec)
1179 if (! allMinorZeroedSpecies) {
1180 if (m_debug_print_lvl >= 2) {
1181 plogf(
" --- Equilibrium check for major species: ");
1183 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1184 size_t kspec = irxn + m_numComponents;
1185 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MAJOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmaj)) {
1186 if (m_VCount->Its >= maxit) {
1193 if (m_debug_print_lvl >= 2) {
1194 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]]);
1198 iti = ((it1/4) *4) - it1;
1204 debuglog(
" MAJOR SPECIES CONVERGENCE achieved", m_debug_print_lvl >= 2);
1206 debuglog(
" MAJOR SPECIES CONVERGENCE achieved "
1207 "(because there are no major species)\n", m_debug_print_lvl >= 2);
1212 if (m_numRxnMinorZeroed != 0) {
1219 uptodate_minors =
true;
1221 if (m_debug_print_lvl >= 2) {
1222 plogf(
" --- Equilibrium check for minor species: ");
1224 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1225 size_t kspec = irxn + m_numComponents;
1226 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MINOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmin)) {
1227 if (m_VCount->Its >= maxit) {
1234 if (m_debug_print_lvl >= 2) {
1235 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]]);
1245 if (m_debug_print_lvl >= 2) {
1246 plogf(
" CONVERGENCE achieved\n");
1257 if (!giveUpOnElemAbund) {
1258 if (m_debug_print_lvl >= 2) {
1259 plogf(
" --- Check the Full Element Abundances: ");
1264 if (! vcs_elabcheck(1)) {
1265 if (m_debug_print_lvl >= 2) {
1266 if (! vcs_elabcheck(0)) {
1269 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1273 stage = ELEM_ABUND_CHECK;
1276 if (m_debug_print_lvl >= 2) {
1283 if (m_numSpeciesRdc != m_nsp) {
1284 stage = RECHECK_DELETED;
1293 void VCS_SOLVE::solve_tp_elem_abund_check(
size_t& iti,
int& stage,
bool& lec,
1294 bool& giveUpOnElemAbund,
1295 int& finalElemAbundAttempts,
1296 int& rangeErrorFound)
1303 rangeErrorFound = 0;
1304 if (! vcs_elabcheck(1)) {
1305 bool ncBefore = vcs_elabcheck(0);
1306 vcs_elcorr(&m_sm[0], &m_wx[0]);
1307 bool ncAfter = vcs_elabcheck(0);
1308 bool neAfter = vcs_elabcheck(1);
1324 if (finalElemAbundAttempts >= 3) {
1325 giveUpOnElemAbund =
true;
1326 stage = EQUILIB_CHECK;
1328 finalElemAbundAttempts++;
1335 }
else if (ncAfter) {
1338 if (m_debug_print_lvl >= 2) {
1339 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1340 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1341 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1342 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition\n");
1344 rangeErrorFound = 1;
1345 giveUpOnElemAbund =
true;
1350 stage = EQUILIB_CHECK;
1357 stage = EQUILIB_CHECK;
1360 double VCS_SOLVE::vcs_minor_alt_calc(
size_t kspec,
size_t irxn,
bool* do_delete,
1363 double w_kspec = m_molNumSpecies_old[kspec];
1364 double dg_irxn = m_deltaGRxn_old[irxn];
1365 size_t iph = m_phaseID[kspec];
1369 if (w_kspec <= 0.0) {
1372 dg_irxn = std::max(dg_irxn, -200.0);
1374 snprintf(ANOTE, anote_size,
"minor species alternative calc");
1376 if (dg_irxn >= 23.0) {
1377 double molNum_kspec_new = w_kspec * 1.0e-10;
1384 return molNum_kspec_new - w_kspec;
1386 if (fabs(dg_irxn) <= m_tolmin2) {
1392 double s = m_np_dLnActCoeffdMolNum(kspec,kspec) / m_tPhaseMoles_old[iph];
1403 double a =
clip(w_kspec * s, -1.0+1e-8, 100.0);
1404 double tmp =
clip(-dg_irxn / (1.0 + a), -200.0, 200.0);
1405 double wTrial = w_kspec * exp(tmp);
1406 double molNum_kspec_new = wTrial;
1408 if (wTrial > 100. * w_kspec) {
1409 double molNumMax = 0.0001 * m_tPhaseMoles_old[iph];
1410 if (molNumMax < 100. * w_kspec) {
1411 molNumMax = 100. * w_kspec;
1413 if (wTrial > molNumMax) {
1414 molNum_kspec_new = molNumMax;
1416 molNum_kspec_new = wTrial;
1418 }
else if (1.0E10 * wTrial < w_kspec) {
1419 molNum_kspec_new= 1.0E-10 * w_kspec;
1421 molNum_kspec_new = wTrial;
1430 return molNum_kspec_new - w_kspec;
1435 double dx = m_deltaGRxn_old[irxn]/ m_Faraday_dim;
1437 snprintf(ANOTE, anote_size,
"voltage species alternative calc");
1443 int VCS_SOLVE::delta_species(
const size_t kspec,
double*
const delta_ptr)
1445 size_t irxn = kspec - m_numComponents;
1447 AssertThrowMsg(kspec >= m_numComponents,
"VCS_SOLVE::delta_species",
1448 "delete_species() ERROR: called for a component {}", kspec);
1452 double dx = *delta_ptr;
1453 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
1454 for (
size_t j = 0; j < m_numComponents; ++j) {
1455 if (m_molNumSpecies_old[j] > 0.0) {
1456 double tmp = sc_irxn[j] * dx;
1457 if (-tmp > m_molNumSpecies_old[j]) {
1459 dx = std::min(dx, - m_molNumSpecies_old[j] / sc_irxn[j]);
1465 if (m_molNumSpecies_old[j] <= 0.0 && sc_irxn[j] < 0.0) {
1473 m_molNumSpecies_old[kspec] += dx;
1474 size_t iph = m_phaseID[kspec];
1475 m_tPhaseMoles_old[iph] += dx;
1478 for (
size_t j = 0; j < m_numComponents; ++j) {
1479 double tmp = sc_irxn[j] * dx;
1482 m_molNumSpecies_old[j] += tmp;
1483 m_tPhaseMoles_old[iph] += tmp;
1485 m_molNumSpecies_old[j] = std::max(m_molNumSpecies_old[j], 0.0);
1492 int VCS_SOLVE::vcs_zero_species(
const size_t kspec)
1498 double dx = -m_molNumSpecies_old[kspec];
1500 retn = delta_species(kspec, &dx);
1501 if (!retn && m_debug_print_lvl >= 1) {
1502 plogf(
"vcs_zero_species: Couldn't zero the species %d, "
1503 "did delta of %g. orig conc of %g\n",
1504 kspec, dx, m_molNumSpecies_old[kspec] + dx);
1511 int VCS_SOLVE::vcs_delete_species(
const size_t kspec)
1513 const size_t klast = m_numSpeciesRdc - 1;
1514 const size_t iph = m_phaseID[kspec];
1515 vcs_VolPhase*
const Vphase = m_VolPhaseList[iph].get();
1516 const size_t irxn = kspec - m_numComponents;
1520 const int retn = vcs_zero_species(kspec);
1523 "Failed to delete a species!");
1529 --m_numRxnMinorZeroed;
1532 m_deltaGRxn_new[irxn] = 0.0;
1533 m_deltaGRxn_old[irxn] = 0.0;
1534 m_feSpecies_new[kspec] = 0.0;
1535 m_feSpecies_old[kspec] = 0.0;
1536 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
1539 if (kspec != klast) {
1540 vcs_switch_pos(
true, klast, kspec);
1545 &m_tPhaseMoles_old[0]);
1554 bool stillExists =
false;
1555 for (
size_t k = 0; k < m_numSpeciesRdc; k++) {
1557 m_phaseID[k] == iph && m_molNumSpecies_old[k] > 0.0) {
1563 vcs_delete_multiphase(iph);
1569 return (m_numRxnRdc == 0);
1572 void VCS_SOLVE::vcs_reinsert_deleted(
size_t kspec)
1574 size_t iph = m_phaseID[kspec];
1575 if (m_debug_print_lvl >= 2) {
1576 plogf(
" --- Add back a deleted species: %-12s\n", m_speciesName[kspec]);
1583 delta_species(kspec, &dx);
1586 if (m_SSPhase[kspec]) {
1588 --m_numRxnMinorZeroed;
1593 &m_molNumSpecies_old[0],
1594 &m_tPhaseMoles_old[0]);
1600 if (! m_SSPhase[kspec]) {
1603 for (
size_t k = 0; k < m_nsp; k++) {
1615 ++m_numRxnMinorZeroed;
1617 if (kspec != (m_numSpeciesRdc - 1)) {
1619 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
1623 bool VCS_SOLVE::vcs_delete_multiphase(
const size_t iph)
1626 bool successful =
true;
1630 if (m_debug_print_lvl >= 2) {
1631 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName);
1635 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1636 if (m_phaseID[kspec] == iph) {
1639 double dx = - m_molNumSpecies_old[kspec];
1642 int retn = delta_species(kspec, &dxTent);
1645 if (m_debug_print_lvl >= 2) {
1646 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
1647 iph, Vphase->
PhaseName, m_speciesName[kspec]);
1648 plogf(
" --- delta attempted: %g achieved: %g "
1649 " Zeroing it manually\n", dx, dxTent);
1651 m_molNumSpecies_old[kspec] = 0.0;
1652 m_molNumSpecies_new[kspec] = 0.0;
1653 m_deltaMolNumSpecies[kspec] = 0.0;
1658 m_molNumSpecies_old[kspec] = 0.0;
1659 m_molNumSpecies_new[kspec] = 0.0;
1660 m_deltaMolNumSpecies[kspec] = 0.0;
1670 double dxPerm = 0.0, dxPerm2 = 0.0;
1671 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
1672 if (m_phaseID[kcomp] == iph) {
1673 if (m_debug_print_lvl >= 2) {
1674 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
1675 kcomp, m_speciesName[kcomp], m_molNumSpecies_old[kcomp]);
1677 if (m_molNumSpecies_old[kcomp] != 0.0) {
1678 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1679 size_t irxn = kspec - m_numComponents;
1680 if (m_phaseID[kspec] != iph) {
1681 if (m_stoichCoeffRxnMatrix(kcomp,irxn) != 0.0) {
1682 double dxWant = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(kcomp,irxn);
1683 if (dxWant + m_molNumSpecies_old[kspec] < 0.0) {
1684 dxPerm = -m_molNumSpecies_old[kspec];
1686 for (
size_t jcomp = 0; kcomp < m_numComponents; ++kcomp) {
1687 if (jcomp != kcomp) {
1688 if (m_phaseID[jcomp] == iph) {
1691 double dj = dxWant * m_stoichCoeffRxnMatrix(jcomp,irxn);
1692 if (dj + m_molNumSpecies_old[kcomp] < 0.0) {
1693 dxPerm2 = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(jcomp,irxn);
1695 if (fabs(dxPerm2) < fabs(dxPerm)) {
1702 if (dxPerm != 0.0) {
1703 delta_species(kspec, &dxPerm);
1709 if (m_molNumSpecies_old[kcomp] != 0.0) {
1710 if (m_debug_print_lvl >= 2) {
1711 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
1712 kcomp, m_speciesName[kcomp], m_molNumSpecies_old[kcomp]);
1713 plogf(
" --- zeroing it \n");
1715 m_molNumSpecies_old[kcomp] = 0.0;
1726 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
1727 if (m_phaseID[kspec] == iph) {
1728 m_molNumSpecies_old[kspec] = 0.0;
1729 m_molNumSpecies_new[kspec] = 0.0;
1730 m_deltaMolNumSpecies[kspec] = 0.0;
1735 if (m_debug_print_lvl >= 2) {
1736 plogf(
" --- Make %s", m_speciesName[kspec]);
1737 plogf(
" an active but zeroed species because its phase "
1740 if (kspec != (m_numSpeciesRdc - 1)) {
1742 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
1748 m_tPhaseMoles_old[iph] = 0.0;
1749 m_tPhaseMoles_new[iph] = 0.0;
1750 m_deltaPhaseMoles[iph] = 0.0;
1757 int VCS_SOLVE::vcs_recheck_deleted()
1759 vector<double>& xtcutoff = m_TmpPhase;
1760 if (m_debug_print_lvl >= 2) {
1761 plogf(
" --- Start rechecking deleted species in multispec phases\n");
1763 if (m_numSpeciesRdc == m_nsp) {
1770 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
1771 size_t iph = m_phaseID[kspec];
1772 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_old[kspec])
1773 - m_lnMnaughtSpecies[kspec]
1774 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
1781 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1782 if (m_tPhaseMoles_old[iph] > 0.0) {
1785 xtcutoff[iph] = 0.0;
1811 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1812 size_t kspec = m_indexRxnToSpecies[irxn];
1813 size_t iph = m_phaseID[kspec];
1814 if (m_tPhaseMoles_old[iph] == 0.0) {
1815 if (m_deltaGRxn_new[irxn] < 0.0) {
1816 vcs_reinsert_deleted(kspec);
1819 m_molNumSpecies_old[kspec] = 0.0;
1821 }
else if (m_tPhaseMoles_old[iph] > 0.0) {
1822 if (m_deltaGRxn_new[irxn] < xtcutoff[iph]) {
1823 vcs_reinsert_deleted(kspec);
1831 size_t VCS_SOLVE::vcs_add_all_deleted()
1833 if (m_numSpeciesRdc == m_nsp) {
1842 m_molNumSpecies_new = m_molNumSpecies_old;
1843 for (
int cits = 0; cits < 3; cits++) {
1844 for (
size_t kspec = m_numSpeciesRdc; kspec < m_nsp; ++kspec) {
1845 size_t iph = m_phaseID[kspec];
1847 if (m_molNumSpecies_new[kspec] == 0.0) {
1853 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_new[kspec]) - m_lnMnaughtSpecies[kspec]
1854 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
1860 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1861 size_t kspec = m_indexRxnToSpecies[irxn];
1862 size_t iph = m_phaseID[kspec];
1863 if (m_tPhaseMoles_old[iph] > 0.0) {
1864 double maxDG = std::min(m_deltaGRxn_new[irxn], 690.0);
1865 double dx = m_tPhaseMoles_old[iph] * exp(- maxDG);
1866 m_molNumSpecies_new[kspec] = dx;
1870 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1871 size_t kspec = m_indexRxnToSpecies[irxn];
1872 size_t iph = m_phaseID[kspec];
1873 if (m_tPhaseMoles_old[iph] > 0.0) {
1874 double dx = m_molNumSpecies_new[kspec];
1875 size_t retn = delta_species(kspec, &dx);
1877 if (m_debug_print_lvl) {
1878 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1879 m_speciesName[kspec], kspec, dx);
1883 retn = delta_species(kspec, &dx);
1884 if (retn == 0 && m_debug_print_lvl) {
1885 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1886 m_speciesName[kspec], kspec, dx);
1890 if (m_debug_print_lvl >= 2) {
1892 plogf(
" --- add_deleted(): species %s added back in with mol number %g\n",
1893 m_speciesName[kspec], dx);
1895 plogf(
" --- add_deleted(): species %s failed to be added back in\n");
1905 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1906 size_t kspec = m_indexRxnToSpecies[irxn];
1907 size_t iph = m_phaseID[kspec];
1908 if (m_tPhaseMoles_old[iph] > 0.0 && fabs(m_deltaGRxn_old[irxn]) > m_tolmin) {
1909 if (((m_molNumSpecies_old[kspec] * exp(-m_deltaGRxn_old[irxn])) >
1913 if (m_debug_print_lvl >= 2) {
1914 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g\n",
1915 m_speciesName[kspec], m_molNumSpecies_old[kspec],
1916 m_deltaGRxn_old[irxn]);
1924 bool VCS_SOLVE::vcs_globStepDamp()
1926 double* dptr = &m_deltaGRxn_new[0];
1930 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1931 size_t kspec = irxn + m_numComponents;
1933 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
1939 dptr = &m_deltaGRxn_old[0];
1940 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1941 size_t kspec = irxn + m_numComponents;
1943 s1 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
1947 if (m_debug_print_lvl >= 2) {
1948 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
1949 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
1952 if (s1 > 0.0 || s2 <= 0.0) {
1953 debuglog(
" --- subroutine FORCE produced no adjustments\n", m_debug_print_lvl >= 2);
1959 if (fabs(s1 -s2) > 1.0E-200) {
1960 al = s1 / (s1 - s2);
1962 if (al >= 0.95 || al < 0.0) {
1963 debuglog(
" --- subroutine FORCE produced no adjustments\n", m_debug_print_lvl >= 2);
1966 if (m_debug_print_lvl >= 2) {
1967 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
1971 if (m_debug_print_lvl >= 2) {
1972 m_deltaGRxn_tmp = m_deltaGRxn_new;
1975 dptr = &m_molNumSpecies_new[0];
1976 for (
size_t kspec = 0; kspec < m_numSpeciesRdc; ++kspec) {
1977 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] +
1978 al * m_deltaMolNumSpecies[kspec];
1980 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1981 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + al * m_deltaPhaseMoles[iph];
1985 if (m_debug_print_lvl >= 2) {
1986 plogf(
" --- subroutine FORCE adjusted the mole "
1987 "numbers, AL = %10.3f\n", al);
2000 dptr = &m_deltaGRxn_new[0];
2002 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2003 size_t kspec = irxn + m_numComponents;
2005 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2009 if (m_debug_print_lvl >= 2) {
2010 plogf(
" --- subroutine FORCE: Adj End Slope = %g\n", s2);
2015 int VCS_SOLVE::vcs_basopt(
const bool doJustComponents,
double aw[],
double sa[],
double sm[],
2016 double ss[],
double test,
bool*
const usedZeroedSpecies)
2020 size_t jlose =
npos;
2023 if (m_debug_print_lvl >= 2) {
2025 for (
size_t i=0; i<77; i++) {
2029 plogf(
" --- Subroutine BASOPT called to ");
2030 if (doJustComponents) {
2031 plogf(
"calculate the number of components\n");
2033 plogf(
"reevaluate the components\n");
2035 if (m_debug_print_lvl >= 2) {
2037 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
2038 plogf(
" --- Active | ");
2039 for (
size_t j = 0; j < m_nelem; j++) {
2040 plogf(
" %1d ", m_elementActive[j]);
2043 plogf(
" --- Species | ");
2044 for (
size_t j = 0; j < m_nelem; j++) {
2045 writelog(
" {:>8.8s}", m_elementName[j]);
2048 for (k = 0; k < m_nsp; k++) {
2049 writelog(
" --- {:>11.11s} | ", m_speciesName[k]);
2050 for (
size_t j = 0; j < m_nelem; j++) {
2051 plogf(
" %8.2g", m_formulaMatrix(k,j));
2062 size_t ncTrial = std::min(m_nelem, m_nsp);
2063 m_numComponents = ncTrial;
2064 *usedZeroedSpecies =
false;
2065 vector<int> ipiv(ncTrial);
2068 std::copy(m_molNumSpecies_old.begin(),
2069 m_molNumSpecies_old.begin() + m_nsp, aw);
2072 for (k = 0; k < m_nsp; k++) {
2082 while (jr < ncTrial) {
2090 k = vcs_basisOptMax(aw, jr, m_nsp);
2130 *usedZeroedSpecies =
true;
2131 double maxConcPossKspec = 0.0;
2132 double maxConcPoss = 0.0;
2133 size_t kfound =
npos;
2134 int minNonZeroes = 100000;
2135 int nonZeroesKspec = 0;
2136 for (
size_t kspec = ncTrial; kspec < m_nsp; kspec++) {
2138 maxConcPossKspec = 1.0E10;
2140 for (
size_t j = 0; j < m_nelem; ++j) {
2142 double nu = m_formulaMatrix(kspec,j);
2145 maxConcPossKspec = std::min(m_elemAbundancesGoal[j] / nu, maxConcPossKspec);
2149 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
2150 if (nonZeroesKspec <= minNonZeroes) {
2151 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
2156 if (m_SSfeSpecies[kspec] <= m_SSfeSpecies[kfound]) {
2161 minNonZeroes = std::min(minNonZeroes, nonZeroesKspec);
2162 maxConcPoss = std::max(maxConcPoss, maxConcPossKspec);
2166 if (kfound ==
npos) {
2169 for (
size_t kspec = ncTrial; kspec < m_nsp; kspec++) {
2170 if (aw[kspec] >= 0.0) {
2171 size_t irxn = kspec - ncTrial;
2172 if (m_deltaGRxn_new[irxn] < gmin) {
2173 gmin = m_deltaGRxn_new[irxn];
2182 if (aw[k] == test) {
2183 m_numComponents = jr;
2184 ncTrial = m_numComponents;
2185 size_t numPreDeleted = m_numRxnTot - m_numRxnRdc;
2186 if (numPreDeleted != (m_nsp - m_numSpeciesRdc)) {
2187 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we shouldn't be here");
2189 m_numRxnTot = m_nsp - ncTrial;
2190 m_numRxnRdc = m_numRxnTot - numPreDeleted;
2191 m_numSpeciesRdc = m_nsp - numPreDeleted;
2192 for (
size_t i = 0; i < m_nsp; ++i) {
2193 m_indexRxnToSpecies[i] = ncTrial + i;
2195 if (m_debug_print_lvl >= 2) {
2196 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
2211 for (
size_t j = 0; j < m_nelem; ++j) {
2212 sm[j + jr*m_nelem] = m_formulaMatrix(k,j);
2218 for (
size_t j = 0; j < jl; ++j) {
2220 for (
size_t i = 0; i < m_nelem; ++i) {
2221 ss[j] += sm[i + jr*m_nelem] * sm[i + j*m_nelem];
2227 for (
size_t j = 0; j < jl; ++j) {
2228 for (
size_t i = 0; i < m_nelem; ++i) {
2229 sm[i + jr*m_nelem] -= ss[j] * sm[i + j*m_nelem];
2237 for (
size_t ml = 0; ml < m_nelem; ++ml) {
2238 sa[jr] += pow(sm[ml + jr*m_nelem], 2);
2242 if (sa[jr] > 1.0e-6) {
2249 if (m_debug_print_lvl >= 2) {
2250 plogf(
" --- %-12.12s", m_speciesName[k]);
2252 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[k]);
2254 plogf(
"(%9.2g)", m_molNumSpecies_old[k]);
2256 plogf(
" replaces %-12.12s", m_speciesName[jr]);
2258 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[jr]);
2260 plogf(
"(%9.2g)", m_molNumSpecies_old[jr]);
2262 plogf(
" as component %3d\n", jr);
2264 vcs_switch_pos(
false, jr, k);
2265 std::swap(aw[jr], aw[k]);
2266 }
else if (m_debug_print_lvl >= 2) {
2267 plogf(
" --- %-12.12s", m_speciesName[k]);
2269 plogf(
"(Volts = %9.2g) remains ", m_molNumSpecies_old[k]);
2271 plogf(
"(%9.2g) remains ", m_molNumSpecies_old[k]);
2273 plogf(
" as component %3d\n", jr);
2282 if (doJustComponents) {
2312 C.
resize(ncTrial, ncTrial);
2313 for (
size_t j = 0; j < ncTrial; ++j) {
2314 for (
size_t i = 0; i < ncTrial; ++i) {
2315 C(i, j) = m_formulaMatrix(j,i);
2318 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2319 k = m_indexRxnToSpecies[i];
2320 for (
size_t j = 0; j < ncTrial; ++j) {
2321 m_stoichCoeffRxnMatrix(j,i) = - m_formulaMatrix(k,j);
2326 solve(C, m_stoichCoeffRxnMatrix.
ptrColumn(0), m_numRxnTot, m_nelem);
2332 for (
size_t j = 0; j < m_nelem; j++) {
2333 if (!m_elementActive[j] && !strcmp(m_elementName[j].c_str(),
"E")) {
2337 for (
size_t j = 0; j < m_nelem; j++) {
2338 if (m_elementActive[j] && !strncmp((m_elementName[j]).c_str(),
"cn_", 3)) {
2342 for (k = 0; k < m_nsp; k++) {
2344 for (
size_t j = 0; j < ncTrial; ++j) {
2345 for (
size_t i = 0; i < ncTrial; ++i) {
2347 C(i, j) = m_formulaMatrix(j,juse);
2349 C(i, j) = m_formulaMatrix(j,i);
2353 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2354 k = m_indexRxnToSpecies[i];
2355 for (
size_t j = 0; j < ncTrial; ++j) {
2357 aw[j] = - m_formulaMatrix(k,juse);
2359 aw[j] = - m_formulaMatrix(k,j);
2364 solve(C, aw, 1, m_nelem);
2365 size_t i = k - ncTrial;
2366 for (
size_t j = 0; j < ncTrial; j++) {
2367 m_stoichCoeffRxnMatrix(j,i) = aw[j];
2373 for (
size_t i = 0; i < m_numRxnTot; i++) {
2375 for (
size_t j = 0; j < ncTrial; j++) {
2376 szTmp += fabs(m_stoichCoeffRxnMatrix(j,i));
2378 m_scSize[i] = szTmp;
2381 if (m_debug_print_lvl >= 2) {
2382 plogf(
" --- Components:");
2383 for (
size_t j = 0; j < ncTrial; j++) {
2386 plogf(
"\n --- Components Moles:");
2387 for (
size_t j = 0; j < ncTrial; j++) {
2389 plogf(
" % -10.3E", 0.0);
2391 plogf(
" % -10.3E", m_molNumSpecies_old[j]);
2394 plogf(
"\n --- NonComponent| Moles |");
2395 for (
size_t j = 0; j < ncTrial; j++) {
2396 plogf(
" %10.10s", m_speciesName[j]);
2399 for (
size_t i = 0; i < m_numRxnTot; i++) {
2400 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
2401 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]]);
2403 plogf(
"|% -10.3E|", 0.0);
2405 plogf(
"|% -10.3E|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
2407 for (
size_t j = 0; j < ncTrial; j++) {
2408 plogf(
" %+7.3f", m_stoichCoeffRxnMatrix(j,i));
2415 double sumMax = -1.0;
2418 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2419 k = m_indexRxnToSpecies[i];
2421 for (
size_t j = 0; j < ncTrial; ++j) {
2423 sum = m_formulaMatrix(k,juse);
2424 for (
size_t n = 0; n < ncTrial; n++) {
2425 double numElements = m_formulaMatrix(n,juse);
2426 double coeff = m_stoichCoeffRxnMatrix(n,i);
2427 sum += coeff * numElements;
2430 sum = m_formulaMatrix(k,j);
2431 for (
size_t n = 0; n < ncTrial; n++) {
2432 double numElements = m_formulaMatrix(n,j);
2433 double coeff = m_stoichCoeffRxnMatrix(n,i);
2434 sum += coeff * numElements;
2437 if (fabs(sum) > sumMax) {
2445 if (fabs(sum) > 1.0E-6) {
2446 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we have a prob");
2450 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
2451 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[iMax]]);
2452 plogf(
" element = %d ", jMax);
2453 plogf(
"%-5.5s", m_elementName[jMax]);
2456 for (
size_t i=0; i<77; i++) {
2468 m_deltaMolNumPhase.zero();
2469 m_phaseParticipation.zero();
2474 for (
size_t irxn = 0; irxn < m_numRxnTot; ++irxn) {
2475 double* scrxn_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
2476 size_t kspec = m_indexRxnToSpecies[irxn];
2477 size_t iph = m_phaseID[kspec];
2478 m_deltaMolNumPhase(iph,irxn) = 1.0;
2479 m_phaseParticipation(iph,irxn)++;
2480 for (
size_t j = 0; j < ncTrial; ++j) {
2482 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
2485 m_deltaMolNumPhase(iph,irxn) += scrxn_ptr[j];
2486 m_phaseParticipation(iph,irxn)++;
2494 m_VCount->Time_basopt += tsecond;
2495 m_VCount->Basis_Opts++;
2499 size_t VCS_SOLVE::vcs_basisOptMax(
const double*
const molNum,
const size_t j,
2516 double big = molNum[j] * m_spSize[j] * 1.01;
2517 if (m_spSize[j] <= 0.0) {
2519 "spSize is nonpositive");
2521 for (
size_t i = j + 1; i < n; ++i) {
2522 if (m_spSize[i] <= 0.0) {
2524 "spSize is nonpositive");
2526 bool doSwap =
false;
2528 doSwap = (molNum[i] * m_spSize[i]) > big;
2529 if (!m_SSPhase[i] && doSwap) {
2530 doSwap = molNum[i] > (molNum[largest] * 1.001);
2534 doSwap = (molNum[i] * m_spSize[i]) > big;
2536 doSwap = molNum[i] > (molNum[largest] * 1.001);
2539 doSwap = (molNum[i] * m_spSize[i]) > big;
2544 big = molNum[i] * m_spSize[i] * 1.01;
2550 int VCS_SOLVE::vcs_species_type(
const size_t kspec)
const
2557 size_t iph = m_phaseID[kspec];
2558 int irxn = int(kspec) - int(m_numComponents);
2559 int phaseExist = m_VolPhaseList[iph]->exists();
2562 if (m_molNumSpecies_old[kspec] <= 0.0) {
2563 if (m_tPhaseMoles_old[iph] <= 0.0 && !m_SSPhase[kspec]) {
2569 for (
size_t j = 0; j < m_nelem; ++j) {
2571 double atomComp = m_formulaMatrix(kspec,j);
2572 if (atomComp > 0.0) {
2573 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
2575 if (m_debug_print_lvl >= 2) {
2576 plogf(
" --- %s can not be nonzero because"
2577 " needed element %s is zero\n",
2578 m_speciesName[kspec], m_elementName[j]);
2580 if (m_SSPhase[kspec]) {
2595 for (
size_t j = 0; j < m_numComponents; ++j) {
2596 double stoicC = m_stoichCoeffRxnMatrix(j,irxn);
2597 if (stoicC != 0.0) {
2598 double negChangeComp = - stoicC;
2599 if (negChangeComp > 0.0) {
2600 if (m_molNumSpecies_old[j] < 1.0E-60) {
2601 if (m_debug_print_lvl >= 2) {
2602 plogf(
" --- %s is prevented from popping into existence because"
2603 " a needed component to be consumed, %s, has a zero mole number\n",
2604 m_speciesName[kspec], m_speciesName[j]);
2606 if (m_SSPhase[kspec]) {
2612 }
else if (negChangeComp < 0.0) {
2613 if (m_VolPhaseList[m_phaseID[j]]->exists() <= 0) {
2614 if (m_debug_print_lvl >= 2) {
2615 plogf(
" --- %s is prevented from popping into existence because"
2616 " a needed component %s is in a zeroed-phase that would be "
2617 "popped into existence at the same time\n",
2618 m_speciesName[kspec], m_speciesName[j]);
2620 if (m_SSPhase[kspec]) {
2631 if (irxn >= 0 && m_deltaGRxn_old[irxn] >= 0.0) {
2633 if (m_SSPhase[kspec]) {
2647 if (m_tPhaseMoles_old[iph] > 0.0) {
2648 if (m_SSPhase[kspec]) {
2659 if (m_tPhaseMoles_old[iph] <= 0.0) {
2660 if (m_SSPhase[kspec]) {
2672 if (m_SSPhase[kspec]) {
2681 if (m_molNumSpecies_old[kspec] > (m_tPhaseMoles_old[iph] * 0.001)) {
2693 double szAdj = m_scSize[irxn] * std::sqrt((
double)m_numRxnTot);
2694 for (
size_t k = 0; k < m_numComponents; ++k) {
2695 if (!m_SSPhase[k] && m_stoichCoeffRxnMatrix(k,irxn) != 0.0 && m_molNumSpecies_old[kspec] * szAdj >= m_molNumSpecies_old[k] * 0.01) {
2703 void VCS_SOLVE::vcs_dfe(
const int stateCalc,
2704 const int ll,
const size_t lbot,
const size_t ltop)
2706 double* tPhMoles_ptr=0;
2707 double* actCoeff_ptr=0;
2708 double* feSpecies=0;
2711 feSpecies = &m_feSpecies_old[0];
2712 tPhMoles_ptr = &m_tPhaseMoles_old[0];
2713 actCoeff_ptr = &m_actCoeffSpecies_old[0];
2714 molNum = &m_molNumSpecies_old[0];
2716 feSpecies = &m_feSpecies_new[0];
2717 tPhMoles_ptr = &m_tPhaseMoles_new[0];
2718 actCoeff_ptr = &m_actCoeffSpecies_new[0];
2719 molNum = &m_molNumSpecies_new[0];
2722 "Subroutine vcs_dfe called with bad stateCalc value: {}", stateCalc);
2725 if (m_debug_print_lvl >= 2) {
2728 plogf(
" --- Subroutine vcs_dfe called for one species: ");
2729 plogf(
"%-12.12s", m_speciesName[lbot]);
2731 plogf(
" --- Subroutine vcs_dfe called for all species");
2733 }
else if (ll > 0) {
2734 plogf(
" --- Subroutine vcs_dfe called for components and minors");
2736 plogf(
" --- Subroutine vcs_dfe called for components and majors");
2739 plogf(
" using tentative solution");
2744 double* tlogMoles = &m_TmpPhase[0];
2748 double* tPhInertMoles = &TPhInertMoles[0];
2749 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2750 tlogMoles[iph] = tPhInertMoles[iph];
2753 for (
size_t kspec = 0; kspec < m_nsp; kspec++) {
2755 size_t iph = m_phaseID[kspec];
2756 tlogMoles[iph] += molNum[kspec];
2759 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2761 "VCS_SOLVE::vcs_dfe",
2762 "phase Moles may be off, iph = {}, {} {}",
2763 iph, tlogMoles[iph], tPhMoles_ptr[iph]);
2765 m_TmpPhase.assign(m_TmpPhase.size(), 0.0);
2766 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2767 if (tPhMoles_ptr[iph] > 0.0) {
2768 tlogMoles[iph] = log(tPhMoles_ptr[iph]);
2775 l2 = m_numComponents;
2784 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
2799 for (
size_t kspec = l1; kspec < l2; ++kspec) {
2800 size_t iphase = m_phaseID[kspec];
2802 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
2803 "We have an inconsistency!");
2804 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
2805 "We have an unexpected situation!");
2806 feSpecies[kspec] = m_SSfeSpecies[kspec]
2807 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2809 if (m_SSPhase[kspec]) {
2810 feSpecies[kspec] = m_SSfeSpecies[kspec]
2811 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2814 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2815 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2818 size_t iph = m_phaseID[kspec];
2819 if (tPhMoles_ptr[iph] > 0.0) {
2820 feSpecies[kspec] = m_SSfeSpecies[kspec]
2822 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2823 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2825 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2826 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2829 feSpecies[kspec] = m_SSfeSpecies[kspec]
2830 + log(actCoeff_ptr[kspec] * molNum[kspec])
2831 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2832 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2840 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2841 size_t kspec = m_indexRxnToSpecies[irxn];
2843 size_t iphase = m_phaseID[kspec];
2845 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
2846 "We have an inconsistency!");
2847 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
2848 "We have an unexpected situation!");
2849 feSpecies[kspec] = m_SSfeSpecies[kspec]
2850 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2852 if (m_SSPhase[kspec]) {
2853 feSpecies[kspec] = m_SSfeSpecies[kspec]
2854 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2857 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2858 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2861 size_t iph = m_phaseID[kspec];
2862 if (tPhMoles_ptr[iph] > 0.0) {
2863 feSpecies[kspec] = m_SSfeSpecies[kspec]
2865 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2866 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2868 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2869 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2872 feSpecies[kspec] = m_SSfeSpecies[kspec]
2873 + log(actCoeff_ptr[kspec] * molNum[kspec])
2874 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2875 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2881 }
else if (ll > 0) {
2883 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2884 size_t kspec = m_indexRxnToSpecies[irxn];
2886 size_t iphase = m_phaseID[kspec];
2888 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
2889 "We have an inconsistency!");
2890 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
2891 "We have an unexpected situation!");
2892 feSpecies[kspec] = m_SSfeSpecies[kspec]
2893 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2895 if (m_SSPhase[kspec]) {
2896 feSpecies[kspec] = m_SSfeSpecies[kspec]
2897 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2900 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2901 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2904 size_t iph = m_phaseID[kspec];
2905 if (tPhMoles_ptr[iph] > 0.0) {
2906 feSpecies[kspec] = m_SSfeSpecies[kspec]
2908 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2909 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2911 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2912 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2915 feSpecies[kspec] = m_SSfeSpecies[kspec]
2916 + log(actCoeff_ptr[kspec] * molNum[kspec])
2917 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2918 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2927 double VCS_SOLVE::l2normdg(
double dgLocal[])
const
2929 if (m_numRxnRdc <= 0) {
2933 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2934 size_t kspec = irxn + m_numComponents;
2936 dgLocal[irxn] < 0.0) {
2938 tmp += dgLocal[irxn] * dgLocal[irxn];
2942 return std::sqrt(tmp / m_numRxnRdc);
2945 double VCS_SOLVE::vcs_tmoles()
2947 for (
size_t i = 0; i < m_numPhases; i++) {
2948 m_tPhaseMoles_old[i] = TPhInertMoles[i];
2950 for (
size_t i = 0; i < m_nsp; i++) {
2952 m_tPhaseMoles_old[m_phaseID[i]] += m_molNumSpecies_old[i];
2956 for (
size_t i = 0; i < m_numPhases; i++) {
2957 sum += m_tPhaseMoles_old[i];
2959 if (m_tPhaseMoles_old[i] == 0.0) {
2965 m_totalMolNum = sum;
2966 return m_totalMolNum;
2969 void VCS_SOLVE::check_tmoles()
const
2971 for (
size_t i = 0; i < m_numPhases; i++) {
2972 double m_tPhaseMoles_old_a = TPhInertMoles[i];
2974 for (
size_t k = 0; k < m_nsp; k++) {
2976 m_tPhaseMoles_old_a += m_molNumSpecies_old[k];
2980 double denom = m_tPhaseMoles_old[i]+ m_tPhaseMoles_old_a + 1.0E-19;
2981 if (!
vcs_doubleEqual(m_tPhaseMoles_old[i]/denom, m_tPhaseMoles_old_a/denom)) {
2982 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
2983 i, m_tPhaseMoles_old[i], m_tPhaseMoles_old_a);
2988 void VCS_SOLVE::vcs_updateVP(
const int vcsState)
2990 for (
size_t i = 0; i < m_numPhases; i++) {
2994 &m_molNumSpecies_old[0],
2995 &m_tPhaseMoles_old[0]);
2998 &m_molNumSpecies_new[0],
2999 &m_tPhaseMoles_new[0]);
3002 "wrong stateCalc value: {}", vcsState);
3007 bool VCS_SOLVE::vcs_evaluate_speciesType()
3009 m_numRxnMinorZeroed = 0;
3010 if (m_debug_print_lvl >= 2) {
3011 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
3012 }
else if (m_debug_print_lvl >= 5) {
3013 plogf(
" --- Species Status decision is reevaluated\n");
3015 for (
size_t kspec = 0; kspec < m_nsp; ++kspec) {
3016 m_speciesStatus[kspec] = vcs_species_type(kspec);
3017 if (m_debug_print_lvl >= 5) {
3018 plogf(
" --- %-16s: ", m_speciesName[kspec]);
3019 if (kspec < m_numComponents) {
3024 plogf(
" %10.3g ", m_molNumSpecies_old[kspec]);
3026 plogf(
"%s\n", sString);
3027 }
else if (m_debug_print_lvl >= 2) {
3029 switch (m_speciesStatus[kspec]) {
3033 plogf(
" --- Major Species : %-s\n", m_speciesName[kspec]);
3036 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
3037 m_speciesName[kspec]);
3040 plogf(
" --- Zeroed-MS Phase Species: %-s\n", m_speciesName[kspec]);
3043 plogf(
" --- Zeroed-SS Phase Species: %-s\n", m_speciesName[kspec]);
3046 plogf(
" --- Deleted-Small Species : %-s\n", m_speciesName[kspec]);
3049 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
3050 m_speciesName[kspec]);
3053 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
3054 m_speciesName[kspec]);
3057 plogf(
" --- InterfaceVoltage Species: %-s\n", m_speciesName[kspec]);
3060 throw CanteraError(
"VCS_SOLVE::vcs_evaluate_speciesType",
3061 "Unknown type: {}", m_speciesStatus[kspec]);
3066 ++m_numRxnMinorZeroed;
3069 debuglog(
" ---\n", m_debug_print_lvl >= 2);
3070 return (m_numRxnMinorZeroed >= m_numRxnRdc);
3073 void VCS_SOLVE::vcs_deltag(
const int L,
const bool doDeleted,
3074 const int vcsState,
const bool alterZeroedPhases)
3076 size_t irxnl = m_numRxnRdc;
3078 irxnl = m_numRxnTot;
3083 double* molNumSpecies;
3084 double* actCoeffSpecies;
3086 deltaGRxn = &m_deltaGRxn_new[0];
3087 feSpecies = &m_feSpecies_new[0];
3088 molNumSpecies = &m_molNumSpecies_new[0];
3089 actCoeffSpecies = &m_actCoeffSpecies_new[0];
3091 deltaGRxn = &m_deltaGRxn_old[0];
3092 feSpecies = &m_feSpecies_old[0];
3093 molNumSpecies = &m_molNumSpecies_old[0];
3094 actCoeffSpecies = &m_actCoeffSpecies_old[0];
3096 throw CanteraError(
"VCS_SOLVE::vcs_deltag",
"bad vcsState");
3099 if (m_debug_print_lvl >= 2) {
3100 plogf(
" --- Subroutine vcs_deltag called for ");
3102 plogf(
"major noncomponents\n");
3103 }
else if (L == 0) {
3104 plogf(
"all noncomponents\n");
3106 plogf(
"minor noncomponents\n");
3112 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3113 size_t kspec = irxn + m_numComponents;
3116 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3117 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3118 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3119 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3125 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3129 }
else if (L == 0) {
3131 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3133 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3134 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3135 for (
size_t kspec = 0; kspec < m_numComponents; ++kspec) {
3136 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3138 dtmp_ptr[kspec] < 0.0) {
3143 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3148 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3149 size_t kspec = irxn + m_numComponents;
3152 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3153 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3154 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3155 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3157 dtmp_ptr[kspec] < 0.0) {
3162 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3207 if (alterZeroedPhases &&
false) {
3208 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3213 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3216 sum += molNumSpecies[kspec];
3229 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3232 if (kspec >= m_numComponents) {
3233 size_t irxn = kspec - m_numComponents;
3234 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
3235 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
3243 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3245 if (kspec >= m_numComponents) {
3246 size_t irxn = kspec - m_numComponents;
3247 deltaGRxn[irxn] = 1.0 - poly;
3255 void VCS_SOLVE::vcs_printDeltaG(
const int stateCalc)
3257 double* deltaGRxn = &m_deltaGRxn_old[0];
3258 double* feSpecies = &m_feSpecies_old[0];
3259 double* molNumSpecies = &m_molNumSpecies_old[0];
3260 const double* tPhMoles_ptr = &m_tPhaseMoles_old[0];
3261 const double* actCoeff_ptr = &m_actCoeffSpecies_old[0];
3263 deltaGRxn = &m_deltaGRxn_new[0];
3264 feSpecies = &m_feSpecies_new[0];
3265 molNumSpecies = &m_molNumSpecies_new[0];
3266 actCoeff_ptr = &m_actCoeffSpecies_new[0];
3267 tPhMoles_ptr = &m_tPhaseMoles_new[0];
3270 bool zeroedPhase =
false;
3271 if (m_debug_print_lvl >= 2) {
3272 plogf(
" --- DELTA_G TABLE Components:");
3273 for (
size_t j = 0; j < m_numComponents; j++) {
3276 plogf(
"\n --- Components Moles:");
3277 for (
size_t j = 0; j < m_numComponents; j++) {
3278 plogf(
"%10.3g", m_molNumSpecies_old[j]);
3280 plogf(
"\n --- NonComponent| Moles | ");
3281 for (
size_t j = 0; j < m_numComponents; j++) {
3282 plogf(
"%-10.10s", m_speciesName[j]);
3285 for (
size_t i = 0; i < m_numRxnTot; i++) {
3286 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
3287 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]]);
3291 plogf(
"|%10.3g|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
3293 for (
size_t j = 0; j < m_numComponents; j++) {
3294 plogf(
" %6.2f", m_stoichCoeffRxnMatrix(j,i));
3299 for (
int i=0; i<77; i++) {
3305 writelog(
" --- DeltaG Table (J/kmol) Name PhID MoleNum MolFR "
3306 " ElectrChemStar ElectrChem DeltaGStar DeltaG(Pred) Stability\n");
3308 writeline(
'-', 132);
3310 for (
size_t kspec = 0; kspec < m_nsp; kspec++) {
3312 if (kspec >= m_numComponents) {
3313 irxn = kspec - m_numComponents;
3315 double mfValue = 1.0;
3316 size_t iphase = m_phaseID[kspec];
3317 const vcs_VolPhase* Vphase = m_VolPhaseList[iphase].get();
3323 zeroedPhase =
false;
3325 if (tPhMoles_ptr[iphase] > 0.0) {
3329 mfValue = molNumSpecies[kspec] / tPhMoles_ptr[iphase];
3332 size_t klocal = m_speciesLocalPhaseIndex[kspec];
3333 mfValue = Vphase->moleFraction(klocal);
3340 double feFull = feSpecies[kspec];
3343 feFull += log(actCoeff_ptr[kspec]) + log(mfValue);
3345 writelogf(
"%-24.24s", m_speciesName[kspec]);
3350 writelogf(
" % -12.4e", molNumSpecies[kspec]);
3353 writelogf(
" % -12.4e", feSpecies[kspec] * RT);
3356 writelogf(
" % -12.4e", deltaGRxn[irxn] * RT);
3357 writelogf(
" % -12.4e", (deltaGRxn[irxn] + feFull - feSpecies[kspec]) * RT);
3359 if (deltaGRxn[irxn] < 0.0) {
3360 if (molNumSpecies[kspec] > 0.0) {
3365 }
else if (deltaGRxn[irxn] > 0.0) {
3366 if (molNumSpecies[kspec] > 0.0) {
3378 writeline(
'-', 132);
3381 void VCS_SOLVE::vcs_switch_pos(
const bool ifunc,
const size_t k1,
const size_t k2)
3386 if (k1 >= m_nsp || k2 >= m_nsp) {
3387 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
3392 vcs_VolPhase* pv1 = m_VolPhaseList[m_phaseID[k1]].get();
3393 vcs_VolPhase* pv2 = m_VolPhaseList[m_phaseID[k2]].get();
3394 size_t kp1 = m_speciesLocalPhaseIndex[k1];
3395 size_t kp2 = m_speciesLocalPhaseIndex[k2];
3402 std::swap(m_speciesName[k1], m_speciesName[k2]);
3403 std::swap(m_molNumSpecies_old[k1], m_molNumSpecies_old[k2]);
3404 std::swap(m_speciesUnknownType[k1], m_speciesUnknownType[k2]);
3405 std::swap(m_molNumSpecies_new[k1], m_molNumSpecies_new[k2]);
3406 std::swap(m_SSfeSpecies[k1], m_SSfeSpecies[k2]);
3407 std::swap(m_spSize[k1], m_spSize[k2]);
3408 std::swap(m_deltaMolNumSpecies[k1], m_deltaMolNumSpecies[k2]);
3409 std::swap(m_feSpecies_old[k1], m_feSpecies_old[k2]);
3410 std::swap(m_feSpecies_new[k1], m_feSpecies_new[k2]);
3411 std::swap(m_SSPhase[k1], m_SSPhase[k2]);
3412 std::swap(m_phaseID[k1], m_phaseID[k2]);
3413 std::swap(m_speciesMapIndex[k1], m_speciesMapIndex[k2]);
3414 std::swap(m_speciesLocalPhaseIndex[k1], m_speciesLocalPhaseIndex[k2]);
3415 std::swap(m_actConventionSpecies[k1], m_actConventionSpecies[k2]);
3416 std::swap(m_lnMnaughtSpecies[k1], m_lnMnaughtSpecies[k2]);
3417 std::swap(m_actCoeffSpecies_new[k1], m_actCoeffSpecies_new[k2]);
3418 std::swap(m_actCoeffSpecies_old[k1], m_actCoeffSpecies_old[k2]);
3419 std::swap(m_wtSpecies[k1], m_wtSpecies[k2]);
3420 std::swap(m_chargeSpecies[k1], m_chargeSpecies[k2]);
3421 std::swap(m_speciesThermoList[k1], m_speciesThermoList[k2]);
3422 std::swap(m_PMVolumeSpecies[k1], m_PMVolumeSpecies[k2]);
3424 for (
size_t j = 0; j < m_nelem; ++j) {
3425 std::swap(m_formulaMatrix(k1,j), m_formulaMatrix(k2,j));
3427 if (m_useActCoeffJac && k1 != k2) {
3428 for (
size_t i = 0; i < m_nsp; i++) {
3429 std::swap(m_np_dLnActCoeffdMolNum(k1,i), m_np_dLnActCoeffdMolNum(k2,i));
3431 for (
size_t i = 0; i < m_nsp; i++) {
3432 std::swap(m_np_dLnActCoeffdMolNum(i,k1), m_np_dLnActCoeffdMolNum(i,k2));
3435 std::swap(m_speciesStatus[k1], m_speciesStatus[k2]);
3440 size_t i1 = k1 - m_numComponents;
3441 size_t i2 = k2 - m_numComponents;
3442 if (i1 > m_numRxnTot || i2 >= m_numRxnTot) {
3443 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
3446 for (
size_t j = 0; j < m_numComponents; ++j) {
3447 std::swap(m_stoichCoeffRxnMatrix(j,i1), m_stoichCoeffRxnMatrix(j,i2));
3449 std::swap(m_scSize[i1], m_scSize[i2]);
3450 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3451 std::swap(m_deltaMolNumPhase(iph,i1), m_deltaMolNumPhase(iph,i2));
3452 std::swap(m_phaseParticipation(iph,i1),
3453 m_phaseParticipation(iph,i2));
3455 std::swap(m_deltaGRxn_new[i1], m_deltaGRxn_new[i2]);
3456 std::swap(m_deltaGRxn_old[i1], m_deltaGRxn_old[i2]);
3457 std::swap(m_deltaGRxn_tmp[i1], m_deltaGRxn_tmp[i2]);
3461 void VCS_SOLVE::vcs_setFlagsVolPhases(
const bool upToDate,
const int stateCalc)
3464 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3465 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
3468 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3469 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
3474 void VCS_SOLVE::vcs_setFlagsVolPhase(
const size_t iph,
const bool upToDate,
3475 const int stateCalc)
3478 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
3480 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
3484 void VCS_SOLVE::vcs_updateMolNumVolPhases(
const int stateCalc)
3486 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3487 m_VolPhaseList[iph]->updateFromVCS_MoleNumbers(stateCalc);
Headers for the DenseMatrix object, which deals with dense rectangular matrices and description of th...
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.
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.
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
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.
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.
void debuglog(const string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
void writelogf(const char *fmt, const Args &... args)
Write a formatted message to the screen.
void writelog(const string &fmt, const Args &... args)
Write a formatted message to the screen.
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 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.
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
#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...