20 enum stages {MAIN, EQUILIB_CHECK, ELEM_ABUND_CHECK,
21 RECHECK_DELETED, RETURN_A, RETURN_B};
27 void VCS_SOLVE::checkDelta1(
double*
const dsLocal,
28 double*
const delTPhMoles,
size_t kspec)
31 for (
size_t k = 0; k < kspec; k++) {
33 size_t iph = m_phaseID[k];
34 dchange[iph] += dsLocal[k];
37 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
38 double denom = max(m_totalMolNum, 1.0E-4);
39 if (!
vcs_doubleEqual(dchange[iphase]/denom, delTPhMoles[iphase]/denom)) {
40 throw CanteraError(
"VCS_SOLVE::checkDelta1",
41 "we have found a problem");
46 int VCS_SOLVE::vcs_solve_TP(
int print_lvl,
int printDetails,
int maxit)
49 bool allMinorZeroedSpecies =
false;
52 int rangeErrorFound = 0;
53 bool giveUpOnElemAbund =
false;
54 int finalElemAbundAttempts = 0;
55 bool uptodate_minors =
true;
56 int forceComponentCalc = 1;
60 m_debug_print_lvl = printDetails;
61 if (printDetails > 0 && print_lvl == 0) {
69 m_sm.assign(m_numElemConstraints*m_numElemConstraints, 0.0);
70 m_ss.assign(m_numElemConstraints, 0.0);
71 m_sa.assign(m_numElemConstraints, 0.0);
72 m_aw.assign(m_numSpeciesTot, 0.0);
73 m_wx.assign(m_numElemConstraints, 0.0);
75 int solveFail =
false;
82 plogf(
"VCS CALCULATION METHOD\n\n ");
83 plogf(
"%s\n", m_title);
84 plogf(
"\n\n%5d SPECIES\n%5d ELEMENTS\n", m_numSpeciesTot, m_numElemConstraints);
85 plogf(
"%5d COMPONENTS\n", m_numComponents);
86 plogf(
"%5d PHASES\n", m_numPhases);
87 plogf(
" PRESSURE%22.8g %3s\n", m_pressurePA,
"Pa ");
88 plogf(
" TEMPERATURE%19.3f K\n", m_temperature);
91 plogf(
" PHASE1 INERTS%17.3f\n", TPhInertMoles[0]);
93 if (m_numPhases > 1) {
94 plogf(
" PHASE2 INERTS%17.3f\n", TPhInertMoles[1]);
96 plogf(
"\n ELEMENTAL ABUNDANCES CORRECT");
97 plogf(
" FROM ESTIMATE Type\n\n");
98 for (
size_t i = 0; i < m_numElemConstraints; ++i) {
99 writeline(
' ', 26,
false);
100 plogf(
"%-2.2s", m_elementName[i]);
101 plogf(
"%20.12E%20.12E %3d\n", m_elemAbundancesGoal[i], m_elemAbundances[i],
104 if (m_doEstimateEquil < 0) {
105 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - forced\n");
106 }
else if (m_doEstimateEquil > 0) {
107 plogf(
"\n MODIFIED LINEAR PROGRAMMING ESTIMATE OF EQUILIBRIUM - where necessary\n");
109 if (m_doEstimateEquil == 0) {
110 plogf(
"\n USER ESTIMATE OF EQUILIBRIUM\n");
112 plogf(
" Stan. Chem. Pot. in J/kmol\n");
113 plogf(
"\n SPECIES FORMULA VECTOR ");
114 writeline(
' ', 41,
false);
115 plogf(
" STAN_CHEM_POT EQUILIBRIUM_EST. Species_Type\n\n");
116 writeline(
' ', 20,
false);
117 for (
size_t i = 0; i < m_numElemConstraints; ++i) {
118 plogf(
"%-4.4s ", m_elementName[i]);
121 double RT = GasConstant * m_temperature;
122 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
123 plogf(
" %-18.18s", m_speciesName[i]);
124 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
125 plogf(
"% -7.3g ", m_formulaMatrix(i,j));
127 plogf(
" %3d ", m_phaseID[i]);
128 writeline(
' ', std::max(55-
int(m_numElemConstraints)*8, 0),
false);
129 plogf(
"%12.5E %12.5E", RT * m_SSfeSpecies[i], m_molNumSpecies_old[i]);
141 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
142 if (m_molNumSpecies_old[i] < 0.0) {
143 plogf(
"On Input species %-12s has a negative MF, setting it small",
146 size_t iph = m_phaseID[i];
149 m_molNumSpecies_old[i] = tmp;
165 if (forceComponentCalc) {
166 int retn = solve_tp_component_calc(allMinorZeroedSpecies);
171 forceComponentCalc = 0;
177 if (m_VCount->Its > maxit) {
180 solve_tp_inner(iti, it1, uptodate_minors, allMinorZeroedSpecies,
181 forceComponentCalc, stage, printDetails > 0, ANOTE);
183 }
else if (stage == EQUILIB_CHECK) {
185 solve_tp_equilib_check(allMinorZeroedSpecies, uptodate_minors,
186 giveUpOnElemAbund, solveFail, iti, it1,
188 }
else if (stage == ELEM_ABUND_CHECK) {
190 solve_tp_elem_abund_check(iti, stage, lec, giveUpOnElemAbund,
191 finalElemAbundAttempts, rangeErrorFound);
192 }
else if (stage == RECHECK_DELETED) {
202 size_t npb = vcs_recheck_deleted();
216 }
else if (stage == RETURN_A) {
218 size_t npb = vcs_recheck_deleted();
232 }
else if (stage == RETURN_B) {
235 size_t npb = vcs_add_all_deleted();
238 if (m_debug_print_lvl >= 1) {
239 plogf(
" --- add_all_deleted(): some rxns not converged. RETURNING TO LOOP!");
255 m_molNumSpecies_new.assign(m_molNumSpecies_new.size(), 0.0);
256 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
257 if (m_SSPhase[kspec]) {
258 m_molNumSpecies_new[kspec] = 1.0;
260 size_t iph = m_phaseID[kspec];
261 if (m_tPhaseMoles_old[iph] != 0.0) {
262 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] / m_tPhaseMoles_old[iph];
268 size_t i = m_speciesLocalPhaseIndex[kspec];
269 m_molNumSpecies_new[kspec] = m_VolPhaseList[iph]->molefraction(i);
274 if (rangeErrorFound) {
280 m_VCount->Time_vcs_TP = tsecond;
281 m_VCount->T_Time_vcs_TP += m_VCount->Time_vcs_TP;
282 m_VCount->T_Calls_vcs_TP++;
283 m_VCount->T_Its += m_VCount->Its;
284 m_VCount->T_Basis_Opts += m_VCount->Basis_Opts;
285 m_VCount->T_Time_basopt += m_VCount->Time_basopt;
291 int VCS_SOLVE::solve_tp_component_calc(
bool& allMinorZeroedSpecies)
293 double test = -1.0e-10;
294 bool usedZeroedSpecies;
295 int retn = vcs_basopt(
false, &m_aw[0], &m_sa[0], &m_sm[0], &m_ss[0],
296 test, &usedZeroedSpecies);
306 allMinorZeroedSpecies = vcs_evaluate_speciesType();
309 if (! vcs_elabcheck(0)) {
310 if (m_debug_print_lvl >= 2) {
311 plogf(
" --- Element Abundance check failed");
314 vcs_elcorr(&m_sm[0], &m_wx[0]);
320 }
else if (m_debug_print_lvl >= 2) {
321 plogf(
" --- Element Abundance check passed");
327 void VCS_SOLVE::solve_tp_inner(
size_t& iti,
size_t& it1,
328 bool& uptodate_minors,
329 bool& allMinorZeroedSpecies,
330 int& forceComponentCalc,
331 int& stage,
bool printDetails,
char* ANOTE)
340 if (!uptodate_minors) {
345 uptodate_minors =
true;
347 uptodate_minors =
false;
353 plogf(
" Iteration = %3d, Iterations since last evaluation of " 354 "optimal basis = %3d",
355 m_VCount->Its, it1 - 1);
357 plogf(
" (all species)\n");
359 plogf(
" (only major species)\n");
370 m_feSpecies_new = m_feSpecies_old;
371 m_actCoeffSpecies_new = m_actCoeffSpecies_old;
372 m_deltaGRxn_new = m_deltaGRxn_old;
373 m_deltaGRxn_Deficient = m_deltaGRxn_old;
374 m_tPhaseMoles_new = m_tPhaseMoles_old;
379 m_deltaMolNumSpecies.assign(m_deltaMolNumSpecies.size(), 0.0);
385 std::vector<size_t> phasePopPhaseIDs(0);
386 size_t iphasePop = vcs_popPhaseID(phasePopPhaseIDs);
387 if (iphasePop !=
npos) {
388 int soldel = vcs_popPhaseRxnStepSizes(iphasePop);
391 if (m_debug_print_lvl >= 2) {
392 plogf(
" --- vcs_popPhaseRxnStepSizes() was called but stoich " 393 "prevented phase %d popping\n");
401 size_t iphaseDelete =
npos;
403 if (iphasePop ==
npos) {
407 iphaseDelete = vcs_RxnStepSizes(forceComponentCalc, kspec);
408 }
else if (m_debug_print_lvl >= 2) {
409 plogf(
" --- vcs_RxnStepSizes not called because alternative" 410 "phase creation delta was used instead\n");
412 size_t doPhaseDeleteKspec =
npos;
413 size_t doPhaseDeleteIph =
npos;
416 m_deltaPhaseMoles.assign(m_deltaPhaseMoles.size(), 0.0);
432 if (iphaseDelete !=
npos) {
433 if (m_debug_print_lvl >= 2) {
434 plogf(
" --- Main Loop Treatment -> Circumvented due to Phase Deletion ");
437 for (
size_t k = 0; k < m_numSpeciesTot; k++) {
438 m_molNumSpecies_new[k] = m_molNumSpecies_old[k] + m_deltaMolNumSpecies[k];
439 size_t iph = m_phaseID[k];
440 m_tPhaseMoles_new[iph] += m_deltaMolNumSpecies[k];
442 if (kspec >= m_numComponents) {
443 if (m_molNumSpecies_new[m_numSpeciesTot] != 0.0) {
444 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
445 "we shouldn't be here!");
447 if (m_SSPhase[kspec] == 1) {
450 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
451 "we shouldn't be here!");
453 ++m_numRxnMinorZeroed;
454 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
470 if (m_debug_print_lvl >= 2) {
471 plogf(
" --- Main Loop Treatment of each non-component species ");
473 plogf(
"- Full Calculation:\n");
475 plogf(
"- Major Components Calculation:\n");
477 plogf(
" --- Species IC ");
478 plogf(
" KMoles Tent_KMoles Rxn_Adj | Comment \n");
480 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
481 size_t kspec = m_indexRxnToSpecies[irxn];
482 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
483 size_t iph = m_phaseID[kspec];
484 vcs_VolPhase* Vphase = m_VolPhaseList[iph];
488 if (iphasePop !=
npos) {
489 if (iph == iphasePop) {
490 dx = m_deltaMolNumSpecies[kspec];
491 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
492 sprintf(ANOTE,
"Phase pop");
495 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
500 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
501 m_deltaMolNumSpecies[kspec] = dx;
504 bool resurrect = (m_deltaMolNumSpecies[kspec] > 0.0);
505 if (m_debug_print_lvl >= 3) {
506 plogf(
" --- %s currently zeroed (SpStatus=%-2d):",
507 m_speciesName[kspec], m_speciesStatus[kspec]);
508 plogf(
"%3d DG = %11.4E WT = %11.4E W = %11.4E DS = %11.4E\n",
509 irxn, m_deltaGRxn_new[irxn], m_molNumSpecies_new[kspec],
510 m_molNumSpecies_old[kspec], m_deltaMolNumSpecies[kspec]);
512 if (m_deltaGRxn_new[irxn] >= 0.0 || !resurrect) {
513 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
514 m_deltaMolNumSpecies[kspec] = 0.0;
516 sprintf(ANOTE,
"Species stays zeroed: DG = %11.4E", m_deltaGRxn_new[irxn]);
517 if (m_deltaGRxn_new[irxn] < 0.0) {
519 sprintf(ANOTE,
"Species stays zeroed even though dg neg due to " 520 "STOICH/PHASEPOP constraint: DG = %11.4E",
521 m_deltaGRxn_new[irxn]);
523 sprintf(ANOTE,
"Species stays zeroed even though dg neg: DG = %11.4E, ds zeroed",
524 m_deltaGRxn_new[irxn]);
528 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
529 int elType = m_elType[j];
531 double atomComp = m_formulaMatrix(kspec,j);
532 if (atomComp > 0.0) {
533 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
535 sprintf(ANOTE,
"Species stays zeroed even though dG " 536 "neg, because of %s elemAbund",
537 m_elementName[j].c_str());
549 if (m_debug_print_lvl >= 2) {
550 plogf(
" --- Zeroed species changed to major: ");
551 plogf(
"%-12s\n", m_speciesName[kspec]);
554 allMinorZeroedSpecies =
false;
556 if (m_debug_print_lvl >= 2) {
557 plogf(
" --- Zeroed species changed to minor: ");
558 plogf(
"%-12s\n", m_speciesName[kspec]);
562 if (m_deltaMolNumSpecies[kspec] > 0.0) {
563 dx = m_deltaMolNumSpecies[kspec] * 0.01;
564 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
567 dx = m_molNumSpecies_new[kspec] - m_molNumSpecies_old[kspec];
569 m_deltaMolNumSpecies[kspec] = dx;
570 sprintf(ANOTE,
"Born:IC=-1 to IC=1:DG=%11.4E", m_deltaGRxn_new[irxn]);
572 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
573 m_deltaMolNumSpecies[kspec] = 0.0;
582 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
583 m_deltaMolNumSpecies[kspec] = 0.0;
585 sprintf(ANOTE,
"minor species not considered");
586 if (m_debug_print_lvl >= 2) {
588 plogf(
"%-12s", m_speciesName[kspec]);
589 plogf(
"%3d% 11.4E %11.4E %11.4E | %s",
590 m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
591 m_deltaMolNumSpecies[kspec], ANOTE);
610 dx = vcs_minor_alt_calc(kspec, irxn, &soldel_ret, ANOTE);
611 m_deltaMolNumSpecies[kspec] = dx;
612 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
616 if (m_debug_print_lvl >= 2) {
617 plogf(
" --- Delete minor species in multispec phase: %-12s",
618 m_speciesName[kspec]);
621 m_deltaMolNumSpecies[kspec] = 0.0;
627 size_t lnospec = vcs_delete_species(kspec);
629 stage = RECHECK_DELETED;
643 sprintf(ANOTE,
"Normal Major Calc");
648 if (fabs(m_deltaGRxn_new[irxn]) <= m_tolmaj2) {
649 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
650 m_deltaMolNumSpecies[kspec] = 0.0;
652 sprintf(ANOTE,
"major species is converged");
653 if (m_debug_print_lvl >= 2) {
655 plogf(
"%-12s", m_speciesName[kspec]);
656 plogf(
" %3d %11.4E %11.4E %11.4E | %s",
657 m_speciesStatus[kspec], m_molNumSpecies_old[kspec], m_molNumSpecies_new[kspec],
658 m_deltaMolNumSpecies[kspec], ANOTE);
671 if ((m_deltaGRxn_new[irxn] * m_deltaMolNumSpecies[kspec]) <= 0.0) {
672 dx = m_deltaMolNumSpecies[kspec];
675 m_deltaMolNumSpecies[kspec] = 0.0;
676 sprintf(ANOTE,
"dx set to 0, DG flipped sign due to " 677 "changed initial point");
681 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
687 if (m_molNumSpecies_new[kspec] <= 0.0) {
688 sprintf(ANOTE,
"initial nonpos kmoles= %11.3E",
689 m_molNumSpecies_new[kspec]);
697 if (!m_SSPhase[kspec]) {
702 dx = -0.9 * m_molNumSpecies_old[kspec];
703 m_deltaMolNumSpecies[kspec] = dx;
704 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
709 dx = -m_molNumSpecies_old[kspec];
715 for (
size_t j = 0; j < m_numComponents; ++j) {
716 if (sc_irxn[j] != 0.0) {
717 m_wx[j] = m_molNumSpecies_old[j] + sc_irxn[j] * dx;
718 if (m_wx[j] <= m_molNumSpecies_old[j] * 0.01 - 1.0E-150) {
719 dx = std::max(dx, m_molNumSpecies_old[j] * -0.99 / sc_irxn[j]);
722 m_wx[j] = m_molNumSpecies_old[j];
725 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
726 if (m_molNumSpecies_new[kspec] > 0.0) {
727 m_deltaMolNumSpecies[kspec] = dx;
729 "zeroing SS phase created a neg component species " 730 "-> reducing step size instead");
734 iph = m_phaseID[kspec];
735 Vphase = m_VolPhaseList[iph];
736 sprintf(ANOTE,
"zeroing out SS phase: ");
742 m_molNumSpecies_new[kspec] = 0.0;
743 doPhaseDeleteIph = iph;
745 doPhaseDeleteKspec = kspec;
746 if (m_debug_print_lvl >= 2 && m_speciesStatus[kspec] >= 0) {
747 plogf(
" --- SS species changed to zeroedss: ");
748 plogf(
"%-12s", m_speciesName[kspec]);
752 ++m_numRxnMinorZeroed;
753 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
755 for (
size_t kk = 0; kk < m_numSpeciesTot; kk++) {
756 m_deltaMolNumSpecies[kk] = 0.0;
757 m_molNumSpecies_new[kk] = m_molNumSpecies_old[kk];
759 m_deltaMolNumSpecies[kspec] = dx;
760 m_molNumSpecies_new[kspec] = 0.0;
762 for (
size_t k = 0; k < m_numComponents; ++k) {
763 m_deltaMolNumSpecies[k] = 0.0;
765 for (iph = 0; iph < m_numPhases; iph++) {
766 m_deltaPhaseMoles[iph] = 0.0;
774 if (dx != 0.0 && (m_speciesUnknownType[kspec] !=
781 1.0E-14*(fabs(m_deltaMolNumSpecies[kspec]) + fabs(dx) + 1.0E-32),
782 "VCS_SOLVE::solve_tp_inner",
783 "ds[kspec] = {}, dx = {}, kspec = {}\nwe have a problem!",
784 m_deltaMolNumSpecies[kspec], dx, kspec);
785 for (
size_t k = 0; k < m_numComponents; ++k) {
786 m_deltaMolNumSpecies[k] += sc_irxn[k] * dx;
791 for (iph = 0; iph < m_numPhases; iph++) {
792 m_deltaPhaseMoles[iph] += dx * m_deltaMolNumPhase(iph,irxn);
796 checkDelta1(&m_deltaMolNumSpecies[0],
797 &m_deltaPhaseMoles[0], kspec+1);
800 if (m_debug_print_lvl >= 2) {
801 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
803 plogf(
"%-12.12s", m_speciesName[kspec]);
804 plogf(
"%3d %11.4E %11.4E %11.4E | %s",
805 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
806 m_molNumSpecies_new[kspec],
807 m_deltaMolNumSpecies[kspec], ANOTE);
811 if (doPhaseDeleteIph !=
npos) {
812 if (m_debug_print_lvl >= 2) {
814 plogf(
"%-12.12s Main Loop Special Case deleting phase with species: ",
815 m_speciesName[doPhaseDeleteKspec]);
821 if (m_debug_print_lvl >= 2) {
822 for (
size_t k = 0; k < m_numComponents; k++) {
824 plogf(
"%-12.12s", m_speciesName[k]);
825 plogf(
" c %11.4E %11.4E %11.4E |\n",
826 m_molNumSpecies_old[k],
827 m_molNumSpecies_old[k]+m_deltaMolNumSpecies[k], m_deltaMolNumSpecies[k]);
831 plogf(
" --- Finished Main Loop");
841 for (
size_t k = 0; k < m_numComponents; ++k) {
842 if (m_molNumSpecies_old[k] > 0.0) {
843 double xx = -m_deltaMolNumSpecies[k] / m_molNumSpecies_old[k];
848 }
else if (m_deltaMolNumSpecies[k] < 0.0) {
851 size_t iph = m_phaseID[k];
852 m_deltaPhaseMoles[iph] -= m_deltaMolNumSpecies[k];
853 m_deltaMolNumSpecies[k] = 0.0;
857 if (par <= 1.01 && par > 0.0) {
860 if (m_debug_print_lvl >= 2) {
861 plogf(
" --- Reduction in step size due to component ");
862 plogf(
"%s", m_speciesName[ll]);
863 plogf(
" going negative = %11.3E", par);
866 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
867 m_deltaMolNumSpecies[i] *= par;
869 for (
size_t iph = 0; iph < m_numPhases; iph++) {
870 m_deltaPhaseMoles[iph] *= par;
875 checkDelta1(&m_deltaMolNumSpecies[0],
876 &m_deltaPhaseMoles[0], m_numSpeciesTot);
883 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
884 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + m_deltaMolNumSpecies[kspec];
885 if (m_molNumSpecies_new[kspec] < 0.0 && (m_speciesUnknownType[kspec]
887 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
888 "vcs_solve_TP: ERROR on step change wt[{}:{}]: {} < 0.0",
889 kspec, m_speciesName[kspec], m_molNumSpecies_new[kspec]);
894 for (
size_t iph = 0; iph < m_numPhases; iph++) {
895 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + m_deltaPhaseMoles[iph];
913 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
914 vcs_Total_Gibbs(&m_molNumSpecies_old[0], &m_feSpecies_old[0],
915 &m_tPhaseMoles_old[0]));
916 plogf(
" --- Total tentative Dimensionless Gibbs Free Energy = %20.13E",
917 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
918 &m_tPhaseMoles_new[0]));
922 bool forced = vcs_globStepDamp();
925 if (printDetails && forced) {
926 plogf(
" -----------------------------------------------------\n");
927 plogf(
" --- FORCER SUBROUTINE changed the solution:\n");
928 plogf(
" --- SPECIES Status INIT MOLES TENT_MOLES");
929 plogf(
" FINAL KMOLES INIT_DEL_G/RT TENT_DEL_G/RT FINAL_DELTA_G/RT\n");
930 for (
size_t i = 0; i < m_numComponents; ++i) {
931 plogf(
" --- %-12.12s", m_speciesName[i]);
932 plogf(
" %14.6E %14.6E %14.6E\n", m_molNumSpecies_old[i],
933 m_molNumSpecies_old[i] + m_deltaMolNumSpecies[i], m_molNumSpecies_new[i]);
935 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
936 size_t irxn = kspec - m_numComponents;
937 plogf(
" --- %-12.12s", m_speciesName[kspec]);
938 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n", m_speciesStatus[kspec],
939 m_molNumSpecies_old[kspec],
940 m_molNumSpecies_old[kspec]+m_deltaMolNumSpecies[kspec],
941 m_molNumSpecies_new[kspec], m_deltaGRxn_old[irxn],
942 m_deltaGRxn_tmp[irxn], m_deltaGRxn_new[irxn]);
944 writeline(
' ', 26,
false);
945 plogf(
"Norms of Delta G():%14.6E%14.6E\n",
946 l2normdg(&m_deltaGRxn_old[0]),
947 l2normdg(&m_deltaGRxn_new[0]));
948 plogf(
" Total kmoles of gas = %15.7E\n", m_tPhaseMoles_old[0]);
949 if ((m_numPhases > 1) && (!m_VolPhaseList[1]->m_singleSpecies)) {
950 plogf(
" Total kmoles of liquid = %15.7E\n", m_tPhaseMoles_old[1]);
952 plogf(
" Total kmoles of liquid = %15.7E\n", 0.0);
954 plogf(
" Total New Dimensionless Gibbs Free Energy = %20.13E\n",
955 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
956 &m_tPhaseMoles_new[0]));
957 plogf(
" -----------------------------------------------------");
967 plogf(
" --- Summary of the Update ");
969 plogf(
" (all species):");
971 plogf(
" (only major species):");
973 if (m_totalMoleScale != 1.0) {
974 plogf(
" (Total Mole Scale = %g)", m_totalMoleScale);
977 plogf(
" --- Species Status Initial_KMoles Final_KMoles Initial_Mu/RT");
978 plogf(
" Mu/RT Init_Del_G/RT Delta_G/RT\n");
979 for (
size_t i = 0; i < m_numComponents; ++i) {
980 plogf(
" --- %-12.12s", m_speciesName[i]);
982 plogf(
"%14.6E%14.6E%14.6E%14.6E\n", m_molNumSpecies_old[i],
983 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i]);
985 for (
size_t i = m_numComponents; i < m_numSpeciesRdc; ++i) {
986 size_t l1 = i - m_numComponents;
987 plogf(
" --- %-12.12s", m_speciesName[i]);
988 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
989 m_speciesStatus[i], m_molNumSpecies_old[i],
990 m_molNumSpecies_new[i], m_feSpecies_old[i], m_feSpecies_new[i],
991 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
993 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
994 size_t l1 = kspec - m_numComponents;
995 plogf(
" --- %-12.12s", m_speciesName[kspec]);
996 plogf(
" %2d %14.6E%14.6E%14.6E%14.6E%14.6E%14.6E\n",
997 m_speciesStatus[kspec], m_molNumSpecies_old[kspec],
998 m_molNumSpecies_new[kspec], m_feSpecies_old[kspec], m_feSpecies_new[kspec],
999 m_deltaGRxn_old[l1], m_deltaGRxn_new[l1]);
1002 writeline(
' ', 56,
false);
1003 plogf(
"Norms of Delta G():%14.6E%14.6E",
1004 l2normdg(&m_deltaGRxn_old[0]),
1005 l2normdg(&m_deltaGRxn_new[0]));
1008 plogf(
" --- Phase_Name KMoles(after update)\n");
1011 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1012 vcs_VolPhase* Vphase = m_VolPhaseList[iph];
1013 plogf(
" --- %18s = %15.7E\n", Vphase->PhaseName, m_tPhaseMoles_new[iph]);
1016 writeline(
'-', 103);
1017 plogf(
" --- Total Old Dimensionless Gibbs Free Energy = %20.13E\n",
1018 vcs_Total_Gibbs(&m_molNumSpecies_old[0], &m_feSpecies_old[0],
1019 &m_tPhaseMoles_old[0]));
1020 plogf(
" --- Total New Dimensionless Gibbs Free Energy = %20.13E",
1021 vcs_Total_Gibbs(&m_molNumSpecies_new[0], &m_feSpecies_new[0],
1022 &m_tPhaseMoles_new[0]));
1024 if (m_VCount->Its > 550) {
1025 plogf(
" --- Troublesome solve");
1040 m_tPhaseMoles_old = m_tPhaseMoles_new;
1041 m_molNumSpecies_old = m_molNumSpecies_new;
1042 m_actCoeffSpecies_old = m_actCoeffSpecies_new;
1043 m_deltaGRxn_old = m_deltaGRxn_new;
1044 m_feSpecies_old = m_feSpecies_new;
1051 if (m_debug_print_lvl >= 2) {
1052 plogf(
" --- Increment counter increased, step is accepted: %4d",
1063 bool justDeletedMultiPhase =
false;
1064 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1065 if (!m_VolPhaseList[iph]->m_singleSpecies && m_tPhaseMoles_old[iph] != 0.0 &&
1067 if (m_debug_print_lvl >= 1) {
1068 plogf(
" --- Setting microscopic phase %d to zero", iph);
1071 justDeletedMultiPhase =
true;
1072 vcs_delete_multiphase(iph);
1079 if (justDeletedMultiPhase) {
1080 bool usedZeroedSpecies;
1081 double test = -1.0e-10;
1082 int retn = vcs_basopt(
false, &m_aw[0], &m_sa[0], &m_sm[0], &m_ss[0],
1083 test, &usedZeroedSpecies);
1085 throw CanteraError(
"VCS_SOLVE::solve_tp_inner",
1086 "BASOPT returned with an error condition");
1096 if (m_debug_print_lvl >= 2) {
1097 plogf(
" --- Normal element abundance check");
1100 if (! vcs_elabcheck(0)) {
1101 if (m_debug_print_lvl >= 2) {
1102 plogf(
" - failed -> redoing element abundances.");
1105 vcs_elcorr(&m_sm[0], &m_wx[0]);
1109 uptodate_minors =
true;
1110 }
else if (m_debug_print_lvl >= 2) {
1116 for (
size_t i = 0; i < m_numRxnRdc; ++i) {
1117 size_t k = m_indexRxnToSpecies[i];
1121 for (
size_t j = 0; j < m_numComponents; ++j) {
1122 bool doSwap =
false;
1124 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1125 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1126 if (!m_SSPhase[k] && doSwap) {
1127 doSwap = m_molNumSpecies_old[k] > (m_molNumSpecies_old[j] * 1.01);
1131 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1132 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1134 doSwap = m_molNumSpecies_old[k] > (m_molNumSpecies_old[j] * 1.01);
1137 doSwap = (m_molNumSpecies_old[k] * m_spSize[k]) >
1138 (m_molNumSpecies_old[j] * m_spSize[j] * 1.01);
1141 if (doSwap && m_stoichCoeffRxnMatrix(j,i) != 0.0) {
1142 if (m_debug_print_lvl >= 2) {
1143 plogf(
" --- Get a new basis because ");
1144 plogf(
"%s", m_speciesName[k]);
1145 plogf(
" is better than comp ");
1146 plogf(
"%s", m_speciesName[j]);
1147 plogf(
" and share nonzero stoic: %-9.1f",
1148 m_stoichCoeffRxnMatrix(j,i));
1151 forceComponentCalc = 1;
1156 if (m_debug_print_lvl >= 2) {
1157 plogf(
" --- Check for an optimum basis passed");
1160 stage = EQUILIB_CHECK;
1169 if (m_debug_print_lvl >= 2) {
1170 plogf(
" --- Reevaluate major-minor status of noncomponents:\n");
1172 m_numRxnMinorZeroed = 0;
1173 for (
size_t irxn = 0; irxn < m_numRxnRdc; irxn++) {
1174 size_t kspec = m_indexRxnToSpecies[irxn];
1175 int speciesType = vcs_species_type(kspec);
1178 plogf(
" --- major/minor species is now zeroed out: %s\n",
1179 m_speciesName[kspec]);
1181 ++m_numRxnMinorZeroed;
1185 plogf(
" --- Noncomponent turned from major to minor: ");
1186 }
else if (kspec < m_numComponents) {
1187 plogf(
" --- Component turned into a minor species: ");
1189 plogf(
" --- Zeroed Species turned into a " 1192 plogf(
"%s\n", m_speciesName[kspec]);
1194 ++m_numRxnMinorZeroed;
1197 if (m_debug_print_lvl >= 2) {
1199 plogf(
" --- Noncomponent turned from minor to major: ");
1200 }
else if (kspec < m_numComponents) {
1201 plogf(
" --- Component turned into a major: ");
1203 plogf(
" --- Noncomponent turned from zeroed to major: ");
1205 plogf(
"%s\n", m_speciesName[kspec]);
1210 m_speciesStatus[kspec] = speciesType;
1215 allMinorZeroedSpecies = (m_numRxnMinorZeroed == m_numRxnRdc);
1218 void VCS_SOLVE::solve_tp_equilib_check(
bool& allMinorZeroedSpecies,
1219 bool& uptodate_minors,
1220 bool& giveUpOnElemAbund,
int& solveFail,
1221 size_t& iti,
size_t& it1,
int maxit,
1222 int& stage,
bool& lec)
1224 if (! allMinorZeroedSpecies) {
1225 if (m_debug_print_lvl >= 2) {
1226 plogf(
" --- Equilibrium check for major species: ");
1228 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1229 size_t kspec = irxn + m_numComponents;
1230 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MAJOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmaj)) {
1231 if (m_VCount->Its >= maxit) {
1238 if (m_debug_print_lvl >= 2) {
1239 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]]);
1243 iti = ((it1/4) *4) - it1;
1249 if (m_debug_print_lvl >= 2) {
1250 plogf(
" MAJOR SPECIES CONVERGENCE achieved");
1253 }
else if (m_debug_print_lvl >= 2) {
1254 plogf(
" MAJOR SPECIES CONVERGENCE achieved " 1255 "(because there are no major species)");
1261 if (m_numRxnMinorZeroed != 0) {
1268 uptodate_minors =
true;
1270 if (m_debug_print_lvl >= 2) {
1271 plogf(
" --- Equilibrium check for minor species: ");
1273 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
1274 size_t kspec = irxn + m_numComponents;
1275 if (m_speciesStatus[kspec] ==
VCS_SPECIES_MINOR && (fabs(m_deltaGRxn_new[irxn]) > m_tolmin)) {
1276 if (m_VCount->Its >= maxit) {
1283 if (m_debug_print_lvl >= 2) {
1284 plogf(
"%s failed\n", m_speciesName[m_indexRxnToSpecies[irxn]]);
1294 if (m_debug_print_lvl >= 2) {
1295 plogf(
" CONVERGENCE achieved\n");
1306 if (!giveUpOnElemAbund) {
1307 if (m_debug_print_lvl >= 2) {
1308 plogf(
" --- Check the Full Element Abundances: ");
1313 if (! vcs_elabcheck(1)) {
1314 if (m_debug_print_lvl >= 2) {
1315 if (! vcs_elabcheck(0)) {
1318 plogf(
" passed for NC but failed for NE: RANGE ERROR\n");
1322 stage = ELEM_ABUND_CHECK;
1325 if (m_debug_print_lvl >= 2) {
1332 if (m_numSpeciesRdc != m_numSpeciesTot) {
1333 stage = RECHECK_DELETED;
1342 void VCS_SOLVE::solve_tp_elem_abund_check(
size_t& iti,
int& stage,
bool& lec,
1343 bool& giveUpOnElemAbund,
1344 int& finalElemAbundAttempts,
1345 int& rangeErrorFound)
1352 rangeErrorFound = 0;
1353 if (! vcs_elabcheck(1)) {
1354 bool ncBefore = vcs_elabcheck(0);
1355 vcs_elcorr(&m_sm[0], &m_wx[0]);
1356 bool ncAfter = vcs_elabcheck(0);
1357 bool neAfter = vcs_elabcheck(1);
1373 if (finalElemAbundAttempts >= 3) {
1374 giveUpOnElemAbund =
true;
1375 stage = EQUILIB_CHECK;
1377 finalElemAbundAttempts++;
1384 }
else if (ncAfter) {
1387 if (m_debug_print_lvl >= 2) {
1388 plogf(
" --- vcs_solve_tp: RANGE SPACE ERROR ENCOUNTERED\n");
1389 plogf(
" --- vcs_solve_tp: - Giving up on NE Element Abundance satisfaction \n");
1390 plogf(
" --- vcs_solve_tp: - However, NC Element Abundance criteria is satisfied \n");
1391 plogf(
" --- vcs_solve_tp: - Returning the calculated equilibrium condition ");
1394 rangeErrorFound = 1;
1395 giveUpOnElemAbund =
true;
1400 stage = EQUILIB_CHECK;
1407 stage = EQUILIB_CHECK;
1410 double VCS_SOLVE::vcs_minor_alt_calc(
size_t kspec,
size_t irxn,
bool* do_delete,
1413 double w_kspec = m_molNumSpecies_old[kspec];
1414 double dg_irxn = m_deltaGRxn_old[irxn];
1415 size_t iph = m_phaseID[kspec];
1419 if (w_kspec <= 0.0) {
1422 dg_irxn = std::max(dg_irxn, -200.0);
1424 sprintf(ANOTE,
"minor species alternative calc");
1426 if (dg_irxn >= 23.0) {
1427 double molNum_kspec_new = w_kspec * 1.0e-10;
1434 return molNum_kspec_new - w_kspec;
1436 if (fabs(dg_irxn) <= m_tolmin2) {
1442 double s = m_np_dLnActCoeffdMolNum(kspec,kspec) / m_tPhaseMoles_old[iph];
1453 double a =
clip(w_kspec * s, -1.0+1e-8, 100.0);
1454 double tmp =
clip(-dg_irxn / (1.0 + a), -200.0, 200.0);
1455 double wTrial = w_kspec * exp(tmp);
1456 double molNum_kspec_new = wTrial;
1458 if (wTrial > 100. * w_kspec) {
1459 double molNumMax = 0.0001 * m_tPhaseMoles_old[iph];
1460 if (molNumMax < 100. * w_kspec) {
1461 molNumMax = 100. * w_kspec;
1463 if (wTrial > molNumMax) {
1464 molNum_kspec_new = molNumMax;
1466 molNum_kspec_new = wTrial;
1468 }
else if (1.0E10 * wTrial < w_kspec) {
1469 molNum_kspec_new= 1.0E-10 * w_kspec;
1471 molNum_kspec_new = wTrial;
1480 return molNum_kspec_new - w_kspec;
1485 double dx = m_deltaGRxn_old[irxn]/ m_Faraday_dim;
1487 sprintf(ANOTE,
"voltage species alternative calc");
1493 int VCS_SOLVE::delta_species(
const size_t kspec,
double*
const delta_ptr)
1495 size_t irxn = kspec - m_numComponents;
1497 AssertThrowMsg(kspec >= m_numComponents,
"VCS_SOLVE::delta_species",
1498 "delete_species() ERROR: called for a component {}", kspec);
1502 double dx = *delta_ptr;
1503 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
1504 for (
size_t j = 0; j < m_numComponents; ++j) {
1505 if (m_molNumSpecies_old[j] > 0.0) {
1506 double tmp = sc_irxn[j] * dx;
1507 if (-tmp > m_molNumSpecies_old[j]) {
1509 dx = std::min(dx, - m_molNumSpecies_old[j] / sc_irxn[j]);
1515 if (m_molNumSpecies_old[j] <= 0.0 && sc_irxn[j] < 0.0) {
1523 m_molNumSpecies_old[kspec] += dx;
1524 size_t iph = m_phaseID[kspec];
1525 m_tPhaseMoles_old[iph] += dx;
1528 for (
size_t j = 0; j < m_numComponents; ++j) {
1529 double tmp = sc_irxn[j] * dx;
1532 m_molNumSpecies_old[j] += tmp;
1533 m_tPhaseMoles_old[iph] += tmp;
1535 m_molNumSpecies_old[j] = std::max(m_molNumSpecies_old[j], 0.0);
1542 int VCS_SOLVE::vcs_zero_species(
const size_t kspec)
1548 double dx = -m_molNumSpecies_old[kspec];
1550 retn = delta_species(kspec, &dx);
1551 if (!retn && m_debug_print_lvl >= 1) {
1552 plogf(
"vcs_zero_species: Couldn't zero the species %d, " 1553 "did delta of %g. orig conc of %g",
1554 kspec, dx, m_molNumSpecies_old[kspec] + dx);
1562 int VCS_SOLVE::vcs_delete_species(
const size_t kspec)
1564 const size_t klast = m_numSpeciesRdc - 1;
1565 const size_t iph = m_phaseID[kspec];
1567 const size_t irxn = kspec - m_numComponents;
1571 const int retn = vcs_zero_species(kspec);
1574 "Failed to delete a species!");
1580 --m_numRxnMinorZeroed;
1583 m_deltaGRxn_new[irxn] = 0.0;
1584 m_deltaGRxn_old[irxn] = 0.0;
1585 m_feSpecies_new[kspec] = 0.0;
1586 m_feSpecies_old[kspec] = 0.0;
1587 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec];
1590 if (kspec != klast) {
1591 vcs_switch_pos(
true, klast, kspec);
1596 &m_tPhaseMoles_old[0]);
1605 bool stillExists =
false;
1606 for (
size_t k = 0; k < m_numSpeciesRdc; k++) {
1608 m_phaseID[k] == iph && m_molNumSpecies_old[k] > 0.0) {
1614 vcs_delete_multiphase(iph);
1620 return (m_numRxnRdc == 0);
1623 void VCS_SOLVE::vcs_reinsert_deleted(
size_t kspec)
1625 size_t iph = m_phaseID[kspec];
1626 if (m_debug_print_lvl >= 2) {
1627 plogf(
" --- Add back a deleted species: %-12s\n", m_speciesName[kspec]);
1634 delta_species(kspec, &dx);
1637 if (m_SSPhase[kspec]) {
1639 --m_numRxnMinorZeroed;
1644 &m_molNumSpecies_old[0],
1645 &m_tPhaseMoles_old[0]);
1651 if (! m_SSPhase[kspec]) {
1654 for (
size_t k = 0; k < m_numSpeciesTot; k++) {
1666 ++m_numRxnMinorZeroed;
1668 if (kspec != (m_numSpeciesRdc - 1)) {
1670 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
1674 bool VCS_SOLVE::vcs_delete_multiphase(
const size_t iph)
1677 bool successful =
true;
1681 if (m_debug_print_lvl >= 2) {
1682 plogf(
" --- delete_multiphase %d, %s\n", iph, Vphase->
PhaseName);
1686 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1687 if (m_phaseID[kspec] == iph) {
1690 double dx = - m_molNumSpecies_old[kspec];
1693 int retn = delta_species(kspec, &dxTent);
1696 if (m_debug_print_lvl >= 2) {
1697 plogf(
" --- delete_multiphase %d, %s ERROR problems deleting species %s\n",
1698 iph, Vphase->
PhaseName, m_speciesName[kspec]);
1699 plogf(
" --- delta attempted: %g achieved: %g " 1700 " Zeroing it manually\n", dx, dxTent);
1702 m_molNumSpecies_old[kspec] = 0.0;
1703 m_molNumSpecies_new[kspec] = 0.0;
1704 m_deltaMolNumSpecies[kspec] = 0.0;
1709 m_molNumSpecies_old[kspec] = 0.0;
1710 m_molNumSpecies_new[kspec] = 0.0;
1711 m_deltaMolNumSpecies[kspec] = 0.0;
1721 double dxPerm = 0.0, dxPerm2 = 0.0;
1722 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
1723 if (m_phaseID[kcomp] == iph) {
1724 if (m_debug_print_lvl >= 2) {
1725 plogf(
" --- delete_multiphase One of the species is a component %d - %s with mole number %g\n",
1726 kcomp, m_speciesName[kcomp], m_molNumSpecies_old[kcomp]);
1728 if (m_molNumSpecies_old[kcomp] != 0.0) {
1729 for (
size_t kspec = m_numComponents; kspec < m_numSpeciesRdc; ++kspec) {
1730 size_t irxn = kspec - m_numComponents;
1731 if (m_phaseID[kspec] != iph) {
1732 if (m_stoichCoeffRxnMatrix(kcomp,irxn) != 0.0) {
1733 double dxWant = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(kcomp,irxn);
1734 if (dxWant + m_molNumSpecies_old[kspec] < 0.0) {
1735 dxPerm = -m_molNumSpecies_old[kspec];
1737 for (
size_t jcomp = 0; kcomp < m_numComponents; ++kcomp) {
1738 if (jcomp != kcomp) {
1739 if (m_phaseID[jcomp] == iph) {
1742 double dj = dxWant * m_stoichCoeffRxnMatrix(jcomp,irxn);
1743 if (dj + m_molNumSpecies_old[kcomp] < 0.0) {
1744 dxPerm2 = -m_molNumSpecies_old[kcomp] / m_stoichCoeffRxnMatrix(jcomp,irxn);
1746 if (fabs(dxPerm2) < fabs(dxPerm)) {
1753 if (dxPerm != 0.0) {
1754 delta_species(kspec, &dxPerm);
1760 if (m_molNumSpecies_old[kcomp] != 0.0) {
1761 if (m_debug_print_lvl >= 2) {
1762 plogf(
" --- delete_multiphase One of the species is a component %d - %s still with mole number %g\n",
1763 kcomp, m_speciesName[kcomp], m_molNumSpecies_old[kcomp]);
1764 plogf(
" --- zeroing it \n");
1766 m_molNumSpecies_old[kcomp] = 0.0;
1777 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
1778 if (m_phaseID[kspec] == iph) {
1779 m_molNumSpecies_old[kspec] = 0.0;
1780 m_molNumSpecies_new[kspec] = 0.0;
1781 m_deltaMolNumSpecies[kspec] = 0.0;
1786 if (m_debug_print_lvl >= 2) {
1787 plogf(
" --- Make %s", m_speciesName[kspec]);
1788 plogf(
" an active but zeroed species because its phase " 1791 if (kspec != (m_numSpeciesRdc - 1)) {
1793 vcs_switch_pos(
true, (m_numSpeciesRdc - 1), kspec);
1799 m_tPhaseMoles_old[iph] = 0.0;
1800 m_tPhaseMoles_new[iph] = 0.0;
1801 m_deltaPhaseMoles[iph] = 0.0;
1808 int VCS_SOLVE::vcs_recheck_deleted()
1811 if (m_debug_print_lvl >= 2) {
1812 plogf(
" --- Start rechecking deleted species in multispec phases\n");
1814 if (m_numSpeciesRdc == m_numSpeciesTot) {
1821 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
1822 size_t iph = m_phaseID[kspec];
1823 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_old[kspec])
1824 - m_lnMnaughtSpecies[kspec]
1825 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
1832 for (
size_t iph = 0; iph < m_numPhases; iph++) {
1833 if (m_tPhaseMoles_old[iph] > 0.0) {
1836 xtcutoff[iph] = 0.0;
1862 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1863 size_t kspec = m_indexRxnToSpecies[irxn];
1864 size_t iph = m_phaseID[kspec];
1865 if (m_tPhaseMoles_old[iph] == 0.0) {
1866 if (m_deltaGRxn_new[irxn] < 0.0) {
1867 vcs_reinsert_deleted(kspec);
1870 m_molNumSpecies_old[kspec] = 0.0;
1872 }
else if (m_tPhaseMoles_old[iph] > 0.0) {
1873 if (m_deltaGRxn_new[irxn] < xtcutoff[iph]) {
1874 vcs_reinsert_deleted(kspec);
1882 bool VCS_SOLVE::recheck_deleted_phase(
const int iphase)
1885 "Unused. To be removed after Cantera 2.3.");
1896 size_t irxn = kspec + m_numComponents;
1897 if (m_deltaGRxn_old[irxn] < 0.0) {
1903 double phaseDG = 1.0;
1904 for (
size_t kk = 0; kk < Vphase->
nSpecies(); kk++) {
1906 size_t irxn = kspec + m_numComponents;
1907 m_deltaGRxn_old[irxn] =
clip(m_deltaGRxn_old[irxn], -50.0, 50.0);
1908 phaseDG -= exp(-m_deltaGRxn_old[irxn]);
1911 if (phaseDG < 0.0) {
1917 size_t VCS_SOLVE::vcs_add_all_deleted()
1919 if (m_numSpeciesRdc == m_numSpeciesTot) {
1928 m_molNumSpecies_new = m_molNumSpecies_old;
1929 for (
int cits = 0; cits < 3; cits++) {
1930 for (
size_t kspec = m_numSpeciesRdc; kspec < m_numSpeciesTot; ++kspec) {
1931 size_t iph = m_phaseID[kspec];
1933 if (m_molNumSpecies_new[kspec] == 0.0) {
1939 m_feSpecies_new[kspec] = (m_SSfeSpecies[kspec] + log(m_actCoeffSpecies_new[kspec]) - m_lnMnaughtSpecies[kspec]
1940 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iph]);
1946 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1947 size_t kspec = m_indexRxnToSpecies[irxn];
1948 size_t iph = m_phaseID[kspec];
1949 if (m_tPhaseMoles_old[iph] > 0.0) {
1950 double maxDG = std::min(m_deltaGRxn_new[irxn], 690.0);
1951 double dx = m_tPhaseMoles_old[iph] * exp(- maxDG);
1952 m_molNumSpecies_new[kspec] = dx;
1956 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1957 size_t kspec = m_indexRxnToSpecies[irxn];
1958 size_t iph = m_phaseID[kspec];
1959 if (m_tPhaseMoles_old[iph] > 0.0) {
1960 double dx = m_molNumSpecies_new[kspec];
1961 size_t retn = delta_species(kspec, &dx);
1963 if (m_debug_print_lvl) {
1964 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1965 m_speciesName[kspec], kspec, dx);
1969 retn = delta_species(kspec, &dx);
1970 if (retn == 0 && m_debug_print_lvl) {
1971 plogf(
" --- add_deleted(): delta_species() failed for species %s (%d) with mol number %g\n",
1972 m_speciesName[kspec], kspec, dx);
1976 if (m_debug_print_lvl >= 2) {
1978 plogf(
" --- add_deleted(): species %s added back in with mol number %g",
1979 m_speciesName[kspec], dx);
1982 plogf(
" --- add_deleted(): species %s failed to be added back in");
1993 for (
size_t irxn = m_numRxnRdc; irxn < m_numRxnTot; ++irxn) {
1994 size_t kspec = m_indexRxnToSpecies[irxn];
1995 size_t iph = m_phaseID[kspec];
1996 if (m_tPhaseMoles_old[iph] > 0.0 && fabs(m_deltaGRxn_old[irxn]) > m_tolmin) {
1997 if (((m_molNumSpecies_old[kspec] * exp(-m_deltaGRxn_old[irxn])) >
2001 if (m_debug_print_lvl >= 2) {
2002 plogf(
" --- add_deleted(): species %s with mol number %g not converged: DG = %g",
2003 m_speciesName[kspec], m_molNumSpecies_old[kspec],
2004 m_deltaGRxn_old[irxn]);
2013 bool VCS_SOLVE::vcs_globStepDamp()
2015 double* dptr = &m_deltaGRxn_new[0];
2019 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2020 size_t kspec = irxn + m_numComponents;
2022 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2028 dptr = &m_deltaGRxn_old[0];
2029 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2030 size_t kspec = irxn + m_numComponents;
2032 s1 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2036 if (m_debug_print_lvl >= 2) {
2037 plogf(
" --- subroutine FORCE: Beginning Slope = %g\n", s1);
2038 plogf(
" --- subroutine FORCE: End Slope = %g\n", s2);
2042 if (m_debug_print_lvl >= 2) {
2043 plogf(
" --- subroutine FORCE produced no adjustments,");
2045 plogf(
" s1 positive but really small");
2047 plogf(
" failed s1 test");
2055 if (m_debug_print_lvl >= 2) {
2056 plogf(
" --- subroutine FORCE produced no adjustments, s2 < 0");
2064 if (fabs(s1 -s2) > 1.0E-200) {
2065 al = s1 / (s1 - s2);
2067 if (al >= 0.95 || al < 0.0) {
2068 if (m_debug_print_lvl >= 2) {
2069 plogf(
" --- subroutine FORCE produced no adjustments (al = %g)\n", al);
2073 if (m_debug_print_lvl >= 2) {
2074 plogf(
" --- subroutine FORCE produced a damping factor = %g\n", al);
2078 if (m_debug_print_lvl >= 2) {
2079 m_deltaGRxn_tmp = m_deltaGRxn_new;
2082 dptr = &m_molNumSpecies_new[0];
2083 for (
size_t kspec = 0; kspec < m_numSpeciesRdc; ++kspec) {
2084 m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] +
2085 al * m_deltaMolNumSpecies[kspec];
2087 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2088 m_tPhaseMoles_new[iph] = m_tPhaseMoles_old[iph] + al * m_deltaPhaseMoles[iph];
2092 if (m_debug_print_lvl >= 2) {
2093 plogf(
" --- subroutine FORCE adjusted the mole " 2094 "numbers, AL = %10.3f\n", al);
2107 dptr = &m_deltaGRxn_new[0];
2109 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
2110 size_t kspec = irxn + m_numComponents;
2112 s2 += dptr[irxn] * m_deltaMolNumSpecies[kspec];
2116 if (m_debug_print_lvl >= 2) {
2117 plogf(
" --- subroutine FORCE: Adj End Slope = %g", s2);
2123 int VCS_SOLVE::vcs_basopt(
const bool doJustComponents,
double aw[],
double sa[],
double sm[],
2124 double ss[],
double test,
bool*
const usedZeroedSpecies)
2128 size_t jlose =
npos;
2131 if (m_debug_print_lvl >= 2) {
2133 for (
size_t i=0; i<77; i++) {
2137 plogf(
" --- Subroutine BASOPT called to ");
2138 if (doJustComponents) {
2139 plogf(
"calculate the number of components\n");
2141 plogf(
"reevaluate the components\n");
2143 if (m_debug_print_lvl >= 2) {
2145 plogf(
" --- Formula Matrix used in BASOPT calculation\n");
2146 plogf(
" --- Active | ");
2147 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2148 plogf(
" %1d ", m_elementActive[j]);
2151 plogf(
" --- Species | ");
2152 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2153 writelog(
" {:>8.8s}", m_elementName[j]);
2156 for (k = 0; k < m_numSpeciesTot; k++) {
2157 writelog(
" --- {:>11.11s} | ", m_speciesName[k]);
2158 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2159 plogf(
" %8.2g", m_formulaMatrix(k,j));
2170 size_t ncTrial = std::min(m_numElemConstraints, m_numSpeciesTot);
2171 m_numComponents = ncTrial;
2172 *usedZeroedSpecies =
false;
2176 std::copy(m_molNumSpecies_old.begin(),
2177 m_molNumSpecies_old.begin() + m_numSpeciesTot, aw);
2180 for (k = 0; k < m_numSpeciesTot; k++) {
2190 while (jr < ncTrial) {
2198 k = vcs_basisOptMax(aw, jr, m_numSpeciesTot);
2238 *usedZeroedSpecies =
true;
2239 double maxConcPossKspec = 0.0;
2240 double maxConcPoss = 0.0;
2241 size_t kfound =
npos;
2242 int minNonZeroes = 100000;
2243 int nonZeroesKspec = 0;
2244 for (
size_t kspec = ncTrial; kspec < m_numSpeciesTot; kspec++) {
2246 maxConcPossKspec = 1.0E10;
2248 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
2250 double nu = m_formulaMatrix(kspec,j);
2253 maxConcPossKspec = std::min(m_elemAbundancesGoal[j] / nu, maxConcPossKspec);
2257 if ((maxConcPossKspec >= maxConcPoss) || (maxConcPossKspec > 1.0E-5)) {
2258 if (nonZeroesKspec <= minNonZeroes) {
2259 if (kfound ==
npos || nonZeroesKspec < minNonZeroes) {
2264 if (m_SSfeSpecies[kspec] <= m_SSfeSpecies[kfound]) {
2269 minNonZeroes = std::min(minNonZeroes, nonZeroesKspec);
2270 maxConcPoss = std::max(maxConcPoss, maxConcPossKspec);
2274 if (kfound ==
npos) {
2277 for (
size_t kspec = ncTrial; kspec < m_numSpeciesTot; kspec++) {
2278 if (aw[kspec] >= 0.0) {
2279 size_t irxn = kspec - ncTrial;
2280 if (m_deltaGRxn_new[irxn] < gmin) {
2281 gmin = m_deltaGRxn_new[irxn];
2290 if (aw[k] == test) {
2291 m_numComponents = jr;
2292 ncTrial = m_numComponents;
2293 size_t numPreDeleted = m_numRxnTot - m_numRxnRdc;
2294 if (numPreDeleted != (m_numSpeciesTot - m_numSpeciesRdc)) {
2295 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we shouldn't be here");
2297 m_numRxnTot = m_numSpeciesTot - ncTrial;
2298 m_numRxnRdc = m_numRxnTot - numPreDeleted;
2299 m_numSpeciesRdc = m_numSpeciesTot - numPreDeleted;
2300 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
2301 m_indexRxnToSpecies[i] = ncTrial + i;
2303 if (m_debug_print_lvl >= 2) {
2304 plogf(
" --- Total number of components found = %3d (ne = %d)\n ",
2305 ncTrial, m_numElemConstraints);
2319 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
2320 sm[j + jr*m_numElemConstraints] = m_formulaMatrix(k,j);
2326 for (
size_t j = 0; j < jl; ++j) {
2328 for (
size_t i = 0; i < m_numElemConstraints; ++i) {
2329 ss[j] += sm[i + jr*m_numElemConstraints] * sm[i + j*m_numElemConstraints];
2335 for (
size_t j = 0; j < jl; ++j) {
2336 for (
size_t i = 0; i < m_numElemConstraints; ++i) {
2337 sm[i + jr*m_numElemConstraints] -= ss[j] * sm[i + j*m_numElemConstraints];
2345 for (
size_t ml = 0; ml < m_numElemConstraints; ++ml) {
2346 sa[jr] += pow(sm[ml + jr*m_numElemConstraints], 2);
2350 if (sa[jr] > 1.0e-6) {
2357 if (m_debug_print_lvl >= 2) {
2358 plogf(
" --- %-12.12s", m_speciesName[k]);
2360 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[k]);
2362 plogf(
"(%9.2g)", m_molNumSpecies_old[k]);
2364 plogf(
" replaces %-12.12s", m_speciesName[jr]);
2366 plogf(
"(Volts = %9.2g)", m_molNumSpecies_old[jr]);
2368 plogf(
"(%9.2g)", m_molNumSpecies_old[jr]);
2370 plogf(
" as component %3d\n", jr);
2372 vcs_switch_pos(
false, jr, k);
2373 std::swap(aw[jr], aw[k]);
2374 }
else if (m_debug_print_lvl >= 2) {
2375 plogf(
" --- %-12.12s", m_speciesName[k]);
2377 plogf(
"(Volts = %9.2g) remains ", m_molNumSpecies_old[k]);
2379 plogf(
"(%9.2g) remains ", m_molNumSpecies_old[k]);
2381 plogf(
" as component %3d\n", jr);
2390 if (doJustComponents) {
2420 C.
resize(ncTrial, ncTrial);
2421 for (
size_t j = 0; j < ncTrial; ++j) {
2422 for (
size_t i = 0; i < ncTrial; ++i) {
2423 C(i, j) = m_formulaMatrix(j,i);
2426 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2427 k = m_indexRxnToSpecies[i];
2428 for (
size_t j = 0; j < ncTrial; ++j) {
2429 m_stoichCoeffRxnMatrix(j,i) = - m_formulaMatrix(k,j);
2434 solve(C, m_stoichCoeffRxnMatrix.
ptrColumn(0), m_numRxnTot, m_numElemConstraints);
2440 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2441 if (!m_elementActive[j] && !strcmp(m_elementName[j].c_str(),
"E")) {
2445 for (
size_t j = 0; j < m_numElemConstraints; j++) {
2446 if (m_elementActive[j] && !strncmp((m_elementName[j]).c_str(),
"cn_", 3)) {
2450 for (k = 0; k < m_numSpeciesTot; k++) {
2452 for (
size_t j = 0; j < ncTrial; ++j) {
2453 for (
size_t i = 0; i < ncTrial; ++i) {
2455 C(i, j) = m_formulaMatrix(j,juse);
2457 C(i, j) = m_formulaMatrix(j,i);
2461 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2462 k = m_indexRxnToSpecies[i];
2463 for (
size_t j = 0; j < ncTrial; ++j) {
2465 aw[j] = - m_formulaMatrix(k,juse);
2467 aw[j] = - m_formulaMatrix(k,j);
2472 solve(C, aw, 1, m_numElemConstraints);
2473 size_t i = k - ncTrial;
2474 for (
size_t j = 0; j < ncTrial; j++) {
2475 m_stoichCoeffRxnMatrix(j,i) = aw[j];
2481 for (
size_t i = 0; i < m_numRxnTot; i++) {
2483 for (
size_t j = 0; j < ncTrial; j++) {
2484 szTmp += fabs(m_stoichCoeffRxnMatrix(j,i));
2486 m_scSize[i] = szTmp;
2489 if (m_debug_print_lvl >= 2) {
2490 plogf(
" --- Components:");
2491 for (
size_t j = 0; j < ncTrial; j++) {
2494 plogf(
"\n --- Components Moles:");
2495 for (
size_t j = 0; j < ncTrial; j++) {
2497 plogf(
" % -10.3E", 0.0);
2499 plogf(
" % -10.3E", m_molNumSpecies_old[j]);
2502 plogf(
"\n --- NonComponent| Moles |");
2503 for (
size_t j = 0; j < ncTrial; j++) {
2504 plogf(
" %10.10s", m_speciesName[j]);
2507 for (
size_t i = 0; i < m_numRxnTot; i++) {
2508 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
2509 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]]);
2511 plogf(
"|% -10.3E|", 0.0);
2513 plogf(
"|% -10.3E|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
2515 for (
size_t j = 0; j < ncTrial; j++) {
2516 plogf(
" %+7.3f", m_stoichCoeffRxnMatrix(j,i));
2523 double sumMax = -1.0;
2526 for (
size_t i = 0; i < m_numRxnTot; ++i) {
2527 k = m_indexRxnToSpecies[i];
2529 for (
size_t j = 0; j < ncTrial; ++j) {
2531 sum = m_formulaMatrix(k,juse);
2532 for (
size_t n = 0; n < ncTrial; n++) {
2533 double numElements = m_formulaMatrix(n,juse);
2534 double coeff = m_stoichCoeffRxnMatrix(n,i);
2535 sum += coeff * numElements;
2538 sum = m_formulaMatrix(k,j);
2539 for (
size_t n = 0; n < ncTrial; n++) {
2540 double numElements = m_formulaMatrix(n,j);
2541 double coeff = m_stoichCoeffRxnMatrix(n,i);
2542 sum += coeff * numElements;
2545 if (fabs(sum) > sumMax) {
2553 if (fabs(sum) > 1.0E-6) {
2554 throw CanteraError(
"VCS_SOLVE::vcs_basopt",
"we have a prob");
2558 plogf(
" --- largest error in Stoich coeff = %g at rxn = %d ", sumMax, iMax);
2559 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[iMax]]);
2560 plogf(
" element = %d ", jMax);
2561 plogf(
"%-5.5s", m_elementName[jMax]);
2564 for (
size_t i=0; i<77; i++) {
2576 m_deltaMolNumPhase.zero();
2577 m_phaseParticipation.zero();
2582 for (
size_t irxn = 0; irxn < m_numRxnTot; ++irxn) {
2583 double* scrxn_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
2584 size_t kspec = m_indexRxnToSpecies[irxn];
2585 size_t iph = m_phaseID[kspec];
2586 m_deltaMolNumPhase(iph,irxn) = 1.0;
2587 m_phaseParticipation(iph,irxn)++;
2588 for (
size_t j = 0; j < ncTrial; ++j) {
2590 if (fabs(scrxn_ptr[j]) <= 1.0e-6) {
2593 m_deltaMolNumPhase(iph,irxn) += scrxn_ptr[j];
2594 m_phaseParticipation(iph,irxn)++;
2602 m_VCount->Time_basopt += tsecond;
2603 m_VCount->Basis_Opts++;
2607 size_t VCS_SOLVE::vcs_basisOptMax(
const double*
const molNum,
const size_t j,
2624 double big = molNum[j] * m_spSize[j] * 1.01;
2625 if (m_spSize[j] <= 0.0) {
2627 "spSize is nonpositive");
2629 for (
size_t i = j + 1; i < n; ++i) {
2630 if (m_spSize[i] <= 0.0) {
2632 "spSize is nonpositive");
2634 bool doSwap =
false;
2636 doSwap = (molNum[i] * m_spSize[i]) > big;
2637 if (!m_SSPhase[i] && doSwap) {
2638 doSwap = molNum[i] > (molNum[largest] * 1.001);
2642 doSwap = (molNum[i] * m_spSize[i]) > big;
2644 doSwap = molNum[i] > (molNum[largest] * 1.001);
2647 doSwap = (molNum[i] * m_spSize[i]) > big;
2652 big = molNum[i] * m_spSize[i] * 1.01;
2658 int VCS_SOLVE::vcs_species_type(
const size_t kspec)
const 2665 size_t iph = m_phaseID[kspec];
2666 int irxn = int(kspec) - int(m_numComponents);
2667 int phaseExist = m_VolPhaseList[iph]->exists();
2670 if (m_molNumSpecies_old[kspec] <= 0.0) {
2671 if (m_tPhaseMoles_old[iph] <= 0.0 && !m_SSPhase[kspec]) {
2677 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
2679 double atomComp = m_formulaMatrix(kspec,j);
2680 if (atomComp > 0.0) {
2681 double maxPermissible = m_elemAbundancesGoal[j] / atomComp;
2683 if (m_debug_print_lvl >= 2) {
2684 plogf(
" --- %s can not be nonzero because" 2685 " needed element %s is zero\n",
2686 m_speciesName[kspec], m_elementName[j]);
2688 if (m_SSPhase[kspec]) {
2703 for (
size_t j = 0; j < m_numComponents; ++j) {
2704 double stoicC = m_stoichCoeffRxnMatrix(j,irxn);
2705 if (stoicC != 0.0) {
2706 double negChangeComp = - stoicC;
2707 if (negChangeComp > 0.0) {
2708 if (m_molNumSpecies_old[j] < 1.0E-60) {
2709 if (m_debug_print_lvl >= 2) {
2710 plogf(
" --- %s is prevented from popping into existence because" 2711 " a needed component to be consumed, %s, has a zero mole number\n",
2712 m_speciesName[kspec], m_speciesName[j]);
2714 if (m_SSPhase[kspec]) {
2720 }
else if (negChangeComp < 0.0) {
2721 if (m_VolPhaseList[m_phaseID[j]]->exists() <= 0) {
2722 if (m_debug_print_lvl >= 2) {
2723 plogf(
" --- %s is prevented from popping into existence because" 2724 " a needed component %s is in a zeroed-phase that would be " 2725 "popped into existence at the same time\n",
2726 m_speciesName[kspec], m_speciesName[j]);
2728 if (m_SSPhase[kspec]) {
2739 if (irxn >= 0 && m_deltaGRxn_old[irxn] >= 0.0) {
2741 if (m_SSPhase[kspec]) {
2755 if (m_tPhaseMoles_old[iph] > 0.0) {
2756 if (m_SSPhase[kspec]) {
2767 if (m_tPhaseMoles_old[iph] <= 0.0) {
2768 if (m_SSPhase[kspec]) {
2780 if (m_SSPhase[kspec]) {
2789 if (m_molNumSpecies_old[kspec] > (m_tPhaseMoles_old[iph] * 0.001)) {
2801 double szAdj = m_scSize[irxn] * std::sqrt((
double)m_numRxnTot);
2802 for (
size_t k = 0; k < m_numComponents; ++k) {
2803 if (!m_SSPhase[k] && m_stoichCoeffRxnMatrix(k,irxn) != 0.0 && m_molNumSpecies_old[kspec] * szAdj >= m_molNumSpecies_old[k] * 0.01) {
2811 void VCS_SOLVE::vcs_chemPotPhase(
const int stateCalc,
2812 const size_t iph,
const double*
const molNum,
2813 double*
const ac,
double*
const mu_i,
2814 const bool do_deleted)
2817 "Unused. To be removed after Cantera 2.3.");
2820 double tMoles = TPhInertMoles[iph];
2821 for (
size_t k = 0; k < nkk; k++) {
2823 tMoles += molNum[kspec];
2825 double tlogMoles = 0.0;
2827 tlogMoles = log(tMoles);
2834 double Faraday_phi = m_Faraday_dim * phi;
2836 for (
size_t k = 0; k < nkk; k++) {
2838 if (kspec >= m_numComponents) {
2845 AssertThrowMsg(molNum[kspec] == phi,
"VCS_SOLVE::vcs_chemPotPhase",
2846 "We have an inconsistency!");
2847 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_chemPotPhase",
2848 "We have an unexpected situation!");
2849 mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
2851 if (m_SSPhase[kspec]) {
2852 mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
2855 - tlogMoles - m_lnMnaughtSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
2857 mu_i[kspec] = m_SSfeSpecies[kspec] + log(ac[kspec] * molNum[kspec])
2858 - tlogMoles - m_lnMnaughtSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
2864 void VCS_SOLVE::vcs_dfe(
const int stateCalc,
2865 const int ll,
const size_t lbot,
const size_t ltop)
2867 double* tPhMoles_ptr=0;
2868 double* actCoeff_ptr=0;
2869 double* feSpecies=0;
2872 feSpecies = &m_feSpecies_old[0];
2873 tPhMoles_ptr = &m_tPhaseMoles_old[0];
2874 actCoeff_ptr = &m_actCoeffSpecies_old[0];
2875 molNum = &m_molNumSpecies_old[0];
2877 feSpecies = &m_feSpecies_new[0];
2878 tPhMoles_ptr = &m_tPhaseMoles_new[0];
2879 actCoeff_ptr = &m_actCoeffSpecies_new[0];
2880 molNum = &m_molNumSpecies_new[0];
2883 "Subroutine vcs_dfe called with bad stateCalc value: {}", stateCalc);
2887 "called with wrong units state");
2889 if (m_debug_print_lvl >= 2) {
2892 plogf(
" --- Subroutine vcs_dfe called for one species: ");
2893 plogf(
"%-12.12s", m_speciesName[lbot]);
2895 plogf(
" --- Subroutine vcs_dfe called for all species");
2897 }
else if (ll > 0) {
2898 plogf(
" --- Subroutine vcs_dfe called for components and minors");
2900 plogf(
" --- Subroutine vcs_dfe called for components and majors");
2903 plogf(
" using tentative solution");
2908 double* tlogMoles = &m_TmpPhase[0];
2912 double* tPhInertMoles = &TPhInertMoles[0];
2913 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2914 tlogMoles[iph] = tPhInertMoles[iph];
2917 for (
size_t kspec = 0; kspec < m_numSpeciesTot; kspec++) {
2919 size_t iph = m_phaseID[kspec];
2920 tlogMoles[iph] += molNum[kspec];
2923 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2925 "VCS_SOLVE::vcs_dfe",
2926 "phase Moles may be off, iph = {}, {} {}",
2927 iph, tlogMoles[iph], tPhMoles_ptr[iph]);
2929 m_TmpPhase.assign(m_TmpPhase.size(), 0.0);
2930 for (
size_t iph = 0; iph < m_numPhases; iph++) {
2931 if (tPhMoles_ptr[iph] > 0.0) {
2932 tlogMoles[iph] = log(tPhMoles_ptr[iph]);
2939 l2 = m_numComponents;
2948 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
2963 for (
size_t kspec = l1; kspec < l2; ++kspec) {
2964 size_t iphase = m_phaseID[kspec];
2966 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
2967 "We have an inconsistency!");
2968 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
2969 "We have an unexpected situation!");
2970 feSpecies[kspec] = m_SSfeSpecies[kspec]
2971 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2973 if (m_SSPhase[kspec]) {
2974 feSpecies[kspec] = m_SSfeSpecies[kspec]
2975 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2978 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2979 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2982 size_t iph = m_phaseID[kspec];
2983 if (tPhMoles_ptr[iph] > 0.0) {
2984 feSpecies[kspec] = m_SSfeSpecies[kspec]
2986 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2987 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2989 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
2990 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
2993 feSpecies[kspec] = m_SSfeSpecies[kspec]
2994 + log(actCoeff_ptr[kspec] * molNum[kspec])
2995 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
2996 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3004 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3005 size_t kspec = m_indexRxnToSpecies[irxn];
3007 size_t iphase = m_phaseID[kspec];
3009 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
3010 "We have an inconsistency!");
3011 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
3012 "We have an unexpected situation!");
3013 feSpecies[kspec] = m_SSfeSpecies[kspec]
3014 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3016 if (m_SSPhase[kspec]) {
3017 feSpecies[kspec] = m_SSfeSpecies[kspec]
3018 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3021 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3022 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3025 size_t iph = m_phaseID[kspec];
3026 if (tPhMoles_ptr[iph] > 0.0) {
3027 feSpecies[kspec] = m_SSfeSpecies[kspec]
3029 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3030 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3032 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3033 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3036 feSpecies[kspec] = m_SSfeSpecies[kspec]
3037 + log(actCoeff_ptr[kspec] * molNum[kspec])
3038 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3039 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3045 }
else if (ll > 0) {
3047 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3048 size_t kspec = m_indexRxnToSpecies[irxn];
3050 size_t iphase = m_phaseID[kspec];
3052 AssertThrowMsg(molNum[kspec] == m_phasePhi[iphase],
"VCS_SOLVE::vcs_dfe",
3053 "We have an inconsistency!");
3054 AssertThrowMsg(m_chargeSpecies[kspec] == -1.0,
"VCS_SOLVE::vcs_dfe",
3055 "We have an unexpected situation!");
3056 feSpecies[kspec] = m_SSfeSpecies[kspec]
3057 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3059 if (m_SSPhase[kspec]) {
3060 feSpecies[kspec] = m_SSfeSpecies[kspec]
3061 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3064 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3065 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3068 size_t iph = m_phaseID[kspec];
3069 if (tPhMoles_ptr[iph] > 0.0) {
3070 feSpecies[kspec] = m_SSfeSpecies[kspec]
3072 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3073 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3075 feSpecies[kspec] = m_SSfeSpecies[kspec] - m_lnMnaughtSpecies[kspec]
3076 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3079 feSpecies[kspec] = m_SSfeSpecies[kspec]
3080 + log(actCoeff_ptr[kspec] * molNum[kspec])
3081 - tlogMoles[m_phaseID[kspec]] - m_lnMnaughtSpecies[kspec]
3082 + m_chargeSpecies[kspec] * m_Faraday_dim * m_phasePhi[iphase];
3091 void VCS_SOLVE::vcs_printSpeciesChemPot(
const int stateCalc)
const 3094 "Unused. To be removed after Cantera 2.3.");
3095 double mfValue = 1.0;
3096 bool zeroedPhase =
false;
3098 const double* molNum = &m_molNumSpecies_old[0];
3099 const double* actCoeff_ptr = &m_actCoeffSpecies_old[0];
3101 actCoeff_ptr = &m_actCoeffSpecies_new[0];
3102 molNum = &m_molNumSpecies_new[0];
3105 double* tMoles = &m_TmpPhase[0];
3106 const double* tPhInertMoles = &TPhInertMoles[0];
3107 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3108 tMoles[iph] = tPhInertMoles[iph];
3110 for (
size_t kspec = 0; kspec < m_numSpeciesTot; kspec++) {
3112 size_t iph = m_phaseID[kspec];
3113 tMoles[iph] += molNum[kspec];
3117 double RT = m_temperature * GasConstant;
3118 writelog(
" --- CHEMICAL POT TABLE (J/kmol) Name PhID MolFR ChemoSS " 3119 " logMF Gamma Elect extra ElectrChem\n");
3121 writeline(
'-', 132);
3123 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
3125 size_t iphase = m_phaseID[kspec];
3132 zeroedPhase =
false;
3134 if (tMoles[iphase] > 0.0) {
3138 mfValue = molNum[kspec]/tMoles[iphase];
3141 size_t klocal = m_speciesLocalPhaseIndex[kspec];
3142 mfValue = Vphase->moleFraction(klocal);
3145 double elect = m_chargeSpecies[kspec] * m_Faraday_dim * volts;
3146 double comb = - m_lnMnaughtSpecies[kspec];
3147 double total = (m_SSfeSpecies[kspec] + log(mfValue) + elect + log(actCoeff_ptr[kspec]) + comb);
3154 writelogf(
"%-24.24s", m_speciesName[kspec]);
3157 writelogf(
" % -12.4e", m_SSfeSpecies[kspec] * RT);
3158 writelogf(
" % -12.4e", log(mfValue) * RT);
3159 writelogf(
" % -12.4e", log(actCoeff_ptr[kspec]) * RT);
3165 writeline(
'-', 132);
3168 void VCS_SOLVE::prneav()
const 3171 "Unused. To be removed after Cantera 2.3.");
3172 vector_fp eav(m_numElemConstraints, 0.0);
3174 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3175 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
3177 eav[j] += m_formulaMatrix(i,j) * m_molNumSpecies_old[i];
3182 plogf(
"--------------------------------------------------");
3183 plogf(
"ELEMENT ABUNDANCE VECTOR:\n");
3184 plogf(
" Element Now Orignal Deviation Type\n");
3185 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3187 plogf(
"%-2.2s", m_elementName[j]);
3188 plogf(
" = %15.6E %15.6E %15.6E %3d\n",
3189 eav[j], m_elemAbundancesGoal[j], eav[j] - m_elemAbundancesGoal[j], m_elType[j]);
3190 if (m_elemAbundancesGoal[j] != 0.) {
3191 if (fabs(eav[j] - m_elemAbundancesGoal[j]) > m_elemAbundancesGoal[j] * 5.0e-9) {
3195 if (fabs(eav[j]) > 1.0e-10) {
3201 plogf(
"Element abundance check failure\n");
3203 plogf(
"--------------------------------------------------");
3207 double VCS_SOLVE::l2normdg(
double dgLocal[])
const 3209 if (m_numRxnRdc <= 0) {
3213 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3214 size_t kspec = irxn + m_numComponents;
3216 dgLocal[irxn] < 0.0) {
3218 tmp += dgLocal[irxn] * dgLocal[irxn];
3222 return std::sqrt(tmp / m_numRxnRdc);
3225 double VCS_SOLVE::vcs_tmoles()
3227 for (
size_t i = 0; i < m_numPhases; i++) {
3228 m_tPhaseMoles_old[i] = TPhInertMoles[i];
3230 for (
size_t i = 0; i < m_numSpeciesTot; i++) {
3232 m_tPhaseMoles_old[m_phaseID[i]] += m_molNumSpecies_old[i];
3236 for (
size_t i = 0; i < m_numPhases; i++) {
3237 sum += m_tPhaseMoles_old[i];
3239 if (m_tPhaseMoles_old[i] == 0.0) {
3245 m_totalMolNum = sum;
3246 return m_totalMolNum;
3249 void VCS_SOLVE::check_tmoles()
const 3252 for (
size_t i = 0; i < m_numPhases; i++) {
3253 double m_tPhaseMoles_old_a = TPhInertMoles[i];
3255 for (
size_t k = 0; k < m_numSpeciesTot; k++) {
3257 m_tPhaseMoles_old_a += m_molNumSpecies_old[k];
3260 sum += m_tPhaseMoles_old_a;
3262 double denom = m_tPhaseMoles_old[i]+ m_tPhaseMoles_old_a + 1.0E-19;
3263 if (!
vcs_doubleEqual(m_tPhaseMoles_old[i]/denom, m_tPhaseMoles_old_a/denom)) {
3264 plogf(
"check_tmoles: we have found a problem with phase %d: %20.15g, %20.15g\n",
3265 i, m_tPhaseMoles_old[i], m_tPhaseMoles_old_a);
3270 void VCS_SOLVE::vcs_updateVP(
const int vcsState)
3272 for (
size_t i = 0; i < m_numPhases; i++) {
3276 &m_molNumSpecies_old[0],
3277 &m_tPhaseMoles_old[0]);
3280 &m_molNumSpecies_new[0],
3281 &m_tPhaseMoles_new[0]);
3284 "wrong stateCalc value: {}", vcsState);
3289 bool VCS_SOLVE::vcs_evaluate_speciesType()
3291 m_numRxnMinorZeroed = 0;
3292 if (m_debug_print_lvl >= 2) {
3293 plogf(
" --- Species Status decision is reevaluated: All species are minor except for:\n");
3294 }
else if (m_debug_print_lvl >= 5) {
3295 plogf(
" --- Species Status decision is reevaluated");
3298 for (
size_t kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
3299 m_speciesStatus[kspec] = vcs_species_type(kspec);
3300 if (m_debug_print_lvl >= 5) {
3301 plogf(
" --- %-16s: ", m_speciesName[kspec]);
3302 if (kspec < m_numComponents) {
3307 plogf(
" %10.3g ", m_molNumSpecies_old[kspec]);
3309 plogf(
"%s\n", sString);
3310 }
else if (m_debug_print_lvl >= 2) {
3312 switch (m_speciesStatus[kspec]) {
3316 plogf(
" --- Major Species : %-s\n", m_speciesName[kspec]);
3319 plogf(
" --- Purposely Zeroed-Phase Species (not in problem): %-s\n",
3320 m_speciesName[kspec]);
3323 plogf(
" --- Zeroed-MS Phase Species: %-s\n", m_speciesName[kspec]);
3326 plogf(
" --- Zeroed-SS Phase Species: %-s\n", m_speciesName[kspec]);
3329 plogf(
" --- Deleted-Small Species : %-s\n", m_speciesName[kspec]);
3332 plogf(
" --- Zeroed Species in an active MS phase (tmp): %-s\n",
3333 m_speciesName[kspec]);
3336 plogf(
" --- Zeroed Species in an active MS phase (Stoich Constraint): %-s\n",
3337 m_speciesName[kspec]);
3340 plogf(
" --- InterfaceVoltage Species: %-s\n", m_speciesName[kspec]);
3343 throw CanteraError(
"VCS_SOLVE::vcs_evaluate_speciesType",
3344 "Unknown type: {}", m_speciesStatus[kspec]);
3349 ++m_numRxnMinorZeroed;
3352 if (m_debug_print_lvl >= 2) {
3356 return (m_numRxnMinorZeroed >= m_numRxnRdc);
3359 void VCS_SOLVE::vcs_deltag(
const int L,
const bool doDeleted,
3360 const int vcsState,
const bool alterZeroedPhases)
3362 size_t irxnl = m_numRxnRdc;
3364 irxnl = m_numRxnTot;
3369 double* molNumSpecies;
3370 double* actCoeffSpecies;
3372 deltaGRxn = &m_deltaGRxn_new[0];
3373 feSpecies = &m_feSpecies_new[0];
3374 molNumSpecies = &m_molNumSpecies_new[0];
3375 actCoeffSpecies = &m_actCoeffSpecies_new[0];
3377 deltaGRxn = &m_deltaGRxn_old[0];
3378 feSpecies = &m_feSpecies_old[0];
3379 molNumSpecies = &m_molNumSpecies_old[0];
3380 actCoeffSpecies = &m_actCoeffSpecies_old[0];
3382 throw CanteraError(
"VCS_SOLVE::vcs_deltag",
"bad vcsState");
3385 if (m_debug_print_lvl >= 2) {
3386 plogf(
" --- Subroutine vcs_deltag called for ");
3388 plogf(
"major noncomponents\n");
3389 }
else if (L == 0) {
3390 plogf(
"all noncomponents\n");
3392 plogf(
"minor noncomponents\n");
3398 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3399 size_t kspec = irxn + m_numComponents;
3402 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3403 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3404 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3405 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3411 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3415 }
else if (L == 0) {
3417 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3419 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3420 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3421 for (
size_t kspec = 0; kspec < m_numComponents; ++kspec) {
3422 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3424 dtmp_ptr[kspec] < 0.0) {
3429 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3434 for (
size_t irxn = 0; irxn < m_numRxnRdc; ++irxn) {
3435 size_t kspec = irxn + m_numComponents;
3438 deltaGRxn[irxn] = feSpecies[m_indexRxnToSpecies[irxn]];
3439 double* dtmp_ptr = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3440 for (kspec = 0; kspec < m_numComponents; ++kspec) {
3441 deltaGRxn[irxn] += dtmp_ptr[kspec] * feSpecies[kspec];
3443 dtmp_ptr[kspec] < 0.0) {
3448 deltaGRxn[irxn] = std::max(0.0, deltaGRxn[irxn]);
3493 if (alterZeroedPhases &&
false) {
3494 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3499 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3502 sum += molNumSpecies[kspec];
3515 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3518 if (kspec >= m_numComponents) {
3519 size_t irxn = kspec - m_numComponents;
3520 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
3521 poly += exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
3529 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
3531 if (kspec >= m_numComponents) {
3532 size_t irxn = kspec - m_numComponents;
3533 deltaGRxn[irxn] = 1.0 - poly;
3541 void VCS_SOLVE::vcs_printDeltaG(
const int stateCalc)
3543 double* deltaGRxn = &m_deltaGRxn_old[0];
3544 double* feSpecies = &m_feSpecies_old[0];
3545 double* molNumSpecies = &m_molNumSpecies_old[0];
3546 const double* tPhMoles_ptr = &m_tPhaseMoles_old[0];
3547 const double* actCoeff_ptr = &m_actCoeffSpecies_old[0];
3549 deltaGRxn = &m_deltaGRxn_new[0];
3550 feSpecies = &m_feSpecies_new[0];
3551 molNumSpecies = &m_molNumSpecies_new[0];
3552 actCoeff_ptr = &m_actCoeffSpecies_new[0];
3553 tPhMoles_ptr = &m_tPhaseMoles_new[0];
3555 double RT = m_temperature * GasConstant;
3556 bool zeroedPhase =
false;
3557 if (m_debug_print_lvl >= 2) {
3558 plogf(
" --- DELTA_G TABLE Components:");
3559 for (
size_t j = 0; j < m_numComponents; j++) {
3562 plogf(
"\n --- Components Moles:");
3563 for (
size_t j = 0; j < m_numComponents; j++) {
3564 plogf(
"%10.3g", m_molNumSpecies_old[j]);
3566 plogf(
"\n --- NonComponent| Moles | ");
3567 for (
size_t j = 0; j < m_numComponents; j++) {
3568 plogf(
"%-10.10s", m_speciesName[j]);
3571 for (
size_t i = 0; i < m_numRxnTot; i++) {
3572 plogf(
" --- %3d ", m_indexRxnToSpecies[i]);
3573 plogf(
"%-10.10s", m_speciesName[m_indexRxnToSpecies[i]]);
3577 plogf(
"|%10.3g|", m_molNumSpecies_old[m_indexRxnToSpecies[i]]);
3579 for (
size_t j = 0; j < m_numComponents; j++) {
3580 plogf(
" %6.2f", m_stoichCoeffRxnMatrix(j,i));
3585 for (
int i=0; i<77; i++) {
3591 writelog(
" --- DeltaG Table (J/kmol) Name PhID MoleNum MolFR " 3592 " ElectrChemStar ElectrChem DeltaGStar DeltaG(Pred) Stability\n");
3594 writeline(
'-', 132);
3596 for (
size_t kspec = 0; kspec < m_numSpeciesTot; kspec++) {
3598 if (kspec >= m_numComponents) {
3599 irxn = kspec - m_numComponents;
3601 double mfValue = 1.0;
3602 size_t iphase = m_phaseID[kspec];
3603 const vcs_VolPhase* Vphase = m_VolPhaseList[iphase];
3609 zeroedPhase =
false;
3611 if (tPhMoles_ptr[iphase] > 0.0) {
3615 mfValue = molNumSpecies[kspec] / tPhMoles_ptr[iphase];
3618 size_t klocal = m_speciesLocalPhaseIndex[kspec];
3619 mfValue = Vphase->moleFraction(klocal);
3626 double feFull = feSpecies[kspec];
3629 feFull += log(actCoeff_ptr[kspec]) + log(mfValue);
3631 writelogf(
"%-24.24s", m_speciesName[kspec]);
3636 writelogf(
" % -12.4e", molNumSpecies[kspec]);
3639 writelogf(
" % -12.4e", feSpecies[kspec] * RT);
3642 writelogf(
" % -12.4e", deltaGRxn[irxn] * RT);
3643 writelogf(
" % -12.4e", (deltaGRxn[irxn] + feFull - feSpecies[kspec]) * RT);
3645 if (deltaGRxn[irxn] < 0.0) {
3646 if (molNumSpecies[kspec] > 0.0) {
3651 }
else if (deltaGRxn[irxn] > 0.0) {
3652 if (molNumSpecies[kspec] > 0.0) {
3664 writeline(
'-', 132);
3667 void VCS_SOLVE::vcs_deltag_Phase(
const size_t iphase,
const bool doDeleted,
3668 const int stateCalc,
const bool alterZeroedPhases)
3671 "Unused. To be removed after Cantera 2.3.");
3672 double* feSpecies=0;
3673 double* deltaGRxn=0;
3674 double* actCoeffSpecies=0;
3676 feSpecies = &m_feSpecies_new[0];
3677 deltaGRxn = &m_deltaGRxn_new[0];
3678 actCoeffSpecies = &m_actCoeffSpecies_new[0];
3680 feSpecies = &m_feSpecies_old[0];
3681 deltaGRxn = &m_deltaGRxn_old[0];
3682 actCoeffSpecies = &m_actCoeffSpecies_old[0];
3684 throw CanteraError(
"VCS_SOLVE::vcs_deltag_Phase",
"bad stateCalc");
3687 size_t irxnl = (doDeleted) ? m_numRxnTot : m_numRxnRdc;
3690 if (m_debug_print_lvl >= 2) {
3691 plogf(
" --- Subroutine vcs_deltag_Phase called for phase %d\n",
3698 AssertThrowMsg(iphase == m_phaseID[kspec],
"VCS_SOLVE::vcs_deltag_Phase",
3700 if (kspec >= m_numComponents) {
3701 size_t irxn = kspec - m_numComponents;
3702 deltaGRxn[irxn] = feSpecies[kspec];
3703 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
3704 deltaGRxn[irxn] += m_stoichCoeffRxnMatrix(kcomp,irxn) * feSpecies[kcomp];
3709 bool zeroedPhase =
true;
3710 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3711 size_t kspec = m_indexRxnToSpecies[irxn];
3713 if (m_molNumSpecies_old[kspec] > 0.0) {
3714 zeroedPhase =
false;
3716 deltaGRxn[irxn] = feSpecies[kspec];
3717 for (
size_t kcomp = 0; kcomp < m_numComponents; ++kcomp) {
3718 deltaGRxn[irxn] += m_stoichCoeffRxnMatrix(kcomp,irxn) * feSpecies[kcomp];
3757 if (alterZeroedPhases && zeroedPhase) {
3758 double phaseDG = 1.0;
3759 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3760 size_t kspec = m_indexRxnToSpecies[irxn];
3761 if (m_phaseID[kspec] == iphase) {
3762 deltaGRxn[irxn] =
clip(deltaGRxn[irxn], -50.0, 50.0);
3763 phaseDG -= exp(-deltaGRxn[irxn])/actCoeffSpecies[kspec];
3768 for (
size_t irxn = 0; irxn < irxnl; ++irxn) {
3769 size_t kspec = m_indexRxnToSpecies[irxn];
3770 if (m_phaseID[kspec] == iphase) {
3771 deltaGRxn[irxn] = 1.0 - phaseDG;
3778 void VCS_SOLVE::vcs_switch_pos(
const bool ifunc,
const size_t k1,
const size_t k2)
3783 if (k1 >= m_numSpeciesTot || k2 >= m_numSpeciesTot) {
3784 plogf(
"vcs_switch_pos: ifunc = 0: inappropriate args: %d %d\n",
3791 size_t kp1 = m_speciesLocalPhaseIndex[k1];
3792 size_t kp2 = m_speciesLocalPhaseIndex[k2];
3799 std::swap(m_speciesName[k1], m_speciesName[k2]);
3800 std::swap(m_molNumSpecies_old[k1], m_molNumSpecies_old[k2]);
3801 std::swap(m_speciesUnknownType[k1], m_speciesUnknownType[k2]);
3802 std::swap(m_molNumSpecies_new[k1], m_molNumSpecies_new[k2]);
3803 std::swap(m_SSfeSpecies[k1], m_SSfeSpecies[k2]);
3804 std::swap(m_spSize[k1], m_spSize[k2]);
3805 std::swap(m_deltaMolNumSpecies[k1], m_deltaMolNumSpecies[k2]);
3806 std::swap(m_feSpecies_old[k1], m_feSpecies_old[k2]);
3807 std::swap(m_feSpecies_new[k1], m_feSpecies_new[k2]);
3808 std::swap(m_SSPhase[k1], m_SSPhase[k2]);
3809 std::swap(m_phaseID[k1], m_phaseID[k2]);
3810 std::swap(m_speciesMapIndex[k1], m_speciesMapIndex[k2]);
3811 std::swap(m_speciesLocalPhaseIndex[k1], m_speciesLocalPhaseIndex[k2]);
3812 std::swap(m_actConventionSpecies[k1], m_actConventionSpecies[k2]);
3813 std::swap(m_lnMnaughtSpecies[k1], m_lnMnaughtSpecies[k2]);
3814 std::swap(m_actCoeffSpecies_new[k1], m_actCoeffSpecies_new[k2]);
3815 std::swap(m_actCoeffSpecies_old[k1], m_actCoeffSpecies_old[k2]);
3816 std::swap(m_wtSpecies[k1], m_wtSpecies[k2]);
3817 std::swap(m_chargeSpecies[k1], m_chargeSpecies[k2]);
3818 std::swap(m_speciesThermoList[k1], m_speciesThermoList[k2]);
3819 std::swap(m_PMVolumeSpecies[k1], m_PMVolumeSpecies[k2]);
3821 for (
size_t j = 0; j < m_numElemConstraints; ++j) {
3822 std::swap(m_formulaMatrix(k1,j), m_formulaMatrix(k2,j));
3824 if (m_useActCoeffJac && k1 != k2) {
3825 for (
size_t i = 0; i < m_numSpeciesTot; i++) {
3826 std::swap(m_np_dLnActCoeffdMolNum(k1,i), m_np_dLnActCoeffdMolNum(k2,i));
3828 for (
size_t i = 0; i < m_numSpeciesTot; i++) {
3829 std::swap(m_np_dLnActCoeffdMolNum(i,k1), m_np_dLnActCoeffdMolNum(i,k2));
3832 std::swap(m_speciesStatus[k1], m_speciesStatus[k2]);
3837 size_t i1 = k1 - m_numComponents;
3838 size_t i2 = k2 - m_numComponents;
3839 if (i1 > m_numRxnTot || i2 >= m_numRxnTot) {
3840 plogf(
"switch_pos: ifunc = 1: inappropriate noncomp values: %d %d\n",
3843 for (
size_t j = 0; j < m_numComponents; ++j) {
3844 std::swap(m_stoichCoeffRxnMatrix(j,i1), m_stoichCoeffRxnMatrix(j,i2));
3846 std::swap(m_scSize[i1], m_scSize[i2]);
3847 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3848 std::swap(m_deltaMolNumPhase(iph,i1), m_deltaMolNumPhase(iph,i2));
3849 std::swap(m_phaseParticipation(iph,i1),
3850 m_phaseParticipation(iph,i2));
3852 std::swap(m_deltaGRxn_new[i1], m_deltaGRxn_new[i2]);
3853 std::swap(m_deltaGRxn_old[i1], m_deltaGRxn_old[i2]);
3854 std::swap(m_deltaGRxn_tmp[i1], m_deltaGRxn_tmp[i2]);
3858 double VCS_SOLVE::vcs_birthGuess(
const int kspec)
3861 "Unused. To be removed after Cantera 2.3.");
3862 size_t irxn = kspec - m_numComponents;
3871 "VCS_SOLVE::vcs_birthGuess",
"we shouldn't be here");
3872 if (!m_SSPhase[kspec]) {
3876 double dxm = vcs_minor_alt_calc(kspec, irxn, &soldel_ret);
3888 double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
3889 for (
size_t j = 0; j < m_numComponents; ++j) {
3892 if (m_molNumSpecies_old[j] > 0.0) {
3893 double tmp = sc_irxn[j] * dx;
3894 if (3.0*(-tmp) > m_molNumSpecies_old[j]) {
3895 dx = std::min(dx, - 0.3333* m_molNumSpecies_old[j] / sc_irxn[j]);
3898 if (m_molNumSpecies_old[j] <= 0.0 && sc_irxn[j] < 0.0) {
3906 void VCS_SOLVE::vcs_setFlagsVolPhases(
const bool upToDate,
const int stateCalc)
3909 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3910 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
3913 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3914 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
3919 void VCS_SOLVE::vcs_setFlagsVolPhase(
const size_t iph,
const bool upToDate,
3920 const int stateCalc)
3923 m_VolPhaseList[iph]->setMolesOutOfDate(stateCalc);
3925 m_VolPhaseList[iph]->setMolesCurrent(stateCalc);
3929 void VCS_SOLVE::vcs_updateMolNumVolPhases(
const int stateCalc)
3931 for (
size_t iph = 0; iph < m_numPhases; iph++) {
3932 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.
bool m_singleSpecies
If true, this phase consists of a single species.
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"
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
double electricPotential() const
Returns the electric field of the phase.
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
size_t spGlobalIndexVCS(const size_t spIndex) const
Return the Global VCS index of the kth species in the phase.
int solve(DenseMatrix &A, double *b, size_t nrhs, size_t ldb)
Solve Ax = b. Array b is overwritten on exit with x.
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.
doublereal * ptrColumn(size_t j)
Return a pointer to the top of column j, columns are contiguous in memory.
#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.
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.
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the 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.
#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 nSpecies() const
Return the number of species in the phase.
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.
#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...
void writelogf(const char *fmt, const Args &... args)
Write a formatted message to the screen.
Phase information and Phase calculations for vcs.
#define VCS_DIMENSIONAL_G
dimensioned
#define AssertThrowMsg(expr, procedure,...)
Assertion must be true or an error is thrown.
#define VCS_STATECALC_OLD
State Calculation based on the old or base mole numbers.
int exists() const
int indicating whether the phase exists or not
#define plogendl()
define this Cantera function to replace cout << endl;
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Headers for the DenseMatrix object, which deals with dense rectangular matrices and description of th...
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.
Namespace for the Cantera kernel.
#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...
A class for full (non-sparse) matrices with Fortran-compatible data storage, which adds matrix operat...
void setTotalMoles(const double totalMols)
Sets the total moles in the phase.