23 enum stages {MAIN, EQUILIB_CHECK, ELEM_ABUND_CHECK,
24 RECHECK_DELETED, RETURN_A, RETURN_B};
30 void VCS_SOLVE::checkDelta1(
double*
const dsLocal,
31 double*
const delTPhMoles,
size_t kspec)
33 std::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)
53 bool allMinorZeroedSpecies =
false;
56 int rangeErrorFound = 0;
57 bool giveUpOnElemAbund =
false;
58 int finalElemAbundAttempts = 0;
59 bool uptodate_minors =
true;
60 int forceComponentCalc = 1;
67 m_debug_print_lvl = printDetails;
71 if (printDetails > 0 && print_lvl == 0) {
91 m_sm.assign(m_numElemConstraints*m_numElemConstraints, 0.0);
92 m_ss.assign(m_numElemConstraints, 0.0);
93 m_sa.assign(m_numElemConstraints, 0.0);
94 m_aw.assign(m_numSpeciesTot, 0.0);
95 m_wx.assign(m_numElemConstraints, 0.0);
108 if (print_lvl != 0) {
109 plogf(
"VCS CALCULATION METHOD\n\n ");
110 plogf(
"%s\n", m_title.c_str());
111 plogf(
"\n\n%5d SPECIES\n%5d ELEMENTS\n", m_numSpeciesTot, m_numElemConstraints);
112 plogf(
"%5d COMPONENTS\n", m_numComponents);
113 plogf(
"%5d PHASES\n", m_numPhases);
115 plogf(
" PRESSURE%22.8g %3s\n", m_pressurePA,
"Pa ");
116 plogf(
" TEMPERATURE%19.3f K\n", m_temperature);
119 plogf(
" PHASE1 INERTS%17.3f\n", TPhInertMoles[0]);
121 if (m_numPhases > 1) {
122 plogf(
" PHASE2 INERTS%17.3f\n", TPhInertMoles[1]);
124 plogf(
"\n ELEMENTAL ABUNDANCES CORRECT");
125 plogf(
" FROM ESTIMATE Type\n\n");
126 for (
size_t i = 0; i < m_numElemConstraints; ++i) {
127 writeline(
' ', 26,
false);
128 plogf(
"%-2.2s", (m_elementName[i]).c_str());
129 plogf(
"%20.12E%20.12E %3d\n", m_elemAbundancesGoal[i], m_elemAbundances[i],
132 if (m_doEstimateEquil < 0) {
133 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - forced\n");
134 }
else if (m_doEstimateEquil > 0) {
135 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - where necessary\n");
137 if (m_doEstimateEquil == 0) {
138 plogf(
"\n USER ESTIMATE OF EQUILIBRIUM\n");
140 if (m_VCS_UnitsFormat == VCS_UNITS_KCALMOL) {
141 plogf(
" Stan. Chem. Pot. in kcal/mole\n");
143 if (m_VCS_UnitsFormat == VCS_UNITS_UNITLESS) {
144 plogf(
" Stan. Chem. Pot. is MU/RT\n");
146 if (m_VCS_UnitsFormat == VCS_UNITS_KJMOL) {
147 plogf(
" Stan. Chem. Pot. in KJ/mole\n");
149 if (m_VCS_UnitsFormat == VCS_UNITS_KELVIN) {
150 plogf(
" Stan. Chem. Pot. in Kelvin\n");
152 if (m_VCS_UnitsFormat == VCS_UNITS_MKS) {
153 plogf(
" Stan. Chem. Pot. in J/kmol\n");
155 plogf(
"\n SPECIES FORMULA VECTOR ");
156 writeline(
' ', 41,
false);
157 plogf(
" STAN_CHEM_POT EQUILIBRIUM_EST. Species_Type\n\n");
158 writeline(
' ', 20,
false);
159 for (
size_t i = 0; i < m_numElemConstraints; ++i) {
160 plogf(
"%-4.4s ", m_elementName[i].c_str());
163 double RT = vcs_nondimMult_TP(m_VCS_UnitsFormat, m_temperature);
164 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
165 plogf(
" %-18.18s", m_speciesName[i].c_str());
166 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
167 plogf(
"% -7.3g ", m_formulaMatrix(i,j));
169 plogf(
" %3d ", m_phaseID[i]);
170 writeline(
' ', std::max(55-
int(m_numElemConstraints)*8, 0),
false);
171 plogf(
"%12.5E %12.5E", RT * m_SSfeSpecies[i], m_molNumSpecies_old[i]);
183 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
184 if (m_molNumSpecies_old[i] < 0.0) {
185 plogf(
"On Input species %-12s has a "
186 "negative MF, setting it small",
187 m_speciesName[i].c_str());
189 size_t iph = m_phaseID[i];
192 m_molNumSpecies_old[i] = tmp;
214 if (forceComponentCalc) {
215 int retn = solve_tp_component_calc(allMinorZeroedSpecies);
221 forceComponentCalc = 0;
229 if (m_VCount->Its > maxit) {
232 solve_tp_inner(iti, it1, uptodate_minors, allMinorZeroedSpecies,
233 forceComponentCalc, stage, printDetails, ANOTE);
236 }
else if (stage == EQUILIB_CHECK) {
240 solve_tp_equilib_check(allMinorZeroedSpecies, uptodate_minors,
241 giveUpOnElemAbund, solveFail, iti, it1,
244 }
else if (stage == ELEM_ABUND_CHECK) {
248 solve_tp_elem_abund_check(iti, stage, lec, giveUpOnElemAbund,
249 finalElemAbundAttempts, rangeErrorFound);
250 }
else if (stage == RECHECK_DELETED) {
264 npb = vcs_recheck_deleted();
281 }
else if (stage == RETURN_A) {
285 npb = vcs_recheck_deleted();
302 }
else if (stage == RETURN_B) {
307 npb = vcs_add_all_deleted();
310 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 1) {
311 plogf(
" --- add_all_deleted(): some rxns not converged. RETURNING TO LOOP!");
330 m_molNumSpecies_new.assign(m_molNumSpecies_new.size(), 0.0);
331 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
332 if (m_SSPhase[kspec]) {
333 m_molNumSpecies_new[kspec] = 1.0;
335 size_t iph = m_phaseID[kspec];
336 if (m_tPhaseMoles_old[iph] != 0.0) {
337 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] / m_tPhaseMoles_old[iph];
345 size_t i = m_speciesLocalPhaseIndex[kspec];
346 m_molNumSpecies_new[kspec] = m_VolPhaseList[iph]->molefraction(i);
351 if (rangeErrorFound) {
358 m_VCount->Time_vcs_TP = tsecond;
359 m_VCount->T_Time_vcs_TP += m_VCount->Time_vcs_TP;
360 (m_VCount->T_Calls_vcs_TP)++;
361 m_VCount->T_Its += m_VCount->Its;
362 m_VCount->T_Basis_Opts += m_VCount->Basis_Opts;
363 m_VCount->T_Time_basopt += m_VCount->Time_basopt;
370 int VCS_SOLVE::solve_tp_component_calc(
bool& allMinorZeroedSpecies)
372 double test = -1.0e-10;
373 bool usedZeroedSpecies;
376 test, &usedZeroedSpecies);
388 allMinorZeroedSpecies = vcs_evaluate_speciesType();
393 if (! vcs_elabcheck(0)) {
394 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
395 plogf(
" --- Element Abundance check failed");
404 }
else if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
405 plogf(
" --- Element Abundance check passed");
411 void VCS_SOLVE::solve_tp_inner(
size_t& iti,
size_t& it1,
412 bool& uptodate_minors,
413 bool& allMinorZeroedSpecies,
414 int& forceComponentCalc,
415 int& stage,
bool printDetails,
char* ANOTE)
427 if (!uptodate_minors) {
432 uptodate_minors =
true;
434 uptodate_minors =
false;
440 plogf(
" Iteration = %3d, Iterations since last evaluation of "
441 "optimal basis = %3d",
442 m_VCount->Its, it1 - 1);
444 plogf(
" (all species)\n");
446 plogf(
" (only major species)\n");
464 m_feSpecies_new = m_feSpecies_old;
465 m_actCoeffSpecies_new = m_actCoeffSpecies_old;
466 m_deltaGRxn_new = m_deltaGRxn_old;
467 m_deltaGRxn_Deficient = m_deltaGRxn_old;
468 m_tPhaseMoles_new = m_tPhaseMoles_old;
475 m_deltaMolNumSpecies.assign(m_deltaMolNumSpecies.size(), 0.0);
484 std::vector<size_t> phasePopPhaseIDs(0);
485 size_t iphasePop = vcs_popPhaseID(phasePopPhaseIDs);
486 if (iphasePop !=
npos) {
487 int soldel = vcs_popPhaseRxnStepSizes(iphasePop);
490 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
491 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich "
492 "prevented phase %d popping\n");
503 size_t iphaseDelete =
npos;
505 if (iphasePop ==
npos) {
511 iphaseDelete = vcs_RxnStepSizes(forceComponentCalc, kspec);
512 }
else if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
513 plogf(
" --- vcs_RxnStepSizes not called because alternative"
514 "phase creation delta was used instead\n");
516 size_t doPhaseDeleteKspec =
npos;
517 size_t doPhaseDeleteIph =
npos;
521 m_deltaPhaseMoles.assign(m_deltaPhaseMoles.size(), 0.0);
542 if (iphaseDelete !=
npos) {
543 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
544 plogf(
" --- Main Loop Treatment -> Circumvented due to Phase Deletion ");
547 for (
size_t k = 0; k < m_numSpeciesTot; k++) {
548 m_molNumSpecies_new[k] = m_molNumSpecies_old[k] + m_deltaMolNumSpecies[k];
549 size_t iph = m_phaseID[k];
550 m_tPhaseMoles_new[iph] += m_deltaMolNumSpecies[k];
552 if (kspec >= m_numComponents) {
553 if (m_molNumSpecies_new[m_numSpeciesTot] != 0.0) {
554 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
555 "we shouldn't be here!");
557 if (m_SSPhase[kspec] == 1) {
560 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
561 "we shouldn't be here!");
563 ++m_numRxnMinorZeroed;
564 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
585 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
586 plogf(
" --- Main Loop Treatment of each non-component species ");
588 plogf(
"- Full Calculation:\n");
590 plogf(
"- Major Components Calculation:\n");
592 plogf(
" --- Species IC ");
593 plogf(
" KMoles Tent_KMoles Rxn_Adj | Comment \n");
595 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
596 size_t kspec = m_indexRxnToSpecies[irxn];
597 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
598 size_t iph = m_phaseID[kspec];
599 vcs_VolPhase* Vphase = m_VolPhaseList[iph];
600 if (DEBUG_MODE_ENABLED) {
605 if (iphasePop !=
npos) {
606 if (iph == iphasePop) {
607 dx = m_deltaMolNumSpecies[kspec];
608 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
609 if (DEBUG_MODE_ENABLED) {
610 sprintf(ANOTE,
"Phase pop");
614 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
621 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
622 m_deltaMolNumSpecies[kspec] = dx;
627 bool resurrect = (m_deltaMolNumSpecies[kspec] > 0.0);
628 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 3) {
629 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
630 m_speciesName[kspec].c_str(), m_speciesStatus[kspec]);
631 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
632 irxn, m_deltaGRxn_new[irxn], m_molNumSpecies_new[kspec],
633 m_molNumSpecies_old[kspec], m_deltaMolNumSpecies[kspec]);
635 if (m_deltaGRxn_new[irxn] >= 0.0 || !resurrect) {
636 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
637 m_deltaMolNumSpecies[kspec] = 0.0;
639 if (DEBUG_MODE_ENABLED) {
640 sprintf(ANOTE,
"Species stays zeroed: DG = %11.4E", m_deltaGRxn_new[irxn]);
641 if (m_deltaGRxn_new[irxn] < 0.0) {
643 sprintf(ANOTE,
"Species stays zeroed even though dg neg due to "
644 "STOICH/PHASEPOP constraint: DG = %11.4E",
645 m_deltaGRxn_new[irxn]);
647 sprintf(ANOTE,
"Species stays zeroed even though dg neg: DG = %11.4E, ds zeroed",
648 m_deltaGRxn_new[irxn]);
653 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
654 int elType = m_elType[j];
656 double atomComp = m_formulaMatrix(kspec,j);
657 if (atomComp > 0.0) {
658 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
660 if (DEBUG_MODE_ENABLED) {
661 sprintf(ANOTE,
"Species stays zeroed even though dG "
662 "neg, because of %s elemAbund",
663 m_elementName[j].c_str());
677 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
678 plogf(
" --- Zeroed species changed to major: ");
679 plogf(
"%-12s\n", m_speciesName[kspec].c_str());
682 allMinorZeroedSpecies =
false;
684 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
685 plogf(
" --- Zeroed species changed to minor: ");
686 plogf(
"%-12s\n", m_speciesName[kspec].c_str());
690 if (m_deltaMolNumSpecies[kspec] > 0.0) {
691 dx = m_deltaMolNumSpecies[kspec] * 0.01;
692 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
695 dx = m_molNumSpecies_new[kspec] - m_molNumSpecies_old[kspec];
697 m_deltaMolNumSpecies[kspec] = dx;
698 if (DEBUG_MODE_ENABLED) {
699 sprintf(ANOTE,
"Born:IC=-1 to IC=1:DG=%11.4E", m_deltaGRxn_new[irxn]);
702 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
703 m_deltaMolNumSpecies[kspec] = 0.0;
715 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
716 m_deltaMolNumSpecies[kspec] = 0.0;
718 if (DEBUG_MODE_ENABLED) {
719 sprintf(ANOTE,
"minor species not considered");
720 if (m_debug_print_lvl >= 2) {
722 plogf(
"%-12s", m_speciesName[kspec].c_str());
723 plogf(
"%3d%11.4E%11.4E%11.4E | %s",
724 m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
725 m_deltaMolNumSpecies[kspec], ANOTE);
746 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
747 m_deltaMolNumSpecies[kspec] = dx;
748 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
754 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
755 plogf(
" --- Delete minor species in multispec phase: %-12s",
756 m_speciesName[kspec].c_str());
759 m_deltaMolNumSpecies[kspec] = 0.0;
766 size_t lnospec = vcs_delete_species(kspec);
769 stage = RECHECK_DELETED;
787 if (DEBUG_MODE_ENABLED) {
788 sprintf(ANOTE,
"Normal Major Calc");
795 if (fabs(m_deltaGRxn_new[irxn]) <= m_tolmaj2) {
796 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
797 m_deltaMolNumSpecies[kspec] = 0.0;
799 if (DEBUG_MODE_ENABLED) {
800 sprintf(ANOTE,
"major species is converged");
801 if (m_debug_print_lvl >= 2) {
803 plogf(
"%-12s", m_speciesName[kspec].c_str());
804 plogf(
"%3d%11.4E%11.4E%11.4E | %s",
805 m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
806 m_deltaMolNumSpecies[kspec], ANOTE);
821 if ((m_deltaGRxn_new[irxn] * m_deltaMolNumSpecies[kspec]) <= 0.0) {
822 dx = m_deltaMolNumSpecies[kspec];
825 m_deltaMolNumSpecies[kspec] = 0.0;
826 if (DEBUG_MODE_ENABLED) {
827 sprintf(ANOTE,
"dx set to 0, DG flipped sign due to "
828 "changed initial point");
834 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
842 if (m_molNumSpecies_new[kspec] <= 0.0) {
843 if (DEBUG_MODE_ENABLED) {
844 sprintf(ANOTE,
"initial nonpos kmoles= %11.3E",
845 m_molNumSpecies_new[kspec]);
857 if (!(m_SSPhase[kspec])) {
864 dx = -0.9 * m_molNumSpecies_old[kspec];
865 m_deltaMolNumSpecies[kspec] = dx;
866 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
873 dx = -m_molNumSpecies_old[kspec];
880 for (
size_t j = 0; j < m_numComponents; ++j) {
881 if (sc_irxn[j] != 0.0) {
882 m_wx[j] = m_molNumSpecies_old[j] + sc_irxn[j] * dx;
883 if (m_wx[j] <= m_molNumSpecies_old[j] * 0.01 - 1.0E-150) {
884 dx = std::max(dx, m_molNumSpecies_old[j] * -0.99 / sc_irxn[j]);
887 m_wx[j] = m_molNumSpecies_old[j];
890 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
891 if (m_molNumSpecies_new[kspec] > 0.0) {
892 m_deltaMolNumSpecies[kspec] = dx;
893 if (DEBUG_MODE_ENABLED) {
895 "zeroing SS phase created a neg component species "
896 "-> reducing step size instead");
903 iph = m_phaseID[kspec];
904 Vphase = m_VolPhaseList[iph];
905 if (DEBUG_MODE_ENABLED) {
906 sprintf(ANOTE,
"zeroing out SS phase: ");
914 m_molNumSpecies_new[kspec] = 0.0;
915 doPhaseDeleteIph = iph;
917 if (DEBUG_MODE_ENABLED) {
918 doPhaseDeleteKspec = kspec;
919 if (m_debug_print_lvl >= 2) {
920 if (m_speciesStatus[kspec] >= 0) {
921 plogf(
" --- SS species changed to zeroedss: ");
922 plogf(
"%-12s", m_speciesName[kspec].c_str());
928 ++m_numRxnMinorZeroed;
929 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
931 for (
size_t kk = 0; kk < m_numSpeciesTot; kk++) {
932 m_deltaMolNumSpecies[kk] = 0.0;
933 m_molNumSpecies_new[kk] = m_molNumSpecies_old[kk];
935 m_deltaMolNumSpecies[kspec] = dx;
936 m_molNumSpecies_new[kspec] = 0.0;
938 for (
size_t k = 0; k < m_numComponents; ++k) {
939 m_deltaMolNumSpecies[k] = 0.0;
941 for (iph = 0; iph < m_numPhases; iph++) {
942 m_deltaPhaseMoles[iph] = 0.0;
948 #ifdef VCS_LINE_SEARCH
956 (m_molNumSpecies_old[kspec] > 0.0) &&
957 (doPhaseDeleteIph == -1) &&
961 dx = vcs_line_search(irxn, dx_old, ANOTE);
964 m_deltaMolNumSpecies[kspec] = dx;
970 if (dx != 0.0 && (m_speciesUnknownType[kspec] !=
978 1.0E-14*(fabs(m_deltaMolNumSpecies[kspec]) + fabs(dx) + 1.0E-32),
979 "VCS_SOLVE::solve_tp_inner",
980 "ds[kspec] = " +
fp2str(m_deltaMolNumSpecies[kspec]) +
982 "\nwe have a problem!");
983 for (
size_t k = 0; k < m_numComponents; ++k) {
984 m_deltaMolNumSpecies[k] += sc_irxn[k] * dx;
990 for (iph = 0; iph < m_numPhases; iph++) {
991 m_deltaPhaseMoles[iph] += dx * m_deltaMolNumPhase(iph,irxn);
995 if (DEBUG_MODE_ENABLED) {
1003 if (m_debug_print_lvl >= 2) {
1004 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
1006 plogf(
"%-12.12s", m_speciesName[kspec].c_str());
1007 plogf(
"%3d%11.4E%11.4E%11.4E | %s",
1008 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
1009 m_molNumSpecies_new[kspec],
1010 m_deltaMolNumSpecies[kspec], ANOTE);
1014 if (doPhaseDeleteIph !=
npos) {
1015 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1017 plogf(
"%-12.12s Main Loop Special Case deleting phase with species: ",
1018 m_speciesName[doPhaseDeleteKspec].c_str());
1024 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1025 for (
size_t k = 0; k < m_numComponents; k++) {
1027 plogf(
"%-12.12s", m_speciesName[k].c_str());
1028 plogf(
" c%11.4E%11.4E%11.4E |\n",
1029 m_molNumSpecies_old[k],
1030 m_molNumSpecies_old[k]+m_deltaMolNumSpecies[k], m_deltaMolNumSpecies[k]);
1034 plogf(
" --- Finished Main Loop");
1047 for (
size_t k = 0; k < m_numComponents; ++k) {
1048 if (m_molNumSpecies_old[k] > 0.0) {
1049 double xx = -m_deltaMolNumSpecies[k] / m_molNumSpecies_old[k];
1054 }
else if (m_deltaMolNumSpecies[k] < 0.0) {
1059 size_t iph = m_phaseID[k];
1060 m_deltaPhaseMoles[iph] -= m_deltaMolNumSpecies[k];
1061 m_deltaMolNumSpecies[k] = 0.0;
1065 if (par <= 1.01 && par > 0.0) {
1068 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1069 plogf(
" --- Reduction in step size due to component ");
1070 plogf(
"%s", m_speciesName[ll].c_str());
1071 plogf(
" going negative = %11.3E", par);
1074 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
1075 m_deltaMolNumSpecies[i] *= par;
1077 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1078 m_deltaPhaseMoles[iph] *= par;
1083 if (DEBUG_MODE_ENABLED) {
1094 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
1095 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
1096 if (m_molNumSpecies_new[kspec] < 0.0 && (m_speciesUnknownType[kspec]
1098 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
1099 "vcs_solve_TP: ERROR on step change wt[" +
int2str(kspec) +
":" +
1100 m_speciesName[kspec] +
"]: " +
1101 fp2str(m_molNumSpecies_new[kspec]) +
" < 0.0");
1108 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1109 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + m_deltaPhaseMoles[iph];
1135 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
1138 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E",
1144 bool forced = vcs_globStepDamp();
1149 if (printDetails && forced) {
1151 plogf(
" -----------------------------------------------------\n");
1152 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
1153 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
1154 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
1155 for (
size_t i = 0; i < m_numComponents; ++i) {
1156 plogf(
" --- %-12.12s", m_speciesName[i].c_str());
1157 plogf(
" %14.6E %14.6E %14.6E\n", m_molNumSpecies_old[i],
1158 m_molNumSpecies_old[i] + m_deltaMolNumSpecies[i], m_molNumSpecies_new[i]);
1160 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1161 size_t irxn = kspec - m_numComponents;
1162 plogf(
" --- %-12.12s", m_speciesName[kspec].c_str());
1163 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n", m_speciesStatus[kspec],
1164 m_molNumSpecies_old[kspec],
1165 m_molNumSpecies_old[kspec]+m_deltaMolNumSpecies[kspec],
1166 m_molNumSpecies_new[kspec], m_deltaGRxn_old[irxn],
1167 m_deltaGRxn_tmp[irxn], m_deltaGRxn_new[irxn]);
1169 writeline(
' ', 26,
false);
1170 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
1173 plogf(
" Total kmoles of gas = %15.7E\n", m_tPhaseMoles_old[0]);
1174 if ((m_numPhases > 1) && (!(m_VolPhaseList[1])->m_singleSpecies)) {
1175 plogf(
" Total kmoles of liquid = %15.7E\n", m_tPhaseMoles_old[1]);
1177 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
1179 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
1182 plogf(
" -----------------------------------------------------");
1193 writeline(
'-', 103);
1194 plogf(
" --- Summary of the Update ");
1196 plogf(
" (all species):");
1198 plogf(
" (only major species):");
1200 if (m_totalMoleScale != 1.0) {
1201 plogf(
" (Total Mole Scale = %g)", m_totalMoleScale);
1204 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
1205 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
1206 for (
size_t i = 0; i < m_numComponents; ++i) {
1207 plogf(
" --- %-12.12s", m_speciesName[i].c_str());
1209 plogf(
"%14.6E%14.6E%14.6E%14.6E\n", m_molNumSpecies_old[i],
1210 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i]);
1212 for (
size_t i = m_numComponents; i < m_numSpeciesRdc; ++i) {
1213 size_t l1 = i - m_numComponents;
1214 plogf(
" --- %-12.12s", m_speciesName[i].c_str());
1215 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
1216 m_speciesStatus[i], m_molNumSpecies_old[i],
1217 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i],
1218 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
1220 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
1221 size_t l1 = kspec - m_numComponents;
1222 plogf(
" --- %-12.12s", m_speciesName[kspec].c_str());
1223 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
1224 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
1225 m_molNumSpecies_new[kspec], m_feSpecies_old[kspec], m_feSpecies_new[kspec],
1226 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
1229 writeline(
' ', 56,
false);
1230 plogf(
"Norms of Delta G():%14.6E%14.6E",
1235 plogf(
" --- Phase_Name KMoles(after update)\n");
1238 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1239 vcs_VolPhase* Vphase = m_VolPhaseList[iph];
1240 plogf(
" --- %18s = %15.7E\n", Vphase->PhaseName.c_str(), m_tPhaseMoles_new[iph]);
1243 writeline(
'-', 103);
1244 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
1247 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E",
1251 if (DEBUG_MODE_ENABLED && m_VCount->Its > 550) {
1252 plogf(
" --- Troublesome solve");
1272 m_tPhaseMoles_old = m_tPhaseMoles_new;
1273 m_molNumSpecies_old = m_molNumSpecies_new;
1274 m_actCoeffSpecies_old = m_actCoeffSpecies_new;
1275 m_deltaGRxn_old = m_deltaGRxn_new;
1276 m_feSpecies_old = m_feSpecies_new;
1284 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1285 plogf(
" --- Increment counter increased, step is accepted: %4d",
1299 bool justDeletedMultiPhase =
false;
1300 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1301 if (!m_VolPhaseList[iph]->m_singleSpecies && m_tPhaseMoles_old[iph] != 0.0 &&
1303 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 1) {
1304 plogf(
" --- Setting microscopic phase %d to zero", iph);
1307 justDeletedMultiPhase =
true;
1308 vcs_delete_multiphase(iph);
1317 if (justDeletedMultiPhase) {
1318 bool usedZeroedSpecies;
1319 double test = -1.0e-10;
1322 &usedZeroedSpecies);
1324 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
1325 "BASOPT returned with an error condition");
1337 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1338 plogf(
" --- Normal element abundance check");
1341 if (! vcs_elabcheck(0)) {
1342 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1343 plogf(
" - failed -> redoing element abundances.");
1350 uptodate_minors =
true;
1351 }
else if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1359 for (
size_t i = 0; i < m_numRxnRdc; ++i) {
1360 size_t l = m_indexRxnToSpecies[i];
1364 for (
size_t j = 0; j < m_numComponents; ++j) {
1365 bool doSwap =
false;
1367 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1368 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1369 if (!m_SSPhase[l] && doSwap) {
1370 doSwap = (m_molNumSpecies_old[l]) > (m_molNumSpecies_old[j] * 1.01);
1374 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1375 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1377 doSwap = (m_molNumSpecies_old[l]) > (m_molNumSpecies_old[j] * 1.01);
1380 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1381 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1384 if (doSwap && m_stoichCoeffRxnMatrix(j,i) != 0.0) {
1385 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1386 plogf(
" --- Get a new basis because ");
1387 plogf(
"%s", m_speciesName[l].c_str());
1388 plogf(
" is better than comp ");
1389 plogf(
"%s", m_speciesName[j].c_str());
1390 plogf(
" and share nonzero stoic: %-9.1f",
1391 m_stoichCoeffRxnMatrix(j,i));
1394 forceComponentCalc = 1;
1398 if (m_speciesStatus[l] ==
VCS_SPECIES_ZEROEDMS && m_molNumSpecies_old[j] == 0.0 && m_stoichCoeffRxnMatrix(j,i) != 0.0 && dg[i] < 0.0) {
1399 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1400 plogf(
" --- Get a new basis because %s", m_speciesName[l].c_str());
1401 plogf(
" has dg < 0.0 and comp %s has zero mole num",
1402 m_speciesName[j].c_str());
1403 plogf(
" and share nonzero stoic: %-9.1f",
1404 m_stoichCoeffRxnMatrix(j,i));
1412 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1413 plogf(
" --- Check for an optimum basis passed");
1416 stage = EQUILIB_CHECK;
1427 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1428 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1430 m_numRxnMinorZeroed = 0;
1431 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
1432 size_t kspec = m_indexRxnToSpecies[irxn];
1433 int speciesType = vcs_species_type(kspec);
1435 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1437 plogf(
" --- major/minor species is now zeroed out: %s\n",
1438 m_speciesName[kspec].c_str());
1441 ++m_numRxnMinorZeroed;
1443 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1446 plogf(
" --- Noncomponent turned from major to minor: ");
1447 }
else if (kspec < m_numComponents) {
1448 plogf(
" --- Component turned into a minor species: ");
1450 plogf(
" --- Zeroed Species turned into a "
1453 plogf(
"%s\n", m_speciesName[kspec].c_str());
1456 ++m_numRxnMinorZeroed;
1459 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1461 plogf(
" --- Noncomponent turned from minor to major: ");
1462 }
else if (kspec < m_numComponents) {
1463 plogf(
" --- Component turned into a major: ");
1465 plogf(
" --- Noncomponent turned from zeroed to major: ");
1467 plogf(
"%s\n", m_speciesName[kspec].c_str());
1472 m_speciesStatus[kspec] = speciesType;
1478 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
1481 void VCS_SOLVE::solve_tp_equilib_check(
bool& allMinorZeroedSpecies,
1482 bool& uptodate_minors,
1483 bool& giveUpOnElemAbund,
int& solveFail,
1484 size_t& iti,
size_t& it1,
int maxit,
1485 int& stage,
bool& lec)
1487 if (! allMinorZeroedSpecies) {
1488 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1489 plogf(
" --- Equilibrium check for major species: ");
1491 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1492 size_t kspec = irxn + m_numComponents;
1493 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MAJOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmaj)) {
1494 if (m_VCount->Its >= maxit) {
1502 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1503 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]].c_str());
1509 iti = ((it1/4) *4) - it1;
1515 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1516 plogf(
" MAJOR SPECIES CONVERGENCE achieved");
1520 else if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1521 plogf(
" MAJOR SPECIES CONVERGENCE achieved "
1522 "(because there are no major species)");
1531 if (m_numRxnMinorZeroed != 0) {
1540 uptodate_minors =
true;
1542 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1543 plogf(
" --- Equilibrium check for minor species: ");
1545 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1546 size_t kspec = irxn + m_numComponents;
1547 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MINOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmin)) {
1548 if (m_VCount->Its >= maxit) {
1557 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1558 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]].c_str());
1569 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1570 plogf(
" CONVERGENCE achieved\n");
1584 if (!giveUpOnElemAbund) {
1585 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1586 plogf(
" --- Check the Full Element Abundances: ");
1593 if (! vcs_elabcheck(1)) {
1594 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1595 if (! vcs_elabcheck(0)) {
1598 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1602 stage = ELEM_ABUND_CHECK;
1605 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1613 if (m_numSpeciesRdc != m_numSpeciesTot) {
1614 stage = RECHECK_DELETED;
1623 void VCS_SOLVE::solve_tp_elem_abund_check(
size_t& iti,
int& stage,
bool& lec,
1624 bool& giveUpOnElemAbund,
1625 int& finalElemAbundAttempts,
1626 int& rangeErrorFound)
1635 rangeErrorFound = 0;
1636 if (! vcs_elabcheck(1)) {
1637 bool ncBefore = vcs_elabcheck(0);
1639 bool ncAfter = vcs_elabcheck(0);
1640 bool neAfter = vcs_elabcheck(1);
1662 if (finalElemAbundAttempts >= 3) {
1663 giveUpOnElemAbund =
true;
1664 stage = EQUILIB_CHECK;
1666 finalElemAbundAttempts++;
1673 }
else if (ncAfter) {
1678 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1679 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1680 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1681 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1682 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition ");
1685 rangeErrorFound = 1;
1686 giveUpOnElemAbund =
true;
1693 stage = EQUILIB_CHECK;
1700 stage = EQUILIB_CHECK;
1703 double VCS_SOLVE::vcs_minor_alt_calc(
size_t kspec,
size_t irxn,
bool* do_delete,
1707 double w_kspec = m_molNumSpecies_old[kspec];
1708 double molNum_kspec_new;
1710 double dg_irxn = m_deltaGRxn_old[irxn];
1712 size_t iph = m_phaseID[kspec];
1716 if (w_kspec <= 0.0) {
1719 dg_irxn = std::max(dg_irxn, -200.0);
1720 if (DEBUG_MODE_ENABLED && ANOTE) {
1721 sprintf(ANOTE,
"minor species alternative calc");
1723 if (dg_irxn >= 23.0) {
1724 molNum_kspec_new = w_kspec * 1.0e-10;
1726 goto L_ZERO_SPECIES;
1728 return molNum_kspec_new - w_kspec;
1730 if (fabs(dg_irxn) <= m_tolmin2) {
1731 molNum_kspec_new = w_kspec;
1739 s = m_np_dLnActCoeffdMolNum(kspec,kspec) / (m_tPhaseMoles_old[iph]);
1754 a =
clip(w_kspec * s, -1.0+1e-8, 100.0);
1755 tmp =
clip(-dg_irxn / (1.0 + a), -200.0, 200.0);
1756 wTrial = w_kspec * exp(tmp);
1758 molNum_kspec_new = wTrial;
1760 if (wTrial > 100. * w_kspec) {
1761 double molNumMax = 0.0001 * m_tPhaseMoles_old[iph];
1762 if (molNumMax < 100. * w_kspec) {
1763 molNumMax = 100. * w_kspec;
1765 if (wTrial > molNumMax) {
1766 molNum_kspec_new = molNumMax;
1768 molNum_kspec_new = wTrial;
1771 }
else if (1.0E10 * wTrial < w_kspec) {
1772 molNum_kspec_new= 1.0E-10 * w_kspec;
1774 molNum_kspec_new = wTrial;
1779 goto L_ZERO_SPECIES;
1781 return molNum_kspec_new - w_kspec;
1797 dx = m_deltaGRxn_old[irxn]/ m_Faraday_dim;
1798 if (DEBUG_MODE_ENABLED && ANOTE) {
1799 sprintf(ANOTE,
"voltage species alternative calc");
1805 int VCS_SOLVE::delta_species(
const size_t kspec,
double*
const delta_ptr)
1807 size_t irxn = kspec - m_numComponents;
1809 double delta = *delta_ptr;
1810 AssertThrowMsg(kspec >= m_numComponents,
"VCS_SOLVE::delta_species",
1811 "delete_species() ERROR: called for a component " +
int2str(kspec));
1818 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
1819 for (
size_t j = 0; j < m_numComponents; ++j) {
1820 if (m_molNumSpecies_old[j] > 0.0) {
1821 double tmp = sc_irxn[j] * dx;
1822 if (-tmp > m_molNumSpecies_old[j]) {
1824 dx = std::min(dx, - m_molNumSpecies_old[j] / sc_irxn[j]);
1831 if (m_molNumSpecies_old[j] <= 0.0) {
1832 if (sc_irxn[j] < 0.0) {
1842 m_molNumSpecies_old[kspec] += dx;
1843 size_t iph = m_phaseID[kspec];
1844 m_tPhaseMoles_old[iph] += dx;
1847 for (
size_t j = 0; j < m_numComponents; ++j) {
1848 double tmp = sc_irxn[j] * dx;
1851 m_molNumSpecies_old[j] += tmp;
1852 m_tPhaseMoles_old[iph] += tmp;
1854 m_molNumSpecies_old[j] = std::max(m_molNumSpecies_old[j], 0.0);
1861 int VCS_SOLVE::vcs_zero_species(
const size_t kspec)
1868 double dx = -(m_molNumSpecies_old[kspec]);
1870 retn = delta_species(kspec, &dx);
1871 if (DEBUG_MODE_ENABLED && !retn && m_debug_print_lvl >= 1) {
1872 plogf(
"vcs_zero_species: Couldn't zero the species %d, "
1873 "did delta of %g. orig conc of %g",
1874 kspec, dx, m_molNumSpecies_old[kspec] + dx);
1882 int VCS_SOLVE::vcs_delete_species(
const size_t kspec)
1884 const size_t klast = m_numSpeciesRdc - 1;
1885 const size_t iph = m_phaseID[kspec];
1887 const size_t irxn = kspec - m_numComponents;
1892 const int retn = vcs_zero_species(kspec);
1895 "Failed to delete a species!");
1902 --(m_numRxnMinorZeroed);
1905 m_deltaGRxn_new[irxn] = 0.0;
1906 m_deltaGRxn_old[irxn] = 0.0;
1907 m_feSpecies_new[kspec] = 0.0;
1908 m_feSpecies_old[kspec] = 0.0;
1909 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
1914 if (kspec != klast) {
1915 vcs_switch_pos(
true, klast, kspec);
1928 --(m_numSpeciesRdc);
1934 if (! m_SSPhase[klast]) {
1936 bool stillExists =
false;
1937 for (
size_t k = 0; k < m_numSpeciesRdc; k++) {
1939 if (m_phaseID[k] == iph) {
1940 if (m_molNumSpecies_old[k] > 0.0) {
1948 vcs_delete_multiphase(iph);
1956 return (m_numRxnRdc == 0);
1959 void VCS_SOLVE::vcs_reinsert_deleted(
size_t kspec)
1961 size_t iph = m_phaseID[kspec];
1962 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
1963 plogf(
" --- Add back a deleted species: %-12s\n", m_speciesName[kspec].c_str());
1971 delta_species(kspec, &dx);
1974 if (m_SSPhase[kspec]) {
1976 --(m_numRxnMinorZeroed);
1992 if (! m_SSPhase[kspec]) {
1995 for (
size_t k = 0; k < m_numSpeciesTot; k++) {
1996 if (m_phaseID[k] == iph) {
2008 ++(m_numSpeciesRdc);
2009 ++(m_numRxnMinorZeroed);
2011 if (kspec != (m_numSpeciesRdc - 1)) {
2015 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
2019 bool VCS_SOLVE::vcs_delete_multiphase(
const size_t iph)
2022 bool successful =
true;
2027 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2028 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName.c_str());
2034 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
2035 if (m_phaseID[kspec] == iph) {
2040 double dx = - (m_molNumSpecies_old[kspec]);
2043 int retn = delta_species(kspec, &dxTent);
2046 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2047 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
2048 iph, Vphase->
PhaseName.c_str(), m_speciesName[kspec].c_str());
2049 plogf(
" --- delta attempted: %g achieved: %g "
2050 " Zeroing it manually\n", dx, dxTent);
2052 m_molNumSpecies_old[kspec] = 0.0;
2053 m_molNumSpecies_new[kspec] = 0.0;
2054 m_deltaMolNumSpecies[kspec] = 0.0;
2061 m_molNumSpecies_old[kspec] = 0.0;
2062 m_molNumSpecies_new[kspec] = 0.0;
2063 m_deltaMolNumSpecies[kspec] = 0.0;
2074 double dj, dxWant, dxPerm = 0.0, dxPerm2 = 0.0;
2075 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
2076 if (m_phaseID[kcomp] == iph) {
2077 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2078 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
2079 kcomp, m_speciesName[kcomp].c_str(), m_molNumSpecies_old[kcomp]);
2081 if (m_molNumSpecies_old[kcomp] != 0.0) {
2082 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
2083 size_t irxn = kspec - m_numComponents;
2084 if (m_phaseID[kspec] != iph) {
2085 if (m_stoichCoeffRxnMatrix(kcomp,irxn) != 0.0) {
2086 dxWant = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(kcomp,irxn);
2087 if (dxWant + m_molNumSpecies_old[kspec] < 0.0) {
2088 dxPerm = -m_molNumSpecies_old[kspec];
2090 for (
size_t jcomp = 0; kcomp < m_numComponents; ++kcomp) {
2091 if (jcomp != kcomp) {
2092 if (m_phaseID[jcomp] == iph) {
2095 dj = dxWant * m_stoichCoeffRxnMatrix(jcomp,irxn);
2096 if (dj + m_molNumSpecies_old[kcomp] < 0.0) {
2097 dxPerm2 = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(jcomp,irxn);
2099 if (fabs(dxPerm2) < fabs(dxPerm)) {
2106 if (dxPerm != 0.0) {
2107 delta_species(kspec, &dxPerm);
2113 if (m_molNumSpecies_old[kcomp] != 0.0) {
2114 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2115 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
2116 kcomp, m_speciesName[kcomp].c_str(), m_molNumSpecies_old[kcomp]);
2117 plogf(
" --- zeroing it \n");
2119 m_molNumSpecies_old[kcomp] = 0.0;
2135 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
2136 if (m_phaseID[kspec] == iph) {
2137 m_molNumSpecies_old[kspec] = 0.0;
2138 m_molNumSpecies_new[kspec] = 0.0;
2139 m_deltaMolNumSpecies[kspec] = 0.0;
2143 ++(m_numSpeciesRdc);
2144 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2145 plogf(
" --- Make %s", m_speciesName[kspec].c_str());
2146 plogf(
" an active but zeroed species because its phase "
2149 if (kspec != (m_numSpeciesRdc - 1)) {
2153 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
2161 m_tPhaseMoles_old[iph] = 0.0;
2162 m_tPhaseMoles_new[iph] = 0.0;
2163 m_deltaPhaseMoles[iph] = 0.0;
2172 int VCS_SOLVE::vcs_recheck_deleted()
2175 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2176 plogf(
" --- Start rechecking deleted species in multispec phases\n");
2178 if (m_numSpeciesRdc == m_numSpeciesTot) {
2187 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
2188 size_t iph = m_phaseID[kspec];
2189 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_old[kspec])
2190 - m_lnMnaughtSpecies[kspec]
2191 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
2200 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2201 if (m_tPhaseMoles_old[iph] > 0.0) {
2204 xtcutoff[iph] = 0.0;
2235 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2236 size_t kspec = m_indexRxnToSpecies[irxn];
2237 size_t iph = m_phaseID[kspec];
2238 if (m_tPhaseMoles_old[iph] == 0.0) {
2239 if (m_deltaGRxn_new[irxn] < 0.0) {
2240 vcs_reinsert_deleted(kspec);
2243 m_molNumSpecies_old[kspec] = 0.0;
2245 }
else if (m_tPhaseMoles_old[iph] > 0.0) {
2246 if (m_deltaGRxn_new[irxn] < xtcutoff[iph]) {
2247 vcs_reinsert_deleted(kspec);
2255 bool VCS_SOLVE::recheck_deleted_phase(
const int iphase)
2268 size_t irxn = kspec + m_numComponents;
2269 if (m_deltaGRxn_old[irxn] < 0.0) {
2275 double phaseDG = 1.0;
2276 for (
size_t kk = 0; kk < Vphase->
nSpecies(); kk++) {
2278 size_t irxn = kspec + m_numComponents;
2279 m_deltaGRxn_old[irxn] =
clip(m_deltaGRxn_old[irxn], -50.0, 50.0);
2280 phaseDG -= exp(-m_deltaGRxn_old[irxn]);
2283 if (phaseDG < 0.0) {
2289 size_t VCS_SOLVE::vcs_add_all_deleted()
2292 if (m_numSpeciesRdc == m_numSpeciesTot) {
2301 m_molNumSpecies_new = m_molNumSpecies_old;
2303 for (
int cits = 0; cits < 3; cits++) {
2304 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
2305 size_t iph = m_phaseID[kspec];
2307 if (m_molNumSpecies_new[kspec] == 0.0) {
2313 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_new[kspec]) - m_lnMnaughtSpecies[kspec]
2314 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
2320 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2321 size_t kspec = m_indexRxnToSpecies[irxn];
2322 size_t iph = m_phaseID[kspec];
2323 if (m_tPhaseMoles_old[iph] > 0.0) {
2324 double maxDG = std::min(m_deltaGRxn_new[irxn], 690.0);
2325 double dx = m_tPhaseMoles_old[iph] * exp(- maxDG);
2326 m_molNumSpecies_new[kspec] = dx;
2330 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2331 size_t kspec = m_indexRxnToSpecies[irxn];
2332 size_t iph = m_phaseID[kspec];
2333 if (m_tPhaseMoles_old[iph] > 0.0) {
2334 double dx = m_molNumSpecies_new[kspec];
2335 retn = delta_species(kspec, &dx);
2337 if (DEBUG_MODE_ENABLED && m_debug_print_lvl) {
2338 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
2339 m_speciesName[kspec].c_str(), kspec, dx);
2343 retn = delta_species(kspec, &dx);
2344 if (DEBUG_MODE_ENABLED && retn == 0 && m_debug_print_lvl) {
2345 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
2346 m_speciesName[kspec].c_str(), kspec, dx);
2350 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2352 plogf(
" --- add_deleted(): species %s added back in with mol number %g",
2353 m_speciesName[kspec].c_str(), dx);
2356 plogf(
" --- add_deleted(): species %s failed to be added back in");
2367 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2368 size_t kspec = m_indexRxnToSpecies[irxn];
2369 size_t iph = m_phaseID[kspec];
2370 if (m_tPhaseMoles_old[iph] > 0.0) {
2371 if (fabs(m_deltaGRxn_old[irxn]) > m_tolmin) {
2372 if (((m_molNumSpecies_old[kspec] * exp(-m_deltaGRxn_old[irxn])) >
2376 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2377 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g",
2378 m_speciesName[kspec].c_str(), m_molNumSpecies_old[kspec],
2379 m_deltaGRxn_old[irxn]);
2389 bool VCS_SOLVE::vcs_globStepDamp()
2397 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2398 size_t kspec = irxn + m_numComponents;
2400 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2410 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2411 size_t kspec = irxn + m_numComponents;
2413 s1 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2417 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2418 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
2419 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
2423 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2424 plogf(
" --- subroutine FORCE produced no adjustments,");
2426 plogf(
" s1 positive but really small");
2428 plogf(
" failed s1 test");
2436 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2437 plogf(
" --- subroutine FORCE produced no adjustments, s2 < 0");
2447 if (fabs(s1 -s2) > 1.0E-200) {
2448 al = s1 / (s1 - s2);
2450 if (al >= 0.95 || al < 0.0) {
2451 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2452 plogf(
" --- subroutine FORCE produced no adjustments (al = %g)\n", al);
2456 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2457 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
2463 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2464 m_deltaGRxn_tmp = m_deltaGRxn_new;
2468 for (
size_t kspec = 0; kspec < m_numSpeciesRdc; ++kspec) {
2469 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] +
2470 al * m_deltaMolNumSpecies[kspec];
2472 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2473 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + al * m_deltaPhaseMoles[iph];
2477 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2478 plogf(
" --- subroutine FORCE adjusted the mole "
2479 "numbers, AL = %10.3f\n", al);
2498 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2499 size_t kspec = irxn + m_numComponents;
2501 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2505 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2506 plogf(
" --- subroutine FORCE: Adj End Slope = %g", s2);
2512 int VCS_SOLVE::vcs_basopt(
const bool doJustComponents,
double aw[],
double sa[],
double sm[],
2513 double ss[],
double test,
bool*
const usedZeroedSpecies)
2518 size_t jlose =
npos;
2521 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2523 for (
size_t i=0; i<77; i++) {
2527 plogf(
" --- Subroutine BASOPT called to ");
2528 if (doJustComponents) {
2529 plogf(
"calculate the number of components\n");
2531 plogf(
"reevaluate the components\n");
2533 if (m_debug_print_lvl >= 2) {
2535 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
2536 plogf(
" --- Active | ");
2537 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2538 plogf(
" %1d ", m_elementActive[j]);
2541 plogf(
" --- Species | ");
2542 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2547 for (k = 0; k < m_numSpeciesTot; k++) {
2551 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2552 plogf(
" %8.2g", m_formulaMatrix(k,j));
2565 size_t ncTrial = std::min(m_numElemConstraints, m_numSpeciesTot);
2566 m_numComponents = ncTrial;
2567 *usedZeroedSpecies =
false;
2574 std::copy(m_molNumSpecies_old.begin(),
2575 m_molNumSpecies_old.begin() + m_numSpeciesTot, aw);
2579 for (k = 0; k < m_numSpeciesTot; k++) {
2601 k = vcs_basisOptMax(aw, jr, m_numSpeciesTot);
2643 *usedZeroedSpecies =
true;
2645 double maxConcPossKspec = 0.0;
2646 double maxConcPoss = 0.0;
2647 size_t kfound =
npos;
2648 int minNonZeroes = 100000;
2649 int nonZeroesKspec = 0;
2650 for (
size_t kspec = ncTrial; kspec < m_numSpeciesTot; kspec++) {
2651 if (aw[kspec] >= 0.0) {
2653 maxConcPossKspec = 1.0E10;
2655 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
2656 if (m_elementActive[j]) {
2658 double nu = m_formulaMatrix(kspec,j);
2661 maxConcPossKspec = std::min(m_elemAbundancesGoal[j] / nu, maxConcPossKspec);
2666 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
2667 if (nonZeroesKspec <= minNonZeroes) {
2668 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
2672 if (m_SSfeSpecies[kspec] <= m_SSfeSpecies[kfound]) {
2677 minNonZeroes = std::min(minNonZeroes, nonZeroesKspec);
2678 maxConcPoss = std::max(maxConcPoss, maxConcPossKspec);
2683 if (kfound ==
npos) {
2686 for (
size_t kspec = ncTrial; kspec < m_numSpeciesTot; kspec++) {
2687 if (aw[kspec] >= 0.0) {
2688 size_t irxn = kspec - ncTrial;
2689 if (m_deltaGRxn_new[irxn] < gmin) {
2690 gmin = m_deltaGRxn_new[irxn];
2700 if (aw[k] == test) {
2701 m_numComponents = jr;
2702 ncTrial = m_numComponents;
2703 size_t numPreDeleted = m_numRxnTot - m_numRxnRdc;
2704 if (numPreDeleted != (m_numSpeciesTot - m_numSpeciesRdc)) {
2705 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we shouldn't be here");
2707 m_numRxnTot = m_numSpeciesTot - ncTrial;
2708 m_numRxnRdc = m_numRxnTot - numPreDeleted;
2709 m_numSpeciesRdc = m_numSpeciesTot - numPreDeleted;
2710 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
2711 m_indexRxnToSpecies[i] = ncTrial + i;
2713 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2714 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
2715 ncTrial, m_numElemConstraints);
2732 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
2733 sm[j + jr*m_numElemConstraints] = m_formulaMatrix(k,j);
2742 for (
size_t j = 0; j < jl; ++j) {
2744 for (
size_t i = 0; i < m_numElemConstraints; ++i) {
2745 ss[j] += sm[i + jr*m_numElemConstraints] * sm[i + j*m_numElemConstraints];
2753 for (
size_t j = 0; j < jl; ++j) {
2754 for (
size_t l = 0; l < m_numElemConstraints; ++l) {
2755 sm[l + jr*m_numElemConstraints] -= ss[j] * sm[l + j*m_numElemConstraints];
2764 for (
size_t ml = 0; ml < m_numElemConstraints; ++ml) {
2765 sa[jr] += pow(sm[ml + jr*m_numElemConstraints], 2);
2770 lindep = (sa[jr] < 1.0e-6);
2776 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2777 plogf(
" --- %-12.12s", (m_speciesName[k]).c_str());
2779 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[k]);
2781 plogf(
"(%9.2g)", m_molNumSpecies_old[k]);
2783 plogf(
" replaces %-12.12s", m_speciesName[jr].c_str());
2785 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[jr]);
2787 plogf(
"(%9.2g)", m_molNumSpecies_old[jr]);
2789 plogf(
" as component %3d\n", jr);
2791 vcs_switch_pos(
false, jr, k);
2792 std::swap(aw[jr], aw[k]);
2794 else if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2795 plogf(
" --- %-12.12s", m_speciesName[k].c_str());
2797 plogf(
"(Volts = %9.2g) remains ", m_molNumSpecies_old[k]);
2799 plogf(
"(%9.2g) remains ", m_molNumSpecies_old[k]);
2801 plogf(
" as component %3d\n", jr);
2811 }
while (jr < (ncTrial-1));
2813 if (doJustComponents) {
2850 for (
size_t j = 0; j < ncTrial; ++j) {
2851 for (
size_t i = 0; i < ncTrial; ++i) {
2852 sm[i + j*m_numElemConstraints] = m_formulaMatrix(j,i);
2855 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2856 k = m_indexRxnToSpecies[i];
2857 for (
size_t j = 0; j < ncTrial; ++j) {
2858 m_stoichCoeffRxnMatrix(j,i) = - m_formulaMatrix(k,j);
2863 ct_dgetrf(ncTrial, ncTrial, sm, m_numElemConstraints, &ipiv[0], info);
2865 plogf(
"vcs_solve_TP ERROR: Error factorizing stoichiometric coefficient matrix\n");
2866 return VCS_FAILED_CONVERGENCE;
2868 ct_dgetrs(ctlapack::NoTranspose, ncTrial, m_numRxnTot, sm, m_numElemConstraints,
2869 &ipiv[0], m_stoichCoeffRxnMatrix.ptrColumn(0), m_numElemConstraints, info);
2878 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2879 if (!(m_elementActive[j])) {
2880 if (!strcmp((m_elementName[j]).c_str(),
"E")) {
2885 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2886 if (m_elementActive[j]) {
2887 if (!strncmp((m_elementName[j]).c_str(),
"cn_", 3)) {
2892 for (k = 0; k < m_numSpeciesTot; k++) {
2895 for (
size_t j = 0; j < ncTrial; ++j) {
2896 for (
size_t i = 0; i < ncTrial; ++i) {
2898 sm[i + j*m_numElemConstraints] = m_formulaMatrix(j,juse);
2900 sm[i + j*m_numElemConstraints] = m_formulaMatrix(j,i);
2904 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2905 k = m_indexRxnToSpecies[i];
2906 for (
size_t j = 0; j < ncTrial; ++j) {
2908 aw[j] = - m_formulaMatrix(k,juse);
2910 aw[j] = - m_formulaMatrix(k,j);
2915 ct_dgetrf(ncTrial, ncTrial, sm, m_numElemConstraints, &ipiv[0], info);
2917 plogf(
"vcs_solve_TP ERROR: Error factorizing matrix\n");
2918 return VCS_FAILED_CONVERGENCE;
2920 ct_dgetrs(ctlapack::NoTranspose, ncTrial, 1, sm, m_numElemConstraints,
2921 &ipiv[0], aw, m_numElemConstraints, info);
2922 size_t i = k - ncTrial;
2923 for (
size_t j = 0; j < ncTrial; j++) {
2924 m_stoichCoeffRxnMatrix(j,i) = aw[j];
2933 for (
size_t i = 0; i < m_numRxnTot; i++) {
2935 for (
size_t j = 0; j < ncTrial; j++) {
2936 szTmp += fabs(m_stoichCoeffRxnMatrix(j,i));
2938 m_scSize[i] = szTmp;
2941 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
2942 plogf(
" --- Components:");
2943 for (
size_t j = 0; j < ncTrial; j++) {
2946 plogf(
"\n --- Components Moles:");
2947 for (
size_t j = 0; j < ncTrial; j++) {
2949 plogf(
" % -10.3E", 0.0);
2951 plogf(
" % -10.3E", m_molNumSpecies_old[j]);
2954 plogf(
"\n --- NonComponent| Moles |");
2955 for (
size_t j = 0; j < ncTrial; j++) {
2956 plogf(
" %10.10s", m_speciesName[j].c_str());
2959 for (
size_t i = 0; i < m_numRxnTot; i++) {
2960 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
2961 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]].c_str());
2963 plogf(
"|% -10.3E|", 0.0);
2965 plogf(
"|% -10.3E|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
2967 for (
size_t j = 0; j < ncTrial; j++) {
2968 plogf(
" %+7.3f", m_stoichCoeffRxnMatrix(j,i));
2978 double sumMax = -1.0;
2981 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2982 k = m_indexRxnToSpecies[i];
2984 for (
size_t j = 0; j < ncTrial; ++j) {
2986 sum = m_formulaMatrix(k,juse);
2987 for (
size_t n = 0; n < ncTrial; n++) {
2988 double numElements = m_formulaMatrix(n,juse);
2989 double coeff = m_stoichCoeffRxnMatrix(n,i);
2990 sum += coeff * numElements;
2993 sum = m_formulaMatrix(k,j);
2994 for (
size_t n = 0; n < ncTrial; n++) {
2995 double numElements = m_formulaMatrix(n,j);
2996 double coeff = m_stoichCoeffRxnMatrix(n,i);
2997 sum += coeff * numElements;
3000 if (fabs(sum) > sumMax) {
3008 if (fabs(sum) > 1.0E-6) {
3009 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we have a prob");
3013 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
3014 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[iMax]].c_str());
3015 plogf(
" element = %d ", jMax);
3016 plogf(
"%-5.5s", m_elementName[jMax].c_str());
3019 for (
size_t i=0; i<77; i++) {
3035 m_deltaMolNumPhase.zero();
3036 m_phaseParticipation.zero();
3042 for (
size_t irxn = 0; irxn < m_numRxnTot; ++irxn) {
3043 scrxn_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3044 size_t kspec = m_indexRxnToSpecies[irxn];
3045 size_t iph = m_phaseID[kspec];
3046 m_deltaMolNumPhase(iph,irxn) = 1.0;
3047 m_phaseParticipation(iph,irxn)++;
3048 for (
size_t j = 0; j < ncTrial; ++j) {
3050 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
3053 m_deltaMolNumPhase(iph,irxn) += scrxn_ptr[j];
3054 m_phaseParticipation(iph,irxn)++;
3062 m_VCount->Time_basopt += tsecond;
3063 (m_VCount->Basis_Opts)++;
3067 size_t VCS_SOLVE::vcs_basisOptMax(
const double*
const molNum,
const size_t j,
3086 double big = molNum[j] * m_spSize[j] * 1.01;
3087 if (m_spSize[j] <= 0.0) {
3089 "spSize is nonpositive");
3091 for (
size_t i = j + 1; i < n; ++i) {
3092 if (m_spSize[i] <= 0.0) {
3094 "spSize is nonpositive");
3096 bool doSwap =
false;
3098 doSwap = (molNum[i] * m_spSize[i]) > (big);
3099 if (!m_SSPhase[i]) {
3101 doSwap = (molNum[i]) > (molNum[largest] * 1.001);
3106 doSwap = (molNum[i] * m_spSize[i]) > (big);
3108 doSwap = (molNum[i]) > (molNum[largest] * 1.001);
3111 doSwap = (molNum[i] * m_spSize[i]) > (big);
3116 big = molNum[i] * m_spSize[i] * 1.01;
3122 int VCS_SOLVE::vcs_species_type(
const size_t kspec)
const
3132 size_t iph = m_phaseID[kspec];
3133 int irxn = int(kspec) - int(m_numComponents);
3135 int phaseExist = VPhase->
exists();
3139 if (m_molNumSpecies_old[kspec] <= 0.0) {
3141 if (m_tPhaseMoles_old[iph] <= 0.0) {
3142 if (!m_SSPhase[kspec]) {
3152 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3153 int elType = m_elType[j];
3155 double atomComp = m_formulaMatrix(kspec,j);
3156 if (atomComp > 0.0) {
3157 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
3159 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3160 plogf(
" --- %s can not be nonzero because"
3161 " needed element %s is zero\n",
3162 m_speciesName[kspec].c_str(), (m_elementName[j]).c_str());
3164 if (m_SSPhase[kspec]) {
3184 for (
size_t j = 0; j < m_numComponents; ++j) {
3185 double stoicC = m_stoichCoeffRxnMatrix(j,irxn);
3186 if (stoicC != 0.0) {
3187 double negChangeComp = - stoicC;
3188 if (negChangeComp > 0.0) {
3189 if (m_molNumSpecies_old[j] < 1.0E-60) {
3190 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3191 plogf(
" --- %s is prevented from popping into existence because"
3192 " a needed component to be consumed, %s, has a zero mole number\n",
3193 m_speciesName[kspec].c_str(), m_speciesName[j].c_str());
3195 if (m_SSPhase[kspec]) {
3201 }
else if (negChangeComp < 0.0) {
3202 size_t jph = m_phaseID[j];
3204 if (jVPhase->
exists() <= 0) {
3205 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3206 plogf(
" --- %s is prevented from popping into existence because"
3207 " a needed component %s is in a zeroed-phase that would be "
3208 "popped into existence at the same time\n",
3209 m_speciesName[kspec].c_str(), m_speciesName[j].c_str());
3211 if (m_SSPhase[kspec]) {
3223 if (m_deltaGRxn_old[irxn] >= 0.0) {
3227 if (m_SSPhase[kspec]) {
3243 if (m_tPhaseMoles_old[iph] > 0.0) {
3244 if (m_SSPhase[kspec]) {
3260 if (m_tPhaseMoles_old[iph] <= 0.0) {
3261 if (m_SSPhase[kspec]) {
3275 if (m_SSPhase[kspec]) {
3286 if (m_molNumSpecies_old[kspec] > (m_tPhaseMoles_old[iph] * 0.001)) {
3301 double szAdj = m_scSize[irxn] * std::sqrt((
double)m_numRxnTot);
3302 for (
size_t k = 0; k < m_numComponents; ++k) {
3303 if (!(m_SSPhase[k])) {
3304 if (m_stoichCoeffRxnMatrix(k,irxn) != 0.0) {
3305 if (m_molNumSpecies_old[kspec] * szAdj >= m_molNumSpecies_old[k] * 0.01) {
3315 void VCS_SOLVE::vcs_chemPotPhase(
const int stateCalc,
3316 const size_t iph,
const double*
const molNum,
3317 double*
const ac,
double*
const mu_i,
3318 const bool do_deleted)
3322 double tMoles = TPhInertMoles[iph];
3323 for (
size_t k = 0; k < nkk; k++) {
3325 tMoles += molNum[kspec];
3327 double tlogMoles = 0.0;
3329 tlogMoles = log(tMoles);
3336 double Faraday_phi = m_Faraday_dim * phi;
3338 for (
size_t k = 0; k < nkk; k++) {
3340 if (kspec >= m_numComponents) {
3347 AssertThrowMsg(molNum[kspec] == phi,
"VCS_SOLVE::vcs_chemPotPhase",
3348 "We have an inconsistency!");
3349 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_chemPotPhase",
3350 "We have an unexpected situation!");
3351 mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3353 if (m_SSPhase[kspec]) {
3354 mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3357 - tlogMoles - m_lnMnaughtSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3359 mu_i[kspec] = m_SSfeSpecies[kspec] + log(ac[kspec] * molNum[kspec])
3360 - tlogMoles - m_lnMnaughtSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3366 void VCS_SOLVE::vcs_dfe(
const int stateCalc,
3367 const int ll,
const size_t lbot,
const size_t ltop)
3369 double* tPhMoles_ptr=0;
3370 double* actCoeff_ptr=0;
3371 double* feSpecies=0;
3383 }
else if (DEBUG_MODE_ENABLED) {
3385 "Subroutine vcs_dfe called with bad stateCalc value: "+
3390 "called with wrong units state");
3392 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3395 plogf(
" --- Subroutine vcs_dfe called for one species: ");
3396 plogf(
"%-12.12s", m_speciesName[lbot].c_str());
3398 plogf(
" --- Subroutine vcs_dfe called for all species");
3400 }
else if (ll > 0) {
3401 plogf(
" --- Subroutine vcs_dfe called for components and minors");
3403 plogf(
" --- Subroutine vcs_dfe called for components and majors");
3406 plogf(
" using tentative solution");
3417 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3418 tlogMoles[iph] = tPhInertMoles[iph];
3421 for (
size_t kspec = 0; kspec < m_numSpeciesTot; kspec++) {
3423 size_t iph = m_phaseID[kspec];
3424 tlogMoles[iph] += molNum[kspec];
3427 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3429 "VCS_SOLVE::vcs_dfe",
3430 "phase Moles may be off, iph = " +
int2str(iph) +
", " +
3431 fp2str(tlogMoles[iph]) +
" " +
fp2str(tPhMoles_ptr[iph]));
3433 m_TmpPhase.assign(m_TmpPhase.size(), 0.0);
3434 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3435 if (tPhMoles_ptr[iph] > 0.0) {
3436 tlogMoles[iph] = log(tPhMoles_ptr[iph]);
3443 l2 = m_numComponents;
3454 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
3471 for (
size_t kspec = l1; kspec < l2; ++kspec) {
3472 size_t iphase = m_phaseID[kspec];
3474 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
3475 "We have an inconsistency!");
3476 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
3477 "We have an unexpected situation!");
3478 feSpecies[kspec] = m_SSfeSpecies[kspec]
3479 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3481 if (m_SSPhase[kspec]) {
3482 feSpecies[kspec] = m_SSfeSpecies[kspec]
3483 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3486 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3487 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3490 size_t iph = m_phaseID[kspec];
3491 if (tPhMoles_ptr[iph] > 0.0) {
3492 feSpecies[kspec] = m_SSfeSpecies[kspec]
3494 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3495 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3497 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3498 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3501 feSpecies[kspec] = m_SSfeSpecies[kspec]
3502 + log(actCoeff_ptr[kspec] * molNum[kspec])
3503 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3504 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3513 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3514 size_t kspec = m_indexRxnToSpecies[irxn];
3516 size_t iphase = m_phaseID[kspec];
3518 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
3519 "We have an inconsistency!");
3520 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
3521 "We have an unexpected situation!");
3522 feSpecies[kspec] = m_SSfeSpecies[kspec]
3523 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3525 if (m_SSPhase[kspec]) {
3526 feSpecies[kspec] = m_SSfeSpecies[kspec]
3527 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3530 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3531 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3534 size_t iph = m_phaseID[kspec];
3535 if (tPhMoles_ptr[iph] > 0.0) {
3536 feSpecies[kspec] = m_SSfeSpecies[kspec]
3538 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3539 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3541 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3542 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3545 feSpecies[kspec] = m_SSfeSpecies[kspec]
3546 + log(actCoeff_ptr[kspec] * molNum[kspec])
3547 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3548 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3557 }
else if (ll > 0) {
3558 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3559 size_t kspec = m_indexRxnToSpecies[irxn];
3561 size_t iphase = m_phaseID[kspec];
3563 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
3564 "We have an inconsistency!");
3565 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
3566 "We have an unexpected situation!");
3567 feSpecies[kspec] = m_SSfeSpecies[kspec]
3568 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase]; ;
3570 if (m_SSPhase[kspec]) {
3571 feSpecies[kspec] = m_SSfeSpecies[kspec]
3572 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3575 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3576 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3579 size_t iph = m_phaseID[kspec];
3580 if (tPhMoles_ptr[iph] > 0.0) {
3581 feSpecies[kspec] = m_SSfeSpecies[kspec]
3583 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3584 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3586 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3587 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3590 feSpecies[kspec] = m_SSfeSpecies[kspec]
3591 + log(actCoeff_ptr[kspec] * molNum[kspec])
3592 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3593 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3604 void VCS_SOLVE::vcs_printSpeciesChemPot(
const int stateCalc)
const
3606 double mfValue = 1.0;
3607 bool zeroedPhase =
false;
3609 const double* molNum =
VCS_DATA_PTR(m_molNumSpecies_old);
3610 const double* actCoeff_ptr =
VCS_DATA_PTR(m_actCoeffSpecies_old);
3617 const double* tPhInertMoles =
VCS_DATA_PTR(TPhInertMoles);
3618 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3619 tMoles[iph] = tPhInertMoles[iph];
3621 for (
size_t kspec = 0; kspec < m_numSpeciesTot; kspec++) {
3623 size_t iph = m_phaseID[kspec];
3624 tMoles[iph] += molNum[kspec];
3628 double RT = m_temperature * GasConstant;
3629 printf(
" --- CHEMICAL POT TABLE (J/kmol) Name PhID MolFR ChemoSS "
3630 " logMF Gamma Elect extra ElectrChem\n");
3632 writeline(
'-', 132);
3634 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
3636 size_t iphase = m_phaseID[kspec];
3643 zeroedPhase =
false;
3645 if (tMoles[iphase] > 0.0) {
3649 mfValue = molNum[kspec]/tMoles[iphase];
3652 size_t klocal = m_speciesLocalPhaseIndex[kspec];
3653 mfValue = Vphase->moleFraction(klocal);
3656 double elect = m_chargeSpecies[kspec] * m_Faraday_dim * volts;
3657 double comb = - m_lnMnaughtSpecies[kspec];
3658 double total = (m_SSfeSpecies[kspec] + log(mfValue) + elect + log(actCoeff_ptr[kspec]) + comb);
3661 printf(
" --- ** zp *** ");
3665 printf(
"%-24.24s", m_speciesName[kspec].c_str());
3666 printf(
" %-3s",
int2str(iphase).c_str());
3667 printf(
" % -12.4e", mfValue);
3668 printf(
" % -12.4e", m_SSfeSpecies[kspec] * RT);
3669 printf(
" % -12.4e", log(mfValue) * RT);
3670 printf(
" % -12.4e", log(actCoeff_ptr[kspec]) * RT);
3671 printf(
" % -12.4e", elect * RT);
3672 printf(
" % -12.4e", comb * RT);
3673 printf(
" % -12.4e\n", total *RT);
3676 writeline(
'-', 132);
3680 void VCS_SOLVE::prneav()
const
3682 std::vector<double> eav(m_numElemConstraints, 0.0);
3684 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3685 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
3687 eav[j] += m_formulaMatrix(i,j) * m_molNumSpecies_old[i];
3692 plogf(
"--------------------------------------------------");
3693 plogf(
"ELEMENT ABUNDANCE VECTOR:\n");
3694 plogf(
" Element Now Orignal Deviation Type\n");
3695 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3697 plogf(
"%-2.2s", (m_elementName[j]).c_str());
3698 plogf(
" = %15.6E %15.6E %15.6E %3d\n",
3699 eav[j], m_elemAbundancesGoal[j], eav[j] - m_elemAbundancesGoal[j], m_elType[j]);
3700 if (m_elemAbundancesGoal[j] != 0.) {
3701 if (fabs(eav[j] - m_elemAbundancesGoal[j]) > m_elemAbundancesGoal[j] * 5.0e-9) {
3705 if (fabs(eav[j]) > 1.0e-10) {
3711 plogf(
"Element abundance check failure\n");
3713 plogf(
"--------------------------------------------------");
3718 double VCS_SOLVE::l2normdg(
double dgLocal[])
const
3720 if (m_numRxnRdc <= 0) {
3724 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3725 size_t kspec = irxn + m_numComponents;
3727 dgLocal[irxn] < 0.0) {
3729 tmp += dgLocal[irxn] * dgLocal[irxn];
3733 return std::sqrt(tmp / m_numRxnRdc);
3736 double VCS_SOLVE::vcs_tmoles()
3738 for (
size_t i = 0; i < m_numPhases; i++) {
3739 m_tPhaseMoles_old[i] = TPhInertMoles[i];
3741 for (
size_t i = 0; i < m_numSpeciesTot; i++) {
3743 m_tPhaseMoles_old[m_phaseID[i]] += m_molNumSpecies_old[i];
3747 for (
size_t i = 0; i < m_numPhases; i++) {
3748 sum += m_tPhaseMoles_old[i];
3750 if (m_tPhaseMoles_old[i] == 0.0) {
3756 m_totalMolNum = sum;
3757 return m_totalMolNum;
3761 void VCS_SOLVE::check_tmoles()
const
3764 for (
size_t i = 0; i < m_numPhases; i++) {
3765 double m_tPhaseMoles_old_a = TPhInertMoles[i];
3767 for (
size_t k = 0; k < m_numSpeciesTot; k++) {
3769 if (m_phaseID[k] == i) {
3770 m_tPhaseMoles_old_a += m_molNumSpecies_old[k];
3774 sum += m_tPhaseMoles_old_a;
3776 double denom = m_tPhaseMoles_old[i]+ m_tPhaseMoles_old_a + 1.0E-19;
3777 if (!
vcs_doubleEqual(m_tPhaseMoles_old[i]/denom, m_tPhaseMoles_old_a/denom)) {
3778 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
3779 i, m_tPhaseMoles_old[i], m_tPhaseMoles_old_a);
3785 void VCS_SOLVE::vcs_updateVP(
const int vcsState)
3787 for (
size_t i = 0; i < m_numPhases; i++) {
3797 }
else if (DEBUG_MODE_ENABLED) {
3799 "wrong stateCalc value: " +
int2str(vcsState));
3804 bool VCS_SOLVE::vcs_evaluate_speciesType()
3806 m_numRxnMinorZeroed = 0;
3807 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3808 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
3809 }
else if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 5) {
3810 plogf(
" --- Species Status decision is reevaluated");
3813 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
3814 m_speciesStatus[kspec] = vcs_species_type(kspec);
3815 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 5) {
3816 plogf(
" --- %-16s: ", m_speciesName[kspec].c_str());
3817 if (kspec < m_numComponents) {
3822 plogf(
" %10.3g ", m_molNumSpecies_old[kspec]);
3824 plogf(
"%s\n", sString);
3826 }
else if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3828 switch (m_speciesStatus[kspec]) {
3832 plogf(
" --- Major Species : %-s\n", m_speciesName[kspec].c_str());
3835 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
3836 m_speciesName[kspec].c_str());
3839 plogf(
" --- Zeroed-MS Phase Species: %-s\n", m_speciesName[kspec].c_str());
3842 plogf(
" --- Zeroed-SS Phase Species: %-s\n", m_speciesName[kspec].c_str());
3845 plogf(
" --- Deleted-Small Species : %-s\n", m_speciesName[kspec].c_str());
3848 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
3849 m_speciesName[kspec].c_str());
3852 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
3853 m_speciesName[kspec].c_str());
3856 plogf(
" --- InterfaceVoltage Species: %-s\n", m_speciesName[kspec].c_str());
3859 throw CanteraError(
"VCS_SOLVE::vcs_evaluate_speciesType",
3860 "Unknown type: " +
int2str(m_speciesStatus[kspec]));
3864 if (kspec >= m_numComponents) {
3866 ++m_numRxnMinorZeroed;
3870 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3874 return (m_numRxnMinorZeroed >= m_numRxnRdc);
3877 void VCS_SOLVE::vcs_deltag(
const int l,
const bool doDeleted,
3878 const int vcsState,
const bool alterZeroedPhases)
3881 size_t irxnl = m_numRxnRdc;
3883 irxnl = m_numRxnTot;
3888 double* molNumSpecies;
3889 double* actCoeffSpecies;
3901 throw CanteraError(
"VCS_SOLVE::vcs_deltag",
"bad vcsState");
3904 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
3905 plogf(
" --- Subroutine vcs_deltag called for ");
3907 plogf(
"major noncomponents\n");
3908 }
else if (l == 0) {
3909 plogf(
"all noncomponents\n");
3911 plogf(
"minor noncomponents\n");
3918 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3919 size_t kspec = irxn + m_numComponents;
3922 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3923 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3924 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3925 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3931 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3935 }
else if (l == 0) {
3939 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3941 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3942 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3943 for (
size_t kspec = 0; kspec < m_numComponents; ++kspec) {
3944 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3946 dtmp_ptr[kspec] < 0.0) {
3951 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3958 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3959 size_t kspec = irxn + m_numComponents;
3962 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3963 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3964 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3965 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3967 dtmp_ptr[kspec] < 0.0) {
3972 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
4019 if (alterZeroedPhases &&
false) {
4020 for (
size_t iph = 0; iph < m_numPhases; iph++) {
4025 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
4028 sum += molNumSpecies[kspec];
4041 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
4044 if (kspec >= m_numComponents) {
4045 size_t irxn = kspec - m_numComponents;
4046 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
4047 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
4055 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
4057 if (kspec >= m_numComponents) {
4058 size_t irxn = kspec - m_numComponents;
4059 deltaGRxn[irxn] = 1.0 - poly;
4069 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
4075 void VCS_SOLVE::vcs_printDeltaG(
const int stateCalc)
4079 double* molNumSpecies =
VCS_DATA_PTR(m_molNumSpecies_old);
4080 const double* tPhMoles_ptr =
VCS_DATA_PTR(m_tPhaseMoles_old);
4081 const double* actCoeff_ptr =
VCS_DATA_PTR(m_actCoeffSpecies_old);
4089 double RT = m_temperature * GasConstant;
4090 bool zeroedPhase =
false;
4091 if (m_debug_print_lvl >= 2) {
4092 plogf(
" --- DELTA_G TABLE Components:");
4093 for (
size_t j = 0; j < m_numComponents; j++) {
4096 plogf(
"\n --- Components Moles:");
4097 for (
size_t j = 0; j < m_numComponents; j++) {
4098 plogf(
"%10.3g", m_molNumSpecies_old[j]);
4100 plogf(
"\n --- NonComponent| Moles | ");
4101 for (
size_t j = 0; j < m_numComponents; j++) {
4102 plogf(
"%-10.10s", m_speciesName[j].c_str());
4105 for (
size_t i = 0; i < m_numRxnTot; i++) {
4106 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
4107 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]].c_str());
4111 plogf(
"|%10.3g|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
4113 for (
size_t j = 0; j < m_numComponents; j++) {
4114 plogf(
" %6.2f", m_stoichCoeffRxnMatrix(j,i));
4119 for (
int i=0; i<77; i++) {
4125 printf(
" --- DeltaG Table (J/kmol) Name PhID MoleNum MolFR "
4126 " ElectrChemStar ElectrChem DeltaGStar DeltaG(Pred) Stability\n");
4128 writeline(
'-', 132);
4130 for (
size_t kspec = 0; kspec < m_numSpeciesTot; kspec++) {
4133 if (kspec >= m_numComponents) {
4134 irxn = kspec - m_numComponents;
4137 double mfValue = 1.0;
4138 size_t iphase = m_phaseID[kspec];
4139 const vcs_VolPhase* Vphase = m_VolPhaseList[iphase];
4145 zeroedPhase =
false;
4147 if (tPhMoles_ptr[iphase] > 0.0) {
4151 mfValue = molNumSpecies[kspec] / tPhMoles_ptr[iphase];
4154 size_t klocal = m_speciesLocalPhaseIndex[kspec];
4155 mfValue = Vphase->moleFraction(klocal);
4158 printf(
" --- ** zp *** ");
4162 double feFull = feSpecies[kspec];
4165 feFull += log(actCoeff_ptr[kspec]) + log(mfValue);
4167 printf(
"%-24.24s", m_speciesName[kspec].c_str());
4168 printf(
" %-3s",
int2str(iphase).c_str());
4172 printf(
" % -12.4e", molNumSpecies[kspec]);
4174 printf(
" % -12.4e", mfValue);
4175 printf(
" % -12.4e", feSpecies[kspec] * RT);
4176 printf(
" % -12.4e", feFull * RT);
4178 printf(
" % -12.4e", deltaGRxn[irxn] * RT);
4179 printf(
" % -12.4e", (deltaGRxn[irxn] + feFull - feSpecies[kspec]) * RT);
4181 if (deltaGRxn[irxn] < 0.0) {
4182 if (molNumSpecies[kspec] > 0.0) {
4187 }
else if (deltaGRxn[irxn] > 0.0) {
4188 if (molNumSpecies[kspec] > 0.0) {
4189 printf(
" shrinking");
4191 printf(
" unstable");
4194 printf(
" balanced");
4202 writeline(
'-', 132);
4206 void VCS_SOLVE::vcs_deltag_Phase(
const size_t iphase,
const bool doDeleted,
4207 const int stateCalc,
const bool alterZeroedPhases)
4209 double* feSpecies=0;
4210 double* deltaGRxn=0;
4211 double* actCoeffSpecies=0;
4220 }
else if (DEBUG_MODE_ENABLED) {
4221 throw CanteraError(
"VCS_SOLVE::vcs_deltag_Phase",
"bad stateCalc");
4224 size_t irxnl = m_numRxnRdc;
4226 irxnl = m_numRxnTot;
4230 if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
4231 plogf(
" --- Subroutine vcs_deltag_Phase called for phase %d\n",
4240 AssertThrowMsg(iphase == m_phaseID[kspec],
"VCS_SOLVE::vcs_deltag_Phase",
4242 if (kspec >= m_numComponents) {
4243 size_t irxn = kspec - m_numComponents;
4244 deltaGRxn[irxn] = feSpecies[kspec];
4245 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
4246 deltaGRxn[irxn] += m_stoichCoeffRxnMatrix(kcomp,irxn) * feSpecies[kcomp];
4254 bool zeroedPhase =
true;
4256 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
4257 size_t kspec = m_indexRxnToSpecies[irxn];
4259 if (m_phaseID[kspec] == iphase) {
4260 if (m_molNumSpecies_old[kspec] > 0.0) {
4261 zeroedPhase =
false;
4263 deltaGRxn[irxn] = feSpecies[kspec];
4264 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
4265 deltaGRxn[irxn] += m_stoichCoeffRxnMatrix(kcomp,irxn) * feSpecies[kcomp];
4311 if (alterZeroedPhases) {
4313 double phaseDG = 1.0;
4314 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
4315 size_t kspec = m_indexRxnToSpecies[irxn];
4316 if (m_phaseID[kspec] == iphase) {
4317 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
4318 phaseDG -= exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
4324 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
4325 size_t kspec = m_indexRxnToSpecies[irxn];
4326 if (m_phaseID[kspec] == iphase) {
4327 deltaGRxn[irxn] = 1.0 - phaseDG;
4335 void VCS_SOLVE::vcs_switch_pos(
const bool ifunc,
const size_t k1,
const size_t k2)
4340 if (DEBUG_MODE_ENABLED && (k1 >= m_numSpeciesTot ||
4341 k2 >= m_numSpeciesTot)) {
4342 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
4351 size_t kp1 = m_speciesLocalPhaseIndex[k1];
4352 size_t kp2 = m_speciesLocalPhaseIndex[k2];
4359 std::swap(m_speciesName[k1], m_speciesName[k2]);
4360 std::swap(m_molNumSpecies_old[k1], m_molNumSpecies_old[k2]);
4361 std::swap(m_speciesUnknownType[k1], m_speciesUnknownType[k2]);
4362 std::swap(m_molNumSpecies_new[k1], m_molNumSpecies_new[k2]);
4363 std::swap(m_SSfeSpecies[k1], m_SSfeSpecies[k2]);
4364 std::swap(m_spSize[k1], m_spSize[k2]);
4365 std::swap(m_deltaMolNumSpecies[k1], m_deltaMolNumSpecies[k2]);
4366 std::swap(m_feSpecies_old[k1], m_feSpecies_old[k2]);
4367 std::swap(m_feSpecies_new[k1], m_feSpecies_new[k2]);
4368 std::swap(m_SSPhase[k1], m_SSPhase[k2]);
4369 std::swap(m_phaseID[k1], m_phaseID[k2]);
4370 std::swap(m_speciesMapIndex[k1], m_speciesMapIndex[k2]);
4371 std::swap(m_speciesLocalPhaseIndex[k1], m_speciesLocalPhaseIndex[k2]);
4372 std::swap(m_actConventionSpecies[k1], m_actConventionSpecies[k2]);
4373 std::swap(m_lnMnaughtSpecies[k1], m_lnMnaughtSpecies[k2]);
4374 std::swap(m_actCoeffSpecies_new[k1], m_actCoeffSpecies_new[k2]);
4375 std::swap(m_actCoeffSpecies_old[k1], m_actCoeffSpecies_old[k2]);
4376 std::swap(m_wtSpecies[k1], m_wtSpecies[k2]);
4377 std::swap(m_chargeSpecies[k1], m_chargeSpecies[k2]);
4378 std::swap(m_speciesThermoList[k1], m_speciesThermoList[k2]);
4379 std::swap(m_PMVolumeSpecies[k1], m_PMVolumeSpecies[k2]);
4381 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
4382 std::swap(m_formulaMatrix(k1,j), m_formulaMatrix(k2,j));
4384 if (m_useActCoeffJac && k1 != k2) {
4385 for (
size_t i = 0; i < m_numSpeciesTot; i++) {
4386 std::swap(m_np_dLnActCoeffdMolNum(k1,i), m_np_dLnActCoeffdMolNum(k2,i));
4388 for (
size_t i = 0; i < m_numSpeciesTot; i++) {
4389 std::swap(m_np_dLnActCoeffdMolNum(i,k1), m_np_dLnActCoeffdMolNum(i,k2));
4392 std::swap(m_speciesStatus[k1], m_speciesStatus[k2]);
4402 size_t i1 = k1 - m_numComponents;
4403 size_t i2 = k2 - m_numComponents;
4404 if (DEBUG_MODE_ENABLED && (i1 > m_numRxnTot || i2 >= m_numRxnTot)) {
4405 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
4408 for (
size_t j = 0; j < m_numComponents; ++j) {
4409 std::swap(m_stoichCoeffRxnMatrix(j,i1), m_stoichCoeffRxnMatrix(j,i2));
4411 std::swap(m_scSize[i1], m_scSize[i2]);
4412 for (
size_t iph = 0; iph < m_numPhases; iph++) {
4413 std::swap(m_deltaMolNumPhase(iph,i1), m_deltaMolNumPhase(iph,i2));
4414 std::swap(m_phaseParticipation(iph,i1),
4415 m_phaseParticipation(iph,i2));
4417 std::swap(m_deltaGRxn_new[i1], m_deltaGRxn_new[i2]);
4418 std::swap(m_deltaGRxn_old[i1], m_deltaGRxn_old[i2]);
4419 std::swap(m_deltaGRxn_tmp[i1], m_deltaGRxn_tmp[i2]);
4423 double VCS_SOLVE::vcs_birthGuess(
const int kspec)
4425 size_t irxn = kspec - m_numComponents;
4435 "VCS_SOLVE::vcs_birthGuess",
"we shouldn't be here");
4436 int ss = m_SSPhase[kspec];
4443 double dxm = vcs_minor_alt_calc(kspec, irxn, &soldel_ret);
4444 dx = std::min(w_kspec + dxm, 1e-15);
4463 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
4464 for (
size_t j = 0; j < m_numComponents; ++j) {
4467 if (m_molNumSpecies_old[j] > 0.0) {
4468 double tmp = sc_irxn[j] * dx;
4469 if (3.0*(-tmp) > m_molNumSpecies_old[j]) {
4470 dx = std::min(dx, - 0.3333* m_molNumSpecies_old[j] / sc_irxn[j]);
4473 if (m_molNumSpecies_old[j] <= 0.0) {
4474 if (sc_irxn[j] < 0.0) {
4483 void VCS_SOLVE::vcs_setFlagsVolPhases(
const bool upToDate,
const int stateCalc)
4486 for (
size_t iph = 0; iph < m_numPhases; iph++) {
4487 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
4490 for (
size_t iph = 0; iph < m_numPhases; iph++) {
4491 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
4496 void VCS_SOLVE::vcs_setFlagsVolPhase(
const size_t iph,
const bool upToDate,
4497 const int stateCalc)
4500 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
4502 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
4506 void VCS_SOLVE::vcs_updateMolNumVolPhases(
const int stateCalc)
4508 for (
size_t iph = 0; iph < m_numPhases; iph++) {
4509 m_VolPhaseList[iph]->updateFromVCS_MoleNumbers(stateCalc);
#define VCS_PHASE_EXIST_NO
Phase doesn't currently exist in the mixture.
bool vcs_doubleEqual(double d1, double d2)
Simple routine to check whether two doubles are equal up to roundoff error.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
bool m_singleSpecies
If true, this phase consists of a single species.
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
void updateFromVCS_MoleNumbers(const int stateCalc)
Update the moles within the phase, if necessary.
#define VCS_SPECIES_ZEROEDMS
Species lies in a multicomponent phase with concentration zero.
#define VCS_SPECIES_MINOR
Species is a major species.
Declarations for a simple class that implements an Ansi C wall clock timer (see Cantera::clockWC).
#define VCS_PHASE_EXIST_ALWAYS
Always exists because it contains inerts which can't exist in any other phase.
void setMolesFromVCSCheck(const int vcsStateStatus, const double *molesSpeciesVCS, const double *const TPhMoles)
Set the moles within the phase.
#define VCS_PHASE_EXIST_ZEROEDPHASE
Phase currently is zeroed due to a programmatic issue.
const size_t npos
index returned by functions to indicate "no position"
#define VCS_DATA_PTR(vvv)
Points to the data in a std::vector<> object.
size_t nSpecies() const
Return the number of species in the phase.
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
The class provides the wall clock timer in seconds.
#define VCS_SPECIES_INTERFACIALVOLTAGE
Species refers to an electron in the metal.
std::string PhaseName
String name for the phase.
#define VCS_PHASE_EXIST_YES
Phase is a normal phase that currently exists.
void setExistence(const int existence)
Set the existence flag in the object.
double electricPotential() const
Returns the electric field of the phase.
#define AssertThrowMsg(expr, procedure, message)
Assertion must be true or an error is thrown.
void setMolesFromVCS(const int stateCalc, const double *molesSpeciesVCS=0)
Set the moles within the phase.
std::vector< int > vector_int
Vector of ints.
Header file for the internal object that holds the vcs equilibrium problem (see Class VCS_SOLVE and E...
Header for the object representing each phase within vcs.
#define VCS_SPECIES_ZEROEDSS
Species is a SS phase, that is currently zeroed out.
#define VCS_SPECIES_TYPE_MOLNUM
Unknown refers to mole number of a single species.
#define VCS_ELEM_TYPE_ABSPOS
Normal element constraint consisting of positive coefficients for the formula matrix.
#define VCS_SPECIES_ZEROEDPHASE
Species lies in a multicomponent phase that is zeroed atm.
#define VCS_DELETE_MINORSPECIES_CUTOFF
Cutoff relative mole number value, below which species are deleted from the equilibrium problem...
double secondsWC()
Returns the wall clock time in seconds since the last reset.
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
#define VCS_DELETE_PHASE_CUTOFF
Cutoff relative moles below which a phase is deleted from the equilibrium problem.
#define VCS_STATECALC_NEW
State Calculation based on the new or tentative mole numbers.
void vcs_print_stringTrunc(const char *str, size_t space, int alignment)
Print a string within a given space limit.
Base class for exceptions thrown by Cantera classes.
#define VCS_SPECIES_ACTIVEBUTZERO
Species lies in a multicomponent phase that is active, but species concentration is zero...
void sendToVCS_ActCoeff(const int stateCalc, double *const AC)
Fill in an activity coefficients vector within a VCS_SOLVE object.
int exists() const
int indicating whether the phase exists or not
#define VCS_SPECIES_MAJOR
Species is a major species.
#define VCS_RELDELETE_SPECIES_CUTOFF
Cutoff relative mole fraction value, below which species are deleted from the equilibrium problem...
#define VCS_SPECIES_STOICHZERO
Species lies in a multicomponent phase that is active, but species concentration is zero due to stoic...
Phase information and Phase calculations for vcs.
#define VCS_DIMENSIONAL_G
dimensioned
#define VCS_STATECALC_OLD
State Calculation based on the old or base mole numbers.
#define plogendl()
define this Cantera function to replace cout << endl;
void setSpGlobalIndexVCS(const size_t spIndex, const size_t spGlobalIndex)
set the Global VCS index of the kth species in the phase
Contains declarations for string manipulation functions within Cantera.
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...
#define plogf
define this Cantera function to replace printf
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
Unknown refers to the voltage level of a phase.
#define VCS_SPECIES_COMPONENT
Species is a component which can be nonzero.
size_t spGlobalIndexVCS(const size_t spIndex) const
Return the Global VCS index of the kth species in the phase.
#define VCS_SPECIES_DELETED
Species has such a small mole fraction it is deleted even though its phase may possibly exist...
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
void setTotalMoles(const double totalMols)
Sets the total moles in the phase.