Cantera  2.3.0
vcs_solve.h
Go to the documentation of this file.
1 /**
2  * @file vcs_solve.h Header file for the internal object that holds the vcs
3  * equilibrium problem (see Class \link Cantera::VCS_SOLVE
4  * VCS_SOLVE\endlink and \ref equilfunctions ).
5  */
6 
7 // This file is part of Cantera. See License.txt in the top-level directory or
8 // at http://www.cantera.org/license.txt for license and copyright information.
9 
10 #ifndef _VCS_SOLVE_H
11 #define _VCS_SOLVE_H
12 
13 /*
14 * Index of Symbols
15 * -------------------
16 * irxn -> refers to the species or rxn between the species and
17 * the components in the problem
18 * k -> refers to the species
19 * j -> refers to the element or component
20 *
21 * ### -> to be eliminated
22 */
23 
24 #include "cantera/base/ct_defs.h"
25 #include "cantera/equil/vcs_defs.h"
27 #include "cantera/base/Array.h"
28 
29 namespace Cantera
30 {
31 
32 class vcs_VolPhase;
33 class VCS_SPECIES_THERMO;
34 class VCS_PROB;
35 class VCS_COUNTERS;
36 
37 //! This is the main structure used to hold the internal data
38 //! used in vcs_solve_TP(), and to solve TP systems.
39 /*!
40  * The indices of information in this structure may change when the species
41  * basis changes or when phases pop in and out of existence. Both of these
42  * operations change the species ordering.
43  */
44 class VCS_SOLVE
45 {
46 public:
47  VCS_SOLVE();
48 
49  ~VCS_SOLVE();
50 
51  //! Initialize the sizes within the VCS_SOLVE object
52  /*!
53  * This resizes all of the internal arrays within the object. This routine
54  * operates in two modes. If all of the parameters are the same as it
55  * currently exists in the object, nothing is done by this routine; a quick
56  * exit is carried out and all of the data in the object persists.
57  *
58  * If any of the parameters are different than currently exists in the
59  * object, then all of the data in the object must be redone. It may not be
60  * zeroed, but it must be redone.
61  *
62  * @param nspecies0 Number of species within the object
63  * @param nelements Number of element constraints within the problem
64  * @param nphase0 Number of phases defined within the problem.
65  */
66  void vcs_initSizes(const size_t nspecies0, const size_t nelements, const size_t nphase0);
67 
68  //! Solve an equilibrium problem
69  /*!
70  * This is the main interface routine to the equilibrium solver
71  *
72  * @param vprob Object containing the equilibrium Problem statement
73  * @param ifunc Determines the operation to be done: Valid values:
74  * 0 -> Solve a new problem by initializing structures first. An
75  * initial estimate may or may not have been already
76  * determined. This is indicated in the VCS_PROB structure.
77  * 1 -> The problem has already been initialized and set up. We
78  * call this routine to resolve it using the problem
79  * statement and solution estimate contained in the VCS_PROB
80  * structure.
81  * 2 -> Don't solve a problem. Destroy all the private
82  * structures.
83  * @param ipr Printing of results
84  * ipr = 1 -> Print problem statement and final results to
85  * standard output
86  * 0 -> don't report on anything
87  * @param ip1 Printing of intermediate results
88  * IP1 = 1 -> Print intermediate results.
89  * @param maxit Maximum number of iterations for the algorithm
90  * @return nonzero value: failure to solve the problem at hand. zero :
91  * success
92  */
93  int vcs(VCS_PROB* vprob, int ifunc, int ipr, int ip1, int maxit);
94 
95  //! Main routine that solves for equilibrium at constant T and P using a
96  //! variant of the VCS method
97  /*!
98  * This is the main routine that solves for equilibrium at constant T and P
99  * using a variant of the VCS method. Nonideal phases can be accommodated as
100  * well.
101  *
102  * Any number of single-species phases and multi-species phases can be
103  * handled by the present version.
104  *
105  * @param print_lvl 1 -> Print results to standard output;
106  * 0 -> don't report on anything
107  * @param printDetails 1 -> Print intermediate results.
108  * @param maxit Maximum number of iterations for the algorithm
109  * @return
110  * * 0 = Equilibrium Achieved
111  * * 1 = Range space error encountered. The element abundance criteria
112  * are only partially satisfied. Specifically, the first NC= (number
113  * of components) conditions are satisfied. However, the full NE
114  * (number of elements) conditions are not satisfied. The
115  * equilibrium condition is returned.
116  * * -1 = Maximum number of iterations is exceeded. Convergence was
117  * not found.
118  */
119  int vcs_solve_TP(int print_lvl, int printDetails, int maxit);
120 
121  //! @deprecated Broken and unused. To be removed after Cantera 2.3.
122  int vcs_PS(VCS_PROB* vprob, int iph, int printLvl, double& feStable);
123 
124  /*!
125  * We make decisions on the initial mole number, and major-minor status
126  * here. We also fix up the total moles in a phase.
127  *
128  * irxn = id of the noncomponent species formation reaction for the
129  * species to be added in.
130  *
131  * The algorithm proceeds to implement these decisions in the previous
132  * position of the species. Then, vcs_switch_pos is called to move the
133  * species into the last active species slot, incrementing the number of
134  * active species at the same time.
135  *
136  * This routine is responsible for the global data manipulation only.
137  */
138  void vcs_reinsert_deleted(size_t kspec);
139 
140  //! Choose the optimum species basis for the calculations
141  /*!
142  * This is done by choosing the species with the largest mole fraction not
143  * currently a linear combination of the previous components. Then,
144  * calculate the stoichiometric coefficient matrix for that basis.
145  *
146  * Rearranges the solution data to put the component data at the
147  * front of the species list.
148  *
149  * Then, calculates `m_stoichCoeffRxnMatrix(jcomp,irxn)` the formation
150  * reactions for all noncomponent species in the mechanism. Also
151  * calculates DNG(I) and DNL(I), the net mole change for each formation
152  * reaction. Also, initializes IR(I) to the default state.
153  *
154  * @param[in] doJustComponents If true, the #m_stoichCoeffRxnMatrix and
155  * #m_deltaMolNumPhase are not calculated.
156  * @param[in] aw Vector of mole fractions which will be used to
157  * construct an optimal basis from.
158  * @param[in] sa Gram-Schmidt orthog work space (nc in length) sa[j]
159  * @param[in] ss Gram-Schmidt orthog work space (nc in length) ss[j]
160  * @param[in] sm QR matrix work space (nc*ne in length) sm[i+j*ne]
161  * @param[in] test This is a small negative number dependent upon whether
162  * an estimate is supplied or not.
163  * @param[out] usedZeroedSpecies If true, then a species with a zero
164  * concentration was used as a component.
165  * The problem may be converged. Or, the
166  * problem may have a range space error and
167  * may not have a proper solution.
168  * @returns VCS_SUCCESS if everything went ok. Returns
169  * VCS_FAILED_CONVERGENCE if there is a problem.
170  *
171  * ### Internal Variables calculated by this routine:
172  *
173  * - #m_numComponents: Number of component species. This routine
174  * calculates the #m_numComponents species. It switches their positions
175  * in the species vector so that they occupy the first #m_numComponents
176  * spots in the species vector.
177  * - `m_stoichCoeffRxnMatrix(jcomp,irxn)` Stoichiometric coefficient
178  * matrix for the reaction mechanism expressed in Reduced Canonical
179  * Form. jcomp refers to the component number, and irxn refers to the
180  * irxn_th non-component species.
181  * - `m_deltaMolNumPhase(iphase,irxn)`: Change in the number of moles in
182  * phase, iphase, due to the noncomponent formation reaction, irxn.
183  * - `m_phaseParticipation(iphase,irxn)`: This is 1 if the phase, iphase,
184  * participates in the formation reaction, irxn, and zero otherwise.
185  */
186  int vcs_basopt(const bool doJustComponents, double aw[], double sa[], double sm[],
187  double ss[], double test, bool* const usedZeroedSpecies);
188 
189  //! Choose a species to test for the next component
190  /*!
191  * We make the choice based on testing (molNum[i] * spSize[i]) for its
192  * maximum value. Preference for single species phases is also made.
193  *
194  * @param molNum Mole number vector
195  * @param j index into molNum[] that indicates where the search will
196  * start from Previous successful components are swapped into the front
197  * of molNum[].
198  * @param n Length of molNum[]
199  */
200  size_t vcs_basisOptMax(const double* const molNum, const size_t j, const size_t n);
201 
202  //! Evaluate the species category for the indicated species
203  /*!
204  * All evaluations are done using the "old" version of the solution.
205  *
206  * @param kspec Species to be evaluated
207  * @returns the calculated species type
208  */
209  int vcs_species_type(const size_t kspec) const;
210 
211  //! This routine evaluates the species type for all species
212  /*!
213  * - #VCS_SPECIES_MAJOR: Major species
214  * - #VCS_SPECIES_MINOR: Minor species
215  * - #VCS_SPECIES_SMALLMS: The species lies in a multicomponent phase
216  * that exists. Its concentration is currently very low, necessitating
217  * a different method of calculation.
218  * - #VCS_SPECIES_ZEROEDMS: The species lies in a multicomponent phase
219  * which currently doesn't exist. Its concentration is currently zero.
220  * - #VCS_SPECIES_ZEROEDSS: Species lies in a single-species phase which
221  * is currently zeroed out.
222  * - #VCS_SPECIES_DELETED: Species has such a small mole fraction it is
223  * deleted even though its phase may possibly exist. The species is
224  * believed to have such a small mole fraction that it best to throw
225  * the calculation of it out. It will be added back in at the end of
226  * the calculation.
227  * - #VCS_SPECIES_INTERFACIALVOLTAGE: Species refers to an electron in
228  * the metal The unknown is equal to the interfacial voltage drop
229  * across the interface on the SHE (standard hydrogen electrode) scale
230  * (volts).
231  * - #VCS_SPECIES_ZEROEDPHASE: Species lies in a multicomponent phase
232  * that is zeroed atm and will stay deleted due to a choice from a
233  * higher level. These species will formally always have zero mole
234  * numbers in the solution vector.
235  * - #VCS_SPECIES_ACTIVEBUTZERO: The species lies in a multicomponent
236  * phase which currently does exist. Its concentration is currently
237  * identically zero, though the phase exists. Note, this is a temporary
238  * condition that exists at the start of an equilibrium problem. The
239  * species is soon "birthed" or "deleted".
240  * - #VCS_SPECIES_STOICHZERO: The species lies in a multicomponent phase
241  * which currently does exist. Its concentration is currently
242  * identically zero, though the phase exists. This is a permanent
243  * condition due to stoich constraints
244  */
246 
247  //! We calculate the dimensionless chemical potentials of all species
248  //! in a single phase.
249  /*!
250  * Note, for multispecies phases which are currently zeroed out, the
251  * chemical potential is filled out with the standard chemical potential.
252  *
253  * For species in multispecies phases whose concentration is zero, we need
254  * to set the mole fraction to a very low value. Its chemical potential is
255  * then calculated using the #VCS_DELETE_MINORSPECIES_CUTOFF concentration
256  * to keep numbers positive.
257  *
258  * # Formula:
259  *
260  * ## Ideal Mixtures:
261  *
262  * m_feSpecies(I) = m_SSfeSpecies(I) + ln(z(I)) - ln(m_tPhaseMoles[iph])
263  * + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
264  *
265  * (This is equivalent to the adding the log of the mole fraction onto
266  * the standard chemical potential. )
267  *
268  * ## Non-Ideal Mixtures:
269  *
270  * ### ActivityConvention = 0: molarity activity formulation
271  *
272  * m_feSpecies(I) = m_SSfeSpecies(I)
273  * + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
274  * + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
275  *
276  * (This is equivalent to the adding the log of the mole fraction multiplied
277  * by the activity coefficient onto the standard chemical potential.)
278  *
279  * ### ActivityConvention = 1: molality activity formulation
280  *
281  * m_feSpecies(I) = m_SSfeSpecies(I)
282  * + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
283  * - ln(Mnaught * m_units)
284  * + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
285  *
286  * Note: `m_SSfeSpecies(I)` is the molality based standard state. However,
287  * `ActCoeff[I]` is the molar based activity coefficient We have used the
288  * formulas:
289  *
290  * ActCoeff_M[I] = ActCoeff[I] / Xmol[N]
291  *
292  * where `Xmol[N]` is the mole fraction of the solvent and `ActCoeff_M[I]`
293  * is the molality based act coeff.
294  *
295  * Note: This is equivalent to the "normal" molality formulation:
296  *
297  * m_feSpecies(I) = m_SSfeSpecies(I)
298  * + ln(ActCoeff_M[I] * m(I))
299  * + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase]
300  *
301  * where `m[I]` is the molality of the ith solute
302  *
303  * m[I] = Xmol[I] / ( Xmol[N] * Mnaught * m_units)
304  *
305  * `z(I)/tPhMoles_ptr[iph] = Xmol[i]` is the mole fraction of i in the phase.
306  *
307  * NOTE: As per the discussion in vcs_dfe(), for small species where the
308  * mole fraction is small:
309  *
310  * z(i) < VCS_DELETE_MINORSPECIES_CUTOFF
311  *
312  * The chemical potential is calculated as:
313  *
314  * m_feSpecies(I) = m_SSfeSpecies(I)
315  * + ln(ActCoeff[i](VCS_DELETE_MINORSPECIES_CUTOFF))
316  *
317  * @param[in] iph Phase to be calculated
318  * @param[in] molNum Number of moles of species i (VCS species order)
319  * @param[out] ac Activity coefficients for species in phase (VCS
320  * species order)
321  * @param[out] mu_i Dimensionless chemical potentials for phase
322  * species (VCS species order)
323  * @deprecated Unused. To be removed after Cantera 2.3.
324  */
325  void vcs_chemPotPhase(const int stateCalc, const size_t iph, const double* const molNum,
326  double* const ac, double* const mu_i,
327  const bool do_deleted = false);
328 
329  //! Calculate the dimensionless chemical potentials of all species or
330  //! of certain groups of species, at a fixed temperature and pressure.
331  /*!
332  * We calculate the dimensionless chemical potentials of all species or
333  * certain groups of species here, at a fixed temperature and pressure, for
334  * the input mole vector z[] in the parameter list. Nondimensionalization is
335  * achieved by division by RT.
336  *
337  * Note, for multispecies phases which are currently zeroed out, the
338  * chemical potential is filled out with the standard chemical potential.
339  *
340  * For species in multispecies phases whose concentration is zero, we need
341  * to set the mole fraction to a very low value. Its chemical potential is
342  * then calculated using the VCS_DELETE_MINORSPECIES_CUTOFF concentration
343  * to keep numbers positive.
344  *
345  * For formulas, see vcs_chemPotPhase().
346  *
347  * Handling of Small Species:
348  * ------------------------------
349  * As per the discussion above, for small species where the mole fraction
350  *
351  * z(i) < VCS_DELETE_MINORSPECIES_CUTOFF
352  *
353  * The chemical potential is calculated as:
354  *
355  * m_feSpecies(I)(I) = m_SSfeSpecies(I) + ln(ActCoeff[i](VCS_DELETE_MINORSPECIES_CUTOFF))
356  *
357  * Species in the following categories are treated as "small species"
358  * - #VCS_SPECIES_DELETED
359  * - #VCS_SPECIES_ACTIVEBUTZERO
360  *
361  * For species in multispecies phases which are currently not active, the
362  * treatment is different. These species are in the following species
363  * categories:
364  * - #VCS_SPECIES_ZEROEDMS
365  * - #VCS_SPECIES_ZEROEDPHASE
366  *
367  * For these species, the `ln( ActCoeff[I] X[I])` term is dropped
368  * altogether. The following equation is used:
369  *
370  * m_feSpecies(I) = m_SSfeSpecies(I)
371  * + Charge[I] * Faraday_dim * phasePhi[iphase];
372  *
373  * Handling of "Species" Representing Interfacial Voltages
374  * ---------------------------------------------------------
375  *
376  * These species have species types of
377  * #VCS_SPECIES_TYPE_INTERFACIALVOLTAGE The chemical potentials for these
378  * "species" refer to electrons in metal electrodes. They have the
379  * following formula
380  *
381  * m_feSpecies(I) = m_SSfeSpecies(I) - F z[I] / RT
382  *
383  * - `F` is Faraday's constant.
384  * - `R` = gas constant
385  * - `T` = temperature
386  * - `V` = potential of the interface = phi_electrode - phi_solution
387  *
388  * For these species, the solution vector unknown, z[I], is V, the phase
389  * voltage, in volts.
390  *
391  * @param ll Determine which group of species gets updated
392  * - `ll = 0`: Calculate for all species
393  * - `ll < 0`: calculate for components and for major non-components
394  * - `ll = 1`: calculate for components and for minor non-components
395  *
396  * @param lbot Restricts the calculation of the chemical potential
397  * to the species between LBOT <= i < LTOP. Usually
398  * LBOT and LTOP will be equal to 0 and MR, respectively.
399  * @param ltop Top value of the loops
400  *
401  * @param stateCalc Determines whether z is old or new or tentative:
402  * - 1: Use the tentative values for the total number of
403  * moles in the phases, i.e., use TG1 instead of TG etc.
404  * - 0: Use the base values of the total number of
405  * moles in each system.
406  *
407  * Also needed:
408  * ff : standard state chemical potentials. These are the
409  * chemical potentials of the standard states at
410  * the same T and P as the solution.
411  * tg : Total Number of moles in the phase.
412  */
413  void vcs_dfe(const int stateCalc, const int ll, const size_t lbot, const size_t ltop);
414 
415  //! Print out a table of chemical potentials
416  /*!
417  * @param stateCalc Determines where to get the mole numbers from.
418  * - VCS_STATECALC_OLD -> from m_molNumSpecies_old
419  * - VCS_STATECALC_NEW -> from m_molNumSpecies_new
420  * @deprecated Unused. To be removed after Cantera 2.3.
421  */
422  void vcs_printSpeciesChemPot(const int stateCalc) const;
423 
424  //! This routine uploads the state of the system into all of the
425  //! vcs_VolumePhase objects in the current problem.
426  /*!
427  * @param stateCalc Determines where to get the mole numbers from.
428  * - VCS_STATECALC_OLD -> from m_molNumSpecies_old
429  * - VCS_STATECALC_NEW -> from m_molNumSpecies_new
430  */
431  void vcs_updateVP(const int stateCalc);
432 
433  //! Utility function that evaluates whether a phase can be popped
434  //! into existence
435  /*!
436  * A phase can be popped iff the stoichiometric coefficients for the
437  * component species, whose concentrations will be lowered during the
438  * process, are positive by at least a small degree.
439  *
440  * If one of the phase species is a zeroed component, then the phase can
441  * be popped if the component increases in mole number as the phase moles
442  * are increased.
443  *
444  * @param iphasePop id of the phase, which is currently zeroed,
445  * @returns true if the phase can come into existence and false otherwise.
446  */
447  bool vcs_popPhasePossible(const size_t iphasePop) const;
448 
449  //! Determine the list of problems that need to be checked to see if there
450  //! are any phases pops
451  /*!
452  * This routine evaluates and fills in #phasePopProblemLists_. Need to
453  * work in species that are zeroed by element constraints.
454  *
455  * @returns the number of problems that must be checked.
456  * @deprecated Unused. To be removed after Cantera 2.3.
457  */
459 
460  //! Decision as to whether a phase pops back into existence
461  /*!
462  * @param phasePopPhaseIDs Vector containing the phase ids of the phases
463  * that will be popped this step.
464  * @returns the phase id of the phase that pops back into existence. Returns
465  * -1 if there are no phases
466  */
467  size_t vcs_popPhaseID(std::vector<size_t> &phasePopPhaseIDs);
468 
469  //! Calculates the deltas of the reactions due to phases popping
470  //! into existence
471  /*!
472  * Updates #m_deltaMolNumSpecies[irxn] : reaction adjustments, where irxn
473  * refers to the irxn'th species formation reaction. This adjustment is
474  * for species irxn + M, where M is the number of components.
475  *
476  * @param iphasePop Phase id of the phase that will come into existence
477  * @returns an int representing the status of the step
478  * - 0 : normal return
479  * - 1 : A single species phase species has been zeroed out
480  * in this routine. The species is a noncomponent
481  * - 2 : Same as one but, the zeroed species is a component.
482  * - 3 : Nothing was done because the phase couldn't be birthed
483  * because a needed component is zero.
484  */
485  int vcs_popPhaseRxnStepSizes(const size_t iphasePop);
486 
487  //! Calculates formation reaction step sizes.
488  /*!
489  * This is equation 6.4-16, p. 143 in Smith and Missen.
490  *
491  * Output
492  * -------
493  * m_deltaMolNumSpecies(irxn) : reaction adjustments, where irxn refers to
494  * the irxn'th species formation reaction.
495  * This adjustment is for species irxn + M,
496  * where M is the number of components.
497  *
498  * Special branching occurs sometimes. This causes the component basis
499  * to be reevaluated
500  *
501  * @param forceComponentCalc integer flagging whether a component
502  * recalculation needs to be carried out.
503  * @param kSpecial species number of phase being zeroed.
504  * @returns an int representing which phase may need to be zeroed
505  */
506  size_t vcs_RxnStepSizes(int& forceComponentCalc, size_t& kSpecial);
507 
508  //! Calculates the total number of moles of species in all phases.
509  /*!
510  * Also updates the variable m_totalMolNum and Reconciles Phase existence
511  * flags with total moles in each phase.
512  */
513  double vcs_tmoles();
514 
515  void check_tmoles() const;
516 
517  //! This subroutine calculates reaction free energy changes for
518  //! all noncomponent formation reactions.
519  /*!
520  * Formation reactions are
521  * reactions which create each noncomponent species from the component
522  * species. `m_stoichCoeffRxnMatrix(jcomp,irxn)` are the stoichiometric
523  * coefficients for these reactions. A stoichiometric coefficient of
524  * one is assumed for species irxn in this reaction.
525  *
526  * @param L
527  * - `L < 0`: Calculate reactions corresponding to major noncomponent
528  * and zeroed species only
529  * - `L = 0`: Do all noncomponent reactions, i, between
530  * 0 <= i < irxnl
531  * - `L > 0`: Calculate reactions corresponding to minor noncomponent
532  * and zeroed species only
533  *
534  * @param doDeleted Do deleted species
535  * @param vcsState Calculate deltaG corresponding to either old or new
536  * free energies
537  * @param alterZeroedPhases boolean indicating whether we should
538  * add in a special section for zeroed phases.
539  *
540  * Note we special case one important issue. If the component has zero
541  * moles, then we do not allow deltaG < 0.0 for formation reactions which
542  * would lead to the loss of more of that same component. This dG < 0.0
543  * condition feeds back into the algorithm in several places, and leads
544  * to a infinite loop in at least one case.
545  */
546  void vcs_deltag(const int L, const bool doDeleted, const int vcsState,
547  const bool alterZeroedPhases = true);
548 
549  void vcs_printDeltaG(const int stateCalc);
550 
551  //! Calculate deltag of formation for all species in a single phase.
552  /*!
553  * Calculate deltag of formation for all species in a single phase. It is
554  * assumed that the fe[] is up to date for all species. However, if the
555  * phase is currently zeroed out, a subproblem is calculated to solve for
556  * AC[i] and pseudo-X[i] for that phase.
557  *
558  * @param iphase phase index of the phase to be calculated
559  * @param doDeleted boolean indicating whether to do deleted
560  * species or not
561  * @param stateCalc integer describing which set of free energies
562  * to use and where to stick the results.
563  * @param alterZeroedPhases boolean indicating whether we should
564  * add in a special section for zeroed phases.
565  *
566  * NOTE: this is currently not used used anywhere.
567  * It may be in the future?
568  * @deprecated Unused. To be removed after Cantera 2.3.
569  */
570  void vcs_deltag_Phase(const size_t iphase, const bool doDeleted,
571  const int stateCalc, const bool alterZeroedPhases = true);
572 
573  //! Swaps the indices for all of the global data for two species, k1
574  //! and k2.
575  /*!
576  * @param ifunc If true, switch the species data and the noncomponent
577  * reaction data. This must be called for a non-component species only.
578  * If false, switch the species data only. Typically, we use this option
579  * when determining the component species and at the end of the
580  * calculation, when we want to return unscrambled results. All rxn data
581  * will be out-of-date.
582  * @param k1 First species index
583  * @param k2 Second species index
584  */
585  void vcs_switch_pos(const bool ifunc, const size_t k1, const size_t k2);
586 
587  //! Birth guess returns the number of moles of a species that is coming back
588  //! to life.
589  /*!
590  * Birth guess returns the number of moles of a species that is coming back
591  * to life. Note, this routine is not applicable if the whole phase is
592  * coming back to life, not just one species in that phase.
593  *
594  * Do a minor alt calculation. But, cap the mole numbers at 1.0E-15. For SS
595  * phases use VCS_DELETE_SPECIES_CUTOFF * 100.
596  *
597  * The routine makes sure the guess doesn't reduce the concentration of a
598  * component by more than 1/3. Note this may mean that the vlaue coming back
599  * from this routine is zero or a very small number.
600  *
601  * @param kspec Species number that is coming back to life
602  * @returns the number of kmol that the species should have.
603  * @deprecated Unused. To be removed after Cantera 2.3.
604  */
605  double vcs_birthGuess(const int kspec);
606 
607  //! Routine that independently determines whether a phase should be popped
608  //! under the current conditions.
609  /*
610  * This is the main routine that solves for equilibrium at constant T and
611  * P using a variant of the VCS method. Nonideal phases can be
612  * accommodated as well. Any number of single-species phases and multi-
613  * species phases can be handled by the present version.
614  *
615  * @param print_lvl 1 -> Print results to standard output; -> don't
616  * report on anything
617  * @param printDetails 1 -> Print intermediate results.
618  * @param maxit Maximum number of iterations for the algorithm
619  * @return
620  * - 0 = Equilibrium Achieved
621  * - 1 = Range space error encountered. The element abundance criteria are
622  * only partially satisfied. Specifically, the first NC= (number of
623  * components) conditions are satisfied. However, the full NE (number of
624  * elements) conditions are not satisfied. The equilibrium condition is
625  * returned.
626  * - -1 = Maximum number of iterations is exceeded. Convergence was not
627  * found.
628  * @deprecated Broken and unused. To be removed after Cantera 2.3.
629  */
630  int vcs_solve_phaseStability(const int iphase, int ifunc, double& funcval, int print_lvl);
631 
632  //! Main program to test whether a deleted phase should be brought
633  //! back into existence
634  /*!
635  * @param iph Phase id of the deleted phase
636  */
637  double vcs_phaseStabilityTest(const size_t iph);
638 
639  //! Solve an equilibrium problem at a particular fixed temperature
640  //! and pressure
641  /*!
642  * The actual problem statement is assumed to be in the structure already.
643  * This is a wrapper around the solve_TP() function. In this wrapper, we
644  * nondimensionalize the system we calculate the standard state Gibbs free
645  * energies of the species, and we decide whether to we need to use the
646  * initial guess algorithm.
647  *
648  * @param ipr = 1 -> Print results to standard output;
649  * 0 -> don't report on anything
650  * @param ip1 = 1 -> Print intermediate results;
651  * 0 -> Dont print any intermediate results
652  * @param maxit Maximum number of iterations for the algorithm
653  * @param T Value of the Temperature (Kelvin)
654  * @param pres Value of the Pressure
655  * @returns an integer representing the success of the algorithm
656  * * 0 = Equilibrium Achieved
657  * * 1 = Range space error encountered. The element abundance criteria are
658  * only partially satisfied. Specifically, the first NC= (number of
659  * components) conditions are satisfied. However, the full NE (number of
660  * elements) conditions are not satisfied. The equilibrium condition is
661  * returned.
662  * * -1 = Maximum number of iterations is exceeded. Convergence was not
663  * found.
664  */
665  int vcs_TP(int ipr, int ip1, int maxit, double T, double pres);
666 
667  /*!
668  * Evaluate the standard state free energies at the current temperature
669  * and pressure. Ideal gas pressure contribution is added in here.
670  *
671  * @param ipr 1 -> Print results to standard output; 0 -> don't report
672  * on anything
673  * @param ip1 1 -> Print intermediate results; 0 -> don't.
674  * @param Temp Temperature (Kelvin)
675  * @param pres Pressure (Pascal)
676  */
677  int vcs_evalSS_TP(int ipr, int ip1, double Temp, double pres);
678 
679  //! Initialize the chemical potential of single species phases
680  /*!
681  * For single species phases, initialize the chemical potential with the
682  * value of the standard state chemical potential. This value doesn't
683  * change during the calculation
684  */
685  void vcs_fePrep_TP();
686 
687  //! Calculation of the total volume and the partial molar volumes
688  /*!
689  * This function calculates the partial molar volume for all species, kspec,
690  * in the thermo problem at the temperature TKelvin and pressure, Pres, pres
691  * is in atm. And, it calculates the total volume of the combined system.
692  *
693  * @param[in] tkelvin Temperature in kelvin()
694  * @param[in] pres Pressure in Pascal
695  * @param[in] w w[] is the vector containing the current mole
696  * numbers in units of kmol.
697  * @param[out] volPM[] For species in all phase, the entries are the
698  * partial molar volumes units of M**3 / kmol.
699  * @returns the total volume of the entire system in units of m**3.
700  */
701  double vcs_VolTotal(const double tkelvin, const double pres,
702  const double w[], double volPM[]);
703 
704  //! This routine is mostly concerned with changing the private data to be
705  //! consistent with what's needed for solution. It is called one time for
706  //! each new problem structure definition.
707  /*!
708  * This routine is always followed by vcs_prep(). Therefore, tasks that need
709  * to be done for every call to vcsc() should be placed in vcs_prep() and
710  * not in this routine.
711  *
712  * The problem structure refers to:
713  *
714  * - the number and identity of the species.
715  * - the formula matrix and thus the number of components.
716  * - the number and identity of the phases.
717  * - the equation of state
718  * - the method and parameters for determining the standard state
719  * - The method and parameters for determining the activity coefficients.
720  *
721  * Tasks:
722  * 1. Fill in the SSPhase[] array.
723  * 2. Check to see if any multispecies phases actually have only one
724  * species in that phase. If true, reassign that phase and species
725  * to be a single-species phase.
726  * 3. Determine the number of components in the problem if not already
727  * done so. During this process the order of the species is changed
728  * in the private data structure. All references to the species
729  * properties must employ the ind[] index vector.
730  *
731  * @param printLvl Print level of the routine
732  * @return VCS_SUCCESS = everything went OK
733  */
734  int vcs_prep_oneTime(int printLvl);
735 
736  //! Prepare the object for solution
737  /*!
738  * This routine is mostly concerned with changing the private data to be
739  * consistent with that needed for solution. It is called for every
740  * invocation of the vcs_solve() except for the cleanup invocation.
741  *
742  * Tasks:
743  * 1. Initialization of arrays to zero.
744  *
745  * @return
746  * VCS_SUCCESS = everything went OK;
747  * VCS_PUB_BAD = There is an irreconcilable difference in the
748  * public data structure from when the problem was
749  * initially set up.
750  */
751  int vcs_prep();
752 
753  //! In this routine, we check for things that will cause the algorithm
754  //! to fail.
755  /*!
756  * We check to see if the problem is well posed. If it is not, we return
757  * false and print out error conditions.
758  *
759  * Current there is one condition. If all the element abundances are zero,
760  * the algorithm will fail.
761  *
762  * @param vprob VCS_PROB pointer to the definition of the equilibrium
763  * problem
764  * @return If true, the problem is well-posed. If false, the problem
765  * is not well posed.
766  */
767  bool vcs_wellPosed(VCS_PROB* vprob);
768 
769  //! Rearrange the constraint equations represented by the Formula
770  //! Matrix so that the operational ones are in the front
771  /*!
772  * This subroutine handles the rearrangement of the constraint equations
773  * represented by the Formula Matrix. Rearrangement is only necessary when
774  * the number of components is less than the number of elements. For this
775  * case, some constraints can never be satisfied exactly, because the
776  * range space represented by the Formula Matrix of the components can't
777  * span the extra space. These constraints, which are out of the range
778  * space of the component Formula matrix entries, are migrated to the back
779  * of the Formula matrix.
780  *
781  * A prototypical example is an extra element column in FormulaMatrix[],
782  * which is identically zero. For example, let's say that argon is has an
783  * element column in FormulaMatrix[], but no species in the mechanism
784  * actually contains argon. Then, nc < ne. Also, without perturbation of
785  * FormulaMatrix[] vcs_basopt[] would produce a zero pivot because the
786  * matrix would be singular (unless the argon element column was already
787  * the last column of FormulaMatrix[].
788  *
789  * This routine borrows heavily from vcs_basopt's algorithm. It finds nc
790  * constraints which span the range space of the Component Formula matrix,
791  * and assigns them as the first nc components in the formula matrix. This
792  * guarantees that vcs_basopt[] has a nonsingular matrix to invert.
793  *
794  * Other Variables
795  * @param aw Mole fraction work space (ne in length)
796  * @param sa Gram-Schmidt orthog work space (ne in length)
797  * @param sm QR matrix work space (ne*ne in length)
798  * @param ss Gram-Schmidt orthog work space (ne in length)
799  */
800  int vcs_elem_rearrange(double* const aw, double* const sa,
801  double* const sm, double* const ss);
802 
803  //! Swaps the indices for all of the global data for two elements, ipos
804  //! and jpos.
805  /*!
806  * This function knows all of the element information with VCS_SOLVE, and
807  * can therefore switch element positions
808  *
809  * @param ipos first global element index
810  * @param jpos second global element index
811  */
812  void vcs_switch_elem_pos(size_t ipos, size_t jpos);
813 
814  //! Calculates reaction adjustments using a full Hessian approximation
815  /*!
816  * This does what equation 6.4-16, p. 143 in Smith and Missen is supposed
817  * to do. However, a full matrix is formed and then solved via a conjugate
818  * gradient algorithm. No preconditioning is done.
819  *
820  * If special branching is warranted, then the program bails out.
821  *
822  * Output
823  * -------
824  * DS(I) : reaction adjustment, where I refers to the Ith species
825  * Special branching occurs sometimes. This causes the component basis
826  * to be reevaluated
827  * return = 0 : normal return
828  * 1 : A single species phase species has been zeroed out
829  * in this routine. The species is a noncomponent
830  * 2 : Same as one but, the zeroed species is a component.
831  *
832  * Special attention is taken to flag cases where the direction of the
833  * update is contrary to the steepest descent rule. This is an important
834  * attribute of the regular vcs algorithm. We don't want to violate this.
835  *
836  * NOTE: currently this routine is not used.
837  * @deprecated Unused. To be removed after Cantera 2.3.
838  */
839  int vcs_rxn_adj_cg();
840 
841  //! Calculates the diagonal contribution to the Hessian due to
842  //! the dependence of the activity coefficients on the mole numbers.
843  /*!
844  * (See framemaker notes, Eqn. 20 - VCS Equations document)
845  *
846  * We allow the diagonal to be increased positively to any degree.
847  * We allow the diagonal to be decreased to 1/3 of the ideal solution
848  * value, but no more -> it must remain positive.
849  */
850  double vcs_Hessian_diag_adj(size_t irxn, double hessianDiag_Ideal);
851 
852  //! Calculates the diagonal contribution to the Hessian due to
853  //! the dependence of the activity coefficients on the mole numbers.
854  /*!
855  * (See framemaker notes, Eqn. 20 - VCS Equations document)
856  */
857  double vcs_Hessian_actCoeff_diag(size_t irxn);
858 
859  //! Recalculate all of the activity coefficients in all of the phases
860  //! based on input mole numbers
861  /*
862  * @param moleSpeciesVCS kmol of species to be used in the update.
863  *
864  * NOTE: This routine needs to be regulated.
865  */
866  void vcs_CalcLnActCoeffJac(const double* const moleSpeciesVCS);
867 
868  //! A line search algorithm is carried out on one reaction
869  /*!
870  * In this routine we carry out a rough line search algorithm to make
871  * sure that the m_deltaGRxn_new doesn't switch signs prematurely.
872  *
873  * @param irxn Reaction number
874  * @param dx_orig Original step length
875  * @param ANOTE Output character string stating the conclusions of the
876  * line search
877  * @returns the optimized step length found by the search
878  * @deprecated Unused. To be removed after Cantera 2.3.
879  */
880  double vcs_line_search(const size_t irxn, const double dx_orig,
881  char* const ANOTE=0);
882 
883  //! Print out a report on the state of the equilibrium problem to
884  //! standard output.
885  /*!
886  * @param iconv Indicator of convergence, to be printed out in the report:
887  * - 0 converged
888  * - 1 range space error
889  * - -1 not converged
890  */
891  int vcs_report(int iconv);
892 
893  //! Switch all species data back to the original order.
894  /*!
895  * This destroys the data based on reaction ordering.
896  * @deprecated Unused. To be removed after Cantera 2.3.
897  */
898  int vcs_rearrange();
899 
900  //! Nondimensionalize the problem data
901  /*!
902  * Nondimensionalize the free energies using the divisor, R * T
903  *
904  * Essentially the internal data can either be in dimensional form or in
905  * nondimensional form. This routine switches the data from dimensional form
906  * into nondimensional form.
907  *
908  * @todo Add a scale factor based on the total mole numbers. The algorithm
909  * contains hard coded numbers based on the total mole number. If we
910  * ever were faced with a problem with significantly different total
911  * kmol numbers than one the algorithm would have problems.
912  */
913  void vcs_nondim_TP();
914 
915  //! Redimensionalize the problem data
916  /*!
917  * Redimensionalize the free energies using the multiplier R * T
918  *
919  * Essentially the internal data can either be in dimensional form or in
920  * nondimensional form. This routine switches the data from nondimensional
921  * form into dimensional form.
922  */
923  void vcs_redim_TP();
924 
925  //! Computes the current elemental abundances vector
926  /*!
927  * Computes the elemental abundances vector, m_elemAbundances[], and stores
928  * it back into the global structure
929  */
930  void vcs_elab();
931 
932  /*!
933  * Checks to see if the element abundances are in compliance. If they are,
934  * then TRUE is returned. If not, FALSE is returned. Note the number of
935  * constraints checked is usually equal to the number of components in the
936  * problem. This routine can check satisfaction of all of the constraints
937  * in the problem, which is equal to ne. However, the solver can't fix
938  * breakage of constraints above nc, because that nc is the range space by
939  * definition. Satisfaction of extra constraints would have had to occur
940  * in the problem specification.
941  *
942  * The constraints should be broken up into 2 sections. If a constraint
943  * involves a formula matrix with positive and negative signs, and eaSet =
944  * 0.0, then you can't expect that the sum will be zero. There may be
945  * roundoff that inhibits this. However, if the formula matrix is all of
946  * one sign, then this requires that all species with nonzero entries in
947  * the formula matrix be identically zero. We put this into the logic
948  * below.
949  *
950  * @param ibound 1: Checks constraints up to the number of elements;
951  * 0: Checks constraints up to the number of components.
952  */
953  bool vcs_elabcheck(int ibound);
954 
955  /*!
956  * Computes the elemental abundances vector for a single phase,
957  * elemAbundPhase[], and returns it through the argument list. The mole
958  * numbers of species are taken from the current value in
959  * m_molNumSpecies_old[].
960  */
961  void vcs_elabPhase(size_t iphase, double* const elemAbundPhase);
962 
963  /*!
964  * This subroutine corrects for element abundances. At the end of the
965  * subroutine, the total moles in all phases are recalculated again,
966  * because we have changed the number of moles in this routine.
967  *
968  * @param aa temporary work vector, length ne*ne
969  * @param x temporary work vector, length ne
970  *
971  * @returns
972  * - 0 = Nothing of significance happened, Element abundances were and
973  * still are good.
974  * - 1 = The solution changed significantly; The element abundances are
975  * now good.
976  * - 2 = The solution changed significantly, The element abundances are
977  * still bad.
978  * - 3 = The solution changed significantly, The element abundances are
979  * still bad and a component species got zeroed out.
980  *
981  * Internal data to be worked on::
982  * - ga Current element abundances
983  * - m_elemAbundancesGoal Required elemental abundances
984  * - m_molNumSpecies_old Current mole number of species.
985  * - m_formulaMatrix[][] Formula matrix of the species
986  * - ne Number of elements
987  * - nc Number of components.
988  *
989  * NOTES:
990  * This routine is turning out to be very problematic. There are
991  * lots of special cases and problems with zeroing out species.
992  *
993  * Still need to check out when we do loops over nc vs. ne.
994  */
995  int vcs_elcorr(double aa[], double x[]);
996 
997  //! Create an initial estimate of the solution to the thermodynamic
998  //! equilibrium problem.
999  /*!
1000  * @return value indicates success:
1001  * - 0: successful initial guess
1002  * - -1: Unsuccessful initial guess; the elemental abundances aren't
1003  * satisfied.
1004  */
1005  int vcs_inest_TP();
1006 
1007  //! Estimate the initial mole numbers by constrained linear programming
1008  /*!
1009  * This is done by running each reaction as far forward or backward as
1010  * possible, subject to the constraint that all mole numbers remain non-
1011  * negative. Reactions for which \f$ \Delta \mu^0 \f$ are positive are run
1012  * in reverse, and ones for which it is negative are run in the forward
1013  * direction. The end result is equivalent to solving the linear
1014  * programming problem of minimizing the linear Gibbs function subject to
1015  * the element and non-negativity constraints.
1016  */
1017  int vcs_setMolesLinProg();
1018 
1019  //! Calculate the total dimensionless Gibbs free energy
1020  /*!
1021  * Inert species are handled as if they had a standard free energy of
1022  * zero. Note, for this algorithm this function should be monotonically
1023  * decreasing.
1024  */
1025  double vcs_Total_Gibbs(double* w, double* fe, double* tPhMoles);
1026 
1027  //! Calculate the total dimensionless Gibbs free energy of a single phase
1028  /*!
1029  * Inert species are handled as if they had a standard free energy of
1030  * zero and if they obeyed ideal solution/gas theory.
1031  *
1032  * @param iphase ID of the phase
1033  * @param w Species mole number vector for all species
1034  * @param fe vector of partial molar free energies of all of the
1035  * species
1036  */
1037  double vcs_GibbsPhase(size_t iphase, const double* const w,
1038  const double* const fe);
1039 
1040  //! Transfer the results of the equilibrium calculation back to VCS_PROB
1041  /*!
1042  * The VCS_PROB structure is returned to the user.
1043  *
1044  * @param pub Pointer to VCS_PROB object that will get the results of the
1045  * equilibrium calculation transfered to it.
1046  */
1047  int vcs_prob_update(VCS_PROB* pub);
1048 
1049  //! Fully specify the problem to be solved using VCS_PROB
1050  /*!
1051  * Use the contents of the VCS_PROB to specify the contents of the
1052  * private data, VCS_SOLVE.
1053  *
1054  * @param pub Pointer to VCS_PROB that will be used to
1055  * initialize the current equilibrium problem
1056  */
1057  int vcs_prob_specifyFully(const VCS_PROB* pub);
1058 
1059  //! Specify the problem to be solved using VCS_PROB, incrementally
1060  /*!
1061  * Use the contents of the VCS_PROB to specify the contents of the
1062  * private data, VCS_SOLVE.
1063  *
1064  * It's assumed we are solving the same problem.
1065  *
1066  * @param pub Pointer to VCS_PROB that will be used to initialize the
1067  * current equilibrium problem
1068  */
1069  int vcs_prob_specify(const VCS_PROB* pub);
1070 
1071 private:
1072  //! Zero out the concentration of a species.
1073  /*!
1074  * Make sure to conserve elements and keep track of the total moles in all
1075  * phases.
1076  * - w[]
1077  * - m_tPhaseMoles_old[]
1078  *
1079  * @param kspec Species index
1080  * @return:
1081  * 1: succeeded
1082  * 0: failed.
1083  */
1084  int vcs_zero_species(const size_t kspec);
1085 
1086  //! Change a single species from active to inactive status
1087  /*!
1088  * Rearrange data when species is added or removed. The Lth species is
1089  * moved to the back of the species vector. The back of the species
1090  * vector is indicated by the value of MR, the current number of
1091  * active species in the mechanism.
1092  *
1093  * @param kspec Species Index
1094  * @return
1095  * Returns 0 unless.
1096  * The return is 1 when the current number of
1097  * noncomponent species is equal to zero. A recheck of deleted species
1098  * is carried out in the main code.
1099  */
1100  int vcs_delete_species(const size_t kspec);
1101 
1102  //! This routine handles the bookkeeping involved with the deletion of
1103  //! multiphase phases from the problem.
1104  /*!
1105  * When they are deleted, all of their species become active species, even
1106  * though their mole numbers are set to zero. The routine does not make the
1107  * decision to eliminate multiphases.
1108  *
1109  * Note, species in phases with zero mole numbers are still considered
1110  * active. Whether the phase pops back into existence or not is checked as
1111  * part of the main iteration loop.
1112  *
1113  * @param iph Phase to be deleted
1114  * @returns whether the operation was successful or not
1115  */
1116  bool vcs_delete_multiphase(const size_t iph);
1117 
1118  //! Change the concentration of a species by delta moles.
1119  /*!
1120  * Make sure to conserve elements and keep track of the total kmoles in
1121  * all phases.
1122  *
1123  * @param kspec The species index
1124  * @param delta_ptr pointer to the delta for the species. This may
1125  * change during the calculation
1126  * @return
1127  * 1: succeeded without change of dx
1128  * 0: Had to adjust dx, perhaps to zero, in order to do the delta.
1129  */
1130  int delta_species(const size_t kspec, double* const delta_ptr);
1131 
1132  //! Provide an estimate for the deleted species in phases that are not
1133  //! zeroed out
1134  /*!
1135  * Try to add back in all deleted species. An estimate of the kmol numbers
1136  * are obtained and the species is added back into the equation system, into
1137  * the old state vector.
1138  *
1139  * This routine is called at the end of the calculation, just before
1140  * returning to the user.
1141  */
1142  size_t vcs_add_all_deleted();
1143 
1144  //! Recheck deleted species in multispecies phases.
1145  /*!
1146  * We are checking the equation:
1147  *
1148  * sum_u = sum_j_comp [ sigma_i_j * u_j ]
1149  * = u_i_O + log((AC_i * W_i)/m_tPhaseMoles_old)
1150  *
1151  * by first evaluating:
1152  *
1153  * DG_i_O = u_i_O - sum_u.
1154  *
1155  * Then, if TL is zero, the phase pops into existence if DG_i_O < 0. Also,
1156  * if the phase exists, then we check to see if the species can have a mole
1157  * number larger than VCS_DELETE_SPECIES_CUTOFF (default value = 1.0E-32).
1158  */
1159  int vcs_recheck_deleted();
1160 
1161  //! Recheck deletion condition for multispecies phases.
1162  /*!
1163  * We assume here that DG_i_0 has been calculated for deleted species
1164  * correctly
1165  *
1166  * m_feSpecies(I) = m_SSfeSpecies(I)
1167  * + ln(ActCoeff[I])
1168  * - ln(Mnaught * m_units)
1169  * + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
1170  *
1171  * sum_u = sum_j_comp [ sigma_i_j * u_j ]
1172  * = u_i_O + log((AC_i * W_i)/m_tPhaseMoles_old)
1173  *
1174  * DG_i_0 = m_feSpecies(I) - sum_m{ a_i_m DG_m }
1175  *
1176  * by first evaluating:
1177  *
1178  * DG_i_O = u_i_O - sum_u.
1179  *
1180  * Then, the phase pops into existence iff
1181  *
1182  * phaseDG = 1.0 - sum_i{exp(-DG_i_O)} < 0.0
1183  *
1184  * This formula works for both single species phases and for multispecies
1185  * phases. It's an overkill for single species phases.
1186  *
1187  * @param iphase Phase index number
1188  * @returns true if the phase is currently deleted but should be
1189  * reinstated. Returns false otherwise.
1190  *
1191  * NOTE: this routine is currently not used in the code, and
1192  * contains some basic changes that are incompatible.
1193  *
1194  * assumptions:
1195  * 1. Vphase Existence is up to date
1196  * 2. Vphase->IndSpecies is up to date
1197  * 3. m_deltaGRxn_old[irxn] is up to date
1198  * @deprecated Unused. To be removed after Cantera 2.3.
1199  */
1200  bool recheck_deleted_phase(const int iphase);
1201 
1202  //! Minor species alternative calculation
1203  /*!
1204  * This is based upon the following approximation: The mole fraction
1205  * changes due to these reactions don't affect the mole numbers of the
1206  * component species. Therefore the following approximation is valid for
1207  * a small component of an ideal phase:
1208  *
1209  * 0 = m_deltaGRxn_old(I) + log(molNum_new(I)/molNum_old(I))
1210  *
1211  * `m_deltaGRxn_old` contains the contribution from
1212  *
1213  * m_feSpecies_old(I) =
1214  * m_SSfeSpecies(I) +
1215  * log(ActCoeff[i] * molNum_old(I) / m_tPhaseMoles_old(iph))
1216  * Thus,
1217  *
1218  * molNum_new(I)= molNum_old(I) * EXP(-m_deltaGRxn_old(I))
1219  *
1220  * Most of this section is mainly restricting the update to reasonable
1221  * values. We restrict the update a factor of 1.0E10 up and 1.0E-10 down
1222  * because we run into trouble with the addition operator due to roundoff if
1223  * we go larger than ~1.0E15. Roundoff will then sometimes produce zero mole
1224  * fractions.
1225  *
1226  * Note: This routine was generalized to incorporate nonideal phases and
1227  * phases on the molality basis
1228  *
1229  * @param[in] kspec The current species and corresponding formation
1230  * reaction number.
1231  * @param[in] irxn The current species and corresponding formation
1232  * reaction number.
1233  * @param[out] do_delete: BOOLEAN which if true on return, then we
1234  * branch to the section that deletes a species
1235  * from the current set of active species.
1236  */
1237  double vcs_minor_alt_calc(size_t kspec, size_t irxn, bool* do_delete,
1238  char* ANOTE=0) const;
1239 
1240  //! This routine optimizes the minimization of the total Gibbs free energy
1241  //! by making sure the slope of the following functional stays negative:
1242  /*!
1243  * The slope of the following functional is equivalent to the slope of the
1244  * total Gibbs free energy of the system:
1245  *
1246  * d_Gibbs/ds = sum_k( m_deltaGRxn * m_deltaMolNumSpecies[k] )
1247  *
1248  * along the current direction m_deltaMolNumSpecies[], by choosing a value, al: (0<al<1)
1249  * such that the a parabola approximation to Gibbs(al) fit to the
1250  * end points al = 0 and al = 1 is minimized.
1251  * - s1 = slope of Gibbs function at al = 0, which is the previous
1252  * solution = d(Gibbs)/d(al).
1253  * - s2 = slope of Gibbs function at al = 1, which is the current
1254  * solution = d(Gibbs)/d(al).
1255  *
1256  * Only if there has been an inflection point (i.e., s1 < 0 and s2 > 0),
1257  * does this code section kick in. It finds the point on the parabola
1258  * where the slope is equal to zero.
1259  */
1260  bool vcs_globStepDamp();
1261 
1262  //! Calculate the norm of a deltaGibbs free energy vector
1263  /*!
1264  * Positive DG for species which don't exist are ignored.
1265  *
1266  * @param dg Vector of local delta G's.
1267  */
1268  double l2normdg(double dg[]) const;
1269 
1270  //! Print out and check the elemental abundance vector
1271  //! @deprecated Unused. To be removed after Cantera 2.3.
1272  void prneav() const;
1273 
1274  void checkDelta1(double* const ds, double* const delTPhMoles, size_t kspec);
1275 
1276  //! Estimate equilibrium compositions
1277  /*!
1278  * Algorithm covered in a section of Smith and Missen's Book.
1279  *
1280  * Linear programming module is based on using dbolm.
1281  *
1282  * @param aw aw[i[ Mole fraction work space (ne in length)
1283  * @param sa sa[j] = Gram-Schmidt orthog work space (ne in length)
1284  * @param sm sm[i+j*ne] = QR matrix work space (ne*ne in length)
1285  * @param ss ss[j] = Gram-Schmidt orthog work space (ne in length)
1286  * @param test This is a small negative number.
1287  */
1288  void vcs_inest(double* const aw, double* const sa, double* const sm,
1289  double* const ss, double test);
1290 
1291  //! Calculate the status of single species phases.
1292  void vcs_SSPhase();
1293 
1294  //! This function recalculates the deltaG for reaction, irxn
1295  /*!
1296  * This function recalculates the deltaG for reaction irxn, given the mole
1297  * numbers in molNum. It uses the temporary space mu_i, to hold the
1298  * recalculated chemical potentials. It only recalculates the chemical
1299  * potentials for species in phases which participate in the irxn reaction.
1300  * This function is used by the vcs_line_search algorithm() and should not
1301  * be used widely due to the unknown state it leaves the system.
1302  *
1303  * @param[in] irxn Reaction number
1304  * @param[in] molNum Current mole numbers of species to be used as input
1305  * to the calculation (units = kmol), (length = totalNuMSpecies)
1306  * @param[out] ac Activity coefficients (length = totalNumSpecies) Note
1307  * this is only partially formed. Only species in phases that
1308  * participate in the reaction will be updated
1309  * @param[out] mu_i dimensionless chemical potentials (length
1310  * totalNumSpecies) Note this is only partially formed. Only
1311  * species in phases that participate in the reaction will be
1312  * updated
1313  * @returns the dimensionless deltaG of the reaction
1314  * @deprecated Unused. To be removed after Cantera 2.3.
1315  */
1316  double deltaG_Recalc_Rxn(const int stateCalc,
1317  const size_t irxn, const double* const molNum,
1318  double* const ac, double* const mu_i);
1319 
1320  //! Delete memory that isn't just resizable STL containers
1321  /*!
1322  * This gets called by the destructor or by InitSizes().
1323  */
1324  void vcs_delete_memory();
1325 
1326  //! Initialize the internal counters
1327  /*!
1328  * Initialize the internal counters containing the subroutine call
1329  * values and times spent in the subroutines.
1330  *
1331  * ifunc = 0 Initialize only those counters appropriate for the top of
1332  * vcs_solve_TP().
1333  * = 1 Initialize all counters.
1334  */
1335  void vcs_counters_init(int ifunc);
1336 
1337  //! Create a report on the plog file containing timing and its information
1338  /*!
1339  * @param timing_print_lvl If 0, just report the iteration count. If larger
1340  * than zero, report the timing information
1341  */
1342  void vcs_TCounters_report(int timing_print_lvl = 1);
1343 
1344  void vcs_setFlagsVolPhases(const bool upToDate, const int stateCalc);
1345 
1346  void vcs_setFlagsVolPhase(const size_t iph, const bool upToDate, const int stateCalc);
1347 
1348  //! Update all underlying vcs_VolPhase objects
1349  /*!
1350  * Update the mole numbers and the phase voltages of all phases in the vcs
1351  * problem
1352  *
1353  * @param stateCalc Location of the update (either VCS_STATECALC_NEW or
1354  * VCS_STATECALC_OLD).
1355  */
1356  void vcs_updateMolNumVolPhases(const int stateCalc);
1357 
1358  // Helper functions used internally by vcs_solve_TP
1359  int solve_tp_component_calc(bool& allMinorZeroedSpecies);
1360  void solve_tp_inner(size_t& iti, size_t& it1, bool& uptodate_minors,
1361  bool& allMinorZeroedSpecies, int& forceComponentCalc,
1362  int& stage, bool printDetails, char* ANOTE);
1363  void solve_tp_equilib_check(bool& allMinorZeroedSpecies, bool& uptodate_minors,
1364  bool& giveUpOnElemAbund, int& solveFail,
1365  size_t& iti, size_t& it1, int maxit,
1366  int& stage, bool& lec);
1367  void solve_tp_elem_abund_check(size_t& iti, int& stage, bool& lec,
1368  bool& giveUpOnElemAbund,
1369  int& finalElemAbundAttempts,
1370  int& rangeErrorFound);
1371 
1372  // data used by vcs_solve_TP and it's helper functions
1373  vector_fp m_sm;
1374  vector_fp m_ss;
1375  vector_fp m_sa;
1376  vector_fp m_aw;
1377  vector_fp m_wx;
1378 
1379 public:
1380  //! value of the number of species used to size data structures
1381  size_t NSPECIES0;
1382 
1383  //! value of the number of phases used to size data structures
1384  size_t NPHASE0;
1385 
1386  //! Total number of species in the problems
1388 
1389  //! Number of element constraints in the problem
1390  /*!
1391  * This is typically equal to the number of elements in the problem
1392  */
1394 
1395  //! Number of components calculated for the problem
1397 
1398  //! Total number of non-component species in the problem
1399  size_t m_numRxnTot;
1400 
1401  //! Current number of species in the problems. Species can be deleted if
1402  //! they aren't stable under the current conditions
1404 
1405  //! Current number of non-component species in the problem. Species can be
1406  //! deleted if they aren't stable under the current conditions
1407  size_t m_numRxnRdc;
1408 
1409  //! Number of active species which are currently either treated as
1410  //! minor species
1412 
1413  //! Number of Phases in the problem
1414  size_t m_numPhases;
1415 
1416  //! Formula matrix for the problem
1417  /*!
1418  * FormulaMatrix(kspec,j) = Number of elements, j, in the kspec species
1419  *
1420  * Both element and species indices are swapped.
1421  */
1423 
1424  //! Stoichiometric coefficient matrix for the reaction mechanism expressed
1425  //! in Reduced Canonical Form.
1426  /*!
1427  * This is the stoichiometric coefficient matrix for the reaction which
1428  * forms species kspec from the component species. A stoichiometric
1429  * coefficient of one is assumed for the species kspec in this mechanism.
1430  *
1431  * NOTE: kspec = irxn + m_numComponents
1432  *
1433  * `m_stoichCoeffRxnMatrix(j,irxn)` : j refers to the component number, and
1434  * irxn refers to the irxn_th non-component species. The stoichiometric
1435  * coefficients multiplied by the Formula coefficients of the component
1436  * species add up to the negative value of the number of elements in the
1437  * species kspec.
1438  *
1439  * size = nelements0 x nspecies0
1440  */
1442 
1443  //! Absolute size of the stoichiometric coefficients
1444  /*!
1445  * scSize[irxn] = abs(Size) of the stoichiometric coefficients. These are
1446  * used to determine whether a given species should be
1447  * handled by the alt_min treatment or should be handled as a
1448  * major species.
1449  */
1451 
1452  //! total size of the species
1453  /*!
1454  * This is used as a multiplier to the mole number in figuring out which
1455  * species should be components.
1456  */
1458 
1459  //! Standard state chemical potentials for species K at the current
1460  //! temperature and pressure.
1461  /*!
1462  * The first NC entries are for components. The following NR entries are
1463  * for the current non-component species in the mechanism.
1464  */
1466 
1467  //! Free energy vector from the start of the current iteration
1468  /*!
1469  * The free energies are saved at the start of the current iteration.
1470  * Length = number of species
1471  */
1473 
1474  //! Dimensionless new free energy for all the species in the mechanism
1475  //! at the new tentative T, P, and mole numbers.
1476  /*!
1477  * The first NC entries are for components. The following
1478  * NR entries are for the current non-component species in the mechanism.
1479  * Length = number of species
1480  */
1482 
1483  //! Setting for whether to do an initial estimate
1484  /*!
1485  * Initial estimate:
1486  * 0 Do not estimate the solution at all. Use the
1487  * supplied mole numbers as is.
1488  * 1 Only do an estimate if the element abundances aren't satisfied.
1489  * -1 Force an estimate of the soln. Throw out the input mole numbers.
1490  */
1492 
1493  //! Total moles of the species
1494  /*!
1495  * Total number of moles of the kth species.
1496  * Length = Total number of species = m
1497  */
1499 
1500  //! Specifies the species unknown type
1501  /*!
1502  * There are two types. One is the straightforward species, with the mole
1503  * number w[k], as the unknown. The second is the an interfacial voltage
1504  * where w[k] refers to the interfacial voltage in volts.
1505  *
1506  * These species types correspond to metallic electrons corresponding to
1507  * electrodes. The voltage and other interfacial conditions sets up an
1508  * interfacial current, which is set to zero in this initial treatment.
1509  * Later we may have non-zero interfacial currents.
1510  */
1512 
1513  //! Change in the number of moles of phase, iphase, due to the
1514  //! noncomponent formation reaction, irxn, for species, k:
1515  /*!
1516  * m_deltaMolNumPhase(iphase,irxn) = k = nc + irxn
1517  */
1519 
1520  //! This is 1 if the phase, iphase, participates in the formation reaction
1521  //! irxn, and zero otherwise. PhaseParticipation(iphase,irxn)
1523 
1524  //! electric potential of the iph phase
1526 
1527  //! Tentative value of the mole number vector. It's also used to store the
1528  //! mole fraction vector.
1530 
1531  //! Delta G(irxn) for the noncomponent species in the mechanism.
1532  /*!
1533  * Computed by the subroutine deltaG. m_deltaGRxn is the free energy change
1534  * for the reaction which forms species K from the component species. This
1535  * vector has length equal to the number of noncomponent species in the
1536  * mechanism. It starts with the first current noncomponent species in the
1537  * mechanism.
1538  */
1540 
1541  //! Last deltag[irxn] from the previous step
1543 
1544  //! Last deltag[irxn] from the previous step with additions for
1545  //! possible births of zeroed phases.
1547 
1548  //! Temporary vector of Rxn DeltaG's
1549  /*!
1550  * This is used from time to time, for printing purposes
1551  */
1553 
1554  //! Reaction Adjustments for each species during the current step
1555  /*!
1556  * delta Moles for each species during the current step.
1557  * Length = number of species
1558  */
1560 
1561  //! Element abundances vector
1562  /*!
1563  * Vector of moles of each element actually in the solution vector. Except
1564  * for certain parts of the algorithm, this is a constant. Note other
1565  * constraint conditions are added to this vector. This is input from the
1566  * input file and is considered a constant from thereon. units = kmoles
1567  */
1569 
1570  //! Element abundances vector Goals
1571  /*!
1572  * Vector of moles of each element that are the goals of the simulation.
1573  * This is a constant in the problem. Note other constraint conditions are
1574  * added to this vector. This is input from the input file and is considered
1575  * a constant from thereon. units = kmoles
1576  */
1578 
1579  //! Total number of kmoles in all phases
1580  /*!
1581  * This number includes the inerts.
1582  * -> Don't use this except for scaling purposes
1583  */
1585 
1586  //! Total kmols of species in each phase
1587  /*!
1588  * This contains the total number of moles of species in each phase
1589  *
1590  * Length = number of phases
1591  */
1593 
1594  //! total kmols of species in each phase in the tentative soln vector
1595  /*!
1596  * This contains the total number of moles of species in each phase
1597  * in the tentative solution vector
1598  *
1599  * Length = number of phases
1600  */
1602 
1603  //! Temporary vector of length NPhase
1605 
1606  //! Temporary vector of length NPhase
1608 
1609  //! Change in the total moles in each phase
1610  /*!
1611  * Length number of phases.
1612  */
1614 
1615  //! Temperature (Kelvin)
1617 
1618  //! Pressure
1620 
1621  //! Total kmoles of inert to add to each phase
1622  /*!
1623  * TPhInertMoles[iph] = Total kmoles of inert to add to each phase
1624  * length = number of phases
1625  */
1627 
1628  //! Tolerance requirement for major species
1629  double m_tolmaj;
1630 
1631  //! Tolerance requirements for minor species
1632  double m_tolmin;
1633 
1634  //! Below this, major species aren't refined any more
1635  double m_tolmaj2;
1636 
1637  //! Below this, minor species aren't refined any more
1638  double m_tolmin2;
1639 
1640  //! Index vector that keeps track of the species vector rearrangement
1641  /*!
1642  * At the end of each run, the species vector and associated data gets put
1643  * back in the original order.
1644  *
1645  * Example
1646  *
1647  * k = m_speciesMapIndex[kspec]
1648  *
1649  * kspec = current order in the vcs_solve object
1650  * k = original order in the vcs_prob object and in the MultiPhase object
1651  */
1652  std::vector<size_t> m_speciesMapIndex;
1653 
1654  //! Index that keeps track of the index of the species within the local
1655  //! phase
1656  /*!
1657  * This returns the local index of the species within the phase. Its
1658  * argument is the global species index within the VCS problem.
1659  *
1660  * k = m_speciesLocalPhaseIndex[kspec]
1661  *
1662  * k varies between 0 and the nSpecies in the phase
1663  *
1664  * Length = number of species
1665  */
1666  std::vector<size_t> m_speciesLocalPhaseIndex;
1667 
1668  //! Index vector that keeps track of the rearrangement of the elements
1669  /*!
1670  * At the end of each run, the element vector and associated data gets
1671  * put back in the original order.
1672  *
1673  * Example
1674  *
1675  * e = m_elementMapIndex[eNum]
1676  * eNum = current order in the vcs_solve object
1677  * e = original order in the vcs_prob object and in the MultiPhase object
1678  */
1679  std::vector<size_t> m_elementMapIndex;
1680 
1681  //! Mapping between the species index for noncomponent species and the
1682  //! full species index.
1683  /*!
1684  * ir[irxn] = Mapping between the reaction index for noncomponent
1685  * formation reaction of a species and the full species
1686  * index.
1687  *
1688  * Initially set to a value of K = NC + I This vector has length equal to
1689  * number of noncomponent species in the mechanism. It starts with the
1690  * first current noncomponent species in the mechanism. kspec = ir[irxn]
1691  */
1692  std::vector<size_t> m_indexRxnToSpecies;
1693 
1694  //! Major -Minor status vector for the species in the problem
1695  /*!
1696  * The index for this is species. The reaction that this is referring to
1697  * is `kspec = irxn + m_numComponents`. For possible values and their
1698  * meanings, see vcs_evaluate_speciesType().
1699  */
1701 
1702  //! Mapping from the species number to the phase number
1703  std::vector<size_t> m_phaseID;
1704 
1705  //! Boolean indicating whether a species belongs to a single-species phase
1706  // vector<bool> can't be used here because it doesn't work with std::swap
1707  std::vector<char> m_SSPhase;
1708 
1709  //! Species string name for the kth species
1710  std::vector<std::string> m_speciesName;
1711 
1712  //! Vector of strings containing the element names
1713  /*!
1714  * ElName[j] = String containing element names
1715  */
1716  std::vector<std::string> m_elementName;
1717 
1718  //! Type of the element constraint
1719  /*!
1720  * * 0 - #VCS_ELEM_TYPE_ABSPOS Normal element that is positive or zero in
1721  * all species.
1722  * * 1 - #VCS_ELEM_TYPE_ELECTRONCHARGE element dof that corresponds to
1723  * the electronic charge DOF.
1724  * * 2 - #VCS_ELEM_TYPE_CHARGENEUTRALITY element dof that corresponds to
1725  * a required charge neutrality constraint on the phase. The element
1726  * abundance is always exactly zero.
1727  * * 3 - #VCS_ELEM_TYPE_OTHERCONSTRAINT Other constraint which may mean
1728  * that a species has neg 0 or pos value of that constraint (other than
1729  * charge)
1730  */
1732 
1733  //! Specifies whether an element constraint is active
1734  /*!
1735  * The default is true. Length = nelements
1736  */
1738 
1739  //! Array of Phase Structures. Length = number of phases.
1740  std::vector<vcs_VolPhase*> m_VolPhaseList;
1741 
1742  //! String containing the title of the run
1743  std::string m_title;
1744 
1745  //! This specifies the current state of units for the Gibbs free energy
1746  //! properties in the program.
1747  /*!
1748  * The default is to have this unitless
1749  */
1751 
1752  //! Multiplier for the mole numbers within the nondimensional formulation
1753  /*!
1754  * All numbers within the main routine are on an absolute basis. This
1755  * presents some problems wrt very large and very small mole numbers. We get
1756  * around this by using a multiplier coming into and coming out of the
1757  * equilibrium routines
1758  */
1760 
1761  //! specifies the activity convention of the phase containing the species
1762  /*!
1763  * * 0 = molar based
1764  * * 1 = molality based
1765  *
1766  * length = number of species
1767  */
1769 
1770  //! specifies the activity convention of the phase.
1771  /*!
1772  * * 0 = molar based
1773  * * 1 = molality based
1774  *
1775  * length = number of phases
1776  */
1778 
1779  //! specifies the ln(Mnaught) used to calculate the chemical potentials
1780  /*!
1781  * For molar based activity conventions this will be equal to 0.0.
1782  * length = number of species.
1783  */
1785 
1786  //! Molar-based Activity Coefficients for Species.
1787  //! Length = number of species
1789 
1790  //! Molar-based Activity Coefficients for Species based on old mole numbers
1791  /*!
1792  * These activity coefficients are based on the m_molNumSpecies_old
1793  * values Molar based activity coefficients. Length = number of species
1794  */
1796 
1797  //! Change in the log of the activity coefficient with respect to the mole
1798  //! number multiplied by the phase mole number
1799  /*!
1800  * size = nspecies x nspecies
1801  *
1802  * This is a temporary array that gets regenerated every time it's needed.
1803  * It is not swapped wrt species.
1804  */
1806 
1807  //! Molecular weight of each species
1808  /*!
1809  * units = kg/kmol. length = number of species.
1810  *
1811  * note: this is a candidate for removal. I don't think we use it.
1812  */
1814 
1815  //! Charge of each species. Length = number of species.
1817 
1818  std::vector<std::vector<size_t> > phasePopProblemLists_;
1819 
1820  //! Vector of pointers to thermo structures which identify the model
1821  //! and parameters for evaluating the thermodynamic functions for that
1822  //! particular species.
1823  /*!
1824  * SpeciesThermo[k] pointer to the thermo information for the kth species
1825  */
1826  std::vector<VCS_SPECIES_THERMO*> m_speciesThermoList;
1827 
1828  //! Choice of Hessians
1829  /*!
1830  * If this is true, then we will use a better approximation to the Hessian
1831  * based on Jacobian of the ln(ActCoeff) with respect to mole numbers
1832  */
1834 
1835  //! Total volume of all phases. Units are m^3
1836  double m_totalVol;
1837 
1838  //! Partial molar volumes of the species
1839  /*!
1840  * units = mks (m^3/kmol)
1841  * Length = number of species
1842  */
1844 
1845  //! dimensionless value of Faraday's constant, F / RT (1/volt)
1847 
1848  //! Timing and iteration counters for the vcs object
1850 
1851  //! Debug printing lvl
1852  /*!
1853  * Levels correspond to the following guidelines
1854  * * 0 No printing at all
1855  * * 1 Serious warnings or fatal errors get one line
1856  * * 2 one line per each successful vcs package call
1857  * * 3 one line per every successful solve_TP calculation
1858  * * 4 one line for every successful operation -> solve_TP gets a summary report
1859  * * 5 each iteration in solve_TP gets a report with one line per species
1860  * * 6 Each decision in solve_TP gets a line per species in addition to 4
1861  * * 10 Additionally Hessian matrix is printed out
1862  */
1864 
1865  //! printing level of timing information
1866  /*!
1867  * * 1 allowing printing of timing
1868  * * 0 do not allow printing of timing -> everything is printed as a NA.
1869  */
1871 
1872  //! Disable printing of timing information. Used to generate consistent
1873  //! output for tests.
1874  static void disableTiming();
1875 
1876  friend class vcs_phaseStabilitySolve;
1877 };
1878 
1879 }
1880 #endif
size_t vcs_RxnStepSizes(int &forceComponentCalc, size_t &kSpecial)
Calculates formation reaction step sizes.
Definition: vcs_rxnadj.cpp:18
int vcs_zero_species(const size_t kspec)
Zero out the concentration of a species.
void vcs_inest(double *const aw, double *const sa, double *const sm, double *const ss, double test)
Estimate equilibrium compositions.
Definition: vcs_inest.cpp:19
void vcs_SSPhase()
Calculate the status of single species phases.
Definition: vcs_prep.cpp:15
vector_fp m_phasePhi
electric potential of the iph phase
Definition: vcs_solve.h:1525
int vcs_elem_rearrange(double *const aw, double *const sa, double *const sm, double *const ss)
Rearrange the constraint equations represented by the Formula Matrix so that the operational ones are...
std::vector< size_t > m_phaseID
Mapping from the species number to the phase number.
Definition: vcs_solve.h:1703
double vcs_Hessian_actCoeff_diag(size_t irxn)
Calculates the diagonal contribution to the Hessian due to the dependence of the activity coefficient...
Definition: vcs_rxnadj.cpp:475
double vcs_line_search(const size_t irxn, const double dx_orig, char *const ANOTE=0)
A line search algorithm is carried out on one reaction.
Definition: vcs_rxnadj.cpp:541
double vcs_Total_Gibbs(double *w, double *fe, double *tPhMoles)
Calculate the total dimensionless Gibbs free energy.
Definition: vcs_Gibbs.cpp:14
vector_int m_speciesUnknownType
Specifies the species unknown type.
Definition: vcs_solve.h:1511
double m_totalMolNum
Total number of kmoles in all phases.
Definition: vcs_solve.h:1584
vector_fp m_elemAbundances
Element abundances vector.
Definition: vcs_solve.h:1568
vector_fp m_TmpPhase
Temporary vector of length NPhase.
Definition: vcs_solve.h:1604
double m_Faraday_dim
dimensionless value of Faraday&#39;s constant, F / RT (1/volt)
Definition: vcs_solve.h:1846
VCS_COUNTERS * m_VCount
Timing and iteration counters for the vcs object.
Definition: vcs_solve.h:1849
vector_fp m_PMVolumeSpecies
Partial molar volumes of the species.
Definition: vcs_solve.h:1843
void vcs_chemPotPhase(const int stateCalc, const size_t iph, const double *const molNum, double *const ac, double *const mu_i, const bool do_deleted=false)
We calculate the dimensionless chemical potentials of all species in a single phase.
vector_fp m_SSfeSpecies
Standard state chemical potentials for species K at the current temperature and pressure.
Definition: vcs_solve.h:1465
vector_fp m_molNumSpecies_old
Total moles of the species.
Definition: vcs_solve.h:1498
std::vector< 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:1826
double vcs_Hessian_diag_adj(size_t irxn, double hessianDiag_Ideal)
Calculates the diagonal contribution to the Hessian due to the dependence of the activity coefficient...
Definition: vcs_rxnadj.cpp:457
vector_fp m_wtSpecies
Molecular weight of each species.
Definition: vcs_solve.h:1813
vector_fp m_scSize
Absolute size of the stoichiometric coefficients.
Definition: vcs_solve.h:1450
Array2D m_stoichCoeffRxnMatrix
Stoichiometric coefficient matrix for the reaction mechanism expressed in Reduced Canonical Form...
Definition: vcs_solve.h:1441
double vcs_birthGuess(const int kspec)
Birth guess returns the number of moles of a species that is coming back to life. ...
int m_useActCoeffJac
Choice of Hessians.
Definition: vcs_solve.h:1833
int vcs_elcorr(double aa[], double x[])
Definition: vcs_elem.cpp:97
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
size_t vcs_basisOptMax(const double *const molNum, const size_t j, const size_t n)
Choose a species to test for the next component.
void vcs_initSizes(const size_t nspecies0, const size_t nelements, const size_t nphase0)
Initialize the sizes within the VCS_SOLVE object.
Definition: vcs_solve.cpp:54
void vcs_dfe(const int stateCalc, const int ll, const size_t lbot, const size_t ltop)
Calculate the dimensionless chemical potentials of all species or of certain groups of species...
void vcs_elabPhase(size_t iphase, double *const elemAbundPhase)
Definition: vcs_elem.cpp:85
std::vector< vcs_VolPhase * > m_VolPhaseList
Array of Phase Structures. Length = number of phases.
Definition: vcs_solve.h:1740
vector_fp m_lnMnaughtSpecies
specifies the ln(Mnaught) used to calculate the chemical potentials
Definition: vcs_solve.h:1784
void vcs_nondim_TP()
Nondimensionalize the problem data.
Definition: vcs_nondim.cpp:17
double vcs_tmoles()
Calculates the total number of moles of species in all phases.
This file contains definitions of terms that are used in internal routines and are unlikely to need m...
vector_fp m_deltaGRxn_Deficient
Last deltag[irxn] from the previous step with additions for possible births of zeroed phases...
Definition: vcs_solve.h:1546
std::vector< size_t > m_elementMapIndex
Index vector that keeps track of the rearrangement of the elements.
Definition: vcs_solve.h:1679
bool vcs_popPhasePossible(const size_t iphasePop) const
Utility function that evaluates whether a phase can be popped into existence.
bool vcs_wellPosed(VCS_PROB *vprob)
In this routine, we check for things that will cause the algorithm to fail.
Definition: vcs_prep.cpp:198
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:1481
int vcs_prob_update(VCS_PROB *pub)
Transfer the results of the equilibrium calculation back to VCS_PROB.
Definition: vcs_solve.cpp:718
void vcs_deltag_Phase(const size_t iphase, const bool doDeleted, const int stateCalc, const bool alterZeroedPhases=true)
Calculate deltag of formation for all species in a single phase.
vector_fp m_deltaMolNumSpecies
Reaction Adjustments for each species during the current step.
Definition: vcs_solve.h:1559
double m_tolmin
Tolerance requirements for minor species.
Definition: vcs_solve.h:1632
double l2normdg(double dg[]) const
Calculate the norm of a deltaGibbs free energy vector.
void vcs_redim_TP()
Redimensionalize the problem data.
Definition: vcs_nondim.cpp:91
int delta_species(const size_t kspec, double *const delta_ptr)
Change the concentration of a species by delta moles.
vector_fp m_spSize
total size of the species
Definition: vcs_solve.h:1457
size_t m_numRxnRdc
Current number of non-component species in the problem.
Definition: vcs_solve.h:1407
bool vcs_globStepDamp()
This routine optimizes the minimization of the total Gibbs free energy by making sure the slope of th...
size_t m_numSpeciesRdc
Current number of species in the problems.
Definition: vcs_solve.h:1403
int vcs_prep()
Prepare the object for solution.
Definition: vcs_prep.cpp:182
A class for 2D arrays stored in column-major (Fortran-compatible) form.
Definition: Array.h:31
vector_fp m_tPhaseMoles_new
total kmols of species in each phase in the tentative soln vector
Definition: vcs_solve.h:1601
Header file for class Cantera::Array2D.
vector_fp m_deltaGRxn_new
Delta G(irxn) for the noncomponent species in the mechanism.
Definition: vcs_solve.h:1539
double vcs_GibbsPhase(size_t iphase, const double *const w, const double *const fe)
Calculate the total dimensionless Gibbs free energy of a single phase.
Definition: vcs_Gibbs.cpp:39
vector_int m_elementActive
Specifies whether an element constraint is active.
Definition: vcs_solve.h:1737
std::vector< int > vector_int
Vector of ints.
Definition: ct_defs.h:159
std::vector< std::string > m_elementName
Vector of strings containing the element names.
Definition: vcs_solve.h:1716
double vcs_phaseStabilityTest(const size_t iph)
Main program to test whether a deleted phase should be brought back into existence.
std::string m_title
String containing the title of the run.
Definition: vcs_solve.h:1743
int vcs_report(int iconv)
Print out a report on the state of the equilibrium problem to standard output.
Definition: vcs_report.cpp:12
Defines and definitions within the vcs package.
int m_doEstimateEquil
Setting for whether to do an initial estimate.
Definition: vcs_solve.h:1491
int vcs_inest_TP()
Create an initial estimate of the solution to the thermodynamic equilibrium problem.
Definition: vcs_inest.cpp:283
vector_fp m_deltaGRxn_tmp
Temporary vector of Rxn DeltaG&#39;s.
Definition: vcs_solve.h:1552
std::vector< size_t > m_speciesMapIndex
Index vector that keeps track of the species vector rearrangement.
Definition: vcs_solve.h:1652
Internal declarations for the VCSnonideal package.
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:812
size_t vcs_add_all_deleted()
Provide an estimate for the deleted species in phases that are not zeroed out.
void vcs_printSpeciesChemPot(const int stateCalc) const
Print out a table of chemical potentials.
void vcs_updateVP(const int stateCalc)
This routine uploads the state of the system into all of the vcs_VolumePhase objects in the current p...
int vcs_species_type(const size_t kspec) const
Evaluate the species category for the indicated species.
size_t m_numElemConstraints
Number of element constraints in the problem.
Definition: vcs_solve.h:1393
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:335
double m_tolmin2
Below this, minor species aren&#39;t refined any more.
Definition: vcs_solve.h:1638
size_t m_numSpeciesTot
Total number of species in the problems.
Definition: vcs_solve.h:1387
vector_fp m_deltaPhaseMoles
Change in the total moles in each phase.
Definition: vcs_solve.h:1613
int vcs_recheck_deleted()
Recheck deleted species in multispecies phases.
bool recheck_deleted_phase(const int iphase)
Recheck deletion condition for multispecies phases.
double vcs_minor_alt_calc(size_t kspec, size_t irxn, bool *do_delete, char *ANOTE=0) const
Minor species alternative calculation.
int vcs_solve_phaseStability(const int iphase, int ifunc, double &funcval, int print_lvl)
Routine that independently determines whether a phase should be popped under the current conditions...
int vcs(VCS_PROB *vprob, int ifunc, int ipr, int ip1, int maxit)
Solve an equilibrium problem.
Definition: vcs_solve.cpp:205
vector_fp m_deltaGRxn_old
Last deltag[irxn] from the previous step.
Definition: vcs_solve.h:1542
vector_fp m_feSpecies_old
Free energy vector from the start of the current iteration.
Definition: vcs_solve.h:1472
vector_fp TPhInertMoles
Total kmoles of inert to add to each phase.
Definition: vcs_solve.h:1626
int m_debug_print_lvl
Debug printing lvl.
Definition: vcs_solve.h:1863
int m_timing_print_lvl
printing level of timing information
Definition: vcs_solve.h:1870
int vcs_evalSS_TP(int ipr, int ip1, double Temp, double pres)
Definition: vcs_TP.cpp:50
size_t m_numComponents
Number of components calculated for the problem.
Definition: vcs_solve.h:1396
vector_int m_actConventionSpecies
specifies the activity convention of the phase containing the species
Definition: vcs_solve.h:1768
size_t vcs_popPhaseID(std::vector< size_t > &phasePopPhaseIDs)
Decision as to whether a phase pops back into existence.
size_t NPHASE0
value of the number of phases used to size data structures
Definition: vcs_solve.h:1384
vector_fp m_elemAbundancesGoal
Element abundances vector Goals.
Definition: vcs_solve.h:1577
int vcs_prep_oneTime(int printLvl)
This routine is mostly concerned with changing the private data to be consistent with what&#39;s needed f...
Definition: vcs_prep.cpp:50
size_t m_numRxnMinorZeroed
Number of active species which are currently either treated as minor species.
Definition: vcs_solve.h:1411
int vcs_delete_species(const size_t kspec)
Change a single species from active to inactive status.
double m_totalVol
Total volume of all phases. Units are m^3.
Definition: vcs_solve.h:1836
double m_temperature
Temperature (Kelvin)
Definition: vcs_solve.h:1616
void vcs_reinsert_deleted(size_t kspec)
std::vector< char > m_SSPhase
Boolean indicating whether a species belongs to a single-species phase.
Definition: vcs_solve.h:1707
int vcs_rearrange()
Switch all species data back to the original order.
vector_int m_phaseActConvention
specifies the activity convention of the phase.
Definition: vcs_solve.h:1777
vector_fp m_tPhaseMoles_old
Total kmols of species in each phase.
Definition: vcs_solve.h:1592
int vcs_phasePopDeterminePossibleList()
Determine the list of problems that need to be checked to see if there are any phases pops...
std::vector< std::string > m_speciesName
Species string name for the kth species.
Definition: vcs_solve.h:1710
void vcs_deltag(const int L, const bool doDeleted, const int vcsState, const bool alterZeroedPhases=true)
This subroutine calculates reaction free energy changes for all noncomponent formation reactions...
int vcs_PS(VCS_PROB *vprob, int iph, int printLvl, double &feStable)
Array2D m_deltaMolNumPhase
Change in the number of moles of phase, iphase, due to the noncomponent formation reaction...
Definition: vcs_solve.h:1518
Array2D m_formulaMatrix
Formula matrix for the problem.
Definition: vcs_solve.h:1422
double m_pressurePA
Pressure.
Definition: vcs_solve.h:1619
double m_tolmaj
Tolerance requirement for major species.
Definition: vcs_solve.h:1629
vector_fp m_actCoeffSpecies_new
Molar-based Activity Coefficients for Species.
Definition: vcs_solve.h:1788
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:157
void vcs_elab()
Computes the current elemental abundances vector.
Definition: vcs_elem.cpp:17
int vcs_setMolesLinProg()
Estimate the initial mole numbers by constrained linear programming.
double deltaG_Recalc_Rxn(const int stateCalc, const size_t irxn, const double *const molNum, double *const ac, double *const mu_i)
This function recalculates the deltaG for reaction, irxn.
Definition: vcs_rxnadj.cpp:523
int vcs_rxn_adj_cg()
Calculates reaction adjustments using a full Hessian approximation.
Definition: vcs_rxnadj.cpp:301
vector_int m_speciesStatus
Major -Minor status vector for the species in the problem.
Definition: vcs_solve.h:1700
int vcs_basopt(const bool doJustComponents, double aw[], double sa[], double sm[], double ss[], double test, bool *const usedZeroedSpecies)
Choose the optimum species basis for the calculations.
int vcs_prob_specify(const VCS_PROB *pub)
Specify the problem to be solved using VCS_PROB, incrementally.
Definition: vcs_solve.cpp:616
void vcs_switch_pos(const bool ifunc, const size_t k1, const size_t k2)
Swaps the indices for all of the global data for two species, k1 and k2.
void vcs_updateMolNumVolPhases(const int stateCalc)
Update all underlying vcs_VolPhase objects.
int vcs_popPhaseRxnStepSizes(const size_t iphasePop)
Calculates the deltas of the reactions due to phases popping into existence.
void prneav() const
Print out and check the elemental abundance vector.
Class to keep track of time and iterations.
Definition: vcs_internal.h:43
void vcs_delete_memory()
Delete memory that isn&#39;t just resizable STL containers.
Definition: vcs_solve.cpp:182
Array2D m_phaseParticipation
This is 1 if the phase, iphase, participates in the formation reaction irxn, and zero otherwise...
Definition: vcs_solve.h:1522
vector_fp m_TmpPhase2
Temporary vector of length NPhase.
Definition: vcs_solve.h:1607
vector_int m_elType
Type of the element constraint.
Definition: vcs_solve.h:1731
size_t NSPECIES0
value of the number of species used to size data structures
Definition: vcs_solve.h:1381
Namespace for the Cantera kernel.
Definition: application.cpp:29
char m_unitsState
This specifies the current state of units for the Gibbs free energy properties in the program...
Definition: vcs_solve.h:1750
std::vector< size_t > m_indexRxnToSpecies
Mapping between the species index for noncomponent species and the full species index.
Definition: vcs_solve.h:1692
int vcs_solve_TP(int print_lvl, int printDetails, int maxit)
Main routine that solves for equilibrium at constant T and P using a variant of the VCS method...
size_t m_numPhases
Number of Phases in the problem.
Definition: vcs_solve.h:1414
Interface class for the vcs thermo equilibrium solver package, which generally describes the problem ...
Definition: vcs_prob.h:22
double m_totalMoleScale
Multiplier for the mole numbers within the nondimensional formulation.
Definition: vcs_solve.h:1759
size_t m_numRxnTot
Total number of non-component species in the problem.
Definition: vcs_solve.h:1399
void vcs_fePrep_TP()
Initialize the chemical potential of single species phases.
Definition: vcs_TP.cpp:61
double m_tolmaj2
Below this, major species aren&#39;t refined any more.
Definition: vcs_solve.h:1635
vector_fp m_molNumSpecies_new
Tentative value of the mole number vector.
Definition: vcs_solve.h:1529
static void disableTiming()
Disable printing of timing information.
Definition: vcs_solve.cpp:826
bool vcs_evaluate_speciesType()
This routine evaluates the species type for all species.
void vcs_switch_elem_pos(size_t ipos, size_t jpos)
Swaps the indices for all of the global data for two elements, ipos and jpos.
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:1805
bool vcs_delete_multiphase(const size_t iph)
This routine handles the bookkeeping involved with the deletion of multiphase phases from the problem...
vector_fp m_actCoeffSpecies_old
Molar-based Activity Coefficients for Species based on old mole numbers.
Definition: vcs_solve.h:1795
int vcs_prob_specifyFully(const VCS_PROB *pub)
Fully specify the problem to be solved using VCS_PROB.
Definition: vcs_solve.cpp:311
void vcs_counters_init(int ifunc)
Initialize the internal counters.
Definition: vcs_solve.cpp:794
vector_fp m_chargeSpecies
Charge of each species. Length = number of species.
Definition: vcs_solve.h:1816
void vcs_CalcLnActCoeffJac(const double *const moleSpeciesVCS)
Recalculate all of the activity coefficients in all of the phases based on input mole numbers...
Definition: vcs_rxnadj.cpp:505
This is the main structure used to hold the internal data used in vcs_solve_TP(), and to solve TP sys...
Definition: vcs_solve.h:44
bool vcs_elabcheck(int ibound)
Definition: vcs_elem.cpp:29
std::vector< size_t > m_speciesLocalPhaseIndex
Index that keeps track of the index of the species within the local phase.
Definition: vcs_solve.h:1666