Cleaned up Doxygen documentation for class VCS_SOLVE

This commit is contained in:
Ray Speth 2013-04-18 22:07:59 +00:00
parent 28414eb77d
commit 30b01ab8fd
17 changed files with 719 additions and 2205 deletions

File diff suppressed because it is too large Load diff

View file

@ -15,24 +15,8 @@
namespace VCSnonideal
{
/***************************************************************************/
/***************************************************************************/
/***************************************************************************/
double VCS_SOLVE::vcs_Total_Gibbs(double* molesSp, double* chemPot,
double* tPhMoles)
/*************************************************************************
*
* vcs_Total_Gibbs:
*
* Calculate the total dimensionless Gibbs free energy
* -> Inert species are handled as if they had a standard free
* energy of zero.
* Note, for this algorithm this function should be MONOTONICALLY
* DECREASING.
*************************************************************************/
{
double g = 0.0;
@ -56,15 +40,6 @@ double VCS_SOLVE::vcs_Total_Gibbs(double* molesSp, double* chemPot,
return g;
}
// Calculate the total dimensionless Gibbs free energy of a single phase
/*
* -> Inert species are handled as if they had a standard free
* energy of zero and if they obeyed ideal solution/gas theory
*
* @param iphase ID of the phase
* @param w Species mole number vector
* @param fe vector of partial molar free energies of the species.
*/
double VCS_SOLVE::vcs_GibbsPhase(size_t iphase, const double* const w,
const double* const fe)
{

View file

@ -9,38 +9,7 @@
namespace VCSnonideal
{
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int VCS_SOLVE::vcs_TP(int ipr, int ip1, int maxit, double T_arg, double pres_arg)
/**************************************************************************
*
* vcs_TP:
*
* Solve an equilibrium problem at a particular fixed temperature
* and pressure
*
* ipr = 1 -> Print results to standard output
* 0 -> don't report on anything
* ip1 = 1 -> Print intermediate results.
* maxit -> Maximum number of iterations for the algorithm
* T = Temperature (Kelvin)
* pres = Pressure (pascal)
*
* Return Codes
* ------------------
* 0 = Equilibrium Achieved
* 1 = Range space error encountered. The element abundance criteria are
* only partially satisfied. Specifically, the first NC= (number of
* components) conditions are satisfied. However, the full NE
* (number of elements) conditions are not satisfied. The equilibrium
* condition is returned.
* -1 = Maximum number of iterations is exceeded. Convergence was not
* found.
***************************************************************************/
{
int retn, iconv;
/*
@ -91,26 +60,8 @@ int VCS_SOLVE::vcs_TP(int ipr, int ip1, int maxit, double T_arg, double pres_arg
*/
return iconv;
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*ARGSUSED*/
int VCS_SOLVE::vcs_evalSS_TP(int ipr, int ip1, double Temp, double pres)
/**************************************************************************
*
* vcs_evalSS_TP:
*
* IPR = 1 -> Print results to standard output
* 0 -> don't report on anything
* IP1 = 1 -> Print intermediate results.
* T = Temperature (Kelvin)
* Pres = Pressure (Pascal)
*
* Evaluate the standard state free energies at the current temperature
* and pressure. Ideal gas pressure contribution is added in here.
*
***************************************************************************/
int VCS_SOLVE::vcs_evalSS_TP(int ipr, int ip1, double Temp, double pres)
{
// int i;
//double R;
@ -156,18 +107,9 @@ int VCS_SOLVE::vcs_evalSS_TP(int ipr, int ip1, double Temp, double pres)
}
}
return VCS_SUCCESS;
} /***************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
}
void VCS_SOLVE::vcs_fePrep_TP(void)
/**************************************************************************
*
*
***************************************************************************/
{
for (size_t i = 0; i < m_numSpeciesTot; ++i) {
/*
@ -180,7 +122,6 @@ void VCS_SOLVE::vcs_fePrep_TP(void)
m_feSpecies_new[i] = m_SSfeSpecies[i];
}
}
} /* vcs_fePrep_TP() ********************************************************/
}
}

View file

@ -11,13 +11,6 @@
namespace VCSnonideal
{
//! Computes the current elemental abundances vector
/*!
* Computes the elemental abundances vector, m_elemAbundances[], and stores it
* back into the global structure
*/
void VCS_SOLVE::vcs_elab()
{
for (size_t j = 0; j < m_numElemConstraints; ++j) {
@ -30,36 +23,6 @@ void VCS_SOLVE::vcs_elab()
}
}
/*
*
* vcs_elabcheck:
*
* This function checks to see if the element abundances are in
* compliance. If they are, then TRUE is returned. If not,
* FALSE is returned. Note the number of constraints checked is
* usually equal to the number of components in the problem. This
* routine can check satisfaction of all of the constraints in the
* problem, which is equal to ne. However, the solver can't fix
* breakage of constraints above nc, because that nc is the
* range space by definition. Satisfaction of extra constraints would
* have had to occur in the problem specification.
*
* The constraints should be broken up into 2 sections. If
* a constraint involves a formula matrix with positive and
* negative signs, and eaSet = 0.0, then you can't expect that the
* sum will be zero. There may be roundoff that inhibits this.
* However, if the formula matrix is all of one sign, then
* this requires that all species with nonzero entries in the
* formula matrix be identically zero. We put this into
* the logic below.
*
* Input
* -------
* ibound = 1 : Checks constraints up to the number of elements
* 0 : Checks constraints up to the number of components.
*
*/
bool VCS_SOLVE::vcs_elabcheck(int ibound)
{
size_t top = m_numComponents;
@ -127,23 +90,9 @@ bool VCS_SOLVE::vcs_elabcheck(int ibound)
}
}
return true;
} /* vcs_elabcheck() *********************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
}
void VCS_SOLVE::vcs_elabPhase(size_t iphase, double* const elemAbundPhase)
/*************************************************************************
*
* vcs_elabPhase:
*
* Computes the elemental abundances vector for a single phase,
* elemAbundPhase[], and returns it through the argument list.
* The mole numbers of species are taken from the current value
* in m_molNumSpecies_old[].
*************************************************************************/
{
for (size_t j = 0; j < m_numElemConstraints; ++j) {
elemAbundPhase[j] = 0.0;
@ -157,52 +106,7 @@ void VCS_SOLVE::vcs_elabPhase(size_t iphase, double* const elemAbundPhase)
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
int VCS_SOLVE::vcs_elcorr(double aa[], double x[])
/**************************************************************************
*
* vcs_elcorr:
*
* This subroutine corrects for element abundances. At the end of the
* subroutine, the total moles in all phases are recalculated again,
* because we have changed the number of moles in this routine.
*
* Input
* -> temporary work vectors:
* aa[ne*ne]
* x[ne]
*
* Return Values:
* 0 = Nothing of significance happened,
* Element abundances were and still are good.
* 1 = The solution changed significantly;
* The element abundances are now good.
* 2 = The solution changed significantly,
* The element abundances are still bad.
* 3 = The solution changed significantly,
* The element abundances are still bad and a component
* species got zeroed out.
*
* Internal data to be worked on::
*
* ga Current element abundances
* m_elemAbundancesGoal Required elemental abundances
* m_molNumSpecies_old Current mole number of species.
* m_formulaMatrix[][] Formula matrix of the species
* ne Number of elements
* nc Number of components.
*
* NOTES:
* This routine is turning out to be very problematic. There are
* lots of special cases and problems with zeroing out species.
*
* Still need to check out when we do loops over nc vs. ne.
*
*************************************************************************/
{
int retn = 0, its;
bool goodSpec;
@ -608,4 +512,3 @@ L_CLEANUP:
}
}

View file

@ -20,43 +20,6 @@
namespace VCSnonideal
{
// Rearrange the constraint equations represented by the Formula
// Matrix so that the operational ones are in the front
/*
*
* This subroutine handles the rearrangement of the constraint
* equations represented by the Formula Matrix. Rearrangement is only
* necessary when the number of components is less than the number of
* elements. For this case, some constraints can never be satisfied
* exactly, because the range space represented by the Formula
* Matrix of the components can't span the extra space. These
* constraints, which are out of the range space of the component
* Formula matrix entries, are migrated to the back of the Formula
* matrix.
*
* A prototypical example is an extra element column in
* FormulaMatrix[],
* which is identically zero. For example, let's say that argon is
* has an element column in FormulaMatrix[], but no species in the
* mechanism
* actually contains argon. Then, nc < ne. Also, without perturbation
* of FormulaMatrix[] vcs_basopt[] would produce a zero pivot
* because the matrix
* would be singular (unless the argon element column was already the
* last column of FormulaMatrix[].
* This routine borrows heavily from vcs_basopt's algorithm. It
* finds nc constraints which span the range space of the Component
* Formula matrix, and assigns them as the first nc components in the
* formula matrix. This guarantees that vcs_basopt[] has a
* nonsingular matrix to invert.
*
* Other Variables
* aw[i] = Mole fraction work space (ne in length)
* sa[j] = Gramm-Schmidt orthog work space (ne in length)
* ss[j] = Gramm-Schmidt orthog work space (ne in length)
* sm[i+j*ne] = QR matrix work space (ne*ne in length)
*
*/
int VCS_SOLVE::vcs_elem_rearrange(double* const aw, double* const sa,
double* const sm, double* const ss)
{
@ -217,15 +180,6 @@ int VCS_SOLVE::vcs_elem_rearrange(double* const aw, double* const sa,
return VCS_SUCCESS;
}
// Swaps the indices for all of the global data for two elements, ipos
// and jpos.
/*
* This function knows all of the element information with VCS_SOLVE, and
* can therefore switch element positions
*
* @param ipos first global element index
* @param jpos second global element index
*/
void VCS_SOLVE::vcs_switch_elem_pos(size_t ipos, size_t jpos)
{
if (ipos == jpos) {
@ -268,4 +222,3 @@ void VCS_SOLVE::vcs_switch_elem_pos(size_t ipos, size_t jpos)
std::swap(m_elementName[ipos], m_elementName[jpos]);
}
}

View file

@ -23,19 +23,6 @@ namespace VCSnonideal
static char pprefix[20] = " --- vcs_inest: ";
// Estimate equilibrium compositions
/*
* Estimates equilibrium compositions.
* Algorithm covered in a section of Smith and Missen's Book.
*
* Linear programming module is based on using dbolm.
*
* @param aw aw[i[ Mole fraction work space (ne in length)
* @param sa sa[j] = Gramm-Schmidt orthog work space (ne in length)
* @param sm sm[i+j*ne] = QR matrix work space (ne*ne in length)
* @param ss ss[j] = Gramm-Schmidt orthog work space (ne in length)
* @param test This is a small negative number.
*/
void VCS_SOLVE::vcs_inest(double* const aw, double* const sa, double* const sm,
double* const ss, double test)
{
@ -358,16 +345,7 @@ finished:
}
#endif
}
/***************************************************************************/
// Create an initial estimate of the solution to the thermodynamic
// equilibrium problem.
/*
* @return Return value indicates success:
* - 0: successful initial guess
* - -1: Unsuccessful initial guess; the elemental abundances aren't
* satisfied.
*/
int VCS_SOLVE::vcs_inest_TP()
{
int retn = 0;

View file

@ -20,16 +20,6 @@
namespace VCSnonideal
{
// Returns the multiplier for electric charge terms
/*
* This is basically equal to F/RT
*
* @param mu_units integer representing the dimensional units system
* @param TKelvin double Temperature in Kelvin
*
* @return Returns the value of F/RT
*/
double VCS_SOLVE::vcs_nondim_Farad(int mu_units, double TKelvin) const
{
double Farad;
@ -57,15 +47,6 @@ double VCS_SOLVE::vcs_nondim_Farad(int mu_units, double TKelvin) const
return Farad;
}
// Returns the multiplier for the nondimensionalization of the equations
/*
* This is basically equal to RT
*
* @param mu_units integer representing the dimensional units system
* @param TKelvin double Temperature in Kelvin
*
* @return Returns the value of RT
*/
double VCS_SOLVE::vcs_nondimMult_TP(int mu_units, double TKelvin) const
{
double rt;
@ -96,22 +77,6 @@ double VCS_SOLVE::vcs_nondimMult_TP(int mu_units, double TKelvin) const
return rt;
}
// Nondimensionalize the problem data
/*
* Nondimensionalize the free energies using the divisor, R * T
*
* Essentially the internal data can either be in dimensional form
* or in nondimensional form. This routine switches the data from
* dimensional form into nondimensional form.
*
* What we do is to divide by RT.
*
* @todo Add a scale factor based on the total mole numbers.
* The algorithm contains hard coded numbers based on the
* total mole number. If we ever were faced with a problem
* with significantly different total kmol numbers than one
* the algorithm would have problems.
*/
void VCS_SOLVE::vcs_nondim_TP()
{
double tf;
@ -203,16 +168,6 @@ void VCS_SOLVE::vcs_nondim_TP()
}
}
// Redimensionalize the problem data
/*
* Redimensionalize the free energies using the multiplier R * T
*
* Essentially the internal data can either be in dimensional form
* or in nondimensional form. This routine switches the data from
* nondimensional form into dimensional form.
*
* What we do is to multiply by RT.
*/
void VCS_SOLVE::vcs_redim_TP(void)
{
double tf;
@ -260,11 +215,6 @@ void VCS_SOLVE::vcs_redim_TP(void)
}
}
// Computes the current elemental abundances vector
/*
* Computes the elemental abundances vector, m_elemAbundances[], and stores it
* back into the global structure
*/
void VCS_SOLVE::vcs_printChemPotUnits(int unitsFormat) const
{
switch (unitsFormat) {
@ -290,4 +240,3 @@ void VCS_SOLVE::vcs_printChemPotUnits(int unitsFormat) const
}
}

View file

@ -1,7 +1,7 @@
/**
* @file vcs_phaseStability.cpp
* Implementation class for functions associated with determining the stability of a phase
* (see Class \link Cantera::VCS_SOLVE VCS_SOLVE\endlink and \ref equilfunctions ).
* (see Class \link VCSnonideal::VCS_SOLVE VCS_SOLVE\endlink and \ref equilfunctions ).
*/
#include "cantera/equil/vcs_solve.h"
#include "cantera/equil/vcs_internal.h"
@ -20,25 +20,8 @@ using namespace std;
namespace VCSnonideal
{
//====================================================================================================================
// Utility function that evaluates whether a phase can be popped into existence
/*
* A phase can be popped iff the stoichiometric coefficients for the
* component species, whose concentrations will be lowered during the
* process, are positive by at least a small degree.
*
* If one of the phase species is a zeroed component, then the phase can
* be popped if the component increases in mole number as the phase moles
* are increased.
*
* @param iphasePop id of the phase, which is currently zeroed,
*
* @return Returns true if the phase can come into existence
* and false otherwise.
*/
bool VCS_SOLVE::vcs_popPhasePossible(const size_t iphasePop) const
{
vcs_VolPhase* Vphase = m_VolPhaseList[iphasePop];
#ifdef DEBUG_MODE
@ -133,16 +116,6 @@ bool VCS_SOLVE::vcs_popPhasePossible(const size_t iphasePop) const
return false;
}
//====================================================================================================================
// Determine the list of problems that need to be checked to see if there are any phases pops
/*
* This routine evaluates and fills in the following quantities
* phasePopProblemLists_
*
* Need to work in species that are zeroed by element constraints
*
* @return Returns the number of problems that must be checked.
*/
int VCS_SOLVE::vcs_phasePopDeterminePossibleList()
{
int nfound = 0;
@ -270,13 +243,6 @@ int VCS_SOLVE::vcs_phasePopDeterminePossibleList()
return nfound;
}
//====================================================================================================================
// Decision as to whether a phase pops back into existence
/*
* @return returns the phase id of the phases that pops back into
* existence. Returns npos if there are no phases
*/
size_t VCS_SOLVE::vcs_popPhaseID(std::vector<size_t> & phasePopPhaseIDs)
{
size_t iphasePop = npos;
@ -407,29 +373,7 @@ size_t VCS_SOLVE::vcs_popPhaseID(std::vector<size_t> & phasePopPhaseIDs)
#endif
return iphasePop;
}
//====================================================================================================================
// Calculates the deltas of the reactions due to phases popping
// into existence
/*
* @param iphasePop Phase id of the phase that will come into existence
*
* Output
* -------
* m_deltaMolNumSpecies(irxn) : reaction adjustments, where irxn refers
* to the irxn'th species
* formation reaction. This adjustment
* is for species
* irxn + M, where M is the number
* of components.
*
* @return Returns an int representing the status of the step
* - 0 : normal return
* - 1 : A single species phase species has been zeroed out
* in this routine. The species is a noncomponent
* - 2 : Same as one but, the zeroed species is a component.
* - 3 : Nothing was done because the phase couldn't be birthed
* because a needed component is zero.
*/
int VCS_SOLVE::vcs_popPhaseRxnStepSizes(const size_t iphasePop)
{
vcs_VolPhase* Vphase = m_VolPhaseList[iphasePop];
@ -626,19 +570,8 @@ int VCS_SOLVE::vcs_popPhaseRxnStepSizes(const size_t iphasePop)
return 0;
}
//======================================================================================================================
// Main program to test whether a deleted phase should be brought
// back into existence
/*
*
* @param iph Phase id of the deleted phase
*
* So far this algorithm seems to be stable. I haven't run across any instance where it hasn't
* converged. However, it's probably only a matter of time
*/
double VCS_SOLVE::vcs_phaseStabilityTest(const size_t iph)
{
/*
* We will use the _new state calc here
*/
@ -970,4 +903,3 @@ double VCS_SOLVE::vcs_phaseStabilityTest(const size_t iph)
}
}

View file

@ -21,9 +21,6 @@
namespace VCSnonideal
{
// Calculate the status of single species phases.
void VCS_SOLVE::vcs_SSPhase()
{
size_t iph;
@ -68,41 +65,7 @@ void VCS_SOLVE::vcs_SSPhase()
}
}
}
/*****************************************************************************/
// This routine is mostly concerned with changing the private data
// to be consistent with what's needed for solution. It is called one
// time for each new problem structure definition.
/*
* This routine is always followed by vcs_prep(). Therefore, tasks
* that need to be done for every call to vcsc() should be placed in
* vcs_prep() and not in this routine.
*
* The problem structure refers to:
*
* the number and identity of the species.
* the formula matrix and thus the number of components.
* the number and identity of the phases.
* the equation of state
* the method and parameters for determining the standard state
* The method and parameters for determining the activity coefficients.
*
* Tasks:
* 0) Fill in the SSPhase[] array.
* 1) Check to see if any multispecies phases actually have only one
* species in that phase. If true, reassign that phase and species
* to be a single-species phase.
* 2) Determine the number of components in the problem if not already
* done so. During this process the order of the species is changed
* in the private data structure. All references to the species
* properties must employ the ind[] index vector.
*
* @param printLvl Print level of the routine
*
* @return the return code
* VCS_SUCCESS = everything went OK
*
*/
int VCS_SOLVE::vcs_prep_oneTime(int printLvl)
{
size_t kspec, i;
@ -114,7 +77,6 @@ int VCS_SOLVE::vcs_prep_oneTime(int printLvl)
m_debug_print_lvl = printLvl;
/*
* Calculate the Single Species status of phases
* Also calculate the number of species per phase
@ -258,24 +220,6 @@ int VCS_SOLVE::vcs_prep_oneTime(int printLvl)
return VCS_SUCCESS;
}
/*****************************************************************************/
// Prepare the object for re-solution
/*
* This routine is mostly concerned with changing the private data
* to be consistent with that needed for solution. It is called for
* every invocation of the vcs_solve() except for the cleanup invocation.
*
* Tasks:
* 1) Initialization of arrays to zero.
* 2) Calculate total number of moles in all phases
*
* return code
* VCS_SUCCESS = everything went OK
* VCS_PUB_BAD = There is an irreconcilable difference in the
* public data structure from when the problem was
* initially set up.
*/
int VCS_SOLVE::vcs_prep()
{
/*
@ -295,23 +239,6 @@ int VCS_SOLVE::vcs_prep()
return VCS_SUCCESS;
}
/*****************************************************************************/
// In this routine, we check for things that will cause the algorithm
// to fail.
/*
* We check to see if the problem is well posed. If it is not, we return
* false and print out error conditions.
*
* Current there is one condition. If all the element abundances are
* zero, the algorithm will fail
*
* @param vprob VCS_PROB pointer to the definition of the equilibrium
* problem
*
* @return If true, the problem is well-posed. If false, the problem
* is not well posed.
*/
bool VCS_SOLVE::vcs_wellPosed(VCS_PROB* vprob)
{
double sum = 0.0;
@ -325,5 +252,4 @@ bool VCS_SOLVE::vcs_wellPosed(VCS_PROB* vprob)
return true;
}
/*****************************************************************************/
}

View file

@ -1,18 +1,14 @@
/*!
* @file vcs_rank.cpp
* Header file for the internal class that holds the problem.
*/
/*
* $Id: vcs_solve.cpp 735 2011-07-25 14:44:41Z hkmoffa $
*/
/*
* Copywrite (2005) Sandia Corporation. Under the terms of
* Copyright (2005) Sandia Corporation. Under the terms of
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
* U.S. Government retains certain rights in this software.
*/
#include "cantera/equil/vcs_solve.h"
#include "cantera/equil/vcs_internal.h"
#include "cantera/equil/vcs_prob.h"
@ -30,7 +26,6 @@
using namespace std;
namespace VCSnonideal {
//====================================================================================================================
static int basisOptMax1(const double * const molNum,
const int n) {
// int largest = 0;
@ -49,45 +44,7 @@ namespace VCSnonideal {
}
return n-1;
}
//====================================================================================================================
// Calculate the rank of a matrix and return the rows and columns that will generate an independent basis
// for that rank
/*
* Choose the optimum component species basis for the calculations, finding the rank and
* set of linearly independent rows for that calculation.
* Then find the set of linearly indepedent element columns that can support that rank.
* This is done by taking the transpose of the matrix and redoing the same calculation.
* (there may be a better way to do this. I don't know.)
*
*
* Input
* ---------
*
* @param awtmp Vector of mole numbers which will be used to construct a
* ranking for how to pick the basis species. This is largely ignored
* here.
*
* @param numSpecies Number of species. This is the number of rows in the matrix.
*
* @param matrix Matrix. This is the formula matrix. Nominally, the rows are species, while
* the columns are element compositions. However, this routine
* is totally general, so that the rows and columns can be anything.
*
* @param numElemConstraints Number of element constraints
*
* Output
* ---------
* @param usedZeroedSpecies = If true, then a species with a zero concentration
* was used as a component.
*
*
* @param compRes Vector of rows which are linearly independent. (these are the components)
*
* @param elemComp Vector of columns which are linearly independent (These are the actionable element
* constraints).
*
* @return Returns number of components. This is the rank of the matrix
*/
int VCS_SOLVE::vcs_rank(const double * awtmp, size_t numSpecies, const double matrix[], size_t numElemConstraints,
std::vector<size_t> &compRes, std::vector<size_t>& elemComp, int * const usedZeroedSpecies) const
{
@ -343,6 +300,5 @@ namespace VCSnonideal {
}
return numComponents;
}
}

View file

@ -15,15 +15,8 @@
#include <cstdlib>
#include <cmath>
namespace VCSnonideal
{
// Switch all species data back to the original order.
/*
* This destroys the data based on reaction ordering.
*/
int VCS_SOLVE::vcs_rearrange()
{
size_t i, l, j;
@ -53,4 +46,3 @@ int VCS_SOLVE::vcs_rearrange()
}
}

View file

@ -1,11 +1,9 @@
/*
* Copyright (2005) Sandia Corporation. Under the terms of
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
* U.S. Government retains certain rights in this software.
*/
#include "cantera/equil/vcs_solve.h"
#include "cantera/equil/vcs_internal.h"
#include "cantera/equil/vcs_VolPhase.h"
@ -16,8 +14,6 @@
namespace VCSnonideal
{
/*****************************************************************************/
static void print_space(int num)
{
for (int j = 0; j < num; j++) {
@ -33,17 +29,6 @@ static void print_line(const std::string& schar, size_t num)
plogf("\n");
}
/*****************************************************************************/
/**************************************************************************
*
* vcs_report:
*
* Print out a report on the state of the equilibrium problem to
* standard output.
* This prints out the current contents of the VCS_SOLVE class, V.
* The "old" solution vector is printed out.
***************************************************************************/
int VCS_SOLVE::vcs_report(int iconv)
{
bool printActualMoles = true, inertYes = false;
@ -409,19 +394,9 @@ int VCS_SOLVE::vcs_report(int iconv)
* Return a successful completion flag
*/
return VCS_SUCCESS;
} /* vcs_report() ************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
}
void VCS_SOLVE::vcs_TCounters_report(int timing_print_lvl)
/**************************************************************************
*
* vcs_TCounters_report:
*
* Print out the total Its and time counters to standard output
***************************************************************************/
{
plogf("\nTCounters: Num_Calls Total_Its Total_Time (seconds)\n");
if (timing_print_lvl > 0) {
@ -447,8 +422,4 @@ void VCS_SOLVE::vcs_TCounters_report(int timing_print_lvl)
}
}
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
}

View file

@ -19,28 +19,6 @@
namespace VCSnonideal
{
// Calculates formation reaction step sizes.
/*
* This is equation 6.4-16, p. 143 in Smith and Missen.
*
* Output
* -------
* m_deltaMolNumSpecies[kspec] : reaction adjustments, where irxn refers
* to the irxn'th species
* formation reaction. This adjustment
* is for species
* irxn + M, where M is the number
* of components.
*
* Special branching occurs sometimes. This causes the component basis
* to be reevaluated
*
* @return Returns an int representing the status of the step
* - 0 : normal return
* - 1 : A single species phase species has been zeroed out
* in this routine. The species is a noncomponent
* - 2 : Same as one but, the zeroed species is a component.
*/
size_t VCS_SOLVE::vcs_RxnStepSizes(int& forceComponentCalc, size_t& kSpecial)
{
size_t kspec, iph;
@ -404,32 +382,6 @@ size_t VCS_SOLVE::vcs_RxnStepSizes(int& forceComponentCalc, size_t& kSpecial)
return iphDel;
}
//====================================================================================================================
// Calculates reaction adjustments using a full Hessian approximation
/*
* Calculates reaction adjustments. This does what equation 6.4-16, p. 143
* in Smith and Missen is suppose to do. However, a full matrix is
* formed and then solved via a conjugate gradient algorithm. No
* preconditioning is done.
*
* If special branching is warranted, then the program bails out.
*
* Output
* -------
* DS(I) : reaction adjustment, where I refers to the Ith species
* Special branching occurs sometimes. This causes the component basis
* to be reevaluated
* return = 0 : normal return
* 1 : A single species phase species has been zeroed out
* in this routine. The species is a noncomponent
* 2 : Same as one but, the zeroed species is a component.
*
* Special attention is taken to flag cases where the direction of the
* update is contrary to the steepest descent rule. This is an important
* attribute of the regular vcs algorithm. We don't want to violate this.
*
* NOTE: currently this routine is not used.
*/
int VCS_SOLVE::vcs_rxn_adj_cg()
{
size_t irxn, j;
@ -640,18 +592,6 @@ int VCS_SOLVE::vcs_rxn_adj_cg()
return soldel;
}
//====================================================================================================================
// Calculates the diagonal contribution to the Hessian due to
// the dependence of the activity coefficients on the mole numbers.
/*
* (See framemaker notes, Eqn. 20 - VCS Equations document)
*
* We allow the diagonal to be increased positively to any degree.
* We allow the diagonal to be decreased to 1/3 of the ideal solution
* value, but no more -> it must remain positive.
*
* NOTE: currently this routine is not used
*/
double VCS_SOLVE::vcs_Hessian_diag_adj(size_t irxn, double hessianDiag_Ideal)
{
double diag = hessianDiag_Ideal;
@ -670,14 +610,6 @@ double VCS_SOLVE::vcs_Hessian_diag_adj(size_t irxn, double hessianDiag_Ideal)
return diag;
}
//====================================================================================================================
//! Calculates the diagonal contribution to the Hessian due to
//! the dependence of the activity coefficients on the mole numbers.
/*!
* (See framemaker notes, Eqn. 20 - VCS Equations document)
*
* NOTE: currently this routine is not used
*/
double VCS_SOLVE::vcs_Hessian_actCoeff_diag(size_t irxn)
{
size_t kspec, k, l, kph;
@ -716,15 +648,7 @@ double VCS_SOLVE::vcs_Hessian_actCoeff_diag(size_t irxn)
}
return s;
}
//====================================================================================================================
// Recalculate all of the activity coefficients in all of the phases
// based on input mole numbers
/*
*
* @param moleSpeciesVCS kmol of species to be used in the update.
*
* NOTE: This routine needs to be regulated.
*/
void VCS_SOLVE::vcs_CalcLnActCoeffJac(const double* const moleSpeciesVCS)
{
/*
@ -749,41 +673,7 @@ void VCS_SOLVE::vcs_CalcLnActCoeffJac(const double* const moleSpeciesVCS)
}
}
}
/*****************************************************************************/
//! This function recalculates the deltaG for reaction, irxn
/*!
* This function recalculates the deltaG for reaction irxn,
* given the mole numbers in molNum. It uses the temporary
* space mu_i, to hold the recalculated chemical potentials.
* It only recalculates the chemical potentials for species in phases
* which participate in the irxn reaction.
*
* This function is used by the vcs_line_search algorithm() and
* should not be used widely due to the unknown state it leaves the
* system.
*
* Input
* ------------
* @param irxn Reaction number
* @param molNum Current mole numbers of species to be used as
* input to the calculation (units = kmol)
* (length = totalNuMSpecies)
*
* Output
* ------------
* @param ac output Activity coefficients (length = totalNumSpecies)
* Note this is only partially formed. Only species in
* phases that participate in the reaction will be updated
* @param mu_i dimensionless chemical potentials (length - totalNumSpecies
* Note this is only partially formed. Only species in
* phases that participate in the reaction will be updated
*
* @return Returns the dimensionless deltaG of the reaction
*
* Note, this is a dangerous routine that leaves the underlying objects in
* an unknown state.
*/
double VCS_SOLVE::deltaG_Recalc_Rxn(const int stateCalc, const size_t irxn, const double* const molNum, double* const ac,
double* const mu_i)
{
@ -801,22 +691,8 @@ double VCS_SOLVE::deltaG_Recalc_Rxn(const int stateCalc, const size_t irxn, cons
}
return deltaG;
}
/*****************************************************************************/
#ifdef DEBUG_MODE
// A line search algorithm is carried out on one reaction
/*
* In this routine we carry out a rough line search algorithm
* to make sure that the m_deltaGRxn_new doesn't switch signs prematurely.
*
* @param irxn Reaction number
* @param dx_orig Original step length
*
* @param ANOTE Output character string stating the conclusions of the
* line search
*
* @return Returns the optimized step length found by the search
*/
double VCS_SOLVE::vcs_line_search(const size_t irxn, const double dx_orig, char* const ANOTE)
#else
double VCS_SOLVE::vcs_line_search(const size_t irxn, const double dx_orig)
@ -955,6 +831,5 @@ finalize:
return dx;
}
/*****************************************************************************/
}
}

View file

@ -1,6 +1,5 @@
/*!
* @file vcs_setMolesLinProg.cpp
*
*/
/*
* Copyright (2005) Sandia Corporation. Under the terms of
@ -45,18 +44,6 @@ static void printProgress(const vector<string> &spName,
}
#endif
//! Estimate the initial mole numbers.
/*!
* This is done by running
* each reaction as far forward or backward as possible, subject
* to the constraint that all mole numbers remain
* non-negative. Reactions for which \f$ \Delta \mu^0 \f$ are
* positive are run in reverse, and ones for which it is negative
* are run in the forward direction. The end result is equivalent
* to solving the linear programming problem of minimizing the
* linear Gibbs function subject to the element and
* non-negativity constraints.
*/
int VCS_SOLVE::vcs_setMolesLinProg()
{
size_t ik, irxn;

View file

@ -1,6 +1,6 @@
/*!
* @file vcs_solve.h
* Header file for the internal class that holds the problem.
* @file vcs_solve.h Header file for the internal class that holds the
* problem.
*/
/*
* Copyright (2005) Sandia Corporation. Under the terms of
@ -8,7 +8,6 @@
* U.S. Government retains certain rights in this software.
*/
#include "cantera/equil/vcs_solve.h"
#include "cantera/base/ctexceptions.h"
#include "cantera/equil/vcs_internal.h"
@ -62,27 +61,9 @@ VCS_SOLVE::VCS_SOLVE() :
{
}
// Initialize the sizes within the VCS_SOLVE object
/*
* This resizes all of the internal arrays within the object. This routine
* operates in two modes. If all of the parameters are the same as it
* currently exists in the object, nothing is done by this routine; a quick
* exit is carried out and all of the data in the object persists.
*
* IF any of the parameters are different than currently exists in the
* object, then all of the data in the object must be redone. It may not
* be zeroed, but it must be redone.
*
* @param nspecies0 Number of species within the object
* @param nelements Number of element constraints within the problem
* @param nphase0 Number of phases defined within the problem.
*
*/
void VCS_SOLVE::vcs_initSizes(const size_t nspecies0, const size_t nelements,
const size_t nphase0)
{
if (NSPECIES0 != 0) {
if ((nspecies0 != NSPECIES0) || (nelements != m_numElemConstraints) || (nphase0 != NPHASE0)) {
vcs_delete_memory();
@ -237,19 +218,12 @@ void VCS_SOLVE::vcs_initSizes(const size_t nspecies0, const size_t nelements,
return;
}
/****************************************************************************/
// Destructor
VCS_SOLVE::~VCS_SOLVE()
{
vcs_delete_memory();
}
/*****************************************************************************/
// Delete memory that isn't just resizeable STL containers
/*
* This gets called by the destructor or by InitSizes().
*/
void VCS_SOLVE::vcs_delete_memory()
{
size_t j;
@ -273,44 +247,7 @@ void VCS_SOLVE::vcs_delete_memory()
m_numElemConstraints = 0;
m_numComponents = 0;
}
/*****************************************************************************/
// Solve an equilibrium problem
/*
* This is the main interface routine to the equilibrium solver
*
* Input:
* @param vprob Object containing the equilibrium Problem statement
*
* @param ifunc Determines the operation to be done: Valid values:
* 0 -> Solve a new problem by initializing structures
* first. An initial estimate may or may not have
* been already determined. This is indicated in the
* VCS_PROB structure.
* 1 -> The problem has already been initialized and
* set up. We call this routine to resolve it
* using the problem statement and
* solution estimate contained in
* the VCS_PROB structure.
* 2 -> Don't solve a problem. Destroy all the private
* structures.
*
* @param ipr Printing of results
* ipr = 1 -> Print problem statement and final results to
* standard output
* 0 -> don't report on anything
* @param ip1 Printing of intermediate results
* ip1 = 1 -> Print intermediate results.
* = 0 -> No intermediate results printing
*
* @param maxit Maximum number of iterations for the algorithm
*
* Output:
*
* @return
* nonzero value: failure to solve the problem at hand.
* zero : success
*/
int VCS_SOLVE::vcs(VCS_PROB* vprob, int ifunc, int ipr, int ip1, int maxit)
{
int retn = 0, iconv = 0;
@ -444,16 +381,7 @@ int VCS_SOLVE::vcs(VCS_PROB* vprob, int ifunc, int ipr, int ip1, int maxit)
}
return iconv;
}
/*****************************************************************************/
// Fully specify the problem to be solved using VCS_PROB
/*
* Use the contents of the VCS_PROB to specify the contents of the
* private data, VCS_SOLVE.
*
* @param pub Pointer to VCS_PROB that will be used to
* initialize the current equilibrium problem
*/
int VCS_SOLVE::vcs_prob_specifyFully(const VCS_PROB* pub)
{
vcs_VolPhase* Vphase = 0;
@ -835,18 +763,7 @@ int VCS_SOLVE::vcs_prob_specifyFully(const VCS_PROB* pub)
*/
return VCS_SUCCESS;
}
/*****************************************************************************/
// Specify the problem to be solved using VCS_PROB, incrementally
/*
* Use the contents of the VCS_PROB to specify the contents of the
* private data, VCS_SOLVE.
*
* It's assumed we are solving the same problem.
*
* @param pub Pointer to VCS_PROdB that will be used to
* initialize the current equilibrium problem
*/
int VCS_SOLVE::vcs_prob_specify(const VCS_PROB* pub)
{
size_t kspec, k, i, j, iph;
@ -971,15 +888,7 @@ int VCS_SOLVE::vcs_prob_specify(const VCS_PROB* pub)
return retn;
}
/*****************************************************************************/
// Transfer the results of the equilibrium calculation back to VCS_PROB
/*
* The VCS_PUB structure is returned to the user.
*
* @param pub Pointer to VCS_PROB that will get the results of the
* equilibrium calculation transfered to it.
*/
int VCS_SOLVE::vcs_prob_update(VCS_PROB* pub)
{
size_t k1 = 0;
@ -1063,17 +972,7 @@ int VCS_SOLVE::vcs_prob_update(VCS_PROB* pub)
return VCS_SUCCESS;
}
/*****************************************************************************/
// Initialize the internal counters
/*
* Initialize the internal counters containing the subroutine call
* values and times spent in the subroutines.
*
* ifunc = 0 Initialize only those counters appropriate for the top of
* vcs_solve_TP().
* = 1 Initialize all counters.
*/
void VCS_SOLVE::vcs_counters_init(int ifunc)
{
m_VCount->Its = 0;
@ -1091,30 +990,7 @@ void VCS_SOLVE::vcs_counters_init(int ifunc)
m_VCount->T_Time_vcs = 0.0;
}
}
/**************************************************************************/
// Calculation of the total volume and the partial molar volumes
/*
* This function calculates the partial molar volume
* for all species, kspec, in the thermo problem
* at the temperature TKelvin and pressure, Pres, pres is in atm.
* And, it calculates the total volume of the combined system.
*
* Input
* ---------------
* @param tkelvin Temperature in kelvin()
* @param pres Pressure in Pascal
* @param w w[] is thevector containing the current mole numbers
* in units of kmol.
*
* Output
* ----------------
* @param volPM[] For species in all phase, the entries are the
* partial molar volumes units of M**3 / kmol.
*
* @return The return value is the total volume of
* the entire system in units of m**3.
*/
double VCS_SOLVE::vcs_VolTotal(const double tkelvin, const double pres,
const double w[], double volPM[])
{
@ -1128,7 +1004,5 @@ double VCS_SOLVE::vcs_VolTotal(const double tkelvin, const double pres,
}
return VolTot;
}
/****************************************************************************/
}

View file

@ -32,15 +32,9 @@ using namespace Cantera;
namespace VCSnonideal
{
/***************************************************************************/
/************ Prototypes for static functions ******************************/
static void print_space(size_t num);
#ifdef DEBUG_MODE
# ifdef DEBUG_NOT
static void prneav(void);
@ -49,7 +43,6 @@ static int prnfm(void);
#endif
/*****************************************************************************/
#ifdef DEBUG_MODE
void VCS_SOLVE::checkDelta1(double* const dsLocal,
double* const delTPhMoles, int kspec)
@ -70,36 +63,7 @@ void VCS_SOLVE::checkDelta1(double* const dsLocal,
}
}
#endif
/*****************************************************************************/
// Main routine that solves for equilibrium at constant T and P
// using a variant of the VCS method
/*
* This is the main routine that solves for equilibrium at constant T and P
* using a variant of the VCS method. Nonideal phases can be accommodated
* as well.
*
* Any number of single-species phases and multi-species phases
* can be handled by the present version.
*
* Input
* ------------
* @param print_lvl 1 -> Print results to standard output
* 0 -> don't report on anything
*
* @param printDetails 1 -> Print intermediate results.
*
* @param maxit Maximum number of iterations for the algorithm
*
* @return 0 = Equilibrium Achieved
* 1 = Range space error encountered. The element abundance criteria are
* only partially satisfied. Specifically, the first NC= (number of
* components) conditions are satisfied. However, the full NE
* (number of elements) conditions are not satisfied. The equilibrium
* condition is returned.
* -1 = Maximum number of iterations is exceeded. Convergence was not
* found.
*/
int VCS_SOLVE::vcs_solve_TP(int print_lvl, int printDetails, int maxit)
{
int retn = VCS_SUCCESS, soldel, solveFail;
@ -2031,7 +1995,6 @@ L_RETURN_BLOCK_B:
*/
return solveFail;
}
/*********************************************************************************/
double VCS_SOLVE::vcs_minor_alt_calc(size_t kspec, size_t irxn, bool* do_delete
#ifdef DEBUG_MODE
@ -2151,21 +2114,7 @@ L_ZERO_SPECIES:
}
return dx;
}
/*****************************************************************************/
// Change the concentration of a species by delta moles.
/*
* Make sure to conserve elements and keep track of the total kmoles in all phases.
*
*
* @param kspec The species index
* @param delta_ptr pointer to the delta for the species. This may change during
* the calculation
*
* @return
* 1: succeeded without change of dx
* 0: Had to adjust dx, perhaps to zero, in order to do the delta.
*/
int VCS_SOLVE::delta_species(const size_t kspec, double* const delta_ptr)
{
size_t irxn = kspec - m_numComponents;
@ -2229,21 +2178,7 @@ int VCS_SOLVE::delta_species(const size_t kspec, double* const delta_ptr)
}
return retn;
}
/*****************************************************************************/
// Zero out the concentration of a species.
/*
* Zero out the concentration of a species. Make sure to conserve
* elements and keep track of the total moles in all phases.
* w[]
* m_tPhaseMoles_old[]
*
* @param kspec Species index
*
* @return:
* 1: succeeded
* 0: failed.
*/
int VCS_SOLVE::vcs_zero_species(const size_t kspec)
{
int retn = 1;
@ -2268,22 +2203,7 @@ int VCS_SOLVE::vcs_zero_species(const size_t kspec)
}
return retn;
}
/**************************************************************************/
// Change a single species from active to inactive status
/*
* Rearrange data when species is added or removed. The kspec species is
* moved to the back of the active species vector. The back of the species
* vector is indicated by the value of m_numSpeciesRdc, the current
* number of active species in the mechanism.
*
* @param kspec Species Index
* @return
* Returns 0 unless.
* The return is 1 when the current number of
* noncomponent species is equal to zero. A recheck of deleted species
* is carried out in the main code.
*/
int VCS_SOLVE::vcs_delete_species(const size_t kspec)
{
const size_t klast = m_numSpeciesRdc - 1;
@ -2361,25 +2281,7 @@ int VCS_SOLVE::vcs_delete_species(const size_t kspec)
*/
return (m_numRxnRdc == 0);
}
/***************************************************************************/
/*
*
* reinsert_deleted():
*
* irxn = id of the noncomponent species formation reaction for the
* species to be added in.
*
* We make decisions on the initial mole number, and major-minor status
* here. We also fix up the total moles in a phase.
*
* The algorithm proceeds to implement these decisions in the previous
* position of the species. Then, vcs_switch_pos is called to move the
* species into the last active species slot, incrementing the number
* of active species at the same time.
*
* This routine is responsible for the global data manipulation only.
*/
void VCS_SOLVE::vcs_reinsert_deleted(size_t kspec)
{
size_t k;
@ -2444,22 +2346,7 @@ void VCS_SOLVE::vcs_reinsert_deleted(size_t kspec)
vcs_switch_pos(true, (m_numSpeciesRdc - 1), kspec);
}
}
/****************************************************************************/
// This routine handles the bookkeeping involved with the
// deletion of multiphase phases from the problem.
/*
* When they are deleted, all of their species become active
* species, even though their mole numbers are set to zero.
* This routine does not make the decision to eliminate multiphases.
*
* Note, species in phases with zero mole numbers are still
* considered active. Whether the phase pops back into
* existence or not is checked as part of the main iteration
* loop.
*
* @param iph Phase to be deleted
*/
bool VCS_SOLVE::vcs_delete_multiphase(const size_t iph)
{
size_t kspec, irxn;
@ -2625,25 +2512,7 @@ bool VCS_SOLVE::vcs_delete_multiphase(const size_t iph)
return successful;
}
/**********************************************************************************/
// Recheck deleted species in multispecies phases.
/*
* We are checking the equation:
*
* sum_u = sum_j_comp [ sigma_i_j * u_j ]
* = u_i_O + log((AC_i * W_i)/m_tPhaseMoles_old)
*
* by first evaluating:
*
* DG_i_O = u_i_O - sum_u.
*
* Then, if TL is zero, the phase pops into existence if DG_i_O < 0.
* Also, if the phase exists, then we check to see if the species
* can have a mole number larger than VCS_DELETE_SPECIES_CUTOFF
* (default value = 1.0E-32).
*
*/
int VCS_SOLVE::vcs_recheck_deleted()
{
int npb;
@ -2730,7 +2599,6 @@ int VCS_SOLVE::vcs_recheck_deleted()
}
return npb;
}
/***********************************************************************************/
bool VCS_SOLVE::recheck_deleted_phase(const int iphase)
{
@ -2771,13 +2639,7 @@ bool VCS_SOLVE::recheck_deleted_phase(const int iphase)
}
return false;
}
//====================================================================================================================
// Provide an estimate for the deleted species in phases that are not zeroed out
/*
* Try to add back in all deleted species. An estimate of the kmol numbers
* are obtained and the species is added back into the equation system,
* into the old state vector.
*/
size_t VCS_SOLVE::vcs_add_all_deleted()
{
size_t iph, kspec, retn;
@ -2890,28 +2752,7 @@ size_t VCS_SOLVE::vcs_add_all_deleted()
}
return retn;
}
/***********************************************************************************/
// This routine optimizes the minimization of the total gibbs free
// energy by making sure the slope of the Gibbs free energy stays negative
/*
* The slope of the following functional is equivalent to the slope of the total
* Gibbs free energy of the system:
*
* d_Gibbs/ds = sum_k( m_deltaGRxn * m_deltaMolNumSpecies[k] )
*
* along the current direction m_deltaMolNumSpecies[], by choosing a value, al: (0<al<1)
* such that the a parabola approximation to Gibbs(al) fit to the
* end points al = 0 and al = 1 is minimized.
* s1 = slope of Gibbs function at al = 0, which is the previous
* solution = d(Gibbs)/d(al).
* s2 = slope of Gibbs function at al = 1, which is the current
* solution = d(Gibbs)/d(al).
* Only if there has been an inflection point (i.e., s1 < 0 and s2 > 0),
* does this code section kick in. It finds the point on the parabola
* where the slope is equal to zero.
*
*/
bool VCS_SOLVE::vcs_globStepDamp()
{
double s1, s2, al;
@ -3054,7 +2895,6 @@ bool VCS_SOLVE::vcs_globStepDamp()
#endif
return true;
}
/****************************************************************************************/
int VCS_SOLVE::vcs_basopt(const bool doJustComponents, double aw[], double sa[], double sm[],
double ss[], double test, bool* const usedZeroedSpecies)
@ -3635,36 +3475,25 @@ L_CLEANUP:
(m_VCount->Basis_Opts)++;
return VCS_SUCCESS;
}
/***************************************************************************************/
// Choose a species to test for the next component
/*
* We make the choice based on testing (molNum[i] * spSize[i]) for its maximum value.
* Preference for single species phases is also made.
*
* The factors of 1.01 and 1.001 are placed in this routine for a purpose.
* The purpose is to ensure that roundoff errors don't influence major decisions.
* This means that the optimized and non-optimized versions of the code remain
* close to each other.
*
* ( we try to avoid the logic: a = b
* if (a > b) { do this }
* else { do something else }
* because roundoff error makes a difference in the inequality evaluation)
*
* Mole numbers are frequently equal to each other in equilibrium problems
* due to constraints. Swaps are only done if there are a 1% difference in the
* mole numbers. Of course this logic isn't foolproof.
*
* @param molNum Mole number vector
* @param j index into molNum[] that indicates where the search will start from
* Previous successful components are swapped into the front of
* molNum[].
* @param n Length of molNum[]
*/
size_t VCS_SOLVE::vcs_basisOptMax(const double* const molNum, const size_t j,
const size_t n)
{
/*
* The factors of 1.01 and 1.001 are placed in this routine for a purpose.
* The purpose is to ensure that roundoff errors don't influence major
* decisions. This means that the optimized and non-optimized versions of
* the code remain close to each other.
*
* (we try to avoid the logic: a = b
* if (a > b) { do this }
* else { do something else }
* because roundoff error makes a difference in the inequality evaluation)
*
* Mole numbers are frequently equal to each other in equilibrium problems
* due to constraints. Swaps are only done if there are a 1% difference in
* the mole numbers. Of course this logic isn't foolproof.
*/
size_t largest = j;
double big = molNum[j] * m_spSize[j] * 1.01;
if (m_spSize[j] <= 0.0) {
@ -3701,16 +3530,7 @@ size_t VCS_SOLVE::vcs_basisOptMax(const double* const molNum, const size_t j,
}
return largest;
}
/**********************************************************************************/
// Evaluate the species category for the indicated species
/*
* All evaluations are done using the "old" version of the solution.
*
* @param kspec Species to be evaluated
*
* @return Returns the calculated species type
*/
int VCS_SOLVE::vcs_species_type(const size_t kspec) const
{
@ -3909,103 +3729,7 @@ int VCS_SOLVE::vcs_species_type(const size_t kspec) const
}
return VCS_SPECIES_MINOR;
}
/*****************************************************************************/
//! We calculate the dimensionless chemical potentials of all species
//! in a single phase.
/*!
*
* We calculate the dimensionless chemical potentials of all species
* in a single phase.
*
* Note, for multispecies phases which are currently zeroed out,
* the chemical potential is filled out with the standard chemical
* potential.
*
* For species in multispecies phases whose concentration is zero,
* we need to set the mole fraction to a very low value.
* Its chemical potential
* is then calculated using the VCS_DELETE_MINORSPECIES_CUTOFF concentration
* to keep numbers positive.
*
* Formula:
* ---------------
*
* Ideal Mixtures:
*
* m_feSpecies(I) = m_SSfeSpecies(I) + ln(z(I)) - ln(m_tPhaseMoles[iph])
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
*
*
* ( This is equivalent to the adding the log of the
* mole fraction onto the standard chemical
* potential. )
*
* Non-Ideal Mixtures:
* ActivityConvention = 0:
*
* m_feSpecies(I) = m_SSfeSpecies(I)
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
*
* ( This is equivalent to the adding the log of the
* mole fraction multiplied by the activity coefficient
* onto the standard chemical potential. )
*
* ActivityConvention = 1: -> molality activity formulation
*
* m_feSpecies(I) = m_SSfeSpecies(I)
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
* - ln(Mnaught * m_units)
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
*
* note: m_SSfeSpecies(I) is the molality based standard state.
* However, ActCoeff[I] is the molar based activity coefficient
* We have used the formulas;
*
* ActCoeff_M[I] = ActCoeff[I] / Xmol[N]
* where Xmol[N] is the mole fraction of the solvent
* ActCoeff_M[I] is the molality based act coeff.
*
* note: This is equivalent to the "normal" molality formulation:
*
* m_feSpecies(I) = m_SSfeSpecies(I)
* + ln(ActCoeff_M[I] * m(I))
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase]
* where m[I] is the molality of the ith solute
*
* m[I] = Xmol[I] / ( Xmol[N] * Mnaught * m_units)
*
*
* note: z(I)/tPhMoles_ptr[iph] = Xmol[i] is the mole fraction
* of i in the phase.
*
* NOTE:
* As per the discussion in vcs_dfe(), for small species where the mole
* fraction is small:
*
* z(i) < VCS_DELETE_MINORSPECIES_CUTOFF
*
* The chemical potential is calculated as:
*
* m_feSpecies(I) = m_SSfeSpecies(I)
* + ln(ActCoeff[i](VCS_DELETE_MINORSPECIES_CUTOFF))
*
* Input
* --------
* @param iph Phase to be calculated
* @param molNum molNum[i] is the number of moles of species i
* (VCS species order)
* @param do_deleted Do species that are deleted (default = false)
*
* Output
* -----------
* @param ac Activity coefficients for species in phase
* (VCS species order)
* @param mu_i Dimensionless chemical potentials for phase species
* (VCS species order)
*
*/
void VCS_SOLVE::vcs_chemPotPhase(const int stateCalc,
const size_t iph, const double* const molNum,
double* const ac, double* const mu_i,
@ -4071,136 +3795,7 @@ void VCS_SOLVE::vcs_chemPotPhase(const int stateCalc,
}
}
}
/*********************************************************************************/
// Calculate the dimensionless chemical potentials of all species or
// of certain groups of species, at a fixed temperature and pressure.
/*
* We calculate the dimensionless chemical potentials of all species
* or certain groups of species here, at a fixed temperature and pressure,
* for the input mole vector z[] in the parameter list.
* Nondimensionalization is achieved by division by RT.
*
* Note, for multispecies phases which are currently zeroed out,
* the chemical potential is filled out with the standard chemical
* potential.
*
* For species in multispecies phases whose concentration is zero,
* we need to set the mole fraction to a very low value.
* Its chemical potential
* is then calculated using the VCS_DELETE_MINORSPECIES_CUTOFF concentration
* to keep numbers positive.
*
*
* Formula:
* ---------------
*
* Ideal Mixtures:
*
* m_feSpecies(I) = m_SSfeSpecies(I) + ln(z(I)) - ln(m_tPhaseMoles[iph])
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
*
* ( This is equivalent to the adding the log of the
* mole fraction onto the standard chemical
* potential. )
*
* Non-Ideal Mixtures: -> molar activity formulation
* ActivityConvention = 0:
*
* m_feSpecies(I) = m_SSfeSpecies(I)
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
*
* ( This is equivalent to the adding the log of the
* mole fraction multiplied by the activity coefficient
* onto the standard chemical potential. )
*
* note: z(I)/tPhMoles_ptr[iph] = Xmol[i] is the mole fraction
* of i in the phase.
*
* ActivityConvention = 1: -> molality activity formulation
*
* m_feSpecies(I) = m_SSfeSpecies(I)
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
* - ln(Mnaught * m_units)
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
*
* note: m_SSfeSpecies(I) is the molality based standard state.
* However, ActCoeff[I] is the molar based activity coefficient
* We have used the formulas;
*
* ActCoeff_M[I] = ActCoeff[I] / Xmol[N]
* where Xmol[N] is the mole fraction of the solvent
* ActCoeff_M[I] is the molality based act coeff.
*
* note: This is equivalent to the "normal" molality formulation below:
*
* m_feSpecies(I) = m_SSfeSpecies(I)
* + ln(ActCoeff_M[I] * m(I))
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase]
* where m[I] is the molality of the ith solute
*
*
* m[I] = Xmol[I] / ( Xmol[N] * Mnaught * m_units)
*
*
* Handling of Small Species:
* ------------------------------
* As per the discussion above, for small species where the mole
* fraction
*
* z(i) < VCS_DELETE_MINORSPECIES_CUTOFF
*
* The chemical potential is calculated as:
*
* m_feSpecies(I) = m_SSfeSpecies(I) + ln(ActCoeff[i](VCS_DELETE_MINORSPECIES_CUTOFF))
*
* Handling of "Species" Representing Interfacial Voltages
* ---------------------------------------------------------
*
* These species have species types of VCS_SPECIES_TYPE_INTERFACIALVOLTAGE
* The chemical potentials for these "species" refer to electrons in
* metal electrodes. They have the following formula
*
* m_feSpecies(I) = m_SSfeSpecies(I) - F z[I] / RT
*
* F is Faraday's constant.
* R = gas constant
* T = temperature
* V = potential of the interface = phi_electrode - phi_solution
*
* For these species, the solution vector unknown, z[I], is V, the phase voltage,
* in volts.
*
* Input
* --------
* @param ll Determine which group of species gets updated
* ll = 0: Calculate for all species
* < 0: calculate for components and for major non-components
* 1: calculate for components and for minor non-components
*
* @param lbot Restricts the calculation of the chemical potential
* to the species between LBOT <= i < LTOP. Usually
* LBOT and LTOP will be equal to 0 and MR, respectively.
* @param ltop Top value of the loops
*
* @param molNum molNum[i] : Number of moles of species i
* -> This can either be the old solution vector
* or the new solution vector depending upon the
* stateCalc value
*
* @param stateCalc Determines whether z is old or new or tmp:
* VCS_STATECALC_NEW: Use the tentative values for the total number of
* moles in the phases, i.e., use TG1 instead of TG etc.
* VCS_STATECALC_OLD: Use the base values of the total number of
* moles in each system.
*
* Also needed:
* m_SSfeSpecies[kspec] : standard state chemical potentials. These are the
* chemical potentials of the standard states at
* the same T and P as the solution.
* tg : Total Number of moles in the phase.
*/
void VCS_SOLVE::vcs_dfe(const int stateCalc,
const int ll, const size_t lbot, const size_t ltop)
{
@ -4474,7 +4069,6 @@ void VCS_SOLVE::vcs_dfe(const int stateCalc,
}
//====================================================================================================================
void VCS_SOLVE::vcs_printSpeciesChemPot(const int stateCalc) const
{
@ -4551,10 +4145,8 @@ void VCS_SOLVE::vcs_printSpeciesChemPot(const int stateCalc) const
printf(" ");
vcs_print_line("-", 132);
}
/*****************************************************************************/
#ifdef DEBUG_MODE
//! Print out and check the elemental abundance vector
void VCS_SOLVE::prneav() const
{
size_t j;
@ -4594,7 +4186,6 @@ void VCS_SOLVE::prneav() const
plogendl();
}
#endif
/*****************************************************************************/
double VCS_SOLVE::l2normdg(double dgLocal[]) const
{
@ -4614,13 +4205,7 @@ double VCS_SOLVE::l2normdg(double dgLocal[]) const
}
return std::sqrt(tmp / m_numRxnRdc);
}
/*****************************************************************************/
// Calculates the total number of moles of species in all phases.
/*
* Calculates the total number of moles in all phases.
* Reconciles Phase existence flags with total moles in each phase.
*/
double VCS_SOLVE::vcs_tmoles()
{
double sum;
@ -4674,7 +4259,6 @@ void VCS_SOLVE::check_tmoles() const
}
}
#endif
/*****************************************************************************/
void VCS_SOLVE::vcs_updateVP(const int vcsState)
{
@ -4700,55 +4284,6 @@ void VCS_SOLVE::vcs_updateVP(const int vcsState)
}
}
// This routine evaluates the species type for all species
/*
* kspec
* 1 -> Major species VCS_SPECIES_MAJOR
* 0 -> Minor species VCS_SPECIES_MINOR
* -1 -> The species lies in a multicomponent phase
* that exists. Its concentration is currently
* very low, necessitating a different method
* of calculation.
* - VCS_SPECIES_ZEROEDPHASE
* -2 -> The species lies in a multicomponent phase
* which currently doesn't exist.
* Its concentration is currently zero.
* - VCS_SPECIES_ZEROEDMS
* -3 -> Species lies in a single-species phase which
* is currently zeroed out.
* - VCS_SPECIES_ZEROEDSS
* -4 -> Species has such a small mole fraction it is
* deleted even though its phase may possibly exist.
* The species is believed to have such a small
* mole fraction that it best to throw the
* calculation of it out. It will be added back in
* at the end of the calculation.
* - VCS_SPECIES_DELETED
* -5 -> Species refers to an electron in the metal
* The unknown is equal to the interfacial voltage
* drop across the interface on the SHE (standard
* hydrogen electrode) scale (volts).
* - VCS_SPECIES_INTERFACIALVOLTAGE
* -6 -> Species lies in a multicomponent phase that
* is zeroed atm and will stay deleted due to a
* choice from a higher level.
* These species will formally always have zero
* mole numbers in the solution vector.
* - VCS_SPECIES_ZEROEDPHASE
* -7 -> The species lies in a multicomponent phase which
* currently does exist. Its concentration is currently
* identically zero, though the phase exists. Note, this
* is a temporary condition that exists at the start
* of an equilibrium problem.
* The species is soon "birthed" or "deleted".
* - VCS_SPECIES_ACTIVEBUTZERO
* -8 -> The species lies in a multicomponent phase which
* currently does exist. Its concentration is currently
* identically zero, though the phase exists. This is
* a permanent condition due to stoich constraints
* - VCS_SPECIES_STOICHZERO
*
*/
bool VCS_SOLVE::vcs_evaluate_speciesType()
{
m_numRxnMinorZeroed = 0;
@ -4829,20 +4364,7 @@ bool VCS_SOLVE::vcs_evaluate_speciesType()
return (m_numRxnMinorZeroed >= m_numRxnRdc);
}
/*****************************************************************************/
// Switch rows and columns of a square matrix
/*
* Switches the row and column of a matrix.
* So that after
*
* J[k1][j] = J_old[k2][j] and J[j][k1] = J_old[j][k2]
* J[k2][j] = J_old[k1][j] and J[j][k2] = J_old[j][k1]
*
* @param Jac Double pointer to the Jacobian
* @param k1 first row/column value to be switched
* @param k2 second row/column value to be switched
*/
void VCS_SOLVE::vcs_switch2D(double* const* const Jac,
const size_t k1, const size_t k2) const
{
@ -4857,7 +4379,6 @@ void VCS_SOLVE::vcs_switch2D(double* const* const Jac,
std::swap(Jac[i][k1], Jac[i][k2]);
}
}
/*****************************************************************************/
static void print_space(size_t num)
{
@ -4866,37 +4387,7 @@ static void print_space(size_t num)
plogf(" ");
}
}
/********************************************************************************/
// This subroutine calculates reaction free energy changes for
// all noncomponent formation reactions.
/*
* Formation reactions are
* reactions which create each noncomponent species from the component
* species. m_stoichCoeffRxnMatrix[irxn][jcomp] are the stoichiometric
* coefficients for these reactions. A stoichiometric coefficient of
* one is assumed for species irxn in this reaction.
*
* INPUT
* @param l
* L < 0 : Calculate reactions corresponding to
* major noncomponent and zeroed species only
* L = 0 : Do all noncomponent reactions, i, between
* 0 <= i < irxnl
* L > 0 : Calculate reactions corresponding to
* minor noncomponent and zeroed species only
*
* @param doDeleted Do deleted species
* @param stateCalc Calculate deltaG corresponding to either old or new
* free energies
*
* Note we special case one important issue.
* If the component has zero moles, then we do not
* allow deltaG < 0.0 for formation reactions which
* would lead to the loss of more of that same component.
* This dG < 0.0 condition feeds back into the algorithm in several
* places, and leads to a infinite loop in at least one case.
*/
void VCS_SOLVE::vcs_deltag(const int l, const bool doDeleted,
const int vcsState, const bool alterZeroedPhases)
{
@ -5107,7 +4598,7 @@ void VCS_SOLVE::vcs_deltag(const int l, const bool doDeleted,
}
#endif
}
//====================================================================================================================
void VCS_SOLVE::vcs_printDeltaG(const int stateCalc)
{
size_t j;
@ -5241,22 +4732,7 @@ void VCS_SOLVE::vcs_printDeltaG(const int stateCalc)
vcs_print_line("-", 132);
}
//====================================================================================================================
// Calculate deltag of formation for all species in a single phase.
/*
* Calculate deltag of formation for all species in a single
* phase. It is assumed that the fe[] is up to date for all species.
* However, if the phase is currently zeroed out, a subproblem
* is calculated to solve for AC[i] and pseudo-X[i] for that
* phase.
*
* @param iphase phase index of the phase to be calculated
* @param doDeleted boolean indicating whether to do deleted species or not
* @param stateCalc integer describing which set of free energies
* to use and where to stick the results.
*
* NOTE: this is currently not used used anywhere. It may be in the future?
*/
void VCS_SOLVE::vcs_deltag_Phase(const size_t iphase, const bool doDeleted,
const int stateCalc, const bool alterZeroedPhases)
{
@ -5410,22 +4886,7 @@ void VCS_SOLVE::vcs_deltag_Phase(const size_t iphase, const bool doDeleted,
}
}
}
/****************************************************************************/
// Swaps the indices for all of the global data for two species, k1
// and k2.
/*
* @param ifunc: If true, switch the species data and the noncomponent reaction
* data. This must be called for a non-component species only.
* If false, switch the species data only. Typically, we use this
* option when determining the component species and at the
* end of the calculation, when we want to return unscrambled
* results. All rxn data will be out-of-date.
*
* @param k1 First species index
*
* @param k2 Second species index
*/
void VCS_SOLVE::vcs_switch_pos(const bool ifunc, const size_t k1, const size_t k2)
{
size_t i1, i2, iph, kp1, kp2;
@ -5530,32 +4991,7 @@ void VCS_SOLVE::vcs_switch_pos(const bool ifunc, const size_t k1, const size_t k
*/
}
}
/*******************************************************************************/
// Birth guess returns the number of moles of a species
// that is coming back to life.
/*
* Birth guess returns the number of moles of a species
* that is coming back to life.
* Note, this routine is not applicable if the whole phase is coming
* back to life, not just one species in that phase.
*
* Do a minor alt calculation. But, cap the mole numbers at
* 1.0E-15.
* For SS phases use VCS_DELETE_SPECIES_CUTOFF * 100.
*
* The routine makes sure the guess doesn't reduce the concentration
* of a component by more than 1/3. Note this may mean that
* the vlaue coming back from this routine is zero or a
* very small number.
*
*
* @param kspec Species number that is coming back to life
*
* @return Returns the number of kmol that the species should
* have.
*/
double VCS_SOLVE::vcs_birthGuess(const int kspec)
{
size_t irxn = kspec - m_numComponents;
@ -5627,7 +5063,6 @@ double VCS_SOLVE::vcs_birthGuess(const int kspec)
}
return dx;
}
/*******************************************************************************/
void VCS_SOLVE::vcs_setFlagsVolPhases(const bool upToDate, const int stateCalc)
{
@ -5644,7 +5079,6 @@ void VCS_SOLVE::vcs_setFlagsVolPhases(const bool upToDate, const int stateCalc)
}
}
}
/*******************************************************************************/
void VCS_SOLVE::vcs_setFlagsVolPhase(const size_t iph, const bool upToDate,
const int stateCalc)
@ -5656,16 +5090,7 @@ void VCS_SOLVE::vcs_setFlagsVolPhase(const size_t iph, const bool upToDate,
Vphase->setMolesCurrent(stateCalc);
}
}
/*******************************************************************************/
// Update all underlying vcs_VolPhase objects
/*
* Update the mole numbers and the phase voltages of all phases in the
* vcs problem
*
* @param stateCalc Location of the update (either VCS_STATECALC_NEW or
* VCS_STATECALC_OLD).
*/
void VCS_SOLVE::vcs_updateMolNumVolPhases(const int stateCalc)
{
vcs_VolPhase* Vphase;
@ -5674,6 +5099,5 @@ void VCS_SOLVE::vcs_updateMolNumVolPhases(const int stateCalc)
Vphase->updateFromVCS_MoleNumbers(stateCalc);
}
}
/*******************************************************************************/
}

View file

@ -27,7 +27,6 @@ using namespace std;
namespace VCSnonideal
{
int VCS_SOLVE::vcs_PS(VCS_PROB* vprob, int iphase, int printLvl, double& feStable)
{
@ -163,38 +162,8 @@ int VCS_SOLVE::vcs_PS(VCS_PROB* vprob, int iphase, int printLvl, double& feStabl
* Return the convergence success flag.
*/
return iStab;
}
//====================================================================================================================
// Routine that independently determines whether a phase should be popped
// under the current conditions.
/*
* This is the main routine that solves for equilibrium at constant T and P
* using a variant of the VCS method. Nonideal phases can be accommodated
* as well.
*
* Any number of single-species phases and multi-species phases
* can be handled by the present version.
*
* Input
* ------------
* @param print_lvl 1 -> Print results to standard output
* 0 -> don't report on anything
*
* @param printDetails 1 -> Print intermediate results.
*
* @param maxit Maximum number of iterations for the algorithm
*
* @return 0 = Equilibrium Achieved
* 1 = Range space error encountered. The element abundance criteria are
* only partially satisfied. Specifically, the first NC= (number of
* components) conditions are satisfied. However, the full NE
* (number of elements) conditions are not satisfied. The equilibrium
* condition is returned.
* -1 = Maximum number of iterations is exceeded. Convergence was not
* found.
*/
int VCS_SOLVE::vcs_solve_phaseStability(const int iph, const int ifunc,
double& funcVal,
int printLvl)