23 using namespace Cantera;
29 static void print_space(
size_t num);
33 static void prneav(
void);
34 static int prnfm(
void);
40 void VCS_SOLVE::checkDelta1(
double*
const dsLocal,
41 double*
const delTPhMoles,
int kspec)
43 std::vector<double> dchange(m_numPhases, 0.0);
44 for (
int k = 0; k < kspec; k++) {
46 int iph = m_phaseID[k];
47 dchange[iph] += dsLocal[k];
50 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
51 double denom = max(m_totalMolNum, 1.0E-4);
52 if (!
vcs_doubleEqual(dchange[iphase]/denom, delTPhMoles[iphase]/denom)) {
53 plogf(
"checkDelta1: we have found a problem\n");
60 int VCS_SOLVE::vcs_solve_TP(
int print_lvl,
int printDetails,
int maxit)
64 size_t j, k, l, l1, kspec, irxn, i;
65 bool conv =
false, allMinorZeroedSpecies =
false, forced, lec;
69 size_t npb, iti, lnospec;
71 int rangeErrorFound = 0;
72 bool giveUpOnElemAbund =
false;
73 int finalElemAbundAttempts = 0;
74 bool uptodate_minors =
true;
75 bool justDeletedMultiPhase =
false;
76 bool usedZeroedSpecies;
79 double* sc_irxn = NULL;
83 int forceComponentCalc = 1;
85 std::vector<size_t> phasePopPhaseIDs(0);
86 size_t doPhaseDeleteIph =
npos;
87 size_t doPhaseDeleteKspec =
npos;
94 m_debug_print_lvl = printDetails;
96 if (printDetails > 0 && print_lvl == 0) {
102 vcs_counters_init(0);
117 std::vector<double> sm(m_numElemConstraints*m_numElemConstraints, 0.0);
118 std::vector<double> ss(m_numElemConstraints, 0.0);
119 std::vector<double> sa(m_numElemConstraints, 0.0);
121 std::vector<double> aw(m_numSpeciesTot, 0.0);
122 std::vector<double> wx(m_numElemConstraints, 0.0);
138 if (print_lvl != 0) {
139 plogf(
"VCS CALCULATION METHOD\n\n ");
140 plogf(
"%s\n", m_title.c_str());
141 plogf(
"\n\n%5d SPECIES\n%5d ELEMENTS\n", m_numSpeciesTot, m_numElemConstraints);
142 plogf(
"%5d COMPONENTS\n", m_numComponents);
143 plogf(
"%5d PHASES\n", m_numPhases);
145 plogf(
" PRESSURE%22.8g %3s\n", m_pressurePA,
"Pa ");
146 plogf(
" TEMPERATURE%19.3f K\n", m_temperature);
147 Vphase = m_VolPhaseList[0];
149 plogf(
" PHASE1 INERTS%17.3f\n", TPhInertMoles[0]);
151 if (m_numPhases > 1) {
152 plogf(
" PHASE2 INERTS%17.3f\n", TPhInertMoles[1]);
154 plogf(
"\n ELEMENTAL ABUNDANCES CORRECT");
155 plogf(
" FROM ESTIMATE Type\n\n");
156 for (i = 0; i < m_numElemConstraints; ++i) {
158 plogf(
"%-2.2s", (m_elementName[i]).c_str());
159 plogf(
"%20.12E%20.12E %3d\n", m_elemAbundancesGoal[i], m_elemAbundances[i],
162 if (m_doEstimateEquil < 0) {
163 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - forced\n");
164 }
else if (m_doEstimateEquil > 0) {
165 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - where necessary\n");
167 if (m_doEstimateEquil == 0) {
168 plogf(
"\n USER ESTIMATE OF EQUILIBRIUM\n");
170 if (m_VCS_UnitsFormat == VCS_UNITS_KCALMOL) {
171 plogf(
" Stan. Chem. Pot. in kcal/mole\n");
173 if (m_VCS_UnitsFormat == VCS_UNITS_UNITLESS) {
174 plogf(
" Stan. Chem. Pot. is MU/RT\n");
176 if (m_VCS_UnitsFormat == VCS_UNITS_KJMOL) {
177 plogf(
" Stan. Chem. Pot. in KJ/mole\n");
179 if (m_VCS_UnitsFormat == VCS_UNITS_KELVIN) {
180 plogf(
" Stan. Chem. Pot. in Kelvin\n");
182 if (m_VCS_UnitsFormat == VCS_UNITS_MKS) {
183 plogf(
" Stan. Chem. Pot. in J/kmol\n");
185 plogf(
"\n SPECIES FORMULA VECTOR ");
187 plogf(
" STAN_CHEM_POT EQUILIBRIUM_EST. Species_Type\n\n");
189 for (i = 0; i < m_numElemConstraints; ++i) {
190 plogf(
"%-4.4s ", m_elementName[i].c_str());
193 RT = vcs_nondimMult_TP(m_VCS_UnitsFormat, m_temperature);
194 for (i = 0; i < m_numSpeciesTot; ++i) {
195 plogf(
" %-18.18s", m_speciesName[i].c_str());
196 for (j = 0; j < m_numElemConstraints; ++j) {
197 plogf(
"% -7.3g ", m_formulaMatrix[j][i]);
199 plogf(
" %3d ", m_phaseID[i]);
200 print_space(std::max(55-
int(m_numElemConstraints)*8, 0));
201 plogf(
"%12.5E %12.5E", RT * m_SSfeSpecies[i], m_molNumSpecies_old[i]);
213 for (i = 0; i < m_numSpeciesTot; ++i) {
214 if (m_molNumSpecies_old[i] < 0.0) {
215 plogf(
"On Input species %-12s has a "
216 "negative MF, setting it small",
217 m_speciesName[i].c_str());
224 m_molNumSpecies_old[i] = tmp;
251 test, &usedZeroedSpecies);
260 forceComponentCalc = 0;
270 allMinorZeroedSpecies = vcs_evaluate_speciesType();
276 if (! vcs_elabcheck(0)) {
278 if (m_debug_print_lvl >= 2) {
279 plogf(
" --- Element Abundance check failed");
292 if (m_debug_print_lvl >= 2) {
293 plogf(
" --- Element Abundance check passed");
300 goto L_MAINLOOP_ALL_SPECIES;
310 L_MAINLOOP_MM4_SPECIES:
312 iti = ((it1/4) *4) - it1;
316 L_MAINLOOP_ALL_SPECIES:
324 if (!uptodate_minors) {
329 uptodate_minors =
true;
331 uptodate_minors =
false;
337 plogf(
" Iteration = %3d, Iterations since last evaluation of "
338 "optimal basis = %3d",
339 m_VCount->Its, it1 - 1);
341 plogf(
" (all species)\n");
343 plogf(
" (only major species)\n");
372 vcs_dzero(
VCS_DATA_PTR(m_deltaMolNumSpecies), m_numSpeciesTot);
381 phasePopPhaseIDs.clear();
382 iphasePop = vcs_popPhaseID(phasePopPhaseIDs);
387 if (iphasePop !=
npos) {
388 soldel = vcs_popPhaseRxnStepSizes(iphasePop);
392 if (m_debug_print_lvl >= 2) {
393 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich "
394 "prevented phase %d popping\n");
407 if (iphasePop ==
npos) {
413 iphaseDelete = vcs_RxnStepSizes(forceComponentCalc, kspec);
417 if (m_debug_print_lvl >= 2) {
418 plogf(
" --- vcs_RxnStepSizes not called because alternative"
419 "phase creation delta was used instead\n");
424 doPhaseDeleteIph =
npos;
425 doPhaseDeleteKspec =
npos;
429 vcs_dzero(
VCS_DATA_PTR(m_deltaPhaseMoles), m_numPhases);
436 if (m_VCount->Its > maxit) {
462 if (iphaseDelete !=
npos) {
464 if (m_debug_print_lvl >= 2) {
465 plogf(
" --- Main Loop Treatment -> Circumvented due to Phase Deletion ");
470 for (k = 0; k < m_numSpeciesTot; k++) {
471 m_molNumSpecies_new[k] = m_molNumSpecies_old[k] + m_deltaMolNumSpecies[k];
473 m_tPhaseMoles_new[iph] += m_deltaMolNumSpecies[k];
475 if (kspec >= m_numComponents) {
476 if (m_molNumSpecies_new[k] != 0.0) {
477 printf(
"vcs_solve_tp:: we shouldn't be here!\n");
480 if (m_SSPhase[kspec] == 1) {
483 printf(
"vcs_solve_tp:: we shouldn't be here!\n");
486 ++m_numRxnMinorZeroed;
487 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
509 if (m_debug_print_lvl >= 2) {
510 plogf(
" --- Main Loop Treatment of each non-component species ");
512 plogf(
"- Full Calculation:\n");
514 plogf(
"- Major Components Calculation:\n");
516 plogf(
" --- Species IC ");
517 plogf(
" KMoles Tent_KMoles Rxn_Adj | Comment \n");
520 for (irxn = 0; irxn < m_numRxnRdc; irxn++) {
521 kspec = m_indexRxnToSpecies[irxn];
522 sc_irxn = m_stoichCoeffRxnMatrix[irxn];
523 iph = m_phaseID[kspec];
524 Vphase = m_VolPhaseList[iph];
528 if (iphasePop !=
npos) {
529 if (iph == iphasePop) {
530 dx = m_deltaMolNumSpecies[kspec];
531 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
533 sprintf(ANOTE,
"Phase pop");
537 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
548 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
550 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret);
553 m_deltaMolNumSpecies[kspec] = dx;
558 bool resurrect = (m_deltaMolNumSpecies[kspec] > 0.0);
560 if (m_debug_print_lvl >= 3) {
561 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
562 m_speciesName[kspec].c_str(), m_speciesStatus[kspec]);
563 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
564 irxn, m_deltaGRxn_new[irxn], m_molNumSpecies_new[kspec],
565 m_molNumSpecies_old[kspec], m_deltaMolNumSpecies[kspec]);
569 if (m_deltaGRxn_new[irxn] >= 0.0 || !resurrect) {
570 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
571 m_deltaMolNumSpecies[kspec] = 0.0;
574 sprintf(ANOTE,
"Species stays zeroed: DG = %11.4E", m_deltaGRxn_new[irxn]);
575 if (m_deltaGRxn_new[irxn] < 0.0) {
577 sprintf(ANOTE,
"Species stays zeroed even though dg neg due to "
578 "STOICH/PHASEPOP constraint: DG = %11.4E",
579 m_deltaGRxn_new[irxn]);
581 sprintf(ANOTE,
"Species stays zeroed even though dg neg: DG = %11.4E, ds zeroed",
582 m_deltaGRxn_new[irxn]);
587 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
588 int elType = m_elType[j];
590 atomComp = m_formulaMatrix[j][kspec];
591 if (atomComp > 0.0) {
592 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
595 sprintf(ANOTE,
"Species stays zeroed even though dG "
596 "neg, because of %s elemAbund",
597 m_elementName[j].c_str());
610 bool phaseResurrected =
false;
613 phaseResurrected =
true;
616 if (phaseResurrected) {
618 if (m_debug_print_lvl >= 2) {
619 plogf(
" --- Zeroed species changed to major: ");
620 plogf(
"%-12s\n", m_speciesName[kspec].c_str());
624 allMinorZeroedSpecies =
false;
627 if (m_debug_print_lvl >= 2) {
628 plogf(
" --- Zeroed species changed to minor: ");
629 plogf(
"%-12s\n", m_speciesName[kspec].c_str());
634 if (m_deltaMolNumSpecies[kspec] > 0.0) {
635 dx = m_deltaMolNumSpecies[kspec] * 0.01;
636 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
639 dx = m_molNumSpecies_new[kspec] - m_molNumSpecies_old[kspec];
641 m_deltaMolNumSpecies[kspec] = dx;
643 sprintf(ANOTE,
"Born:IC=-1 to IC=1:DG=%11.4E", m_deltaGRxn_new[irxn]);
646 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
647 m_deltaMolNumSpecies[kspec] = 0.0;
659 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
660 m_deltaMolNumSpecies[kspec] = 0.0;
663 sprintf(ANOTE,
"minor species not considered");
664 if (m_debug_print_lvl >= 2) {
666 plogf(
"%-12s", m_speciesName[kspec].c_str());
667 plogf(
"%3d%11.4E%11.4E%11.4E | %s",
668 m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
669 m_deltaMolNumSpecies[kspec], ANOTE);
691 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
693 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret);
696 m_deltaMolNumSpecies[kspec] = dx;
697 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
705 if (m_debug_print_lvl >= 2) {
706 plogf(
" --- Delete minor species in multispec phase: %-12s",
707 m_speciesName[kspec].c_str());
711 m_deltaMolNumSpecies[kspec] = 0.0;
718 lnospec = vcs_delete_species(kspec);
720 goto L_RECHECK_DELETED;
732 goto L_MAIN_LOOP_END_NO_PRINT;
734 goto L_MAIN_LOOP_END;
742 sprintf(ANOTE,
"Normal Major Calc");
749 if (fabs(m_deltaGRxn_new[irxn]) <= m_tolmaj2) {
750 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
751 m_deltaMolNumSpecies[kspec] = 0.0;
754 sprintf(ANOTE,
"major species is converged");
755 if (m_debug_print_lvl >= 2) {
757 plogf(
"%-12s", m_speciesName[kspec].c_str());
758 plogf(
"%3d%11.4E%11.4E%11.4E | %s",
759 m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
760 m_deltaMolNumSpecies[kspec], ANOTE);
775 if ((m_deltaGRxn_new[irxn] * m_deltaMolNumSpecies[kspec]) <= 0.0) {
776 dx = m_deltaMolNumSpecies[kspec];
779 m_deltaMolNumSpecies[kspec] = 0.0;
781 sprintf(ANOTE,
"dx set to 0, DG flipped sign due to "
782 "changed initial point");
788 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
796 if (m_molNumSpecies_new[kspec] <= 0.0) {
798 sprintf(ANOTE,
"initial nonpos kmoles= %11.3E",
799 m_molNumSpecies_new[kspec]);
811 if (!(m_SSPhase[kspec])) {
818 dx = -0.9 * m_molNumSpecies_old[kspec];
819 m_deltaMolNumSpecies[kspec] = dx;
820 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
827 dx = -m_molNumSpecies_old[kspec];
834 for (j = 0; j < m_numComponents; ++j) {
835 if (sc_irxn[j] != 0.0) {
836 wx[j] = m_molNumSpecies_old[j] + sc_irxn[j] * dx;
837 if (wx[j] <= m_molNumSpecies_old[j] * 0.01 - 1.0E-150) {
838 dx = std::max(dx, m_molNumSpecies_old[j] * -0.99 / sc_irxn[j]);
841 wx[j] = m_molNumSpecies_old[j];
844 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
845 if (m_molNumSpecies_new[kspec] > 0.0) {
846 m_deltaMolNumSpecies[kspec] = dx;
849 "zeroing SS phase created a neg component species "
850 "-> reducing step size instead");
857 iph = m_phaseID[kspec];
858 Vphase = m_VolPhaseList[iph];
861 sprintf(ANOTE,
"zeroing out SS phase: ");
869 m_molNumSpecies_new[kspec] = 0.0;
870 doPhaseDeleteIph = iph;
871 doPhaseDeleteKspec = kspec;
874 if (m_debug_print_lvl >= 2) {
875 if (m_speciesStatus[kspec] >= 0) {
876 plogf(
" --- SS species changed to zeroedss: ");
877 plogf(
"%-12s", m_speciesName[kspec].c_str());
883 ++m_numRxnMinorZeroed;
884 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
886 for (
size_t kk = 0; kk < m_numSpeciesTot; kk++) {
887 m_deltaMolNumSpecies[kk] = 0.0;
888 m_molNumSpecies_new[kk] = m_molNumSpecies_old[kk];
890 m_deltaMolNumSpecies[kspec] = dx;
891 m_molNumSpecies_new[kspec] = 0.0;
893 for (k = 0; k < m_numComponents; ++k) {
894 m_deltaMolNumSpecies[k] = 0.0;
896 for (iph = 0; iph < m_numPhases; iph++) {
897 m_deltaPhaseMoles[iph] = 0.0;
905 #ifdef VCS_LINE_SEARCH
913 (m_molNumSpecies_old[kspec] > 0.0) &&
914 (doPhaseDeleteIph == -1) &&
919 dx = vcs_line_search(irxn, dx_old, ANOTE);
921 dx = vcs_line_search(irxn, dx_old);
925 m_deltaMolNumSpecies[kspec] = dx;
932 if (dx != 0.0 && (m_speciesUnknownType[kspec] !=
940 if (fabs(m_deltaMolNumSpecies[kspec] -dx) >
941 1.0E-14*(fabs(m_deltaMolNumSpecies[kspec]) + fabs(dx) + 1.0E-32)) {
942 plogf(
" ds[kspec] = %20.16g dx = %20.16g , kspec = %d\n",
943 m_deltaMolNumSpecies[kspec], dx, kspec);
944 plogf(
"we have a problem!");
949 for (k = 0; k < m_numComponents; ++k) {
950 m_deltaMolNumSpecies[k] += sc_irxn[k] * dx;
956 dnPhase_irxn = m_deltaMolNumPhase[irxn];
957 for (iph = 0; iph < m_numPhases; iph++) {
958 m_deltaPhaseMoles[iph] += dx * dnPhase_irxn[iph];
974 if (m_debug_print_lvl >= 2) {
975 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
977 plogf(
"%-12.12s", m_speciesName[kspec].c_str());
978 plogf(
"%3d%11.4E%11.4E%11.4E | %s",
979 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
980 m_molNumSpecies_new[kspec],
981 m_deltaMolNumSpecies[kspec], ANOTE);
984 L_MAIN_LOOP_END_NO_PRINT:
987 if (doPhaseDeleteIph !=
npos) {
989 if (m_debug_print_lvl >= 2) {
991 plogf(
"%-12.12s Main Loop Special Case deleting phase with species: ",
992 m_speciesName[doPhaseDeleteKspec].c_str());
1001 if (m_debug_print_lvl >= 2) {
1002 for (k = 0; k < m_numComponents; k++) {
1004 plogf(
"%-12.12s", m_speciesName[k].c_str());
1005 plogf(
" c%11.4E%11.4E%11.4E |\n",
1006 m_molNumSpecies_old[k],
1007 m_molNumSpecies_old[k]+m_deltaMolNumSpecies[k], m_deltaMolNumSpecies[k]);
1011 plogf(
" --- Finished Main Loop");
1026 for (k = 0; k < m_numComponents; ++k) {
1027 if (m_molNumSpecies_old[k] > 0.0) {
1028 xx = -m_deltaMolNumSpecies[k] / m_molNumSpecies_old[k];
1036 if (m_deltaMolNumSpecies[k] < 0.0) {
1042 m_deltaPhaseMoles[iph] -= m_deltaMolNumSpecies[k];
1043 m_deltaMolNumSpecies[k] = 0.0;
1048 if (par <= 1.01 && par > 0.0) {
1052 if (m_debug_print_lvl >= 2) {
1053 plogf(
" --- Reduction in step size due to component ");
1054 plogf(
"%s", m_speciesName[ll].c_str());
1055 plogf(
" going negative = %11.3E", par);
1059 for (i = 0; i < m_numSpeciesTot; ++i) {
1060 m_deltaMolNumSpecies[i] *= par;
1062 for (iph = 0; iph < m_numPhases; iph++) {
1063 m_deltaPhaseMoles[iph] *= par;
1079 for (kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
1080 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
1081 if (m_molNumSpecies_new[kspec] < 0.0 && (m_speciesUnknownType[kspec]
1083 plogf(
"vcs_solve_TP: ERROR on step change wt[%d:%s]: %g < 0.0",
1084 kspec, m_speciesName[kspec].c_str(), m_molNumSpecies_new[kspec]);
1093 for (iph = 0; iph < m_numPhases; iph++) {
1094 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + m_deltaPhaseMoles[iph];
1120 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
1123 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E",
1129 forced = vcs_globStepDamp();
1134 if (printDetails && forced) {
1136 plogf(
" -----------------------------------------------------\n");
1137 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
1138 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
1139 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
1140 for (i = 0; i < m_numComponents; ++i) {
1141 plogf(
" --- %-12.12s", m_speciesName[i].c_str());
1142 plogf(
" %14.6E %14.6E %14.6E\n", m_molNumSpecies_old[i],
1143 m_molNumSpecies_old[i] + m_deltaMolNumSpecies[i], m_molNumSpecies_new[i]);
1145 for (kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1146 irxn = kspec - m_numComponents;
1147 plogf(
" --- %-12.12s", m_speciesName[kspec].c_str());
1148 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n", m_speciesStatus[kspec],
1149 m_molNumSpecies_old[kspec],
1150 m_molNumSpecies_old[kspec]+m_deltaMolNumSpecies[kspec],
1151 m_molNumSpecies_new[kspec], m_deltaGRxn_old[irxn],
1152 m_deltaGRxn_tmp[irxn], m_deltaGRxn_new[irxn]);
1155 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
1158 plogf(
" Total kmoles of gas = %15.7E\n", m_tPhaseMoles_old[0]);
1159 if ((m_numPhases > 1) && (!(m_VolPhaseList[1])->m_singleSpecies)) {
1160 plogf(
" Total kmoles of liquid = %15.7E\n", m_tPhaseMoles_old[1]);
1162 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
1164 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
1167 plogf(
" -----------------------------------------------------");
1178 plogf(
" --- Summary of the Update ");
1180 plogf(
" (all species):");
1182 plogf(
" (only major species):");
1184 if (m_totalMoleScale != 1.0) {
1185 plogf(
" (Total Mole Scale = %g)", m_totalMoleScale);
1188 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
1189 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
1190 for (i = 0; i < m_numComponents; ++i) {
1191 plogf(
" --- %-12.12s", m_speciesName[i].c_str());
1193 plogf(
"%14.6E%14.6E%14.6E%14.6E\n", m_molNumSpecies_old[i],
1194 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i]);
1196 for (i = m_numComponents; i < m_numSpeciesRdc; ++i) {
1197 l1 = i - m_numComponents;
1198 plogf(
" --- %-12.12s", m_speciesName[i].c_str());
1199 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
1200 m_speciesStatus[i], m_molNumSpecies_old[i],
1201 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i],
1202 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
1204 for (kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
1205 l1 = kspec - m_numComponents;
1206 plogf(
" --- %-12.12s", m_speciesName[kspec].c_str());
1207 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
1208 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
1209 m_molNumSpecies_new[kspec], m_feSpecies_old[kspec], m_feSpecies_new[kspec],
1210 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
1214 plogf(
"Norms of Delta G():%14.6E%14.6E",
1219 plogf(
" --- Phase_Name KMoles(after update)\n");
1222 for (iph = 0; iph < m_numPhases; iph++) {
1223 Vphase = m_VolPhaseList[iph];
1224 plogf(
" --- %18s = %15.7E\n", Vphase->
PhaseName.c_str(), m_tPhaseMoles_new[iph]);
1228 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
1231 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E",
1236 if (m_VCount->Its > 550) {
1237 plogf(
" --- Troublesome solve");
1274 if (m_debug_print_lvl >= 2) {
1275 plogf(
" --- Increment counter increased, step is accepted: %4d",
1290 justDeletedMultiPhase =
false;
1291 for (iph = 0; iph < m_numPhases; iph++) {
1292 Vphase = m_VolPhaseList[iph];
1294 if (m_tPhaseMoles_old[iph] != 0.0 &&
1298 for (kspec = 0; kspec < m_numSpeciesRdc; kspec++) {
1299 if (m_phaseID[kspec] == iph && m_molNumSpecies_old[kspec] > 0.0) {
1300 irxn = kspec - m_numComponents;
1305 if (m_debug_print_lvl >= 1) {
1306 plogf(
" --- Setting microscopic phase %d to zero", iph);
1310 justDeletedMultiPhase =
true;
1311 vcs_delete_multiphase(iph);
1322 if (justDeletedMultiPhase) {
1323 justDeletedMultiPhase =
false;
1326 &usedZeroedSpecies);
1329 plogf(
" --- BASOPT returned with an error condition\n");
1338 goto L_MAINLOOP_ALL_SPECIES ;
1345 if (m_debug_print_lvl >= 2) {
1346 plogf(
" --- Normal element abundance check");
1350 if (! vcs_elabcheck(0)) {
1352 if (m_debug_print_lvl >= 2) {
1353 plogf(
" - failed -> redoing element abundances.");
1361 uptodate_minors =
true;
1365 if (m_debug_print_lvl >= 2) {
1385 dofast = (m_numComponents != 1);
1386 for (i = 1; i < m_numComponents; ++i) {
1387 if ((m_molNumSpecies_old[i - 1] * m_spSize[i-1]) < (m_molNumSpecies_old[i] * m_spSize[i])) {
1394 for (i = 0; i < m_numRxnRdc; ++i) {
1395 l = m_indexRxnToSpecies[i];
1397 for (j = m_numComponents - 1; j !=
npos; j--) {
1398 bool doSwap =
false;
1400 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1401 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1402 if (!m_SSPhase[i]) {
1404 doSwap = (m_molNumSpecies_old[l]) > (m_molNumSpecies_old[j] * 1.01);
1409 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1410 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1412 doSwap = (m_molNumSpecies_old[l]) > (m_molNumSpecies_old[j] * 1.01);
1415 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1416 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1420 if (m_stoichCoeffRxnMatrix[i][j] != 0.0) {
1422 if (m_debug_print_lvl >= 2) {
1423 plogf(
" --- Get a new basis because %s", m_speciesName[l].c_str());
1424 plogf(
" is better than comp %s", m_speciesName[j].c_str());
1425 plogf(
" and share nonzero stoic: %-9.1f",
1426 m_stoichCoeffRxnMatrix[i][j]);
1430 goto L_COMPONENT_CALC;
1437 if (m_molNumSpecies_old[j] == 0.0) {
1438 if (m_stoichCoeffRxnMatrix[i][j] != 0.0) {
1441 if (m_debug_print_lvl >= 2) {
1442 plogf(
" --- Get a new basis because %s", m_speciesName[l].c_str());
1443 plogf(
" has dg < 0.0 and comp %s has zero mole num", m_speciesName[j].c_str());
1444 plogf(
" and share nonzero stoic: %-9.1f",
1445 m_stoichCoeffRxnMatrix[i][j]);
1449 goto L_COMPONENT_CALC;
1459 for (i = 0; i < m_numRxnRdc; ++i) {
1460 l = m_indexRxnToSpecies[i];
1462 for (j = 0; j < m_numComponents; ++j) {
1463 bool doSwap =
false;
1465 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1466 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1467 if (!m_SSPhase[l]) {
1469 doSwap = (m_molNumSpecies_old[l]) > (m_molNumSpecies_old[j] * 1.01);
1474 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1475 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1477 doSwap = (m_molNumSpecies_old[l]) > (m_molNumSpecies_old[j] * 1.01);
1480 doSwap = (m_molNumSpecies_old[l] * m_spSize[l]) >
1481 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1485 if (m_stoichCoeffRxnMatrix[i][j] != 0.0) {
1487 if (m_debug_print_lvl >= 2) {
1488 plogf(
" --- Get a new basis because ");
1489 plogf(
"%s", m_speciesName[l].c_str());
1490 plogf(
" is better than comp ");
1491 plogf(
"%s", m_speciesName[j].c_str());
1492 plogf(
" and share nonzero stoic: %-9.1f",
1493 m_stoichCoeffRxnMatrix[i][j]);
1497 goto L_COMPONENT_CALC;
1502 if (m_molNumSpecies_old[j] == 0.0) {
1503 if (m_stoichCoeffRxnMatrix[i][j] != 0.0) {
1506 if (m_debug_print_lvl >= 2) {
1507 plogf(
" --- Get a new basis because %s", m_speciesName[l].c_str());
1508 plogf(
" has dg < 0.0 and comp %s has zero mole num",
1509 m_speciesName[j].c_str());
1510 plogf(
" and share nonzero stoic: %-9.1f",
1511 m_stoichCoeffRxnMatrix[i][j]);
1515 goto L_COMPONENT_CALC;
1526 if (m_debug_print_lvl >= 2) {
1527 plogf(
" --- Check for an optimum basis passed");
1540 if (m_debug_print_lvl >= 2) {
1541 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1544 m_numRxnMinorZeroed = 0;
1545 for (irxn = 0; irxn < m_numRxnRdc; irxn++) {
1546 kspec = m_indexRxnToSpecies[irxn];
1548 int speciesType = vcs_species_type(kspec);
1551 if (m_debug_print_lvl >= 2) {
1553 plogf(
" --- major/minor species is now zeroed out: %s\n",
1554 m_speciesName[kspec].c_str());
1558 ++m_numRxnMinorZeroed;
1561 if (m_debug_print_lvl >= 2) {
1564 plogf(
" --- Noncomponent turned from major to minor: ");
1565 }
else if (kspec < m_numComponents) {
1566 plogf(
" --- Component turned into a minor species: ");
1568 plogf(
" --- Zeroed Species turned into a "
1571 plogf(
"%s\n", m_speciesName[kspec].c_str());
1575 ++m_numRxnMinorZeroed;
1579 if (m_debug_print_lvl >= 2) {
1581 plogf(
" --- Noncomponent turned from minor to major: ");
1582 }
else if (kspec < m_numComponents) {
1583 plogf(
" --- Component turned into a major: ");
1585 plogf(
" --- Noncomponent turned from zeroed to major: ");
1587 plogf(
"%s\n", m_speciesName[kspec].c_str());
1601 m_speciesStatus[kspec] = speciesType;
1607 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
1614 if (! allMinorZeroedSpecies) {
1616 if (m_debug_print_lvl >= 2) {
1617 plogf(
" --- Equilibrium check for major species: ");
1620 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1621 kspec = irxn + m_numComponents;
1622 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MAJOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmaj)) {
1623 if (m_VCount->Its >= maxit) {
1629 goto L_RETURN_BLOCK;
1632 if (m_debug_print_lvl >= 2) {
1633 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]].c_str());
1640 if (forceComponentCalc) {
1641 goto L_COMPONENT_CALC;
1643 goto L_MAINLOOP_MM4_SPECIES;
1648 if (m_debug_print_lvl >= 2) {
1649 plogf(
" MAJOR SPECIES CONVERGENCE achieved");
1656 if (m_debug_print_lvl >= 2) {
1657 plogf(
" MAJOR SPECIES CONVERGENCE achieved "
1658 "(because there are no major species)");
1668 if (m_numRxnMinorZeroed != 0) {
1677 uptodate_minors =
true;
1680 if (m_debug_print_lvl >= 2) {
1681 plogf(
" --- Equilibrium check for minor species: ");
1684 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1685 kspec = irxn + m_numComponents;
1686 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MINOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmin)) {
1687 if (m_VCount->Its >= maxit) {
1693 goto L_RETURN_BLOCK;
1696 if (m_debug_print_lvl >= 2) {
1697 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]].c_str());
1705 if (forceComponentCalc) {
1706 goto L_COMPONENT_CALC;
1708 goto L_MAINLOOP_ALL_SPECIES;
1712 if (m_debug_print_lvl >= 2) {
1713 plogf(
" CONVERGENCE achieved\n");
1728 if (!giveUpOnElemAbund) {
1730 if (m_debug_print_lvl >= 2) {
1731 plogf(
" --- Check the Full Element Abundances: ");
1739 if (! vcs_elabcheck(1)) {
1741 if (m_debug_print_lvl >= 2) {
1742 if (! vcs_elabcheck(0)) {
1745 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1750 goto L_ELEM_ABUND_CHECK;
1753 if (m_debug_print_lvl >= 2) {
1762 if (m_numSpeciesRdc != m_numSpeciesTot) {
1763 goto L_RECHECK_DELETED;
1766 goto L_RETURN_BLOCK;
1781 rangeErrorFound = 0;
1782 if (! vcs_elabcheck(1)) {
1783 bool ncBefore = vcs_elabcheck(0);
1785 bool ncAfter = vcs_elabcheck(0);
1786 bool neAfter = vcs_elabcheck(1);
1803 goto L_MAINLOOP_ALL_SPECIES;
1808 if (finalElemAbundAttempts >= 3) {
1809 giveUpOnElemAbund =
true;
1810 goto L_EQUILIB_CHECK;
1812 finalElemAbundAttempts++;
1815 goto L_MAINLOOP_ALL_SPECIES;
1826 goto L_EQUILIB_CHECK;
1832 if (m_debug_print_lvl >= 2) {
1833 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1834 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1835 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1836 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition ");
1840 rangeErrorFound = 1;
1841 giveUpOnElemAbund =
true;
1842 goto L_EQUILIB_CHECK;
1850 goto L_EQUILIB_CHECK;
1867 npb = vcs_recheck_deleted();
1872 goto L_RETURN_BLOCK_B;
1882 goto L_MAINLOOP_ALL_SPECIES;
1889 npb = vcs_recheck_deleted();
1902 goto L_MAINLOOP_ALL_SPECIES;
1912 npb = vcs_add_all_deleted();
1916 if (m_debug_print_lvl >= 1) {
1917 plogf(
" --- add_all_deleted(): some rxns not converged. RETURNING TO LOOP!");
1921 goto L_MAINLOOP_ALL_SPECIES;
1946 vcs_vdzero(m_molNumSpecies_new, m_numSpeciesTot);
1947 for (kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
1948 if (m_SSPhase[kspec]) {
1949 m_molNumSpecies_new[kspec] = 1.0;
1951 iph = m_phaseID[kspec];
1952 if (m_tPhaseMoles_old[iph] != 0.0) {
1953 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] / m_tPhaseMoles_old[iph];
1961 i = m_speciesLocalPhaseIndex[kspec];
1962 Vphase = m_VolPhaseList[iph];
1968 if (rangeErrorFound) {
1979 m_VCount->Time_vcs_TP = tsecond;
1980 m_VCount->T_Time_vcs_TP += m_VCount->Time_vcs_TP;
1981 (m_VCount->T_Calls_vcs_TP)++;
1982 m_VCount->T_Its += m_VCount->Its;
1983 m_VCount->T_Basis_Opts += m_VCount->Basis_Opts;
1984 m_VCount->T_Time_basopt += m_VCount->Time_basopt;
1991 double VCS_SOLVE::vcs_minor_alt_calc(
size_t kspec,
size_t irxn,
bool* do_delete
1998 double w_kspec = m_molNumSpecies_old[kspec];
1999 double molNum_kspec_new;
2001 double dg_irxn = m_deltaGRxn_old[irxn];
2003 size_t iph = m_phaseID[kspec];
2007 if (w_kspec <= 0.0) {
2010 if (dg_irxn < -200.) {
2014 sprintf(ANOTE,
"minor species alternative calc");
2016 if (dg_irxn >= 23.0) {
2017 molNum_kspec_new = w_kspec * 1.0e-10;
2019 goto L_ZERO_SPECIES;
2021 return molNum_kspec_new - w_kspec;
2023 if (fabs(dg_irxn) <= m_tolmin2) {
2024 molNum_kspec_new = w_kspec;
2032 s = m_np_dLnActCoeffdMolNum[kspec][kspec] / (m_tPhaseMoles_old[iph]);
2049 if (a < (-1.0 + 1.0E-8)) {
2051 }
else if (a > 100.0) {
2054 tmp = -dg_irxn / (1.0 + a);
2057 }
else if (tmp > 200.) {
2060 wTrial = w_kspec * exp(tmp);
2063 molNum_kspec_new = wTrial;
2065 if (wTrial > 100. * w_kspec) {
2066 double molNumMax = 0.0001 * m_tPhaseMoles_old[iph];
2067 if (molNumMax < 100. * w_kspec) {
2068 molNumMax = 100. * w_kspec;
2070 if (wTrial > molNumMax) {
2071 molNum_kspec_new = molNumMax;
2073 molNum_kspec_new = wTrial;
2076 }
else if (1.0E10 * wTrial < w_kspec) {
2077 molNum_kspec_new= 1.0E-10 * w_kspec;
2079 molNum_kspec_new = wTrial;
2084 goto L_ZERO_SPECIES;
2086 return molNum_kspec_new - w_kspec;
2102 dx = m_deltaGRxn_old[irxn]/ m_Faraday_dim;
2104 sprintf(ANOTE,
"voltage species alternative calc");
2110 int VCS_SOLVE::delta_species(
const size_t kspec,
double*
const delta_ptr)
2112 size_t irxn = kspec - m_numComponents;
2115 double delta = *delta_ptr;
2117 if (kspec < m_numComponents) {
2118 plogf(
" --- delete_species() ERROR: called for a component %d", kspec);
2129 double* sc_irxn = m_stoichCoeffRxnMatrix[irxn];
2130 for (
size_t j = 0; j < m_numComponents; ++j) {
2131 if (m_molNumSpecies_old[j] > 0.0) {
2132 tmp = sc_irxn[j] * dx;
2133 if (-tmp > m_molNumSpecies_old[j]) {
2135 dx = std::min(dx, - m_molNumSpecies_old[j] / sc_irxn[j]);
2142 if (m_molNumSpecies_old[j] <= 0.0) {
2143 if (sc_irxn[j] < 0.0) {
2153 m_molNumSpecies_old[kspec] += dx;
2154 size_t iph = m_phaseID[kspec];
2155 m_tPhaseMoles_old[iph] += dx;
2158 for (
size_t j = 0; j < m_numComponents; ++j) {
2159 tmp = sc_irxn[j] * dx;
2162 m_molNumSpecies_old[j] += tmp;
2163 m_tPhaseMoles_old[iph] += tmp;
2165 if (m_molNumSpecies_old[j] < 0.0) {
2166 m_molNumSpecies_old[j] = 0.0;
2174 int VCS_SOLVE::vcs_zero_species(
const size_t kspec)
2181 double dx = -(m_molNumSpecies_old[kspec]);
2183 retn = delta_species(kspec, &dx);
2186 if (m_debug_print_lvl >= 1) {
2187 plogf(
"vcs_zero_species: Couldn't zero the species %d, "
2188 "did delta of %g. orig conc of %g",
2189 kspec, dx, m_molNumSpecies_old[kspec] + dx);
2199 int VCS_SOLVE::vcs_delete_species(
const size_t kspec)
2201 const size_t klast = m_numSpeciesRdc - 1;
2202 const size_t iph = m_phaseID[kspec];
2204 const size_t irxn = kspec - m_numComponents;
2209 const int retn = vcs_zero_species(kspec);
2210 if (DEBUG_MODE_ENABLED && !retn) {
2211 plogf(
"Failed to delete a species!");
2220 --(m_numRxnMinorZeroed);
2223 m_deltaGRxn_new[irxn] = 0.0;
2224 m_deltaGRxn_old[irxn] = 0.0;
2225 m_feSpecies_new[kspec] = 0.0;
2226 m_feSpecies_old[kspec] = 0.0;
2227 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
2232 if (kspec != klast) {
2233 vcs_switch_pos(
true, klast, kspec);
2246 --(m_numSpeciesRdc);
2252 if (! m_SSPhase[klast]) {
2254 bool stillExists =
false;
2255 for (
size_t k = 0; k < m_numSpeciesRdc; k++) {
2257 if (m_phaseID[k] == iph) {
2258 if (m_molNumSpecies_old[k] > 0.0) {
2266 vcs_delete_multiphase(iph);
2274 return (m_numRxnRdc == 0);
2277 void VCS_SOLVE::vcs_reinsert_deleted(
size_t kspec)
2281 size_t iph = m_phaseID[kspec];
2284 if (m_debug_print_lvl >= 2) {
2285 plogf(
" --- Add back a deleted species: %-12s\n", m_speciesName[kspec].c_str());
2294 delta_species(kspec, &dx);
2297 if (m_SSPhase[kspec]) {
2299 --(m_numRxnMinorZeroed);
2315 if (! m_SSPhase[kspec]) {
2318 for (k = 0; k < m_numSpeciesTot; k++) {
2319 if (m_phaseID[k] == iph) {
2331 ++(m_numSpeciesRdc);
2332 ++(m_numRxnMinorZeroed);
2334 if (kspec != (m_numSpeciesRdc - 1)) {
2338 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
2342 bool VCS_SOLVE::vcs_delete_multiphase(
const size_t iph)
2347 bool successful =
true;
2353 if (m_debug_print_lvl >= 2) {
2354 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName.c_str());
2361 for (kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
2362 if (m_phaseID[kspec] == iph) {
2367 dx = - (m_molNumSpecies_old[kspec]);
2370 int retn = delta_species(kspec, &dxTent);
2374 if (m_debug_print_lvl >= 2) {
2375 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
2376 iph, Vphase->
PhaseName.c_str(), m_speciesName[kspec].c_str());
2377 plogf(
" --- delta attempted: %g achieved: %g "
2378 " Zeroing it manually\n", dx, dxTent);
2381 m_molNumSpecies_old[kspec] = 0.0;
2382 m_molNumSpecies_new[kspec] = 0.0;
2383 m_deltaMolNumSpecies[kspec] = 0.0;
2390 m_molNumSpecies_old[kspec] = 0.0;
2391 m_molNumSpecies_new[kspec] = 0.0;
2392 m_deltaMolNumSpecies[kspec] = 0.0;
2403 double dj, dxWant, dxPerm = 0.0, dxPerm2 = 0.0;
2404 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
2405 if (m_phaseID[kcomp] == iph) {
2407 if (m_debug_print_lvl >= 2) {
2408 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
2409 kcomp, m_speciesName[kcomp].c_str(), m_molNumSpecies_old[kcomp]);
2412 if (m_molNumSpecies_old[kcomp] != 0.0) {
2413 for (kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
2414 irxn = kspec - m_numComponents;
2415 if (m_phaseID[kspec] != iph) {
2416 if (m_stoichCoeffRxnMatrix[irxn][kcomp] != 0.0) {
2417 dxWant = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix[irxn][kcomp];
2418 if (dxWant + m_molNumSpecies_old[kspec] < 0.0) {
2419 dxPerm = -m_molNumSpecies_old[kspec];
2421 for (
size_t jcomp = 0; kcomp < m_numComponents; ++kcomp) {
2422 if (jcomp != kcomp) {
2423 if (m_phaseID[jcomp] == iph) {
2426 dj = dxWant * m_stoichCoeffRxnMatrix[irxn][jcomp];
2427 if (dj + m_molNumSpecies_old[kcomp] < 0.0) {
2428 dxPerm2 = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix[irxn][jcomp];
2430 if (fabs(dxPerm2) < fabs(dxPerm)) {
2437 if (dxPerm != 0.0) {
2438 delta_species(kspec, &dxPerm);
2444 if (m_molNumSpecies_old[kcomp] != 0.0) {
2446 if (m_debug_print_lvl >= 2) {
2447 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
2448 kcomp, m_speciesName[kcomp].c_str(), m_molNumSpecies_old[kcomp]);
2449 plogf(
" --- zeroing it \n");
2452 m_molNumSpecies_old[kcomp] = 0.0;
2468 for (kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
2469 if (m_phaseID[kspec] == iph) {
2470 irxn = kspec - m_numComponents;
2471 m_molNumSpecies_old[kspec] = 0.0;
2472 m_molNumSpecies_new[kspec] = 0.0;
2473 m_deltaMolNumSpecies[kspec] = 0.0;
2477 ++(m_numSpeciesRdc);
2479 if (m_debug_print_lvl >= 2) {
2480 plogf(
" --- Make %s", m_speciesName[kspec].c_str());
2481 plogf(
" an active but zeroed species because its phase "
2485 if (kspec != (m_numSpeciesRdc - 1)) {
2489 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
2497 m_tPhaseMoles_old[iph] = 0.0;
2498 m_tPhaseMoles_new[iph] = 0.0;
2499 m_deltaPhaseMoles[iph] = 0.0;
2508 int VCS_SOLVE::vcs_recheck_deleted()
2511 size_t iph, kspec, irxn;
2514 if (m_debug_print_lvl >= 2) {
2515 plogf(
" --- Start rechecking deleted species in multispec phases\n");
2518 if (m_numSpeciesRdc == m_numSpeciesTot) {
2527 for (kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
2528 iph = m_phaseID[kspec];
2529 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_old[kspec])
2530 - m_lnMnaughtSpecies[kspec]
2531 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
2540 for (iph = 0; iph < m_numPhases; iph++) {
2541 if (m_tPhaseMoles_old[iph] > 0.0) {
2544 xtcutoff[iph] = 0.0;
2575 for (irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2576 kspec = m_indexRxnToSpecies[irxn];
2577 iph = m_phaseID[kspec];
2578 if (m_tPhaseMoles_old[iph] == 0.0) {
2579 if (m_deltaGRxn_new[irxn] < 0.0) {
2580 vcs_reinsert_deleted(kspec);
2583 m_molNumSpecies_old[kspec] = 0.0;
2585 }
else if (m_tPhaseMoles_old[iph] > 0.0) {
2586 if (m_deltaGRxn_new[irxn] < xtcutoff[iph]) {
2587 vcs_reinsert_deleted(kspec);
2595 bool VCS_SOLVE::recheck_deleted_phase(
const int iphase)
2609 irxn = kspec + m_numComponents;
2610 if (m_deltaGRxn_old[irxn] < 0.0) {
2616 double phaseDG = 1.0;
2617 for (
size_t kk = 0; kk < Vphase->
nSpecies(); kk++) {
2619 irxn = kspec + m_numComponents;
2620 if (m_deltaGRxn_old[irxn] > 50.0) {
2621 m_deltaGRxn_old[irxn] = 50.0;
2623 if (m_deltaGRxn_old[irxn] < -50.0) {
2624 m_deltaGRxn_old[irxn] = -50.0;
2626 phaseDG -= exp(-m_deltaGRxn_old[irxn]);
2629 if (phaseDG < 0.0) {
2635 size_t VCS_SOLVE::vcs_add_all_deleted()
2637 size_t iph, kspec, retn;
2638 if (m_numSpeciesRdc == m_numSpeciesTot) {
2649 for (
int cits = 0; cits < 3; cits++) {
2650 for (kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
2651 iph = m_phaseID[kspec];
2653 if (m_molNumSpecies_new[kspec] == 0.0) {
2659 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_new[kspec]) - m_lnMnaughtSpecies[kspec]
2660 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
2666 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2667 kspec = m_indexRxnToSpecies[irxn];
2668 iph = m_phaseID[kspec];
2669 if (m_tPhaseMoles_old[iph] > 0.0) {
2670 double maxDG = std::min(m_deltaGRxn_new[irxn], 690.0);
2671 double dx = m_tPhaseMoles_old[iph] * exp(- maxDG);
2672 m_molNumSpecies_new[kspec] = dx;
2676 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2677 kspec = m_indexRxnToSpecies[irxn];
2678 iph = m_phaseID[kspec];
2679 if (m_tPhaseMoles_old[iph] > 0.0) {
2680 double dx = m_molNumSpecies_new[kspec];
2681 retn = delta_species(kspec, &dx);
2684 if (m_debug_print_lvl) {
2685 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
2686 m_speciesName[kspec].c_str(), kspec, dx);
2691 retn = delta_species(kspec, &dx);
2694 if (m_debug_print_lvl) {
2695 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
2696 m_speciesName[kspec].c_str(), kspec, dx);
2703 if (m_debug_print_lvl >= 2) {
2705 plogf(
" --- add_deleted(): species %s added back in with mol number %g",
2706 m_speciesName[kspec].c_str(), dx);
2709 plogf(
" --- add_deleted(): species %s failed to be added back in");
2721 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
2722 kspec = m_indexRxnToSpecies[irxn];
2723 iph = m_phaseID[kspec];
2724 if (m_tPhaseMoles_old[iph] > 0.0) {
2725 if (fabs(m_deltaGRxn_old[irxn]) > m_tolmin) {
2726 if (((m_molNumSpecies_old[kspec] * exp(-m_deltaGRxn_old[irxn])) >
2731 if (m_debug_print_lvl >= 2) {
2732 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g",
2733 m_speciesName[kspec].c_str(), m_molNumSpecies_old[kspec],
2734 m_deltaGRxn_old[irxn]);
2745 bool VCS_SOLVE::vcs_globStepDamp()
2748 size_t irxn, kspec, iph;
2755 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2756 kspec = irxn + m_numComponents;
2758 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2768 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2769 kspec = irxn + m_numComponents;
2771 s1 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2776 if (m_debug_print_lvl >= 2) {
2777 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
2778 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
2784 if (m_debug_print_lvl >= 2) {
2785 plogf(
" --- subroutine FORCE produced no adjustments,");
2787 plogf(
" s1 positive but really small");
2789 plogf(
" failed s1 test");
2799 if (m_debug_print_lvl >= 2) {
2800 plogf(
" --- subroutine FORCE produced no adjustments, s2 < 0");
2811 if (fabs(s1 -s2) > 1.0E-200) {
2812 al = s1 / (s1 - s2);
2814 if (al >= 0.95 || al < 0.0) {
2816 if (m_debug_print_lvl >= 2) {
2817 plogf(
" --- subroutine FORCE produced no adjustments (al = %g)\n", al);
2823 if (m_debug_print_lvl >= 2) {
2824 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
2832 if (m_debug_print_lvl >= 2) {
2839 for (kspec = 0; kspec < m_numSpeciesRdc; ++kspec) {
2840 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] +
2841 al * m_deltaMolNumSpecies[kspec];
2843 for (iph = 0; iph < m_numPhases; iph++) {
2844 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + al * m_deltaPhaseMoles[iph];
2849 if (m_debug_print_lvl >= 2) {
2850 plogf(
" --- subroutine FORCE adjusted the mole "
2851 "numbers, AL = %10.3f\n", al);
2871 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2872 kspec = irxn + m_numComponents;
2874 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2880 if (m_debug_print_lvl >= 2) {
2881 plogf(
" --- subroutine FORCE: Adj End Slope = %g", s2);
2888 int VCS_SOLVE::vcs_basopt(
const bool doJustComponents,
double aw[],
double sa[],
double sm[],
2889 double ss[],
double test,
bool*
const usedZeroedSpecies)
2891 size_t j, k, l, i, jl, ml, jr, irxn, kspec;
2895 size_t jlose =
npos;
2896 double* dptr, *scrxn_ptr;
2899 if (m_debug_print_lvl >= 2) {
2901 for (i=0; i<77; i++) {
2905 plogf(
" --- Subroutine BASOPT called to ");
2906 if (doJustComponents) {
2907 plogf(
"calculate the number of components\n");
2909 plogf(
"reevaluate the components\n");
2911 if (m_debug_print_lvl >= 2) {
2913 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
2914 plogf(
" --- Active | ");
2915 for (j = 0; j < m_numElemConstraints; j++) {
2916 plogf(
" %1d ", m_elementActive[j]);
2919 plogf(
" --- Species | ");
2920 for (j = 0; j < m_numElemConstraints; j++) {
2925 for (k = 0; k < m_numSpeciesTot; k++) {
2929 for (j = 0; j < m_numElemConstraints; j++) {
2930 plogf(
" %8.2g", m_formulaMatrix[j][k]);
2944 ncTrial = std::min(m_numElemConstraints, m_numSpeciesTot);
2945 m_numComponents = ncTrial;
2946 *usedZeroedSpecies =
false;
2951 vcs_dcopy(aw,
VCS_DATA_PTR(m_molNumSpecies_old), m_numSpeciesTot);
2955 for (k = 0; k < m_numSpeciesTot; k++) {
2977 k = vcs_basisOptMax(aw, jr, m_numSpeciesTot);
3019 *usedZeroedSpecies =
true;
3021 double maxConcPossKspec = 0.0;
3022 double maxConcPoss = 0.0;
3023 size_t kfound =
npos;
3024 int minNonZeroes = 100000;
3025 int nonZeroesKspec = 0;
3026 for (kspec = ncTrial; kspec < m_numSpeciesTot; kspec++) {
3027 if (aw[kspec] >= 0.0) {
3029 maxConcPossKspec = 1.0E10;
3031 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3032 if (m_elementActive[j]) {
3034 double nu = m_formulaMatrix[j][kspec];
3037 maxConcPossKspec = std::min(m_elemAbundancesGoal[j] / nu, maxConcPossKspec);
3042 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
3043 if (nonZeroesKspec <= minNonZeroes) {
3044 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
3048 if (m_SSfeSpecies[kspec] <= m_SSfeSpecies[kfound]) {
3053 if (nonZeroesKspec < minNonZeroes) {
3054 minNonZeroes = nonZeroesKspec;
3056 if (maxConcPossKspec > maxConcPoss) {
3057 maxConcPoss = maxConcPossKspec;
3063 if (kfound ==
npos) {
3066 for (kspec = ncTrial; kspec < m_numSpeciesTot; kspec++) {
3067 if (aw[kspec] >= 0.0) {
3068 irxn = kspec - ncTrial;
3069 if (m_deltaGRxn_new[irxn] < gmin) {
3070 gmin = m_deltaGRxn_new[irxn];
3080 if (aw[k] == test) {
3081 m_numComponents = jr;
3082 ncTrial = m_numComponents;
3083 size_t numPreDeleted = m_numRxnTot - m_numRxnRdc;
3084 if (numPreDeleted != (m_numSpeciesTot - m_numSpeciesRdc)) {
3085 plogf(
"vcs_basopt:: we shouldn't be here\n");
3088 m_numRxnTot = m_numSpeciesTot - ncTrial;
3089 m_numRxnRdc = m_numRxnTot - numPreDeleted;
3090 m_numSpeciesRdc = m_numSpeciesTot - numPreDeleted;
3091 for (i = 0; i < m_numSpeciesTot; ++i) {
3092 m_indexRxnToSpecies[i] = ncTrial + i;
3095 if (m_debug_print_lvl >= 2) {
3096 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
3097 ncTrial, m_numElemConstraints);
3115 for (j = 0; j < m_numElemConstraints; ++j) {
3116 sm[j + jr*m_numElemConstraints] = m_formulaMatrix[j][k];
3125 for (j = 0; j < jl; ++j) {
3127 for (i = 0; i < m_numElemConstraints; ++i) {
3128 ss[j] += sm[i + jr*m_numElemConstraints] * sm[i + j*m_numElemConstraints];
3136 for (j = 0; j < jl; ++j) {
3137 for (l = 0; l < m_numElemConstraints; ++l) {
3138 sm[l + jr*m_numElemConstraints] -= ss[j] * sm[l + j*m_numElemConstraints];
3147 for (ml = 0; ml < m_numElemConstraints; ++ml) {
3148 sa[jr] += SQUARE(sm[ml + jr*m_numElemConstraints]);
3153 lindep = (sa[jr] < 1.0e-6);
3160 if (m_debug_print_lvl >= 2) {
3161 plogf(
" --- %-12.12s", (m_speciesName[k]).c_str());
3163 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[k]);
3165 plogf(
"(%9.2g)", m_molNumSpecies_old[k]);
3167 plogf(
" replaces %-12.12s", m_speciesName[jr].c_str());
3169 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[jr]);
3171 plogf(
"(%9.2g)", m_molNumSpecies_old[jr]);
3173 plogf(
" as component %3d\n", jr);
3176 vcs_switch_pos(
false, jr, k);
3177 std::swap(aw[jr], aw[k]);
3181 if (m_debug_print_lvl >= 2) {
3182 plogf(
" --- %-12.12s", m_speciesName[k].c_str());
3184 plogf(
"(Volts = %9.2g) remains ", m_molNumSpecies_old[k]);
3186 plogf(
"(%9.2g) remains ", m_molNumSpecies_old[k]);
3188 plogf(
" as component %3d\n", jr);
3200 }
while (jr < (ncTrial-1));
3202 if (doJustComponents) {
3239 for (j = 0; j < ncTrial; ++j) {
3240 for (i = 0; i < ncTrial; ++i) {
3241 sm[i + j*m_numElemConstraints] = m_formulaMatrix[i][j];
3244 for (i = 0; i < m_numRxnTot; ++i) {
3245 k = m_indexRxnToSpecies[i];
3246 for (j = 0; j < ncTrial; ++j) {
3247 m_stoichCoeffRxnMatrix[i][j] = m_formulaMatrix[j][k];
3255 j =
vcsUtil_gaussj(sm, m_numElemConstraints, ncTrial, m_stoichCoeffRxnMatrix[0], m_numRxnTot);
3260 plogf(
"vcs_solve_TP ERROR: mlequ returned an error condition\n");
3261 return VCS_FAILED_CONVERGENCE;
3271 for (j = 0; j < m_numElemConstraints; j++) {
3272 if (!(m_elementActive[j])) {
3273 if (!strcmp((m_elementName[j]).c_str(),
"E")) {
3278 for (j = 0; j < m_numElemConstraints; j++) {
3279 if (m_elementActive[j]) {
3280 if (!strncmp((m_elementName[j]).c_str(),
"cn_", 3)) {
3285 for (k = 0; k < m_numSpeciesTot; k++) {
3288 for (j = 0; j < ncTrial; ++j) {
3289 for (i = 0; i < ncTrial; ++i) {
3291 sm[i + j*m_numElemConstraints] = m_formulaMatrix[juse][j];
3293 sm[i + j*m_numElemConstraints] = m_formulaMatrix[i][j];
3297 for (i = 0; i < m_numRxnTot; ++i) {
3298 k = m_indexRxnToSpecies[i];
3299 for (j = 0; j < ncTrial; ++j) {
3301 aw[j] = m_formulaMatrix[juse][k];
3303 aw[j] = m_formulaMatrix[j][k];
3311 plogf(
"vcs_solve_TP ERROR: mlequ returned an error condition\n");
3312 return VCS_FAILED_CONVERGENCE;
3315 for (j = 0; j < ncTrial; j++) {
3316 m_stoichCoeffRxnMatrix[i][j] = aw[j];
3325 for (i = 0; i < m_numRxnTot; i++) {
3327 for (j = 0; j < ncTrial; j++) {
3328 szTmp += fabs(m_stoichCoeffRxnMatrix[i][j]);
3330 m_scSize[i] = szTmp;
3335 if (m_debug_print_lvl >= 2) {
3336 plogf(
" --- Components:");
3337 for (j = 0; j < ncTrial; j++) {
3340 plogf(
"\n --- Components Moles:");
3341 for (j = 0; j < ncTrial; j++) {
3343 plogf(
" % -10.3E", 0.0);
3345 plogf(
" % -10.3E", m_molNumSpecies_old[j]);
3348 plogf(
"\n --- NonComponent| Moles |");
3349 for (j = 0; j < ncTrial; j++) {
3350 plogf(
" %10.10s", m_speciesName[j].c_str());
3354 for (i = 0; i < m_numRxnTot; i++) {
3355 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
3356 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]].c_str());
3358 plogf(
"|% -10.3E|", 0.0);
3360 plogf(
"|% -10.3E|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
3362 for (j = 0; j < ncTrial; j++) {
3363 plogf(
" %+7.3f", m_stoichCoeffRxnMatrix[i][j]);
3375 double sumMax = -1.0;
3379 for (i = 0; i < m_numRxnTot; ++i) {
3380 k = m_indexRxnToSpecies[i];
3381 for (j = 0; j < ncTrial; ++j) {
3383 sum = m_formulaMatrix[juse][k];
3384 for (n = 0; n < ncTrial; n++) {
3385 double numElements = m_formulaMatrix[juse][n];
3386 double coeff = m_stoichCoeffRxnMatrix[i][n];
3387 sum += coeff * numElements;
3390 sum = m_formulaMatrix[j][k];
3391 for (n = 0; n < ncTrial; n++) {
3392 double numElements = m_formulaMatrix[j][n];
3393 double coeff = m_stoichCoeffRxnMatrix[i][n];
3394 sum += coeff * numElements;
3397 if (fabs(sum) > sumMax) {
3405 if (fabs(sum) > 1.0E-6) {
3406 printf(
"we have a prob\n");
3411 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
3412 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[iMax]].c_str());
3413 plogf(
" element = %d ", jMax);
3414 plogf(
"%-5.5s", m_elementName[jMax].c_str());
3417 for (i=0; i<77; i++) {
3434 vcs_dzero(m_deltaMolNumPhase[0], (NSPECIES0)*(NPHASE0));
3435 vcs_izero(m_phaseParticipation[0], (NSPECIES0)*(NPHASE0));
3441 for (irxn = 0; irxn < m_numRxnTot; ++irxn) {
3442 scrxn_ptr = m_stoichCoeffRxnMatrix[irxn];
3443 dptr = m_deltaMolNumPhase[irxn];
3444 kspec = m_indexRxnToSpecies[irxn];
3445 size_t iph = m_phaseID[kspec];
3446 int* pp_ptr = m_phaseParticipation[irxn];
3449 for (j = 0; j < ncTrial; ++j) {
3451 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
3454 dptr[iph] += scrxn_ptr[j];
3463 m_VCount->Time_basopt += tsecond;
3464 (m_VCount->Basis_Opts)++;
3468 size_t VCS_SOLVE::vcs_basisOptMax(
const double*
const molNum,
const size_t j,
3487 double big = molNum[j] * m_spSize[j] * 1.01;
3488 if (m_spSize[j] <= 0.0) {
3490 "spSize is nonpositive");
3492 for (
size_t i = j + 1; i < n; ++i) {
3493 if (m_spSize[i] <= 0.0) {
3495 "spSize is nonpositive");
3497 bool doSwap =
false;
3499 doSwap = (molNum[i] * m_spSize[i]) > (big);
3500 if (!m_SSPhase[i]) {
3502 doSwap = (molNum[i]) > (molNum[largest] * 1.001);
3507 doSwap = (molNum[i] * m_spSize[i]) > (big);
3509 doSwap = (molNum[i]) > (molNum[largest] * 1.001);
3512 doSwap = (molNum[i] * m_spSize[i]) > (big);
3517 big = molNum[i] * m_spSize[i] * 1.01;
3523 int VCS_SOLVE::vcs_species_type(
const size_t kspec)
const
3533 size_t iph = m_phaseID[kspec];
3534 int irxn = int(kspec) - int(m_numComponents);
3536 int phaseExist = VPhase->
exists();
3540 if (m_molNumSpecies_old[kspec] <= 0.0) {
3542 if (m_tPhaseMoles_old[iph] <= 0.0) {
3543 if (!m_SSPhase[kspec]) {
3553 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3554 int elType = m_elType[j];
3556 double atomComp = m_formulaMatrix[j][kspec];
3557 if (atomComp > 0.0) {
3558 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
3561 if (m_debug_print_lvl >= 2) {
3562 plogf(
" --- %s can not be nonzero because"
3563 " needed element %s is zero\n",
3564 m_speciesName[kspec].c_str(), (m_elementName[j]).c_str());
3567 if (m_SSPhase[kspec]) {
3587 for (
size_t j = 0; j < m_numComponents; ++j) {
3588 double stoicC = m_stoichCoeffRxnMatrix[irxn][j];
3589 if (stoicC != 0.0) {
3590 double negChangeComp = - stoicC;
3591 if (negChangeComp > 0.0) {
3592 if (m_molNumSpecies_old[j] < 1.0E-60) {
3594 if (m_debug_print_lvl >= 2) {
3595 plogf(
" --- %s is prevented from popping into existence because"
3596 " a needed component to be consumed, %s, has a zero mole number\n",
3597 m_speciesName[kspec].c_str(), m_speciesName[j].c_str());
3600 if (m_SSPhase[kspec]) {
3606 }
else if (negChangeComp < 0.0) {
3607 size_t jph = m_phaseID[j];
3609 if (jVPhase->
exists() <= 0) {
3611 if (m_debug_print_lvl >= 2) {
3612 plogf(
" --- %s is prevented from popping into existence because"
3613 " a needed component %s is in a zeroed-phase that would be "
3614 "popped into existence at the same time\n",
3615 m_speciesName[kspec].c_str(), m_speciesName[j].c_str());
3618 if (m_SSPhase[kspec]) {
3630 if (m_deltaGRxn_old[irxn] >= 0.0) {
3634 if (m_SSPhase[kspec]) {
3650 if (m_tPhaseMoles_old[iph] > 0.0) {
3651 if (m_SSPhase[kspec]) {
3667 if (m_tPhaseMoles_old[iph] <= 0.0) {
3668 if (m_SSPhase[kspec]) {
3682 if (m_SSPhase[kspec]) {
3693 if (m_molNumSpecies_old[kspec] > (m_tPhaseMoles_old[iph] * 0.001)) {
3708 double szAdj = m_scSize[irxn] * std::sqrt((
double)m_numRxnTot);
3709 for (
size_t k = 0; k < m_numComponents; ++k) {
3710 if (!(m_SSPhase[k])) {
3711 if (m_stoichCoeffRxnMatrix[irxn][k] != 0.0) {
3712 if (m_molNumSpecies_old[kspec] * szAdj >= m_molNumSpecies_old[k] * 0.01) {
3722 void VCS_SOLVE::vcs_chemPotPhase(
const int stateCalc,
3723 const size_t iph,
const double*
const molNum,
3724 double*
const ac,
double*
const mu_i,
3725 const bool do_deleted)
3738 double tMoles = TPhInertMoles[iph];
3739 for (k = 0; k < nkk; k++) {
3741 tMoles += molNum[kspec];
3743 double tlogMoles = 0.0;
3745 tlogMoles = log(tMoles);
3752 double Faraday_phi = m_Faraday_dim * phi;
3754 for (k = 0; k < nkk; k++) {
3756 if (kspec >= m_numComponents) {
3764 if (molNum[kspec] != phi) {
3765 plogf(
"We have an inconsistency!\n");
3768 if (m_chargeSpecies[kspec] != -1.0) {
3769 plogf(
"We have an unexpected situation!\n");
3773 mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3775 if (m_SSPhase[kspec]) {
3776 mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3779 - tlogMoles - m_lnMnaughtSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3781 mu_i[kspec] = m_SSfeSpecies[kspec] + log(ac[kspec] * molNum[kspec])
3782 - tlogMoles - m_lnMnaughtSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
3788 void VCS_SOLVE::vcs_dfe(
const int stateCalc,
3789 const int ll,
const size_t lbot,
const size_t ltop)
3791 size_t l1, l2, iph, kspec, irxn;
3793 double* tPhMoles_ptr=0;
3794 double* actCoeff_ptr=0;
3795 double* tlogMoles=0;
3798 double* feSpecies=0;
3813 plogf(
"vcs_dfe: wrong stateCalc value");
3814 plogf(
" --- Subroutine vcs_dfe called with bad stateCalc value: %d", stateCalc);
3822 printf(
"vcs_dfe: called with wrong units state\n");
3828 if (m_debug_print_lvl >= 2) {
3831 plogf(
" --- Subroutine vcs_dfe called for one species: ");
3832 plogf(
"%-12.12s", m_speciesName[lbot].c_str());
3834 plogf(
" --- Subroutine vcs_dfe called for all species");
3836 }
else if (ll > 0) {
3837 plogf(
" --- Subroutine vcs_dfe called for components and minors");
3839 plogf(
" --- Subroutine vcs_dfe called for components and majors");
3842 plogf(
" using tentative solution");
3854 for (iph = 0; iph < m_numPhases; iph++) {
3855 tlogMoles[iph] = tPhInertMoles[iph];
3858 for (kspec = 0; kspec < m_numSpeciesTot; kspec++) {
3860 iph = m_phaseID[kspec];
3861 tlogMoles[iph] += molNum[kspec];
3865 for (iph = 0; iph < m_numPhases; iph++) {
3867 plogf(
"phase Moles may be off, iph = %d, %20.14g %20.14g \n",
3868 iph, tlogMoles[iph], tPhMoles_ptr[iph]);
3873 vcs_dzero(tlogMoles, m_numPhases);
3874 for (iph = 0; iph < m_numPhases; iph++) {
3875 if (tPhMoles_ptr[iph] > 0.0) {
3876 tlogMoles[iph] = log(tPhMoles_ptr[iph]);
3883 l2 = m_numComponents;
3894 for (iphase = 0; iphase < m_numPhases; iphase++) {
3895 Vphase = m_VolPhaseList[iphase];
3911 for (kspec = l1; kspec < l2; ++kspec) {
3912 iphase = m_phaseID[kspec];
3915 if (molNum[kspec] != m_phasePhi[iphase]) {
3916 plogf(
"We have an inconsistency!\n");
3919 if (m_chargeSpecies[kspec] != -1.0) {
3920 plogf(
"We have an unexpected situation!\n");
3924 feSpecies[kspec] = m_SSfeSpecies[kspec]
3925 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3927 if (m_SSPhase[kspec]) {
3928 feSpecies[kspec] = m_SSfeSpecies[kspec]
3929 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3932 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3933 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3936 iph = m_phaseID[kspec];
3937 if (tPhMoles_ptr[iph] > 0.0) {
3938 feSpecies[kspec] = m_SSfeSpecies[kspec]
3940 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3941 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3943 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3944 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3947 feSpecies[kspec] = m_SSfeSpecies[kspec]
3948 + log(actCoeff_ptr[kspec] * molNum[kspec])
3949 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3950 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3959 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3960 kspec = m_indexRxnToSpecies[irxn];
3962 iphase = m_phaseID[kspec];
3965 if (molNum[kspec] != m_phasePhi[iphase]) {
3966 plogf(
"We have an inconsistency!\n");
3969 if (m_chargeSpecies[kspec] != -1.0) {
3970 plogf(
"We have an unexpected situation!\n");
3974 feSpecies[kspec] = m_SSfeSpecies[kspec]
3975 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3977 if (m_SSPhase[kspec]) {
3978 feSpecies[kspec] = m_SSfeSpecies[kspec]
3979 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3982 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3983 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3986 iph = m_phaseID[kspec];
3987 if (tPhMoles_ptr[iph] > 0.0) {
3988 feSpecies[kspec] = m_SSfeSpecies[kspec]
3990 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3991 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3993 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3994 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3997 feSpecies[kspec] = m_SSfeSpecies[kspec]
3998 + log(actCoeff_ptr[kspec] * molNum[kspec])
3999 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
4000 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
4009 }
else if (ll > 0) {
4010 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
4011 kspec = m_indexRxnToSpecies[irxn];
4013 iphase = m_phaseID[kspec];
4016 if (molNum[kspec] != m_phasePhi[iphase]) {
4017 plogf(
"We have an inconsistency!\n");
4020 if (m_chargeSpecies[kspec] != -1.0) {
4021 plogf(
"We have an unexpected situation!\n");
4025 feSpecies[kspec] = m_SSfeSpecies[kspec]
4026 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase]; ;
4028 if (m_SSPhase[kspec]) {
4029 feSpecies[kspec] = m_SSfeSpecies[kspec]
4030 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
4033 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
4034 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
4037 iph = m_phaseID[kspec];
4038 if (tPhMoles_ptr[iph] > 0.0) {
4039 feSpecies[kspec] = m_SSfeSpecies[kspec]
4041 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
4042 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
4044 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
4045 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
4048 feSpecies[kspec] = m_SSfeSpecies[kspec]
4049 + log(actCoeff_ptr[kspec] * molNum[kspec])
4050 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
4051 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
4062 void VCS_SOLVE::vcs_printSpeciesChemPot(
const int stateCalc)
const
4064 double mfValue = 1.0;
4065 bool zeroedPhase =
false;
4068 const double* molNum =
VCS_DATA_PTR(m_molNumSpecies_old);
4069 const double* actCoeff_ptr =
VCS_DATA_PTR(m_actCoeffSpecies_old);
4076 const double* tPhInertMoles =
VCS_DATA_PTR(TPhInertMoles);
4077 for (
size_t iph = 0; iph < m_numPhases; iph++) {
4078 tMoles[iph] = tPhInertMoles[iph];
4080 for (kspec = 0; kspec < m_numSpeciesTot; kspec++) {
4082 size_t iph = m_phaseID[kspec];
4083 tMoles[iph] += molNum[kspec];
4088 printf(
" --- CHEMICAL POT TABLE (J/kmol) Name PhID MolFR ChemoSS "
4089 " logMF Gamma Elect extra ElectrChem\n");
4093 for (kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
4095 size_t iphase = m_phaseID[kspec];
4102 zeroedPhase =
false;
4104 if (tMoles[iphase] > 0.0) {
4108 mfValue = molNum[kspec]/tMoles[iphase];
4111 size_t klocal = m_speciesLocalPhaseIndex[kspec];
4112 mfValue = Vphase->moleFraction(klocal);
4115 double elect = m_chargeSpecies[kspec] * m_Faraday_dim * volts;
4116 double comb = - m_lnMnaughtSpecies[kspec];
4117 double total = (m_SSfeSpecies[kspec] + log(mfValue) + elect + log(actCoeff_ptr[kspec]) + comb);
4120 printf(
" --- ** zp *** ");
4124 printf(
"%-24.24s", m_speciesName[kspec].c_str());
4126 printf(
" % -12.4e", mfValue);
4127 printf(
" % -12.4e", m_SSfeSpecies[kspec] * RT);
4128 printf(
" % -12.4e", log(mfValue) * RT);
4129 printf(
" % -12.4e", log(actCoeff_ptr[kspec]) * RT);
4130 printf(
" % -12.4e", elect * RT);
4131 printf(
" % -12.4e", comb * RT);
4132 printf(
" % -12.4e\n", total *RT);
4139 void VCS_SOLVE::prneav()
const
4143 std::vector<double> eav(m_numElemConstraints, 0.0);
4145 for (j = 0; j < m_numElemConstraints; ++j) {
4146 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
4148 eav[j] += m_formulaMatrix[j][i] * m_molNumSpecies_old[i];
4153 plogf(
"--------------------------------------------------");
4154 plogf(
"ELEMENT ABUNDANCE VECTOR:\n");
4155 plogf(
" Element Now Orignal Deviation Type\n");
4156 for (j = 0; j < m_numElemConstraints; ++j) {
4158 plogf(
"%-2.2s", (m_elementName[j]).c_str());
4159 plogf(
" = %15.6E %15.6E %15.6E %3d\n",
4160 eav[j], m_elemAbundancesGoal[j], eav[j] - m_elemAbundancesGoal[j], m_elType[j]);
4161 if (m_elemAbundancesGoal[j] != 0.) {
4162 if (fabs(eav[j] - m_elemAbundancesGoal[j]) > m_elemAbundancesGoal[j] * 5.0e-9) {
4166 if (fabs(eav[j]) > 1.0e-10) {
4172 plogf(
"Element abundance check failure\n");
4174 plogf(
"--------------------------------------------------");
4179 double VCS_SOLVE::l2normdg(
double dgLocal[])
const
4183 if (m_numRxnRdc <= 0) {
4186 for (irxn = 0, tmp = 0.0; irxn < m_numRxnRdc; ++irxn) {
4187 size_t kspec = irxn + m_numComponents;
4189 dgLocal[irxn] < 0.0) {
4191 tmp += dgLocal[irxn] * dgLocal[irxn];
4195 return std::sqrt(tmp / m_numRxnRdc);
4198 double VCS_SOLVE::vcs_tmoles()
4202 for (
size_t i = 0; i < m_numPhases; i++) {
4203 m_tPhaseMoles_old[i] = TPhInertMoles[i];
4205 for (
size_t i = 0; i < m_numSpeciesTot; i++) {
4207 m_tPhaseMoles_old[m_phaseID[i]] += m_molNumSpecies_old[i];
4211 for (
size_t i = 0; i < m_numPhases; i++) {
4212 sum += m_tPhaseMoles_old[i];
4213 Vphase = m_VolPhaseList[i];
4216 if (m_tPhaseMoles_old[i] == 0.0) {
4222 m_totalMolNum = sum;
4223 return m_totalMolNum;
4227 void VCS_SOLVE::check_tmoles()
const
4231 for (i = 0; i < m_numPhases; i++) {
4232 double m_tPhaseMoles_old_a = TPhInertMoles[i];
4234 for (
size_t k = 0; k < m_numSpeciesTot; k++) {
4236 if (m_phaseID[k] == i) {
4237 m_tPhaseMoles_old_a += m_molNumSpecies_old[k];
4241 sum += m_tPhaseMoles_old_a;
4243 double denom = m_tPhaseMoles_old[i]+ m_tPhaseMoles_old_a + 1.0E-19;
4244 if (!
vcs_doubleEqual(m_tPhaseMoles_old[i]/denom, m_tPhaseMoles_old_a/denom)) {
4245 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
4246 i, m_tPhaseMoles_old[i], m_tPhaseMoles_old_a);
4252 void VCS_SOLVE::vcs_updateVP(
const int vcsState)
4255 for (
size_t i = 0; i < m_numPhases; i++) {
4256 Vphase = m_VolPhaseList[i];
4268 plogf(
"vcs_updateVP ERROR: wrong stateCalc value: %d", vcsState);
4276 bool VCS_SOLVE::vcs_evaluate_speciesType()
4278 m_numRxnMinorZeroed = 0;
4280 if (m_debug_print_lvl >= 2) {
4281 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
4282 }
else if (m_debug_print_lvl >= 5) {
4283 plogf(
" --- Species Status decision is reevaluated");
4287 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
4288 m_speciesStatus[kspec] = vcs_species_type(kspec);
4290 if (m_debug_print_lvl >= 5) {
4291 plogf(
" --- %-16s: ", m_speciesName[kspec].c_str());
4292 if (kspec < m_numComponents) {
4297 plogf(
" %10.3g ", m_molNumSpecies_old[kspec]);
4299 plogf(
"%s\n", sString);
4301 }
else if (m_debug_print_lvl >= 2) {
4303 switch (m_speciesStatus[kspec]) {
4307 plogf(
" --- Major Species : %-s\n", m_speciesName[kspec].c_str());
4310 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
4311 m_speciesName[kspec].c_str());
4314 plogf(
" --- Zeroed-MS Phase Species: %-s\n", m_speciesName[kspec].c_str());
4317 plogf(
" --- Zeroed-SS Phase Species: %-s\n", m_speciesName[kspec].c_str());
4320 plogf(
" --- Deleted-Small Species : %-s\n", m_speciesName[kspec].c_str());
4323 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
4324 m_speciesName[kspec].c_str());
4327 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
4328 m_speciesName[kspec].c_str());
4331 plogf(
" --- InterfaceVoltage Species: %-s\n", m_speciesName[kspec].c_str());
4334 plogf(
" --- Unknown type - ERROR %d\n", m_speciesStatus[kspec]);
4341 if (kspec >= m_numComponents) {
4343 ++m_numRxnMinorZeroed;
4348 if (m_debug_print_lvl >= 2) {
4354 return (m_numRxnMinorZeroed >= m_numRxnRdc);
4357 void VCS_SOLVE::vcs_switch2D(
double*
const*
const Jac,
4358 const size_t k1,
const size_t k2)
const
4364 for (i = 0; i < m_numSpeciesTot; i++) {
4365 std::swap(Jac[k1][i], Jac[k2][i]);
4367 for (i = 0; i < m_numSpeciesTot; i++) {
4368 std::swap(Jac[i][k1], Jac[i][k2]);
4372 static void print_space(
size_t num)
4375 for (j = 0; j < num; j++) {
4380 void VCS_SOLVE::vcs_deltag(
const int l,
const bool doDeleted,
4381 const int vcsState,
const bool alterZeroedPhases)
4388 size_t irxnl = m_numRxnRdc;
4390 irxnl = m_numRxnTot;
4395 double* molNumSpecies;
4396 double* actCoeffSpecies;
4413 if (m_debug_print_lvl >= 2) {
4414 plogf(
" --- Subroutine vcs_deltag called for ");
4416 plogf(
"major noncomponents\n");
4417 }
else if (l == 0) {
4418 plogf(
"all noncomponents\n");
4420 plogf(
"minor noncomponents\n");
4428 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
4429 kspec = irxn + m_numComponents;
4432 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
4433 dtmp_ptr = m_stoichCoeffRxnMatrix[irxn];
4434 for (kspec = 0; kspec < m_numComponents; ++kspec) {
4435 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
4441 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
4445 }
else if (l == 0) {
4449 for (irxn = 0; irxn < irxnl; ++irxn) {
4451 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
4452 dtmp_ptr = m_stoichCoeffRxnMatrix[irxn];
4453 for (kspec = 0; kspec < m_numComponents; ++kspec) {
4454 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
4456 dtmp_ptr[kspec] < 0.0) {
4461 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
4468 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
4469 kspec = irxn + m_numComponents;
4472 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
4473 dtmp_ptr = m_stoichCoeffRxnMatrix[irxn];
4474 for (kspec = 0; kspec < m_numComponents; ++kspec) {
4475 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
4477 dtmp_ptr[kspec] < 0.0) {
4482 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
4530 if (alterZeroedPhases &&
false) {
4531 for (iph = 0; iph < m_numPhases; iph++) {
4536 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
4539 sum += molNumSpecies[kspec];
4552 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
4555 if (kspec >= m_numComponents) {
4556 irxn = kspec - m_numComponents;
4557 if (deltaGRxn[irxn] > 50.0) {
4558 deltaGRxn[irxn] = 50.0;
4560 if (deltaGRxn[irxn] < -50.0) {
4561 deltaGRxn[irxn] = -50.0;
4563 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
4571 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
4573 if (kspec >= m_numComponents) {
4574 irxn = kspec - m_numComponents;
4575 deltaGRxn[irxn] = 1.0 - poly;
4585 for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
4591 void VCS_SOLVE::vcs_printDeltaG(
const int stateCalc)
4596 double* molNumSpecies =
VCS_DATA_PTR(m_molNumSpecies_old);
4597 const double* tPhMoles_ptr =
VCS_DATA_PTR(m_tPhaseMoles_old);
4598 const double* actCoeff_ptr =
VCS_DATA_PTR(m_actCoeffSpecies_old);
4607 bool zeroedPhase =
false;
4608 if (m_debug_print_lvl >= 2) {
4609 plogf(
" --- DELTA_G TABLE Components:");
4610 for (j = 0; j < m_numComponents; j++) {
4613 plogf(
"\n --- Components Moles:");
4614 for (j = 0; j < m_numComponents; j++) {
4615 plogf(
"%10.3g", m_molNumSpecies_old[j]);
4617 plogf(
"\n --- NonComponent| Moles | ");
4618 for (j = 0; j < m_numComponents; j++) {
4619 plogf(
"%-10.10s", m_speciesName[j].c_str());
4623 for (
size_t i = 0; i < m_numRxnTot; i++) {
4624 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
4625 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]].c_str());
4629 plogf(
"|%10.3g|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
4631 for (j = 0; j < m_numComponents; j++) {
4632 plogf(
" %6.2f", m_stoichCoeffRxnMatrix[i][j]);
4638 for (
int i=0; i<77; i++) {
4644 printf(
" --- DeltaG Table (J/kmol) Name PhID MoleNum MolFR "
4645 " ElectrChemStar ElectrChem DeltaGStar DeltaG(Pred) Stability\n");
4649 for (
size_t kspec = 0; kspec < m_numSpeciesTot; kspec++) {
4652 if (kspec >= m_numComponents) {
4653 irxn = kspec - m_numComponents;
4656 double mfValue = 1.0;
4657 size_t iphase = m_phaseID[kspec];
4658 const vcs_VolPhase* Vphase = m_VolPhaseList[iphase];
4664 zeroedPhase =
false;
4666 if (tPhMoles_ptr[iphase] > 0.0) {
4670 mfValue = molNumSpecies[kspec] / tPhMoles_ptr[iphase];
4673 size_t klocal = m_speciesLocalPhaseIndex[kspec];
4674 mfValue = Vphase->moleFraction(klocal);
4677 printf(
" --- ** zp *** ");
4681 double feFull = feSpecies[kspec];
4684 feFull += log(actCoeff_ptr[kspec]) + log(mfValue);
4686 printf(
"%-24.24s", m_speciesName[kspec].c_str());
4691 printf(
" % -12.4e", molNumSpecies[kspec]);
4693 printf(
" % -12.4e", mfValue);
4694 printf(
" % -12.4e", feSpecies[kspec] * RT);
4695 printf(
" % -12.4e", feFull * RT);
4697 printf(
" % -12.4e", deltaGRxn[irxn] * RT);
4698 printf(
" % -12.4e", (deltaGRxn[irxn] + feFull - feSpecies[kspec]) * RT);
4700 if (deltaGRxn[irxn] < 0.0) {
4701 if (molNumSpecies[kspec] > 0.0) {
4706 }
else if (deltaGRxn[irxn] > 0.0) {
4707 if (molNumSpecies[kspec] > 0.0) {
4708 printf(
" shrinking");
4710 printf(
" unstable");
4713 printf(
" balanced");
4725 void VCS_SOLVE::vcs_deltag_Phase(
const size_t iphase,
const bool doDeleted,
4726 const int stateCalc,
const bool alterZeroedPhases)
4729 size_t irxn, kspec, kcomp;
4732 double* feSpecies=0;
4733 double* deltaGRxn=0;
4734 double* actCoeffSpecies=0;
4746 plogf(
"vcs_deltag_Phase: we shouldn't be here\n");
4752 size_t irxnl = m_numRxnRdc;
4754 irxnl = m_numRxnTot;
4759 if (m_debug_print_lvl >= 2) {
4760 plogf(
" --- Subroutine vcs_deltag_Phase called for phase %d\n",
4771 if (iphase != m_phaseID[kspec]) {
4772 plogf(
"vcs_deltag_Phase index error\n");
4776 if (kspec >= m_numComponents) {
4777 irxn = kspec - m_numComponents;
4778 deltaGRxn[irxn] = feSpecies[kspec];
4779 dtmp_ptr = m_stoichCoeffRxnMatrix[irxn];
4780 for (kcomp = 0; kcomp < m_numComponents; ++kcomp) {
4781 deltaGRxn[irxn] += dtmp_ptr[kcomp] * feSpecies[kcomp];
4789 bool zeroedPhase =
true;
4791 for (irxn = 0; irxn < irxnl; ++irxn) {
4792 kspec = m_indexRxnToSpecies[irxn];
4794 iph = m_phaseID[kspec];
4795 if (iph == iphase) {
4796 if (m_molNumSpecies_old[kspec] > 0.0) {
4797 zeroedPhase =
false;
4799 deltaGRxn[irxn] = feSpecies[kspec];
4800 dtmp_ptr = m_stoichCoeffRxnMatrix[irxn];
4801 for (kcomp = 0; kcomp < m_numComponents; ++kcomp) {
4802 deltaGRxn[irxn] += dtmp_ptr[kcomp] * feSpecies[kcomp];
4848 if (alterZeroedPhases) {
4850 double phaseDG = 1.0;
4851 for (irxn = 0; irxn < irxnl; ++irxn) {
4852 kspec = m_indexRxnToSpecies[irxn];
4853 iph = m_phaseID[kspec];
4854 if (iph == iphase) {
4855 if (deltaGRxn[irxn] > 50.0) {
4856 deltaGRxn[irxn] = 50.0;
4858 if (deltaGRxn[irxn] < -50.0) {
4859 deltaGRxn[irxn] = -50.0;
4861 phaseDG -= exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
4867 for (irxn = 0; irxn < irxnl; ++irxn) {
4868 kspec = m_indexRxnToSpecies[irxn];
4869 iph = m_phaseID[kspec];
4870 if (iph == iphase) {
4871 deltaGRxn[irxn] = 1.0 - phaseDG;
4879 void VCS_SOLVE::vcs_switch_pos(
const bool ifunc,
const size_t k1,
const size_t k2)
4881 size_t i1, i2, iph, kp1, kp2;
4887 if (k1 > (m_numSpeciesTot - 1) ||
4888 k2 > (m_numSpeciesTot - 1)) {
4889 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
4896 pv1 = m_VolPhaseList[m_phaseID[k1]];
4897 pv2 = m_VolPhaseList[m_phaseID[k2]];
4899 kp1 = m_speciesLocalPhaseIndex[k1];
4900 kp2 = m_speciesLocalPhaseIndex[k2];
4903 plogf(
"Indexing error in program\n");
4907 plogf(
"Indexing error in program\n");
4915 std::swap(m_speciesName[k1], m_speciesName[k2]);
4916 std::swap(m_molNumSpecies_old[k1], m_molNumSpecies_old[k2]);
4917 std::swap(m_speciesUnknownType[k1], m_speciesUnknownType[k2]);
4918 std::swap(m_molNumSpecies_new[k1], m_molNumSpecies_new[k2]);
4919 std::swap(m_SSfeSpecies[k1], m_SSfeSpecies[k2]);
4920 std::swap(m_spSize[k1], m_spSize[k2]);
4921 std::swap(m_deltaMolNumSpecies[k1], m_deltaMolNumSpecies[k2]);
4922 std::swap(m_feSpecies_old[k1], m_feSpecies_old[k2]);
4923 std::swap(m_feSpecies_new[k1], m_feSpecies_new[k2]);
4924 std::swap(m_SSPhase[k1], m_SSPhase[k2]);
4925 std::swap(m_phaseID[k1], m_phaseID[k2]);
4926 std::swap(m_speciesMapIndex[k1], m_speciesMapIndex[k2]);
4927 std::swap(m_speciesLocalPhaseIndex[k1], m_speciesLocalPhaseIndex[k2]);
4928 std::swap(m_actConventionSpecies[k1], m_actConventionSpecies[k2]);
4929 std::swap(m_lnMnaughtSpecies[k1], m_lnMnaughtSpecies[k2]);
4930 std::swap(m_actCoeffSpecies_new[k1], m_actCoeffSpecies_new[k2]);
4931 std::swap(m_actCoeffSpecies_old[k1], m_actCoeffSpecies_old[k2]);
4932 std::swap(m_wtSpecies[k1], m_wtSpecies[k2]);
4933 std::swap(m_chargeSpecies[k1], m_chargeSpecies[k2]);
4934 std::swap(m_speciesThermoList[k1], m_speciesThermoList[k2]);
4935 std::swap(m_PMVolumeSpecies[k1], m_PMVolumeSpecies[k2]);
4937 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
4938 std::swap(m_formulaMatrix[j][k1], m_formulaMatrix[j][k2]);
4940 if (m_useActCoeffJac) {
4941 vcs_switch2D(m_np_dLnActCoeffdMolNum.baseDataAddr(), k1, k2);
4943 std::swap(m_speciesStatus[k1], m_speciesStatus[k2]);
4953 i1 = k1 - m_numComponents;
4954 i2 = k2 - m_numComponents;
4956 if (i1 > (m_numRxnTot - 1) ||
4957 i2 > (m_numRxnTot - 1)) {
4958 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
4962 for (
size_t j = 0; j < m_numComponents; ++j) {
4963 std::swap(m_stoichCoeffRxnMatrix[i1][j], m_stoichCoeffRxnMatrix[i2][j]);
4965 std::swap(m_scSize[i1], m_scSize[i2]);
4966 for (iph = 0; iph < m_numPhases; iph++) {
4967 std::swap(m_deltaMolNumPhase[i1][iph], m_deltaMolNumPhase[i2][iph]);
4968 std::swap(m_phaseParticipation[i1][iph],
4969 m_phaseParticipation[i2][iph]);
4971 std::swap(m_deltaGRxn_new[i1], m_deltaGRxn_new[i2]);
4972 std::swap(m_deltaGRxn_old[i1], m_deltaGRxn_old[i2]);
4973 std::swap(m_deltaGRxn_tmp[i1], m_deltaGRxn_tmp[i2]);
4984 double VCS_SOLVE::vcs_birthGuess(
const int kspec)
4986 size_t irxn = kspec - m_numComponents;
4995 if (m_molNumSpecies_old[kspec] != 0.0) {
4997 plogf(
"vcs_birthGuess:: we shouldn't be here\n");
5001 int ss = m_SSPhase[kspec];
5010 double dxm = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
5012 double dxm = vcs_minor_alt_calc(kspec, irxn, &soldel_ret);
5036 double* sc_irxn = m_stoichCoeffRxnMatrix[irxn];
5037 for (
size_t j = 0; j < m_numComponents; ++j) {
5040 if (m_molNumSpecies_old[j] > 0.0) {
5041 double tmp = sc_irxn[j] * dx;
5042 if (3.0*(-tmp) > m_molNumSpecies_old[j]) {
5043 dx = std::min(dx, - 0.3333* m_molNumSpecies_old[j] / sc_irxn[j]);
5046 if (m_molNumSpecies_old[j] <= 0.0) {
5047 if (sc_irxn[j] < 0.0) {
5056 void VCS_SOLVE::vcs_setFlagsVolPhases(
const bool upToDate,
const int stateCalc)
5060 for (
size_t iph = 0; iph < m_numPhases; iph++) {
5061 Vphase = m_VolPhaseList[iph];
5065 for (
size_t iph = 0; iph < m_numPhases; iph++) {
5066 Vphase = m_VolPhaseList[iph];
5072 void VCS_SOLVE::vcs_setFlagsVolPhase(
const size_t iph,
const bool upToDate,
5073 const int stateCalc)
5075 vcs_VolPhase* Vphase = m_VolPhaseList[iph];
5079 Vphase->setMolesCurrent(stateCalc);
5083 void VCS_SOLVE::vcs_updateMolNumVolPhases(
const int stateCalc)
5086 for (
size_t iph = 0; iph < m_numPhases; iph++) {
5087 Vphase = m_VolPhaseList[iph];
void vcs_print_stringTrunc(const char *str, size_t space, int alignment)
Print a string within a given space limit.
#define VCS_PHASE_EXIST_NO
Phase doesn't currently exist in the mixture.
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
void checkFinite(const double tmp)
Check to see that a number is finite (not NaN, +Inf or -Inf)
#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).
std::string PhaseName
String name for the phase.
#define VCS_PHASE_EXIST_ALWAYS
Always exists because it contains inerts which can't exist in any other 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.
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...
void setExistence(const int existence)
Set the existence flag in the object.
The class provides the wall clock timer in seconds.
#define VCS_SPECIES_INTERFACIALVOLTAGE
Species refers to an electron in the metal.
#define VCS_PHASE_EXIST_YES
Phase is a normal phase that currently exists.
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.
Phase information and Phase calculations for vcs.
#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...
Internal declarations for the VCSnonideal package.
double secondsWC()
Returns the wall clock time in seconds since the last reset.
void vcs_print_line(const char *string, int num)
Prints a line consisting of multiple occurrences of the same string.
void setMolesCurrent(int vcsStateStatus)
Sets the mole flag within the object to be current.
#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.
size_t spGlobalIndexVCS(const size_t spIndex) const
Return the Global VCS index of the kth species in the phase.
Base class for exceptions thrown by Cantera classes.
void updateFromVCS_MoleNumbers(const int stateCalc)
Update the moles within the phase, if necessary.
#define VCS_SPECIES_ACTIVEBUTZERO
Species lies in a multicomponent phase that is active, but species concentration is zero...
void setTotalMoles(const double totalMols)
Sets the total moles in the phase.
#define VCS_SPECIES_MAJOR
Species is a major species.
void setSpGlobalIndexVCS(const size_t spIndex, const size_t spGlobalIndex)
set the Global VCS index of the kth species in the phase
#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...
double electricPotential() const
Returns the electric field of the phase.
#define VCS_DIMENSIONAL_G
dimensioned
size_t nSpecies() const
Return the number of species in the phase.
bool m_singleSpecies
If true, this phase consists of a single species.
bool vcs_doubleEqual(double d1, double d2)
Simple routine to check whether two doubles are equal up to roundoff error.
#define VCS_STATECALC_OLD
State Calculation based on the old or base mole numbers.
void setMolesFromVCS(const int stateCalc, const double *molesSpeciesVCS=0)
Set the moles within the phase.
void sendToVCS_ActCoeff(const int stateCalc, double *const AC)
Fill in an activity coefficients vector within a VCS_SOLVE object.
#define plogendl()
define this Cantera function to replace cout << endl;
void setMolesFromVCSCheck(const int vcsStateStatus, const double *molesSpeciesVCS, const double *const TPhMoles)
Set the moles within the phase.
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Contains declarations for string manipulation functions within Cantera.
int vcsUtil_gaussj(double *c, size_t idem, size_t n, double *b, size_t m)
Invert an n x n matrix and solve m rhs's.
int exists() const
int indicating whether the phase exists or not
#define plogf
define this Cantera function to replace printf
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
Unknown refers to the voltage level of a phase.
double molefraction(size_t kspec) const
Returns the mole fraction of the kspec species.
#define VCS_SPECIES_COMPONENT
Species is a component which can be nonzero.
void setMolesOutOfDate(int stateCalc=-1)
Sets the mole flag within the object to out of date.
#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...