Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vcs_setMolesLinProg.cpp
Go to the documentation of this file.
1 /*!
2  * @file vcs_setMolesLinProg.cpp
3  */
4 /*
5  * Copyright (2005) Sandia Corporation. Under the terms of
6  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
7  * U.S. Government retains certain rights in this software.
8  */
9 
11 
12 using namespace std;
13 
14 namespace Cantera
15 {
16 
17 static void printProgress(const vector<string> &spName,
18  const vector<double> &soln,
19  const vector<double> &ff)
20 {
21  double sum = 0.0;
22  plogf(" --- Summary of current progress:\n");
23  plogf(" --- Name Moles - SSGibbs \n");
24  plogf(" -------------------------------------------------------------------------------------\n");
25  for (size_t k = 0; k < soln.size(); k++) {
26  plogf(" --- %20s %12.4g - %12.4g\n", spName[k].c_str(), soln[k], ff[k]);
27  sum += soln[k] * ff[k];
28  }
29  plogf(" --- Total sum to be minimized = %g\n", sum);
30 }
31 
32 int VCS_SOLVE::vcs_setMolesLinProg()
33 {
34  size_t ik, irxn;
35  double test = -1.0E-10;
36 
37  if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
38  plogf(" --- call setInitialMoles\n");
39  }
40 
41  // m_mu are standard state chemical potentials
42  // Boolean on the end specifies standard chem potentials
43  // m_mix->getValidChemPotentials(not_mu, DATA_PTR(m_mu), true);
44  // -> This is already done coming into the routine.
45  double dg_rt;
46 
47  int idir;
48  double nu;
49  double delta_xi, dxi_min = 1.0e10;
50  bool redo = true;
51  int retn;
52  int iter = 0;
53  bool abundancesOK = true;
54  bool usedZeroedSpecies;
55 
56  std::vector<double> sm(m_numElemConstraints*m_numElemConstraints, 0.0);
57  std::vector<double> ss(m_numElemConstraints, 0.0);
58  std::vector<double> sa(m_numElemConstraints, 0.0);
59  std::vector<double> wx(m_numElemConstraints, 0.0);
60  std::vector<double> aw(m_numSpeciesTot, 0.0);
61 
62  for (ik = 0; ik < m_numSpeciesTot; ik++) {
63  if (m_speciesUnknownType[ik] != VCS_SPECIES_INTERFACIALVOLTAGE) {
64  m_molNumSpecies_old[ik] = max(0.0, m_molNumSpecies_old[ik]);
65  }
66  }
67 
68  if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
69  printProgress(m_speciesName, m_molNumSpecies_old, m_SSfeSpecies);
70  }
71 
72  while (redo) {
73 
74  if (!vcs_elabcheck(0)) {
75  if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
76  plogf(" --- seMolesLinProg Mole numbers failing element abundances\n");
77  plogf(" --- seMolesLinProg Call vcs_elcorr to attempt fix\n");
78  }
79  retn = vcs_elcorr(VCS_DATA_PTR(sm), VCS_DATA_PTR(wx));
80  if (retn >= 2) {
81  abundancesOK = false;
82  } else {
83  abundancesOK = true;
84  }
85  } else {
86  abundancesOK = true;
87  }
88  /*
89  * Now find the optimized basis that spans the stoichiometric
90  * coefficient matrix, based on the current composition, m_molNumSpecies_old[]
91  * We also calculate sc[][], the reaction matrix.
92  */
93  retn = vcs_basopt(false, VCS_DATA_PTR(aw), VCS_DATA_PTR(sa),
94  VCS_DATA_PTR(sm), VCS_DATA_PTR(ss),
95  test, &usedZeroedSpecies);
96  if (retn != VCS_SUCCESS) {
97  return retn;
98  }
99 
100  if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
101  plogf("iteration %d\n", iter);
102  }
103  redo = false;
104  iter++;
105  if (iter > 15) {
106  break;
107  }
108 
109  // loop over all reactions
110  for (irxn = 0; irxn < m_numRxnTot; irxn++) {
111 
112  // dg_rt is the Delta_G / RT value for the reaction
113  ik = m_numComponents + irxn;
114  dg_rt = m_SSfeSpecies[ik];
115  dxi_min = 1.0e10;
116  const double* sc_irxn = m_stoichCoeffRxnMatrix.ptrColumn(irxn);
117  for (size_t jcomp = 0; jcomp < m_numElemConstraints; jcomp++) {
118  dg_rt += m_SSfeSpecies[jcomp] * sc_irxn[jcomp];
119  }
120  // fwd or rev direction.
121  // idir > 0 implies increasing the current species
122  // idir < 0 implies decreasing the current species
123  idir = (dg_rt < 0.0 ? 1 : -1);
124  if (idir < 0) {
125  dxi_min = m_molNumSpecies_old[ik];
126  }
127 
128  for (size_t jcomp = 0; jcomp < m_numComponents; jcomp++) {
129  nu = sc_irxn[jcomp];
130 
131  // set max change in progress variable by
132  // non-negativity requirement
133  if (nu*idir < 0) {
134  delta_xi = fabs(m_molNumSpecies_old[jcomp]/nu);
135  // if a component has nearly zero moles, redo
136  // with a new set of components
137  if (!redo) {
138  if (delta_xi < 1.0e-10 && (m_molNumSpecies_old[ik] >= 1.0E-10)) {
139  if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
140  plogf(" --- Component too small: %s\n", m_speciesName[jcomp].c_str());
141  }
142  redo = true;
143  }
144  }
145  dxi_min = std::min(dxi_min, delta_xi);
146  }
147  }
148 
149  // step the composition by dxi_min, check against zero, since
150  // we are zeroing components and species on every step.
151  // Redo the iteration, if a component went from positive to zero on this step.
152  double dsLocal = idir*dxi_min;
153  m_molNumSpecies_old[ik] += dsLocal;
154  m_molNumSpecies_old[ik] = max(0.0, m_molNumSpecies_old[ik]);
155  for (size_t jcomp = 0; jcomp < m_numComponents; jcomp++) {
156  bool full = false;
157  if (m_molNumSpecies_old[jcomp] > 1.0E-15) {
158  full = true;
159  }
160  m_molNumSpecies_old[jcomp] += sc_irxn[jcomp] * dsLocal;
161  m_molNumSpecies_old[jcomp] = max(0.0, m_molNumSpecies_old[jcomp]);
162  if (full) {
163  if (m_molNumSpecies_old[jcomp] < 1.0E-60) {
164  redo = true;
165  }
166  }
167  }
168  }
169 
170  if (DEBUG_MODE_ENABLED && m_debug_print_lvl >= 2) {
171  printProgress(m_speciesName, m_molNumSpecies_old, m_SSfeSpecies);
172  }
173  }
174 
175  if (DEBUG_MODE_ENABLED && m_debug_print_lvl == 1) {
176  printProgress(m_speciesName, m_molNumSpecies_old, m_SSfeSpecies);
177  plogf(" --- setInitialMoles end\n");
178  }
179  retn = 0;
180  if (!abundancesOK) {
181  retn = -1;
182  } else if (iter > 15) {
183  retn = 1;
184  }
185  return retn;
186 }
187 
188 }
#define VCS_DATA_PTR(vvv)
Points to the data in a std::vector<> object.
Definition: vcs_internal.h:18
#define VCS_SPECIES_INTERFACIALVOLTAGE
Species refers to an electron in the metal.
Definition: vcs_defs.h:173
Header file for the internal object that holds the vcs equilibrium problem (see Class VCS_SOLVE and E...
#define VCS_SUCCESS
Definition: vcs_defs.h:21
#define plogf
define this Cantera function to replace printf
Definition: vcs_internal.h:24