29 VCS_SOLVE::VCS_SOLVE() :
33 m_numElemConstraints(0),
38 m_numRxnMinorZeroed(0),
49 m_totalMoleScale(1.0),
52 m_Faraday_dim(Cantera::ElectronCharge* Cantera::
Avogadro),
55 m_timing_print_lvl(1),
56 m_VCS_UnitsFormat(VCS_UNITS_UNITLESS)
60 void VCS_SOLVE::vcs_initSizes(
const size_t nspecies0,
const size_t nelements,
64 if ((nspecies0 != NSPECIES0) || (nelements != m_numElemConstraints) || (nphase0 != NPHASE0)) {
71 NSPECIES0 = nspecies0;
73 m_numSpeciesTot = nspecies0;
74 m_numElemConstraints = nelements;
75 m_numComponents = nelements;
77 string ser =
"VCS_SOLVE: ERROR:\n\t";
79 plogf(
"%s Number of species is nonpositive\n", ser.c_str());
81 " Number of species is nonpositive\n");
84 plogf(
"%s Number of elements is nonpositive\n", ser.c_str());
86 " Number of species is nonpositive\n");
89 plogf(
"%s Number of phases is nonpositive\n", ser.c_str());
91 " Number of species is nonpositive\n");
95 m_VCS_UnitsFormat = VCS_UNITS_UNITLESS;
101 m_stoichCoeffRxnMatrix.resize(nspecies0, nelements, 0.0);
103 m_scSize.resize(nspecies0, 0.0);
104 m_spSize.resize(nspecies0, 1.0);
106 m_SSfeSpecies.resize(nspecies0, 0.0);
107 m_feSpecies_new.resize(nspecies0, 0.0);
108 m_molNumSpecies_old.resize(nspecies0, 0.0);
112 m_deltaMolNumPhase.resize(nspecies0, nphase0, 0.0);
113 m_phaseParticipation.resize(nspecies0, nphase0, 0);
114 m_phasePhi.resize(nphase0, 0.0);
116 m_molNumSpecies_new.resize(nspecies0, 0.0);
118 m_deltaGRxn_new.resize(nspecies0, 0.0);
119 m_deltaGRxn_old.resize(nspecies0, 0.0);
120 m_deltaGRxn_Deficient.resize(nspecies0, 0.0);
121 m_deltaGRxn_tmp.resize(nspecies0, 0.0);
122 m_deltaMolNumSpecies.resize(nspecies0, 0.0);
124 m_feSpecies_old.resize(nspecies0, 0.0);
125 m_elemAbundances.resize(nelements, 0.0);
126 m_elemAbundancesGoal.resize(nelements, 0.0);
128 m_tPhaseMoles_old.resize(nphase0, 0.0);
129 m_tPhaseMoles_new.resize(nphase0, 0.0);
130 m_deltaPhaseMoles.resize(nphase0, 0.0);
131 m_TmpPhase.resize(nphase0, 0.0);
132 m_TmpPhase2.resize(nphase0, 0.0);
134 m_formulaMatrix.resize(nelements, nspecies0);
136 TPhInertMoles.resize(nphase0, 0.0);
142 m_speciesMapIndex.resize(nspecies0, 0);
143 m_speciesLocalPhaseIndex.resize(nspecies0, 0);
148 m_elementMapIndex.resize(nelements, 0);
155 m_indexRxnToSpecies.resize(nspecies0, 0);
159 m_speciesStatus.resize(nspecies0, 1);
161 m_SSPhase.resize(2*nspecies0, 0);
162 m_phaseID.resize(nspecies0, 0);
164 m_numElemConstraints = nelements;
166 m_elementName.resize(nelements, std::string(
""));
167 m_speciesName.resize(nspecies0, std::string(
""));
171 m_elementActive.resize(nelements, 1);
176 m_actConventionSpecies.resize(nspecies0, 0);
177 m_phaseActConvention.resize(nphase0, 0);
178 m_lnMnaughtSpecies.resize(nspecies0, 0.0);
179 m_actCoeffSpecies_new.resize(nspecies0, 1.0);
180 m_actCoeffSpecies_old.resize(nspecies0, 1.0);
181 m_wtSpecies.resize(nspecies0, 0.0);
182 m_chargeSpecies.resize(nspecies0, 0.0);
188 m_VolPhaseList.resize(nphase0, 0);
189 for (
size_t iph = 0; iph < nphase0; iph++) {
196 m_useActCoeffJac =
true;
197 if (m_useActCoeffJac) {
198 m_np_dLnActCoeffdMolNum.resize(nspecies0, nspecies0, 0.0);
201 m_PMVolumeSpecies.resize(nspecies0, 0.0);
208 vcs_counters_init(1);
211 m_timing_print_lvl = 0;
218 VCS_SOLVE::~VCS_SOLVE()
223 void VCS_SOLVE::vcs_delete_memory()
226 size_t nspecies = m_numSpeciesTot;
228 for (j = 0; j < m_numPhases; j++) {
229 delete m_VolPhaseList[j];
230 m_VolPhaseList[j] = 0;
233 for (j = 0; j < nspecies; j++) {
234 delete m_speciesThermoList[j];
235 m_speciesThermoList[j] = 0;
243 m_numElemConstraints = 0;
247 int VCS_SOLVE::vcs(
VCS_PROB* vprob,
int ifunc,
int ipr,
int ip1,
int maxit)
249 int retn = 0, iconv = 0;
250 size_t nspecies0, nelements0, nphase0;
253 int iprintTime = std::max(ipr, ip1);
254 if (m_timing_print_lvl < iprintTime) {
255 iprintTime = m_timing_print_lvl ;
259 plogf(
"vcs: Unrecognized value of ifunc, %d: bailing!\n",
270 nelements0 = vprob->
ne;
273 vcs_initSizes(nspecies0, nelements0, nphase0);
276 plogf(
"vcs_priv_alloc returned a bad status, %d: bailing!\n",
285 retn = vcs_prob_specifyFully(vprob);
287 plogf(
"vcs_pub_to_priv returned a bad status, %d: bailing!\n",
296 retn = vcs_prep_oneTime(ip1);
298 plogf(
"vcs_prep_oneTime returned a bad status, %d: bailing!\n",
308 retn = vcs_prob_specify(vprob);
310 plogf(
"vcs_prob_specify returned a bad status, %d: bailing!\n",
322 plogf(
"vcs_prep returned a bad status, %d: bailing!\n", retn);
329 if (!vcs_wellPosed(vprob)) {
330 plogf(
"vcs has determined the problem is not well posed: Bailing\n");
344 iconv = vcs_TP(ipr, ip1, maxit, vprob->
T, vprob->
PresPA);
356 vcs_prob_update(vprob);
363 m_VCount->T_Time_vcs += te;
364 if (iprintTime > 0) {
365 vcs_TCounters_report(m_timing_print_lvl);
374 plogf(
"ERROR: FAILURE its = %d!\n", m_VCount->Its);
375 }
else if (iconv == 1) {
376 plogf(
"WARNING: RANGE SPACE ERROR encountered\n");
381 int VCS_SOLVE::vcs_prob_specifyFully(
const VCS_PROB* pub)
385 "vcs_pub_to_priv ERROR :ill defined interface -> bailout:\n\t";
392 if (NSPECIES0 < nspecies) {
393 plogf(
"%sPrivate Data is dimensioned too small\n", ser);
398 plogf(
"%sPrivate Data is dimensioned too small\n", ser);
401 size_t nelements = pub->
ne;
402 if (m_numElemConstraints < nelements) {
403 plogf(
"%sPrivate Data is dimensioned too small\n", ser);
410 m_numElemConstraints = nelements;
411 m_numSpeciesTot = nspecies;
412 m_numSpeciesRdc = m_numSpeciesTot;
417 m_numComponents = nelements;
425 if (nelements > nspecies) {
428 m_numRxnTot = nspecies - nelements;
430 m_numRxnRdc = m_numRxnTot;
434 m_numRxnMinorZeroed = 0;
449 for (
size_t i = 0; i < nspecies; i++) {
450 bool nonzero =
false;
451 for (
size_t j = 0; j < nelements; j++) {
458 plogf(
"vcs_prob_specifyFully:: species %d %s has a zero formula matrix!\n", i,
467 vcs_vdcopy(m_wtSpecies, pub->
WtSpecies, nspecies);
472 vcs_vdcopy(m_chargeSpecies, pub->
Charge, nspecies);
478 for (
size_t kspec = 0; kspec < nspecies; kspec++) {
479 delete m_speciesThermoList[kspec];
482 if (m_speciesThermoList[kspec] == NULL) {
483 plogf(
" duplMyselfAsVCS_SPECIES_THERMO returned an error!\n");
497 m_doEstimateEquil = pub->
iest;
502 if (pub->
w.size() != 0) {
503 vcs_vdcopy(m_molNumSpecies_old, pub->
w, nspecies);
505 m_doEstimateEquil = -1;
512 if (pub->
gai.size() != 0) {
513 for (
size_t i = 0; i < nelements; i++) {
514 m_elemAbundancesGoal[i] = pub->
gai[i];
516 if (m_elemAbundancesGoal[i] < 1.0E-10) {
517 m_elemAbundancesGoal[i] = 0.0;
522 if (m_doEstimateEquil == 0) {
524 for (
size_t j = 0; j < nelements; j++) {
525 m_elemAbundancesGoal[j] = 0.0;
526 for (
size_t kspec = 0; kspec < nspecies; kspec++) {
528 sum += m_molNumSpecies_old[kspec];
529 m_elemAbundancesGoal[j] += m_formulaMatrix[j][kspec] * m_molNumSpecies_old[kspec];
533 if (m_elemAbundancesGoal[j] < 1.0E-10 * sum) {
534 m_elemAbundancesGoal[j] = 0.0;
539 plogf(
"%sElement Abundances, m_elemAbundancesGoal[], not specified\n", ser);
556 m_temperature = pub->
T;
558 m_temperature = 293.15;
561 m_pressurePA = pub->
PresPA;
568 for (
size_t iph = 0; iph < nph; iph++) {
583 m_tolmaj2 = 0.01 * m_tolmaj;
584 m_tolmin2 = 0.01 * m_tolmin;
590 for (
size_t i = 0; i < nspecies; i++) {
591 m_speciesMapIndex[i] = i;
598 for (
size_t i = 0; i < nelements; i++) {
599 m_elementMapIndex[i] = i;
605 for (
size_t i = 0; i < nspecies; i++) {
613 if (pub->
PhaseID.size() != 0) {
614 std::vector<size_t> numPhSp(nph, 0);
615 for (
size_t kspec = 0; kspec < nspecies; kspec++) {
616 size_t iph = pub->
PhaseID[kspec];
618 plogf(
"%sSpecies to Phase Mapping, PhaseID, has a bad value\n",
620 plogf(
"\tPhaseID[%d] = %d\n", kspec, iph);
621 plogf(
"\tAllowed values: 0 to %d\n", nph - 1);
624 m_phaseID[kspec] = pub->
PhaseID[kspec];
625 m_speciesLocalPhaseIndex[kspec] = numPhSp[iph];
628 for (
size_t iph = 0; iph < nph; iph++) {
630 if (numPhSp[iph] != Vphase->
nSpecies()) {
631 plogf(
"%sNumber of species in phase %d, %s, doesn't match\n",
637 if (m_numPhases == 1) {
638 for (
size_t kspec = 0; kspec < nspecies; kspec++) {
639 m_phaseID[kspec] = 0;
640 m_speciesLocalPhaseIndex[kspec] = kspec;
643 plogf(
"%sSpecies to Phase Mapping, PhaseID, is not defined\n", ser);
652 m_elementActive.resize(nelements, 1);
657 for (
size_t i = 0; i < nelements; i++) {
658 m_elementName[i] = pub->
ElName[i];
660 m_elementActive[i] = pub->
ElActive[i];
661 if (!strncmp(m_elementName[i].c_str(),
"cn_", 3)) {
664 plogf(
"we have an inconsistency!\n");
670 for (
size_t i = 0; i < nelements; i++) {
672 if (m_elemAbundancesGoal[i] != 0.0) {
673 if (fabs(m_elemAbundancesGoal[i]) > 1.0E-9) {
674 plogf(
"Charge neutrality condition %s is signicantly nonzero, %g. Giving up\n",
675 m_elementName[i].c_str(), m_elemAbundancesGoal[i]);
678 if (m_debug_print_lvl >= 2) {
679 plogf(
"Charge neutrality condition %s not zero, %g. Setting it zero\n",
680 m_elementName[i].c_str(), m_elemAbundancesGoal[i]);
682 m_elemAbundancesGoal[i] = 0.0;
692 for (
size_t i = 0; i < nspecies; i++) {
693 m_speciesName[i] = pub->
SpName[i];
699 for (
size_t iph = 0; iph < nph; iph++) {
700 *(m_VolPhaseList[iph]) = *(pub->
VPhaseList[iph]);
706 Vphase = m_VolPhaseList[iph];
707 for (
size_t k = 0; k < Vphase->
nSpecies(); k++) {
710 sProp->SpeciesThermo = m_speciesThermoList[kT];
717 for (
size_t iph = 0; iph < nph; iph++) {
718 Vphase = m_VolPhaseList[iph];
731 double mnaught = m_wtSpecies[iSolvent] / 1000.;
732 for (
size_t k = 1; k < Vphase->
nSpecies(); k++) {
735 m_lnMnaughtSpecies[kspec] = log(mnaught);
743 if (pub->Title.size() == 0) {
744 m_title =
"Unspecified Problem Title";
746 m_title = pub->Title;
752 m_totalVol = pub->
Vol;
753 if (m_PMVolumeSpecies.size() != 0) {
763 int VCS_SOLVE::vcs_prob_specify(
const VCS_PROB* pub)
765 size_t kspec, k, i, j, iph;
766 string yo(
"vcs_prob_specify ERROR: ");
768 bool status_change =
false;
770 m_temperature = pub->
T;
771 m_pressurePA = pub->
PresPA;
773 m_doEstimateEquil = pub->
iest;
775 m_totalVol = pub->
Vol;
779 m_tolmaj2 = 0.01 * m_tolmaj;
780 m_tolmin2 = 0.01 * m_tolmin;
782 for (kspec = 0; kspec < m_numSpeciesTot; ++kspec) {
783 k = m_speciesMapIndex[kspec];
784 m_molNumSpecies_old[kspec] = pub->
w[k];
785 m_molNumSpecies_new[kspec] = pub->
mf[k];
792 for (i = 0; i < m_numElemConstraints; i++) {
793 j = m_elementMapIndex[i];
794 m_elemAbundancesGoal[i] = pub->
gai[j];
800 if (pub->Title.size() == 0) {
801 if (m_title.size() == 0) {
802 m_title =
"Unspecified Problem Title";
805 m_title = pub->Title;
816 for (iph = 0; iph < m_numPhases; iph++) {
821 plogf(
"%sPhase numbers have changed:%d %d\n", yo.c_str(),
827 plogf(
"%sSingleSpecies value have changed:%d %d\n", yo.c_str(),
834 plogf(
"%sGasPhase value have changed:%d %d\n", yo.c_str(),
843 plogf(
"%sNVolSpecies value have changed:%d %d\n", yo.c_str(),
850 plogf(
"%sPhaseName value have changed:%s %s\n", yo.c_str(),
857 status_change =
true;
864 if (TPhInertMoles[iph] > 0.0) {
893 m_totalVol = vcs_VolTotal(m_temperature, m_pressurePA,
896 for (
size_t i = 0; i < m_numSpeciesTot; ++i) {
901 for (
size_t j = 0; j < m_numSpeciesTot; ++j) {
903 if (m_speciesMapIndex[j] == i) {
911 pub->
w[i] = m_molNumSpecies_old[k1];
918 pub->
VolPM[i] = m_PMVolumeSpecies[k1];
921 pub->
T = m_temperature;
922 pub->
PresPA = m_pressurePA;
923 pub->
Vol = m_totalVol;
925 for (
size_t iph = 0; iph < pub->
NPhase; iph++) {
935 const std::vector<double> & mfVector = pubPhase->
moleFractions();
936 for (
size_t k = 0; k < pubPhase->
nSpecies(); k++) {
938 pub->
mf[kT] = mfVector[k];
941 double tmp = m_molNumSpecies_old[k1];
943 plogf(
"We have an inconsistency in voltage, %g, %g\n",
950 plogf(
"We have an inconsistency in mole fraction, %g, %g\n",
955 sumMoles += pub->
w[kT];
959 plogf(
"We have an inconsistency in total moles, %g %g\n",
972 void VCS_SOLVE::vcs_counters_init(
int ifunc)
975 m_VCount->Basis_Opts = 0;
976 m_VCount->Time_vcs_TP = 0.0;
977 m_VCount->Time_basopt = 0.0;
980 m_VCount->T_Basis_Opts = 0;
981 m_VCount->T_Calls_Inest = 0;
982 m_VCount->T_Calls_vcs_TP = 0;
983 m_VCount->T_Time_vcs_TP = 0.0;
984 m_VCount->T_Time_basopt = 0.0;
985 m_VCount->T_Time_inest = 0.0;
986 m_VCount->T_Time_vcs = 0.0;
990 double VCS_SOLVE::vcs_VolTotal(
const double tkelvin,
const double pres,
991 const double w[],
double volPM[])
994 for (
size_t iphase = 0; iphase < m_numPhases; iphase++) {
std::vector< VCS_SPECIES_THERMO * > SpeciesThermo
Vector of pointers to thermo structures which identify the model and parameters for evaluating the th...
int speciesUnknownType(const size_t k) const
Returns the type of the species unknown.
std::vector< double > WtSpecies
Molecular weight of species.
vcs_SpeciesProperties * speciesProperty(const size_t kindex)
Retrieve the kth Species structure for the species belonging to this phase.
size_t VP_ID_
Original ID of the phase in the problem.
int vcs_timing_print_lvl
Global hook for turning on and off time printing.
int iest
Specification of the initial estimate method.
std::vector< double > w
Total number of moles of the kth species.
const doublereal OneAtm
One atmosphere [Pa].
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_DATA_PTR(vvv)
Points to the data in a std::vector<> object.
void setExistence(const int existence)
Set the existence flag in the object.
int m_NumBasisOptimizations
Number of basis optimizations used. This is an output variable.
The class provides the wall clock timer in seconds.
double tolmaj
Tolerance requirement for major species.
std::vector< int > SpeciesUnknownType
Specifies the species unknown type.
std::vector< double > m_gibbsSpecies
Vector of chemical potentials of the species.
int p_activityConvention
Convention for the activity formulation.
Properties of a single species.
Class to keep track of time and iterations.
std::vector< int > ElActive
Specifies whether an element constraint is active.
int vcs_debug_print_lvl
Debug print lvl.
std::vector< double > Charge
Charge of each species.
double sendToVCS_VolPM(double *const VolPM) const
Fill in the partial molar volume vector for VCS.
size_t NPhase
Number of phases in the problem.
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_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.
Internal declarations for the VCSnonideal package.
double secondsWC()
Returns the wall clock time in seconds since the last reset.
std::vector< std::string > ElName
vector of strings containing the element names
double tolmin
Tolerance requirement for minor species.
Header for the Interface class for the vcs thermo equilibrium solver package,.
std::vector< size_t > PhaseID
Mapping between the species and the phases.
size_t nspecies
Total number of species in the problems.
#define VCS_ELEM_TYPE_CHARGENEUTRALITY
This refers to a charge neutrality of a single phase.
DoubleStarStar FormulaMatrix
Formula Matrix for the problem.
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.
int m_VCS_UnitsFormat
Units for the chemical potential data, pressure data, volume, and species amounts.
void setTotalMolesInert(const double tMolesInert)
Sets the total moles of inert in the phase.
void setTotalMoles(const double totalMols)
Sets the total moles in the phase.
#define VCS_SPECIES_MAJOR
Species is a major species.
size_t phiVarIndex() const
Return the index of the species that represents the the voltage of the phase.
double Vol
Volume of the entire system.
double electricPotential() const
Returns the electric field of the phase.
const std::vector< double > & moleFractions() const
Return a const reference to the mole fractions stored in the object.
#define VCS_DIMENSIONAL_G
dimensioned
const doublereal Avogadro
Avogadro's Number [number/kmol].
size_t nSpecies() const
Return the number of species in the phase.
std::vector< vcs_VolPhase * > VPhaseList
Array of phase structures.
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.
double totalMolesInert() const
returns the value of the total kmol of inert in the phase
void setElectricPotential(const double phi)
set the electric potential of the phase
Interface class for the vcs thermo equilibrium solver package, which generally describes the problem ...
std::vector< std::string > SpName
Vector of strings containing the species names.
std::vector< int > m_elType
vector of Element types
int m_Iterations
Number of iterations. This is an output variable.
double totalMoles() const
Return the total moles in the phase.
#define plogf
define this Cantera function to replace printf
virtual VCS_SPECIES_THERMO * duplMyselfAsVCS_SPECIES_THERMO()
Duplication function for derived classes.
std::vector< double > gai
Element abundances for jth element.
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
Unknown refers to the voltage level of a phase.
void setState_TP(const double temperature_Kelvin, const double pressure_PA)
Sets the temperature and pressure in this object and underlying ThermoPhase objects.
double molefraction(size_t kspec) const
Returns the mole fraction of the kspec species.
#define VCS_ELEM_TYPE_LATTICERATIO
Constraint associated with maintaining a fixed lattice stoichiometry in the solids.
#define VCS_STATECALC_TMP
State Calculation based on a temporary set of mole numbers.
size_t ne
Number of element constraints in the equilibrium problem.
int m_eqnState
Type of the equation of state.
double T
Temperature (Kelvin)
std::vector< double > VolPM
Partial Molar Volumes of species.
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
bool m_gasPhase
If true, this phase is a gas-phase like phase.
std::vector< double > mf
Mole fraction vector.
void setMoleFractionsState(const double molNum, const double *const moleFracVec, const int vcsStateStatus)
Set the moles and/or mole fractions within the phase.