Cantera  2.5.1
vcs_solve.cpp
Go to the documentation of this file.
1 /*!
2  * @file vcs_solve.cpp Implementation file for the internal class that holds
3  * the problem.
4  */
5 
6 // This file is part of Cantera. See License.txt in the top-level directory or
7 // at https://cantera.org/license.txt for license and copyright information.
8 
14 #include "cantera/base/clockWC.h"
16 
17 using namespace std;
18 
19 namespace Cantera
20 {
21 
23 
24 VCS_SOLVE::VCS_SOLVE(MultiPhase* mphase, int printLvl) :
25  m_printLvl(printLvl),
26  m_mix(mphase),
27  m_nsp(mphase->nSpecies()),
28  m_nelem(0),
29  m_numComponents(0),
30  m_numRxnTot(0),
31  m_numSpeciesRdc(mphase->nSpecies()),
32  m_numRxnRdc(0),
33  m_numRxnMinorZeroed(0),
34  m_numPhases(mphase->nPhases()),
35  m_doEstimateEquil(-1),
36  m_totalMolNum(0.0),
37  m_temperature(mphase->temperature()),
38  m_pressurePA(mphase->pressure()),
39  m_tolmaj(1.0E-8),
40  m_tolmin(1.0E-6),
41  m_tolmaj2(1.0E-10),
42  m_tolmin2(1.0E-8),
43  m_useActCoeffJac(0),
44  m_totalVol(mphase->volume()),
45  m_Faraday_dim(Faraday / (m_temperature * GasConstant)),
46  m_VCount(0),
47  m_debug_print_lvl(0),
48  m_timing_print_lvl(1)
49 {
50  m_speciesThermoList.resize(m_nsp);
51  for (size_t kspec = 0; kspec < m_nsp; kspec++) {
52  m_speciesThermoList[kspec].reset(new VCS_SPECIES_THERMO());
53  }
54 
55  string ser = "VCS_SOLVE: ERROR:\n\t";
56  if (m_nsp <= 0) {
57  plogf("%s Number of species is nonpositive\n", ser);
58  throw CanteraError("VCS_SOLVE::VCS_SOLVE", ser +
59  " Number of species is nonpositive\n");
60  }
61  if (m_numPhases <= 0) {
62  plogf("%s Number of phases is nonpositive\n", ser);
63  throw CanteraError("VCS_SOLVE::VCS_SOLVE", ser +
64  " Number of phases is nonpositive\n");
65  }
66 
67  /*
68  * We will initialize sc[] to note the fact that it needs to be
69  * filled with meaningful information.
70  */
71  m_scSize.resize(m_nsp, 0.0);
72  m_spSize.resize(m_nsp, 1.0);
73  m_SSfeSpecies.resize(m_nsp, 0.0);
74  m_feSpecies_new.resize(m_nsp, 0.0);
75  m_molNumSpecies_old.resize(m_nsp, 0.0);
79  m_phasePhi.resize(m_numPhases, 0.0);
80  m_molNumSpecies_new.resize(m_nsp, 0.0);
81  m_deltaGRxn_new.resize(m_nsp, 0.0);
82  m_deltaGRxn_old.resize(m_nsp, 0.0);
83  m_deltaGRxn_Deficient.resize(m_nsp, 0.0);
84  m_deltaGRxn_tmp.resize(m_nsp, 0.0);
85  m_deltaMolNumSpecies.resize(m_nsp, 0.0);
86  m_feSpecies_old.resize(m_nsp, 0.0);
87  m_tPhaseMoles_old.resize(m_numPhases, 0.0);
88  m_tPhaseMoles_new.resize(m_numPhases, 0.0);
89  m_deltaPhaseMoles.resize(m_numPhases, 0.0);
90  m_TmpPhase.resize(m_numPhases, 0.0);
91  m_TmpPhase2.resize(m_numPhases, 0.0);
92  TPhInertMoles.resize(m_numPhases, 0.0);
93 
94  // ind[] is an index variable that keep track of solution vector rotations.
95  m_speciesMapIndex.resize(m_nsp, 0);
97 
98  // ir[] is an index vector that keeps track of the irxn to species mapping.
99  // We can't fill it in until we know the number of c components in the
100  // problem
101  m_indexRxnToSpecies.resize(m_nsp, 0);
102 
103  // Initialize all species to be major species
105 
106  m_SSPhase.resize(2*m_nsp, 0);
107  m_phaseID.resize(m_nsp, 0);
108  m_speciesName.resize(m_nsp);
109 
110  // space for activity coefficients for all species. Set it equal to one.
111  m_actConventionSpecies.resize(m_nsp, 0);
113  m_lnMnaughtSpecies.resize(m_nsp, 0.0);
114  m_actCoeffSpecies_new.resize(m_nsp, 1.0);
115  m_actCoeffSpecies_old.resize(m_nsp, 1.0);
116  m_wtSpecies.resize(m_nsp, 0.0);
117  m_chargeSpecies.resize(m_nsp, 0.0);
118 
119  // Phase Info
120  m_VolPhaseList.resize(m_numPhases);
121  for (size_t iph = 0; iph < m_numPhases; iph++) {
122  m_VolPhaseList[iph].reset(new vcs_VolPhase(this));
123  }
124 
125  // For Future expansion
126  m_useActCoeffJac = true;
127  if (m_useActCoeffJac) {
129  }
130 
131  m_PMVolumeSpecies.resize(m_nsp, 0.0);
132 
133  // counters kept within vcs
134  m_VCount = new VCS_COUNTERS();
136 
137  if (vcs_timing_print_lvl == 0) {
138  m_timing_print_lvl = 0;
139  }
140 
141  VCS_SPECIES_THERMO* ts_ptr = 0;
142 
143  // Loop over the phases, transferring pertinent information
144  int kT = 0;
145  for (size_t iphase = 0; iphase < m_numPhases; iphase++) {
146  // Get the ThermoPhase object - assume volume phase
147  ThermoPhase* tPhase = &mphase->phase(iphase);
148  size_t nelem = tPhase->nElements();
149 
150  // Query Cantera for the equation of state type of the current phase.
151  std::string eos = tPhase->type();
152  bool gasPhase = (eos == "IdealGas");
153 
154  // Find out the number of species in the phase
155  size_t nSpPhase = tPhase->nSpecies();
156  // Find out the name of the phase
157  string phaseName = tPhase->name();
158 
159  // Call the basic vcs_VolPhase creation routine.
160  // Properties set here:
161  // ->PhaseNum = phase number in the thermo problem
162  // ->GasPhase = Boolean indicating whether it is a gas phase
163  // ->NumSpecies = number of species in the phase
164  // ->TMolesInert = Inerts in the phase = 0.0 for cantera
165  // ->PhaseName = Name of the phase
166  vcs_VolPhase* VolPhase = m_VolPhaseList[iphase].get();
167  VolPhase->resize(iphase, nSpPhase, nelem, phaseName.c_str(), 0.0);
168  VolPhase->m_gasPhase = gasPhase;
169 
170  // Tell the vcs_VolPhase pointer about cantera
171  VolPhase->setPtrThermoPhase(tPhase);
172  VolPhase->setTotalMoles(0.0);
173 
174  // Set the electric potential of the volume phase from the
175  // ThermoPhase object's value.
176  VolPhase->setElectricPotential(tPhase->electricPotential());
177 
178  // Query the ThermoPhase object to find out what convention
179  // it uses for the specification of activity and Standard State.
180  VolPhase->p_activityConvention = tPhase->activityConvention();
181 
182  // Assign the value of eqn of state. Handle conflicts here.
183  if (eos == "IdealGas") {
184  VolPhase->m_eqnState = VCS_EOS_IDEAL_GAS;
185  } else if (eos == "ConstDensity") {
186  VolPhase->m_eqnState = VCS_EOS_CONSTANT;
187  } else if (eos == "StoichSubstance") {
188  VolPhase->m_eqnState = VCS_EOS_STOICH_SUB;
189  } else if (eos == "IdealSolidSoln") {
190  VolPhase->m_eqnState = VCS_EOS_IDEAL_SOLN;
191  } else if (eos == "Surf" || eos == "Edge") {
192  throw CanteraError("VCS_SOLVE::VCS_SOLVE",
193  "Surface/edge phase not handled yet.");
194  } else {
195  if (m_printLvl > 1) {
196  writelog("Unknown Cantera EOS to VCSnonideal: '{}'\n", eos);
197  }
198  VolPhase->m_eqnState = VCS_EOS_UNK_CANTERA;
199  }
200 
201  // Transfer all of the element information from the ThermoPhase object
202  // to the vcs_VolPhase object. Also decide whether we need a new charge
203  // neutrality element in the phase to enforce a charge neutrality
204  // constraint. We also decide whether this is a single species phase
205  // with the voltage being the independent variable setting the chemical
206  // potential of the electrons.
207  VolPhase->transferElementsFM(tPhase);
208 
209  // Combine the element information in the vcs_VolPhase
210  // object into the vprob object.
211  addPhaseElements(VolPhase);
213 
214  // Loop through each species in the current phase
215  for (size_t k = 0; k < nSpPhase; k++) {
216  // Obtain the molecular weight of the species from the
217  // ThermoPhase object
218  m_wtSpecies[kT] = tPhase->molecularWeight(k);
219 
220  // Obtain the charges of the species from the ThermoPhase object
221  m_chargeSpecies[kT] = tPhase->charge(k);
222 
223  // Set the phaseid of the species
224  m_phaseID[kT] = iphase;
225 
226  // Transfer the type of unknown
227  m_speciesUnknownType[kT] = VolPhase->speciesUnknownType(k);
229  // Set the initial number of kmoles of the species
230  m_molNumSpecies_old[kT] = mphase->speciesMoles(kT);
232  m_molNumSpecies_old[kT] = tPhase->electricPotential();
233  } else {
234  throw CanteraError("VCS_SOLVE::VCS_SOLVE",
235  "Unknown species type: {}", m_speciesUnknownType[kT]);
236  }
237 
238  // Transfer the species information from the
239  // volPhase structure to the VPROB structure
240  // This includes:
241  // FormulaMatrix[][]
242  // VolPhase->IndSpecies[]
243  addOnePhaseSpecies(VolPhase, k, kT);
244 
245  // Get a pointer to the thermo object
246  ts_ptr = m_speciesThermoList[kT].get();
247 
248  // Fill in the vcs_SpeciesProperty structure
249  vcs_SpeciesProperties* sProp = VolPhase->speciesProperty(k);
250  sProp->NumElements = m_nelem;
251  sProp->SpName = mphase->speciesName(kT);
252  sProp->SpeciesThermo = ts_ptr;
253  sProp->WtSpecies = tPhase->molecularWeight(k);
254  sProp->FormulaMatrixCol.resize(m_nelem, 0.0);
255  for (size_t e = 0; e < m_nelem; e++) {
256  sProp->FormulaMatrixCol[e] = m_formulaMatrix(kT,e);
257  }
258  sProp->Charge = tPhase->charge(k);
259  sProp->SurfaceSpecies = false;
260  sProp->VolPM = 0.0;
261 
262  // Transfer the thermo specification of the species
263  // vsolve->SpeciesThermo[]
264 
265  // Add lookback connectivity into the thermo object first
266  ts_ptr->IndexPhase = iphase;
267  ts_ptr->IndexSpeciesPhase = k;
268  ts_ptr->OwningPhase = VolPhase;
269 
270  // get a reference to the Cantera species thermo.
271  MultiSpeciesThermo& sp = tPhase->speciesThermo();
272 
273  int spType = sp.reportType(k);
274  if (spType == SIMPLE) {
275  double c[4];
276  double minTemp, maxTemp, refPressure;
277  sp.reportParams(k, spType, c, minTemp, maxTemp, refPressure);
278  ts_ptr->SS0_Model = VCS_SS0_CONSTANT;
279  ts_ptr->SS0_T0 = c[0];
280  ts_ptr->SS0_H0 = c[1];
281  ts_ptr->SS0_S0 = c[2];
282  ts_ptr->SS0_Cp0 = c[3];
283  if (gasPhase) {
284  ts_ptr->SSStar_Model = VCS_SSSTAR_IDEAL_GAS;
286  } else {
287  ts_ptr->SSStar_Model = VCS_SSSTAR_CONSTANT;
288  ts_ptr->SSStar_Vol_Model = VCS_SSVOL_CONSTANT;
289  }
290  } else {
291  if (m_printLvl > 2) {
292  plogf("vcs_Cantera_convert: Species Type %d not known \n",
293  spType);
294  }
295  ts_ptr->SS0_Model = VCS_SS0_NOTHANDLED;
296  ts_ptr->SSStar_Model = VCS_SSSTAR_NOTHANDLED;
297  }
298 
299  // Transfer the Volume Information -> NEEDS WORK
300  if (gasPhase) {
302  ts_ptr->SSStar_Vol0 = 82.05 * 273.15 / 1.0;
303  } else {
304  vector_fp phaseTermCoeff(nSpPhase, 0.0);
305  int nCoeff;
306  tPhase->getParameters(nCoeff, &phaseTermCoeff[0]);
307  ts_ptr->SSStar_Vol_Model = VCS_SSVOL_CONSTANT;
308  ts_ptr->SSStar_Vol0 = phaseTermCoeff[k];
309  }
310  kT++;
311  }
312 
314 
315  // Now, calculate a sample naught Gibbs free energy calculation
316  // at the specified temperature.
317  for (size_t k = 0; k < nSpPhase; k++) {
318  vcs_SpeciesProperties* sProp = VolPhase->speciesProperty(k);
319  ts_ptr = sProp->SpeciesThermo;
320  ts_ptr->SS0_feSave = VolPhase->G0_calc_one(k)/ GasConstant;
321  ts_ptr->SS0_TSave = m_temperature;
322  }
323  }
324 
325  // Transfer initial element abundances based on the species mole numbers
326  for (size_t j = 0; j < m_nelem; j++) {
327  for (size_t kspec = 0; kspec < m_nsp; kspec++) {
330  }
331  }
332  if (m_elType[j] == VCS_ELEM_TYPE_LATTICERATIO && m_elemAbundancesGoal[j] < 1.0E-10) {
333  m_elemAbundancesGoal[j] = 0.0;
334  }
335  }
336 
337  // Printout the species information: PhaseID's and mole nums
338  if (m_printLvl > 1) {
339  writeline('=', 80, true, true);
340  writeline('=', 16, false);
341  plogf(" Cantera_to_vprob: START OF PROBLEM STATEMENT ");
342  writeline('=', 20);
343  writeline('=', 80);
344  plogf(" Phase IDs of species\n");
345  plogf(" species phaseID phaseName ");
346  plogf(" Initial_Estimated_kMols\n");
347  for (size_t i = 0; i < m_nsp; i++) {
348  size_t iphase = m_phaseID[i];
349 
350  vcs_VolPhase* VolPhase = m_VolPhaseList[iphase].get();
351  plogf("%16s %5d %16s", mphase->speciesName(i).c_str(), iphase,
352  VolPhase->PhaseName.c_str());
354  plogf(" Volts = %-10.5g\n", m_molNumSpecies_old[i]);
355  } else {
356  plogf(" %-10.5g\n", m_molNumSpecies_old[i]);
357  }
358  }
359 
360  // Printout of the Phase structure information
361  writeline('-', 80, true, true);
362  plogf(" Information about phases\n");
363  plogf(" PhaseName PhaseNum SingSpec GasPhase EqnState NumSpec");
364  plogf(" TMolesInert Tmoles(kmol)\n");
365 
366  for (size_t iphase = 0; iphase < m_numPhases; iphase++) {
367  vcs_VolPhase* VolPhase = m_VolPhaseList[iphase].get();
368  plogf("%16s %5d %5d %8d %16s %8d %16e ", VolPhase->PhaseName.c_str(),
369  VolPhase->VP_ID_, VolPhase->m_singleSpecies,
370  VolPhase->m_gasPhase, VolPhase->eos_name(),
371  VolPhase->nSpecies(), VolPhase->totalMolesInert());
372  plogf("%16e\n", VolPhase->totalMoles());
373  }
374 
375  writeline('=', 80, true, true);
376  writeline('=', 16, false);
377  plogf(" Cantera_to_vprob: END OF PROBLEM STATEMENT ");
378  writeline('=', 20);
379  writeline('=', 80);
380  plogf("\n");
381  }
382 
383  // TPhInertMoles[] -> must be copied over here
384  for (size_t iph = 0; iph < m_numPhases; iph++) {
385  vcs_VolPhase* Vphase = m_VolPhaseList[iph].get();
386  TPhInertMoles[iph] = Vphase->totalMolesInert();
387  }
388 
389  // m_speciesIndexVector[] is an index variable that keep track of solution
390  // vector rotations.
391  for (size_t i = 0; i < m_nsp; i++) {
392  m_speciesMapIndex[i] = i;
393  }
394 
395  // IndEl[] is an index variable that keep track of element vector rotations.
396  for (size_t i = 0; i < m_nelem; i++) {
397  m_elementMapIndex[i] = i;
398  }
399 
400  // Fill in the species to phase mapping. Check for bad values at the same
401  // time.
402  std::vector<size_t> numPhSp(m_numPhases, 0);
403  for (size_t kspec = 0; kspec < m_nsp; kspec++) {
404  size_t iph = m_phaseID[kspec];
405  if (iph >= m_numPhases) {
406  throw CanteraError("VCS_SOLVE::VCS_SOLVE",
407  "Species to Phase Mapping, PhaseID, has a bad value\n"
408  "\tm_phaseID[{}] = {}\n"
409  "Allowed values: 0 to {}", kspec, iph, m_numPhases - 1);
410  }
411  m_phaseID[kspec] = m_phaseID[kspec];
412  m_speciesLocalPhaseIndex[kspec] = numPhSp[iph];
413  numPhSp[iph]++;
414  }
415  for (size_t iph = 0; iph < m_numPhases; iph++) {
416  vcs_VolPhase* Vphase = m_VolPhaseList[iph].get();
417  if (numPhSp[iph] != Vphase->nSpecies()) {
418  throw CanteraError("VCS_SOLVE::VCS_SOLVE",
419  "Number of species in phase {}, {}, doesn't match ({} != {}) [vphase = {}]",
420  ser, iph, Vphase->PhaseName, numPhSp[iph], Vphase->nSpecies(), (size_t) Vphase);
421  }
422  }
423 
424  for (size_t i = 0; i < m_nelem; i++) {
426  if (m_elemAbundancesGoal[i] != 0.0) {
427  if (fabs(m_elemAbundancesGoal[i]) > 1.0E-9) {
428  throw CanteraError("VCS_SOLVE::VCS_SOLVE",
429  "Charge neutrality condition {} is signicantly "
430  "nonzero, {}. Giving up",
432  } else {
433  if (m_debug_print_lvl >= 2) {
434  plogf("Charge neutrality condition %s not zero, %g. Setting it zero\n",
436  }
437  m_elemAbundancesGoal[i] = 0.0;
438  }
439  }
440  }
441  }
442 
443  // Copy over the species names
444  for (size_t i = 0; i < m_nsp; i++) {
445  m_speciesName[i] = m_mix->speciesName(i);
446  }
447 
448  // Specify the Activity Convention information
449  for (size_t iph = 0; iph < m_numPhases; iph++) {
450  vcs_VolPhase* Vphase = m_VolPhaseList[iph].get();
452  if (Vphase->p_activityConvention != 0) {
453  // We assume here that species 0 is the solvent. The solvent isn't
454  // on a unity activity basis The activity for the solvent assumes
455  // that the it goes to one as the species mole fraction goes to one;
456  // i.e., it's really on a molarity framework. So
457  // SpecLnMnaught[iSolvent] = 0.0, and the loop below starts at 1,
458  // not 0.
459  size_t iSolvent = Vphase->spGlobalIndexVCS(0);
460  double mnaught = m_wtSpecies[iSolvent] / 1000.;
461  for (size_t k = 1; k < Vphase->nSpecies(); k++) {
462  size_t kspec = Vphase->spGlobalIndexVCS(k);
464  m_lnMnaughtSpecies[kspec] = log(mnaught);
465  }
466  }
467  }
468 
469 }
470 
471 VCS_SOLVE::~VCS_SOLVE()
472 {
474 }
475 
477 {
478  delete m_VCount;
479  m_VCount = 0;
480 
481  m_nsp = 0;
482  m_nelem = 0;
483  m_numComponents = 0;
484 
485 }
486 
487 int VCS_SOLVE::vcs(int ipr, int ip1, int maxit)
488 {
489  clockWC tickTock;
490 
491  // This function is called to copy the public data and the current
492  // problem specification into the current object's data structure.
494 
496 
497  // Prep the problem data
498  // - adjust the identity of any phases
499  // - determine the number of components in the problem
500  int retn = vcs_prep(ip1);
501  if (retn != 0) {
502  plogf("vcs_prep_oneTime returned a bad status, %d: bailing!\n",
503  retn);
504  return retn;
505  }
506 
507  // Once we have defined the global internal data structure defining the
508  // problem, then we go ahead and solve the problem.
509  //
510  // (right now, all we do is solve fixed T, P problems. Methods for other
511  // problem types will go in at this level. For example, solving for
512  // fixed T, V problems will involve a 2x2 Newton's method, using loops
513  // over vcs_TP() to calculate the residual and Jacobian)
514  int iconv = vcs_TP(ipr, ip1, maxit, m_temperature, m_pressurePA);
515 
516  // If requested to print anything out, go ahead and do so;
517  if (ipr > 0) {
518  vcs_report(iconv);
519  }
520 
521  vcs_prob_update();
522 
523  // Report on the time if requested to do so
524  double te = tickTock.secondsWC();
525  m_VCount->T_Time_vcs += te;
526  if (ipr > 0 || ip1 > 0) {
528  }
529 
530  // FILL IN
531  if (iconv < 0) {
532  plogf("ERROR: FAILURE its = %d!\n", m_VCount->Its);
533  } else if (iconv == 1) {
534  plogf("WARNING: RANGE SPACE ERROR encountered\n");
535  }
536  return iconv;
537 }
538 
540 {
541  // Whether we have an estimate or not gets overwritten on
542  // the call to the equilibrium solver.
543  m_temperature = m_mix->temperature();
544  m_pressurePA = m_mix->pressure();
546  m_totalVol = m_mix->volume();
547 
548  vector<size_t> invSpecies(m_nsp);
549  for (size_t k = 0; k < m_nsp; k++) {
550  invSpecies[m_speciesMapIndex[k]] = k;
551  }
552 
553  for (size_t iphase = 0; iphase < m_numPhases; iphase++) {
554  ThermoPhase* tPhase = &m_mix->phase(iphase);
555  vcs_VolPhase* volPhase = m_VolPhaseList[iphase].get();
556 
558 
559  // Loop through each species in the current phase
560  size_t nSpPhase = tPhase->nSpecies();
561  if ((nSpPhase == 1) && (volPhase->phiVarIndex() == 0)) {
563  } else if (volPhase->totalMoles() > 0.0) {
565  } else {
566  volPhase->setExistence(VCS_PHASE_EXIST_NO);
567  }
568  }
569 
570  // Printout the species information: PhaseID's and mole nums
571  if (m_printLvl > 1) {
572  writeline('=', 80, true, true);
573  writeline('=', 20, false);
574  plogf(" Cantera_to_vprob: START OF PROBLEM STATEMENT ");
575  writeline('=', 20);
576  writeline('=', 80);
577  plogf("\n");
578  plogf(" Phase IDs of species\n");
579  plogf(" species phaseID phaseName ");
580  plogf(" Initial_Estimated_kMols\n");
581  for (size_t i = 0; i < m_nsp; i++) {
582  size_t iphase = m_phaseID[i];
583  vcs_VolPhase* VolPhase = m_VolPhaseList[iphase].get();
584  plogf("%16s %5d %16s", m_speciesName[i].c_str(), iphase,
585  VolPhase->PhaseName.c_str());
587  plogf(" Volts = %-10.5g\n", m_molNumSpecies_old[i]);
588  } else {
589  plogf(" %-10.5g\n", m_molNumSpecies_old[i]);
590  }
591  }
592 
593  // Printout of the Phase structure information
594  writeline('-', 80, true, true);
595  plogf(" Information about phases\n");
596  plogf(" PhaseName PhaseNum SingSpec GasPhase EqnState NumSpec");
597  plogf(" TMolesInert Tmoles(kmol)\n");
598 
599  for (size_t iphase = 0; iphase < m_numPhases; iphase++) {
600  vcs_VolPhase* VolPhase = m_VolPhaseList[iphase].get();
601  plogf("%16s %5d %5d %8d %16s %8d %16e ", VolPhase->PhaseName.c_str(),
602  VolPhase->VP_ID_, VolPhase->m_singleSpecies,
603  VolPhase->m_gasPhase, VolPhase->eos_name(),
604  VolPhase->nSpecies(), VolPhase->totalMolesInert());
605  plogf("%16e\n", VolPhase->totalMoles());
606  }
607 
608  writeline('=', 80, true, true);
609  writeline('=', 20, false);
610  plogf(" Cantera_to_vprob: END OF PROBLEM STATEMENT ");
611  writeline('=', 20);
612  writeline('=', 80);
613  plogf("\n");
614  }
615 
616  // m_numRxnTot = number of noncomponents, also equal to the number of
617  // reactions. Note, it's possible that the number of elements is greater
618  // than the number of species. In that case set the number of reactions to
619  // zero.
620  if (m_nelem > m_nsp) {
621  m_numRxnTot = 0;
622  } else {
624  }
626 }
627 
629 {
630  // Transfer the information back to the MultiPhase object. Note we don't
631  // just call setMoles, because some multispecies solution phases may be
632  // zeroed out, and that would cause a problem for that routine. Also, the
633  // mole fractions of such zeroed out phases actually contain information
634  // about likely reemergent states.
636  for (size_t ip = 0; ip < m_numPhases; ip++) {
637  m_mix->setPhaseMoles(ip, m_VolPhaseList[ip]->totalMoles());
638  }
639 }
640 
642 {
643  m_VCount->Its = 0;
644  m_VCount->Basis_Opts = 0;
645  m_VCount->Time_vcs_TP = 0.0;
646  m_VCount->Time_basopt = 0.0;
647  if (ifunc) {
648  m_VCount->T_Its = 0;
649  m_VCount->T_Basis_Opts = 0;
650  m_VCount->T_Calls_Inest = 0;
652  m_VCount->T_Time_vcs_TP = 0.0;
653  m_VCount->T_Time_basopt = 0.0;
654  m_VCount->T_Time_inest = 0.0;
655  m_VCount->T_Time_vcs = 0.0;
656  }
657 }
658 
659 double VCS_SOLVE::vcs_VolTotal(const double tkelvin, const double pres,
660  const double w[], double volPM[])
661 {
662  double VolTot = 0.0;
663  for (size_t iphase = 0; iphase < m_numPhases; iphase++) {
664  vcs_VolPhase* Vphase = m_VolPhaseList[iphase].get();
665  Vphase->setState_TP(tkelvin, pres);
667  double Volp = Vphase->sendToVCS_VolPM(volPM);
668  VolTot += Volp;
669  }
670  return VolTot;
671 }
672 
675 }
676 
677 }
Headers for the MultiPhase object that is used to set up multiphase equilibrium problems (see Equilfu...
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the array, and fill the new entries with 'v'.
Definition: Array.h:112
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
A class for multiphase mixtures.
Definition: MultiPhase.h:58
doublereal pressure() const
Pressure [Pa].
Definition: MultiPhase.h:389
doublereal speciesMoles(size_t kGlob) const
Returns the moles of global species k. units = kmol.
Definition: MultiPhase.cpp:184
std::string speciesName(const size_t kGlob) const
Name of species with global index kGlob.
Definition: MultiPhase.cpp:759
void uploadMoleFractionsFromPhases()
Update the locally-stored composition within this object to match the current compositions of the pha...
Definition: MultiPhase.cpp:815
doublereal volume() const
The total mixture volume [m^3].
Definition: MultiPhase.cpp:472
void setPhaseMoles(const size_t n, const doublereal moles)
Set the number of moles of phase with index n.
Definition: MultiPhase.cpp:795
doublereal temperature() const
Temperature [K].
Definition: MultiPhase.h:329
thermo_t & phase(size_t n)
Return a reference to phase n.
Definition: MultiPhase.cpp:159
A species thermodynamic property manager for a phase.
virtual int reportType(size_t index) const
This utility function reports the type of parameterization used for the species with index number ind...
virtual void reportParams(size_t index, int &type, doublereal *const c, doublereal &minTemp, doublereal &maxTemp, doublereal &refPressure) const
This utility function reports back the type of parameterization and all of the parameters for the spe...
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:84
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:285
doublereal charge(size_t k) const
Dimensionless electrical charge of a single molecule of species k The charge is normalized by the the...
Definition: Phase.h:643
doublereal molecularWeight(size_t k) const
Molecular weight of species k.
Definition: Phase.cpp:521
size_t nElements() const
Number of elements.
Definition: Phase.cpp:95
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:102
virtual int activityConvention() const
This method returns the convention used in specification of the activities, of which there are curren...
Definition: ThermoPhase.cpp:54
virtual MultiSpeciesThermo & speciesThermo(int k=-1)
Return a changeable reference to the calculation manager for species reference-state thermodynamic pr...
virtual std::string type() const
String indicating the thermodynamic model implemented.
Definition: ThermoPhase.h:113
doublereal electricPotential() const
Returns the electric potential of this phase (V).
Definition: ThermoPhase.h:320
virtual void getParameters(int &n, doublereal *const c) const
Get the equation of state parameters in a vector.
Definition: ThermoPhase.h:1701
Class to keep track of time and iterations.
Definition: vcs_internal.h:36
int Its
Current number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
Definition: vcs_internal.h:44
int T_Calls_Inest
Current number of times the initial thermo equilibrium estimator has been called.
Definition: vcs_internal.h:54
double T_Time_basopt
Total Time spent in basopt.
Definition: vcs_internal.h:66
double T_Time_inest
Time spent in initial estimator.
Definition: vcs_internal.h:72
int T_Basis_Opts
Total number of optimizations of the components basis set done.
Definition: vcs_internal.h:47
double T_Time_vcs_TP
Current time spent in vcs_TP.
Definition: vcs_internal.h:60
int Basis_Opts
number of optimizations of the components basis set done
Definition: vcs_internal.h:50
double T_Time_vcs
Time spent in the vcs suite of programs.
Definition: vcs_internal.h:75
int T_Its
Total number of iterations in the main loop of vcs_TP() to solve for thermo equilibrium.
Definition: vcs_internal.h:40
int T_Calls_vcs_TP
Current number of calls to vcs_TP.
Definition: vcs_internal.h:57
double Time_basopt
Current Time spent in basopt.
Definition: vcs_internal.h:69
double Time_vcs_TP
Current time spent in vcs_TP.
Definition: vcs_internal.h:63
size_t m_numPhases
Number of Phases in the problem.
Definition: vcs_solve.h:1068
vector_fp m_phasePhi
electric potential of the iph phase
Definition: vcs_solve.h:1179
vector_fp m_scSize
Absolute size of the stoichiometric coefficients.
Definition: vcs_solve.h:1104
double vcs_VolTotal(const double tkelvin, const double pres, const double w[], double volPM[])
Calculation of the total volume and the partial molar volumes.
Definition: vcs_solve.cpp:659
std::vector< std::string > m_speciesName
Species string name for the kth species.
Definition: vcs_solve.h:1364
Array2D m_np_dLnActCoeffdMolNum
Change in the log of the activity coefficient with respect to the mole number multiplied by the phase...
Definition: vcs_solve.h:1440
vector_fp m_TmpPhase2
Temporary vector of length NPhase.
Definition: vcs_solve.h:1261
vector_int m_elType
Type of the element constraint.
Definition: vcs_solve.h:1385
size_t m_nelem
Number of element constraints in the problem.
Definition: vcs_solve.h:1047
int m_useActCoeffJac
Choice of Hessians.
Definition: vcs_solve.h:1468
double m_totalVol
Total volume of all phases. Units are m^3.
Definition: vcs_solve.h:1471
vector_int m_speciesStatus
Major -Minor status vector for the species in the problem.
Definition: vcs_solve.h:1354
int vcs_prep(int printLvl)
This routine is mostly concerned with changing the private data to be consistent with what's needed f...
Definition: vcs_prep.cpp:50
vector_int m_actConventionSpecies
specifies the activity convention of the phase containing the species
Definition: vcs_solve.h:1403
vector_fp m_molNumSpecies_old
Total moles of the species.
Definition: vcs_solve.h:1152
void vcs_TCounters_report(int timing_print_lvl=1)
Create a report on the plog file containing timing and its information.
Definition: vcs_report.cpp:298
Array2D m_phaseParticipation
This is 1 if the phase, iphase, participates in the formation reaction irxn, and zero otherwise.
Definition: vcs_solve.h:1176
static void disableTiming()
Disable printing of timing information.
Definition: vcs_solve.cpp:673
vector_fp m_molNumSpecies_new
Tentative value of the mole number vector.
Definition: vcs_solve.h:1183
vector_int m_speciesUnknownType
Specifies the species unknown type.
Definition: vcs_solve.h:1165
vector_fp m_deltaGRxn_tmp
Temporary vector of Rxn DeltaG's.
Definition: vcs_solve.h:1206
vector_fp m_deltaGRxn_old
Last deltag[irxn] from the previous step.
Definition: vcs_solve.h:1196
int vcs_TP(int ipr, int ip1, int maxit, double T, double pres)
Solve an equilibrium problem at a particular fixed temperature and pressure.
Definition: vcs_TP.cpp:11
void prob_report(int print_lvl)
Print out the problem specification in all generality as it currently exists in the VCS_SOLVE object.
Definition: vcs_prob.cpp:25
int m_timing_print_lvl
printing level of timing information
Definition: vcs_solve.h:1505
vector_fp m_tPhaseMoles_new
total kmols of species in each phase in the tentative soln vector
Definition: vcs_solve.h:1255
vector_fp m_feSpecies_new
Dimensionless new free energy for all the species in the mechanism at the new tentative T,...
Definition: vcs_solve.h:1135
vector_fp m_tPhaseMoles_old
Total kmols of species in each phase.
Definition: vcs_solve.h:1246
int m_debug_print_lvl
Debug printing lvl.
Definition: vcs_solve.h:1498
void vcs_counters_init(int ifunc)
Initialize the internal counters.
Definition: vcs_solve.cpp:641
vector_fp m_elemAbundancesGoal
Element abundances vector Goals.
Definition: vcs_solve.h:1231
vector_fp TPhInertMoles
Total kmoles of inert to add to each phase.
Definition: vcs_solve.h:1280
std::vector< size_t > m_phaseID
Mapping from the species number to the phase number.
Definition: vcs_solve.h:1357
std::vector< size_t > m_indexRxnToSpecies
Mapping between the species index for noncomponent species and the full species index.
Definition: vcs_solve.h:1346
Array2D m_formulaMatrix
Formula matrix for the problem.
Definition: vcs_solve.h:1076
vector_fp m_wtSpecies
Molecular weight of each species.
Definition: vcs_solve.h:1448
vector_fp m_deltaPhaseMoles
Change in the total moles in each phase.
Definition: vcs_solve.h:1267
void addPhaseElements(vcs_VolPhase *volPhase)
Add elements to the local element list.
Definition: vcs_prob.cpp:122
std::vector< size_t > m_speciesLocalPhaseIndex
Index that keeps track of the index of the species within the local phase.
Definition: vcs_solve.h:1320
size_t addOnePhaseSpecies(vcs_VolPhase *volPhase, size_t k, size_t kT)
This routines adds entries for the formula matrix for one species.
Definition: vcs_prob.cpp:168
size_t m_numRxnRdc
Current number of non-component species in the problem.
Definition: vcs_solve.h:1061
VCS_COUNTERS * m_VCount
Timing and iteration counters for the vcs object.
Definition: vcs_solve.h:1484
int vcs(int ipr, int ip1, int maxit)
Solve an equilibrium problem.
Definition: vcs_solve.cpp:487
std::vector< std::unique_ptr< VCS_SPECIES_THERMO > > m_speciesThermoList
Vector of pointers to thermo structures which identify the model and parameters for evaluating the th...
Definition: vcs_solve.h:1461
size_t m_numComponents
Number of components calculated for the problem.
Definition: vcs_solve.h:1050
void vcs_prob_specifyFully()
Fully specify the problem to be solved.
Definition: vcs_solve.cpp:539
double m_pressurePA
Pressure.
Definition: vcs_solve.h:1273
vector_fp m_chargeSpecies
Charge of each species. Length = number of species.
Definition: vcs_solve.h:1451
vector_fp m_feSpecies_old
Free energy vector from the start of the current iteration.
Definition: vcs_solve.h:1126
int vcs_report(int iconv)
Print out a report on the state of the equilibrium problem to standard output.
Definition: vcs_report.cpp:12
double m_Faraday_dim
dimensionless value of Faraday's constant, F / RT (1/volt)
Definition: vcs_solve.h:1481
std::vector< char > m_SSPhase
Boolean indicating whether a species belongs to a single-species phase.
Definition: vcs_solve.h:1361
size_t m_nsp
Total number of species in the problems.
Definition: vcs_solve.h:1044
std::vector< std::unique_ptr< vcs_VolPhase > > m_VolPhaseList
Array of Phase Structures. Length = number of phases.
Definition: vcs_solve.h:1394
vector_fp m_spSize
total size of the species
Definition: vcs_solve.h:1111
std::vector< size_t > m_elementMapIndex
Index vector that keeps track of the rearrangement of the elements.
Definition: vcs_solve.h:1333
void vcs_delete_memory()
Delete memory that isn't just resizable STL containers.
Definition: vcs_solve.cpp:476
void vcs_prob_update()
Transfer the results of the equilibrium calculation back from VCS_SOLVE.
Definition: vcs_solve.cpp:628
vector_fp m_deltaMolNumSpecies
Reaction Adjustments for each species during the current step.
Definition: vcs_solve.h:1213
vector_fp m_SSfeSpecies
Standard state chemical potentials for species K at the current temperature and pressure.
Definition: vcs_solve.h:1119
Array2D m_deltaMolNumPhase
Change in the number of moles of phase, iphase, due to the noncomponent formation reaction,...
Definition: vcs_solve.h:1172
std::vector< size_t > m_speciesMapIndex
Index vector that keeps track of the species vector rearrangement.
Definition: vcs_solve.h:1306
vector_fp m_actCoeffSpecies_old
Molar-based Activity Coefficients for Species based on old mole numbers.
Definition: vcs_solve.h:1430
vector_fp m_PMVolumeSpecies
Partial molar volumes of the species.
Definition: vcs_solve.h:1478
vector_fp m_deltaGRxn_new
Delta G(irxn) for the noncomponent species in the mechanism.
Definition: vcs_solve.h:1193
int m_printLvl
Print level for print routines.
Definition: vcs_solve.h:984
vector_fp m_lnMnaughtSpecies
specifies the ln(Mnaught) used to calculate the chemical potentials
Definition: vcs_solve.h:1419
vector_int m_phaseActConvention
specifies the activity convention of the phase.
Definition: vcs_solve.h:1412
size_t m_numRxnTot
Total number of non-component species in the problem.
Definition: vcs_solve.h:1053
vector_fp m_deltaGRxn_Deficient
Last deltag[irxn] from the previous step with additions for possible births of zeroed phases.
Definition: vcs_solve.h:1200
double m_temperature
Temperature (Kelvin)
Definition: vcs_solve.h:1270
vector_fp m_TmpPhase
Temporary vector of length NPhase.
Definition: vcs_solve.h:1258
vector_fp m_actCoeffSpecies_new
Molar-based Activity Coefficients for Species.
Definition: vcs_solve.h:1423
std::vector< std::string > m_elementName
Vector of strings containing the element names.
Definition: vcs_solve.h:1370
size_t IndexSpeciesPhase
Index of this species in the current phase.
int SSStar_Vol_Model
Models for the standard state volume of each species.
double SS0_Cp0
Base heat capacity used in the VCS_SS0_CONSTANT_CP model.
double SSStar_Vol0
parameter that is used in the VCS_SSVOL_CONSTANT model.
double SS0_H0
Base enthalpy used in the VCS_SS0_CONSTANT_CP model.
double SS0_T0
Base temperature used in the VCS_SS0_CONSTANT_CP model.
double SS0_TSave
Internal storage of the last temperature used in the calculation of the reference naught Gibbs free e...
int SSStar_Model
Integer value representing the star state model.
double SS0_S0
Base entropy used in the VCS_SS0_CONSTANT_CP model.
int SS0_Model
Integer representing the models for the species standard state Naught temperature dependence.
double SS0_feSave
Internal storage of the last calculation of the reference naught Gibbs free energy at SS0_TSave.
size_t IndexPhase
Index of the phase that this species belongs to.
vcs_VolPhase * OwningPhase
Pointer to the owning phase object.
The class provides the wall clock timer in seconds.
Definition: clockWC.h:45
double secondsWC()
Returns the wall clock time in seconds since the last reset.
Definition: clockWC.cpp:32
Properties of a single species.
double VolPM
Partial molar volume of the species.
vector_fp FormulaMatrixCol
Column of the formula matrix, comprising the element composition of the species.
int SurfaceSpecies
True if this species belongs to a surface phase.
std::string SpName
Name of the species.
double WtSpecies
Molecular Weight of the species (gm/mol)
VCS_SPECIES_THERMO * SpeciesThermo
Pointer to the thermo structure for this species.
double Charge
Charge state of the species -> This may be duplication of what's in the FormulaMatrixCol entries.
Phase information and Phase calculations for vcs.
Definition: vcs_VolPhase.h:82
void setElectricPotential(const double phi)
set the electric potential of the phase
std::string eos_name() const
Return the name corresponding to the equation of state.
int speciesUnknownType(const size_t k) const
Returns the type of the species unknown.
size_t nSpecies() const
Return the number of species in the phase.
size_t VP_ID_
Original ID of the phase in the problem.
Definition: vcs_VolPhase.h:538
vcs_SpeciesProperties * speciesProperty(const size_t kindex)
Retrieve the kth Species structure for the species belonging to this phase.
size_t phiVarIndex() const
Return the index of the species that represents the the voltage of the phase.
double totalMolesInert() const
Returns the value of the total kmol of inert in the phase.
bool m_singleSpecies
If true, this phase consists of a single species.
Definition: vcs_VolPhase.h:541
void setMolesFromVCS(const int stateCalc, const double *molesSpeciesVCS=0)
Set the moles within the phase.
void resize(const size_t phaseNum, const size_t numSpecies, const size_t numElem, const char *const phaseName, const double molesInert=0.0)
The resize() function fills in all of the initial information if it is not given in the constructor.
size_t spGlobalIndexVCS(const size_t spIndex) const
Return the Global VCS index of the kth species in the phase.
size_t transferElementsFM(const ThermoPhase *const tPhase)
Transfer all of the element information from the ThermoPhase object to the vcs_VolPhase object.
bool m_gasPhase
If true, this phase is a gas-phase like phase.
Definition: vcs_VolPhase.h:548
std::string PhaseName
String name for the phase.
Definition: vcs_VolPhase.h:627
void setTotalMoles(const double totalMols)
Sets the total moles in the phase.
int p_activityConvention
Convention for the activity formulation.
Definition: vcs_VolPhase.h:570
double sendToVCS_VolPM(double *const VolPM) const
Fill in the partial molar volume vector for VCS.
int m_eqnState
Type of the equation of state.
Definition: vcs_VolPhase.h:554
double G0_calc_one(size_t kspec) const
Gibbs free energy calculation at a temperature for the reference state of a species,...
void setState_TP(const double temperature_Kelvin, const double pressure_PA)
Sets the temperature and pressure in this object and underlying ThermoPhase objects.
void setExistence(const int existence)
Set the existence flag in the object.
double totalMoles() const
Return the total moles in the phase.
void setPtrThermoPhase(ThermoPhase *tp_ptr)
Set the pointer for Cantera's ThermoPhase parameter.
Declarations for a simple class that implements an Ansi C wall clock timer (see Cantera::clockWC).
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
const double Faraday
Faraday constant [C/kmol].
Definition: ct_defs.h:123
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:180
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:109
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
Definition: global.h:158
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
int vcs_timing_print_lvl
Global hook for turning on and off time printing.
Definition: vcs_solve.cpp:22
#define SIMPLE
Constant Cp thermo.
Contains declarations for string manipulation functions within Cantera.
Header for the object representing each phase within vcs.
#define VCS_SSVOL_IDEALGAS
Models for the standard state volume of each species.
Definition: vcs_VolPhase.h:21
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
Unknown refers to the voltage level of a phase.
Definition: vcs_defs.h:289
#define VCS_STATECALC_OLD
State Calculation based on the old or base mole numbers.
Definition: vcs_defs.h:300
#define VCS_SPECIES_MAJOR
Species is a major species.
Definition: vcs_defs.h:102
#define VCS_PHASE_EXIST_NO
Phase doesn't currently exist in the mixture.
Definition: vcs_defs.h:198
#define VCS_PHASE_EXIST_ALWAYS
Always exists because it contains inerts which can't exist in any other phase.
Definition: vcs_defs.h:185
#define VCS_SPECIES_TYPE_MOLNUM
Unknown refers to mole number of a single species.
Definition: vcs_defs.h:281
#define VCS_ELEM_TYPE_LATTICERATIO
Constraint associated with maintaining a fixed lattice stoichiometry in the solids.
Definition: vcs_defs.h:248
#define VCS_ELEM_TYPE_CHARGENEUTRALITY
This refers to a charge neutrality of a single phase.
Definition: vcs_defs.h:240
#define VCS_PHASE_EXIST_YES
Phase is a normal phase that currently exists.
Definition: vcs_defs.h:188
#define plogf
define this Cantera function to replace printf
Definition: vcs_internal.h:18
Header file for the internal object that holds the vcs equilibrium problem (see Class VCS_SOLVE and E...