Cantera  2.0
vcs_solve_phaseStability.cpp
1 /**
2  * @file vcs_solve_TP.cpp Implementation file that contains the
3  * main algorithm for finding an equilibrium
4  */
5 
6 /*
7  * Copyright (2005) Sandia Corporation. Under the terms of
8  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
9  * U.S. Government retains certain rights in this software.
10  */
11 
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cmath>
15 #include <cassert>
16 
20 #include "vcs_species_thermo.h"
21 #include "cantera/equil/vcs_prob.h"
22 
23 #include "cantera/base/clockWC.h"
24 
25 using namespace std;
26 
27 namespace VCSnonideal
28 {
29 
30 
31 int VCS_SOLVE::vcs_PS(VCS_PROB* vprob, int iphase, int printLvl, double& feStable)
32 {
33 
34  /*
35  * ifunc determines the problem type
36  */
37  int ifunc = 0;
38  int iStab = 0;
39 
40  /*
41  * This function is called to create the private data
42  * using the public data.
43  */
44  size_t nspecies0 = vprob->nspecies + 10;
45  size_t nelements0 = vprob->ne;
46  size_t nphase0 = vprob->NPhase;
47 
48  vcs_initSizes(nspecies0, nelements0, nphase0);
49 
50 
51  if (ifunc < 0 || ifunc > 2) {
52  plogf("vcs: Unrecognized value of ifunc, %d: bailing!\n",
53  ifunc);
54  return VCS_PUB_BAD;
55  }
56 
57  /*
58  * This function is called to copy the public data
59  * and the current problem specification
60  * into the current object's data structure.
61  */
62  int retn = vcs_prob_specifyFully(vprob);
63  if (retn != 0) {
64  plogf("vcs_pub_to_priv returned a bad status, %d: bailing!\n",
65  retn);
66  return retn;
67  }
68  /*
69  * Prep the problem data
70  * - adjust the identity of any phases
71  * - determine the number of components in the problem
72  */
73  retn = vcs_prep_oneTime(printLvl);
74  if (retn != 0) {
75  plogf("vcs_prep_oneTime returned a bad status, %d: bailing!\n",
76  retn);
77  return retn;
78  }
79 
80 
81  /*
82  * This function is called to copy the current problem
83  * into the current object's data structure.
84  */
85  retn = vcs_prob_specify(vprob);
86  if (retn != 0) {
87  plogf("vcs_prob_specify returned a bad status, %d: bailing!\n",
88  retn);
89  return retn;
90  }
91 
92 
93  /*
94  * Prep the problem data for this particular instantiation of
95  * the problem
96  */
97  retn = vcs_prep();
98  if (retn != VCS_SUCCESS) {
99  plogf("vcs_prep returned a bad status, %d: bailing!\n", retn);
100  return retn;
101  }
102  /*
103  * Check to see if the current problem is well posed.
104  */
105  if (!vcs_wellPosed(vprob)) {
106  plogf("vcs has determined the problem is not well posed: Bailing\n");
107  return VCS_PUB_BAD;
108  }
109 
110  /*
111  * Store the temperature and pressure in the private global variables
112  */
113  m_temperature = vprob->T;
114  m_pressurePA = vprob->PresPA;
115  /*
116  * Evaluate the standard state free energies
117  * at the current temperatures and pressures.
118  */
119  vcs_evalSS_TP(printLvl, printLvl, m_temperature, m_pressurePA);
120 
121  /*
122  * Prepare the problem data:
123  * ->nondimensionalize the free energies using
124  * the divisor, R * T
125  */
126  vcs_nondim_TP();
127  /*
128  * Prep the fe field
129  */
130  vcs_fePrep_TP();
131 
132  /*
133  * Solve the problem at a fixed Temperature and Pressure
134  * (all information concerning Temperature and Pressure has already
135  * been derived. The free energies are now in dimensionless form.)
136  */
137  iStab = vcs_solve_phaseStability(iphase, ifunc, feStable, printLvl);
138 
139 
140  /*
141  * Redimensionalize the free energies using
142  * the reverse of vcs_nondim to add back units.
143  */
144  vcs_redim_TP();
145 
146  /*
147  vcs_VolPhase *Vphase = m_VolPhaseList[iphase];
148 
149  std::vector<double> mfPop = Vphase->moleFractions();
150  int nsp = Vphase->nSpecies();
151 
152  vcs_VolPhase *VPphase = vprob->VPhaseList[iphase];
153  int kstart = Vphase->spGlobalIndexVCS(0);
154  for (int k = 0; k < nsp; k++) {
155  vprob->mf[kstart + k] = mfPop[k];
156  }
157  VPphase->setMoleFractionsState(Vphase->totalMoles(),
158  VCS_DATA_PTR(Vphase->moleFractions()),
159  VCS_STATECALC_TMP);
160  */
161  vcs_prob_update(vprob);
162  /*
163  * Return the convergence success flag.
164  */
165  return iStab;
166 
167 
168 }
169 //====================================================================================================================
170 // Routine that independently determines whether a phase should be popped
171 // under the current conditions.
172 /*
173  * This is the main routine that solves for equilibrium at constant T and P
174  * using a variant of the VCS method. Nonideal phases can be accommodated
175  * as well.
176  *
177  * Any number of single-species phases and multi-species phases
178  * can be handled by the present version.
179  *
180  * Input
181  * ------------
182  * @param print_lvl 1 -> Print results to standard output
183  * 0 -> don't report on anything
184  *
185  * @param printDetails 1 -> Print intermediate results.
186  *
187  * @param maxit Maximum number of iterations for the algorithm
188  *
189  * @return 0 = Equilibrium Achieved
190  * 1 = Range space error encountered. The element abundance criteria are
191  * only partially satisfied. Specifically, the first NC= (number of
192  * components) conditions are satisfied. However, the full NE
193  * (number of elements) conditions are not satisfied. The equilibrium
194  * condition is returned.
195  * -1 = Maximum number of iterations is exceeded. Convergence was not
196  * found.
197  */
198 int VCS_SOLVE::vcs_solve_phaseStability(const int iph, const int ifunc,
199  double& funcVal,
200  int printLvl)
201 {
202  double test = -1.0E-10;
203  bool usedZeroedSpecies;
204  std::vector<size_t> phasePopPhaseIDs(0);
205  int iStab = 0;
206 
207  std::vector<double> sm(m_numElemConstraints*m_numElemConstraints, 0.0);
208  std::vector<double> ss(m_numElemConstraints, 0.0);
209  std::vector<double> sa(m_numElemConstraints, 0.0);
210 
211  std::vector<double> aw(m_numSpeciesTot, 0.0);
212  std::vector<double> wx(m_numElemConstraints, 0.0);
213 
214 
215  vcs_basopt(false, VCS_DATA_PTR(aw), VCS_DATA_PTR(sa),
216  VCS_DATA_PTR(sm), VCS_DATA_PTR(ss),
217  test, &usedZeroedSpecies);
218  vcs_evaluate_speciesType();
219 
220  vcs_dfe(VCS_STATECALC_OLD, 0, 0, m_numSpeciesRdc);
221  if (printLvl > 3) {
222  vcs_printSpeciesChemPot(VCS_STATECALC_OLD);
223  }
224  vcs_deltag(0, true, VCS_STATECALC_OLD);
225 
226  if (printLvl > 3) {
227  vcs_printDeltaG(VCS_STATECALC_OLD);
228  }
229  vcs_dcopy(VCS_DATA_PTR(m_deltaGRxn_Deficient), VCS_DATA_PTR(m_deltaGRxn_old), m_numRxnRdc);
230  phasePopPhaseIDs.clear();
231  vcs_popPhaseID(phasePopPhaseIDs);
232  funcVal = vcs_phaseStabilityTest(iph);
233  if (funcVal > 0.0) {
234  iStab = 1;
235  } else {
236  iStab = 0;
237  }
238 
239  return iStab;
240 }
241 
242 }