Cantera  2.1.2
vcs_equilibrate.cpp
Go to the documentation of this file.
1 /**
2  * @file vcs_equilibrate.cpp
3  * Driver routines for equilibrium solvers
4  */
5 /*
6  * Copyright (2006) Sandia Corporation. Under the terms of
7  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
8  * U.S. Government retains certain rights in this software.
9  */
11 #include "cantera/equil/vcs_prob.h"
18 #include "cantera/equil/equil.h"
19 
26 
27 using namespace std;
28 
29 namespace Cantera
30 {
31 int vcs_equilibrate(thermo_t& s, const char* XY,
32  int estimateEquil, int printLvl,
33  int solver,
34  doublereal rtol, int maxsteps, int maxiter,
35  int loglevel)
36 {
37  MultiPhase* m = 0;
38  int retn = 1;
39  int retnSub = 0;
40 
41  beginLogGroup("equilibrate", loglevel);
42  // retry:
43  addLogEntry("Single-phase equilibrate function");
44  {
45  beginLogGroup("arguments");
46  addLogEntry("phase",s.id());
47  addLogEntry("XY",XY);
48  addLogEntry("solver",solver);
49  addLogEntry("rtol",rtol);
50  addLogEntry("maxsteps",maxsteps);
51  addLogEntry("maxiter",maxiter);
52  addLogEntry("loglevel",loglevel);
53  endLogGroup("arguments");
54  }
55 
56  if (solver == 2) {
57  m = new MultiPhase;
58  try {
59  /*
60  * Set the kmoles of the phase to 1.0, arbitrarily.
61  * It actually doesn't matter.
62  */
63  m->addPhase(&s, 1.0);
64  m->init();
65 
66  retn = vcs_equilibrate(*m, XY, estimateEquil, printLvl, solver,
67  rtol, maxsteps, maxiter, loglevel);
68  if (retn == 1) {
69  addLogEntry("MultiPhaseEquil solver succeeded.");
70  } else {
71  addLogEntry("MultiPhaseEquil solver returned an error code: ", retn);
72  }
73  delete m;
74  } catch (CanteraError& err) {
75  err.save();
76  addLogEntry("MultiPhaseEquil solver failed.");
77  delete m;
78  throw err;
79  }
80  } else if (solver == 1) {
81  m = new MultiPhase;
82  try {
83  m->addPhase(&s, 1.0);
84  m->init();
85  (void) equilibrate(*m, XY, rtol, maxsteps, maxiter, loglevel-1);
86  if (loglevel > 0) {
87  addLogEntry("MultiPhaseEquil solver succeeded.");
88  }
89  delete m;
90  retn = 1;
91  } catch (CanteraError& err) {
92  err.save();
93  if (loglevel > 0) {
94  addLogEntry("MultiPhaseEquil solver failed.");
95  }
96  delete m;
97  throw err;
98  }
99  } else if (solver == 0) {
100  ChemEquil* e = new ChemEquil;
101  try {
102  e->options.maxIterations = maxsteps;
103  e->options.relTolerance = rtol;
104  bool useThermoPhaseElementPotentials = false;
105  if (estimateEquil == 0) {
106  useThermoPhaseElementPotentials = true;
107  }
108  retnSub = e->equilibrate(s, XY,
109  useThermoPhaseElementPotentials, loglevel-1);
110  if (retnSub < 0) {
111  if (loglevel > 0) {
112  addLogEntry("ChemEquil solver failed.");
113  }
114  delete e;
115  throw CanteraError("equilibrate",
116  "ChemEquil equilibrium solver failed");
117  }
118  retn = 1;
119  s.setElementPotentials(e->elementPotentials());
120  delete e;
121  if (loglevel > 0) {
122  addLogEntry("ChemEquil solver succeeded.");
123  }
124  } catch (CanteraError& err) {
125  err.save();
126  if (loglevel > 0) {
127  addLogEntry("ChemEquil solver failed.");
128  }
129  delete e;
130  throw err;
131  }
132  } else {
133  throw CanteraError("vcs_equilibrate",
134  "unknown solver");
135  }
136 
137  /*
138  * We are here only for a success
139  */
140  endLogGroup("equilibrate");
141  return retn;
142 }
143 
144 int vcs_equilibrate(MultiPhase& s, const char* XY,
145  int estimateEquil, int printLvl, int solver,
146  doublereal tol, int maxsteps, int maxiter,
147  int loglevel)
148 {
149  int ixy = _equilflag(XY);
150  int retn = vcs_equilibrate_1(s, ixy, estimateEquil, printLvl, solver,
151  tol, maxsteps, maxiter, loglevel);
152  return retn;
153 }
154 
156  int estimateEquil, int printLvl, int solver,
157  doublereal tol, int maxsteps, int maxiter, int loglevel)
158 {
159  static int counter = 0;
160  int retn = 1;
161 
162  beginLogGroup("equilibrate",loglevel);
163  addLogEntry("multiphase equilibrate function");
164  beginLogGroup("arguments");
165  addLogEntry("XY",ixy);
166  addLogEntry("tol",tol);
167  addLogEntry("maxsteps",maxsteps);
168  addLogEntry("maxiter",maxiter);
169  addLogEntry("loglevel",loglevel);
170  endLogGroup("arguments");
171 
172  int printLvlSub = std::max(0, printLvl-1);
173 
174  s.init();
175 
176  if (solver == 2) {
177  try {
179  int err = eqsolve->equilibrate(ixy, estimateEquil, printLvlSub, tol, maxsteps, loglevel);
180  if (err != 0) {
181  retn = -1;
182  addLogEntry("vcs_equilibrate Error - ", err);
183  } else {
184  addLogEntry("vcs_equilibrate Success - ", err);
185  }
186  endLogGroup("equilibrate");
187  // hard code a csv output file.
188  if (printLvl > 0) {
189  string reportFile = "vcs_equilibrate_res.csv";
190  if (counter > 0) {
191  reportFile = "vcs_equilibrate_res_" + int2str(counter) + ".csv";
192  }
193  eqsolve->reportCSV(reportFile);
194  counter++;
195  }
196  delete eqsolve;
197  } catch (CanteraError& e) {
198  e.save();
199  retn = -1;
200  addLogEntry("Failure.", lastErrorMessage());
201  endLogGroup("equilibrate");
202  throw e;
203  }
204  } else if (solver == 1) {
205  if (ixy == TP || ixy == HP || ixy == SP || ixy == TV) {
206  try {
207  double err = s.equilibrate(ixy, tol, maxsteps, maxiter, loglevel);
208 
209  addLogEntry("Success. Error",err);
210  endLogGroup("equilibrate");
211 
212  return 0;
213  } catch (CanteraError& e) {
214  e.save();
215  addLogEntry("Failure.",lastErrorMessage());
216  endLogGroup("equilibrate");
217 
218  throw e;
219  }
220  } else {
221 
222  addLogEntry("multiphase equilibrium can be done only for TP, HP, SP, or TV");
223  endLogGroup("equilibrate");
224 
225  throw CanteraError("equilibrate","unsupported option");
226  //return -1.0;
227  }
228  } else {
229  throw CanteraError("vcs_equilibrate_1", "unknown solver");
230  }
231  return retn;
232 }
233 
235  double& funcStab, int printLvl, int loglevel)
236 {
237  int iStab = 0;
238  static int counter = 0;
239  beginLogGroup("PhaseStability",loglevel);
240  addLogEntry("multiphase phase stability function");
241  beginLogGroup("arguments");
242  addLogEntry("iphase",iphase);
243  addLogEntry("loglevel",loglevel);
244  endLogGroup("arguments");
245 
246  int printLvlSub = std::max(0, printLvl-1);
247 
248  s.init();
249  try {
251  iStab = eqsolve->determine_PhaseStability(iphase, funcStab, printLvlSub, loglevel);
252  if (iStab != 0) {
253  addLogEntry("Phase is stable - ", iphase);
254  } else {
255  addLogEntry("Phase is not stable - ", iphase);
256  }
257  endLogGroup("PhaseStability");
258  // hard code a csv output file.
259  if (printLvl > 0) {
260  string reportFile = "vcs_phaseStability.csv";
261  if (counter > 0) {
262  reportFile = "vcs_phaseStability_" + int2str(counter) + ".csv";
263  }
264  eqsolve->reportCSV(reportFile);
265  counter++;
266  }
267  delete eqsolve;
268  } catch (CanteraError& e) {
269  addLogEntry("Failure.", lastErrorMessage());
270  endLogGroup("equilibrate");
271  throw e;
272  }
273  return iStab;
274 }
275 
276 }
Class ChemEquil implements a chemical equilibrium solver for single-phase solutions.
Definition: ChemEquil.h:95
EquilOpt options
Options controlling how the calculation is carried out.
Definition: ChemEquil.h:150
ThermoPhase object for the ideal molal equation of state (see Thermodynamic Properties and class Idea...
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:40
doublereal equilibrate(int XY, doublereal err=1.0e-9, int maxsteps=1000, int maxiter=200, int loglevel=-99)
Set the mixture to a state of chemical equilibrium.
Definition: MultiPhase.cpp:581
doublereal relTolerance
Relative tolerance.
Definition: ChemEquil.h:38
void beginLogGroup(const std::string &title, int loglevel)
Create a new group for log messages.
Definition: global.cpp:90
string lastErrorMessage()
Retrieve the last error message in a string.
Definition: global.cpp:166
This file contains the definition of some high level general equilibration routines.
void addPhase(ThermoPhase *p, doublereal moles)
Add a phase to the mixture.
Definition: MultiPhase.cpp:98
int equilibrate(thermo_t &s, const char *XY, bool useThermoPhaseElementPotentials=false, int loglevel=0)
Definition: ChemEquil.cpp:394
doublereal equilibrate(MultiPhase &s, const char *XY, doublereal tol, int maxsteps, int maxiter, int loglevel)
Equilibrate a MultiPhase object.
Definition: equilibrate.cpp:14
int equilibrate(int XY, int estimateEquil=0, int printLvl=0, doublereal err=1.0e-6, int maxsteps=VCS_MAXSTEPS, int loglevel=-99)
Equilibrate the solution using the current element abundances stored in the MultiPhase object...
Cantera's Interface to the Multiphase chemical equilibrium solver.
void reportCSV(const std::string &reportFile)
Report the equilibrium answer in a comma separated table format.
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:101
Contains const definitions for types of species reference-state thermodynamics managers (see Species ...
Header file for the internal object that holds the vcs equilibrium problem (see Class VCS_SOLVE and E...
Header for the object representing each phase within vcs.
A class for multiphase mixtures.
Definition: MultiPhase.h:54
Internal declarations for the VCSnonideal package.
int vcs_determine_PhaseStability(MultiPhase &s, int iphase, double &funcStab, int printLvl, int loglevel)
Determine the phase stability of a single phase given the current conditions in a MultiPhase object...
Header for the Interface class for the vcs thermo equilibrium solver package,.
Header file for an ideal solid solution model with incompressible thermodynamics (see Thermodynamic P...
std::string id() const
Return the string id for the phase.
Definition: Phase.cpp:119
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:68
void setElementPotentials(const vector_fp &lambda)
Stores the element potentials in the ThermoPhase object.
int vcs_equilibrate(MultiPhase &s, const char *XY, int estimateEquil, int printLvl, int solver, doublereal tol, int maxsteps, int maxiter, int loglevel)
Set a multi-phase chemical solution to chemical equilibrium.
void endLogGroup(const std::string &title)
Close the current group of log messages.
Definition: global.cpp:115
Interface class for the vcsnonlinear solver.
void addLogEntry(const std::string &tag, const std::string &value)
Add an entry to an HTML log file.
Definition: global.cpp:95
int determine_PhaseStability(int iph, double &funcStab, int printLvl=0, int logLevel=-99)
Determine the phase stability of a phase at the current conditions.
void init()
Process phases and build atomic composition array.
Definition: MultiPhase.cpp:173
Contains declarations for string manipulation functions within Cantera.
int maxIterations
Maximum number of iterations.
Definition: ChemEquil.h:40
int _equilflag(const char *xy)
map property strings to integers
Definition: ChemEquil.cpp:29
Chemical equilibrium.
int vcs_equilibrate_1(MultiPhase &s, int ixy, int estimateEquil, int printLvl, int solver, doublereal tol, int maxsteps, int maxiter, int loglevel)
Set a multi-phase chemical solution to chemical equilibrium.
void save()
Function to put this error onto Cantera's error stack.