More variable and documentation checks.
Added the VCS_STATECALC_ defines. Will try to clean up the evaluation of phase properties using this concept.
This commit is contained in:
parent
6f07cb109e
commit
f741f96b3c
7 changed files with 706 additions and 568 deletions
|
|
@ -271,7 +271,23 @@ namespace VCSnonideal {
|
||||||
* is ddefined by the interface voltage.
|
* is ddefined by the interface voltage.
|
||||||
*/
|
*/
|
||||||
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE -5
|
#define VCS_SPECIES_TYPE_INTERFACIALVOLTAGE -5
|
||||||
|
//@}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @name Types of State Calculations within VCS
|
||||||
|
* These values determine where the
|
||||||
|
* results are storred within the VCS_SOLVE
|
||||||
|
* object.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
//! State Calculation based on the old or base mole numbers
|
||||||
|
#define VCS_STATECALC_OLD 0
|
||||||
|
|
||||||
|
//! State Calculation based on the new or tentative mole numbers
|
||||||
|
#define VCS_STATECALC_NEW 1
|
||||||
|
|
||||||
|
//! State Calculation based on a temporary set of mole numbers
|
||||||
|
#define VCS_STATECALC_TMP 2
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ namespace VCSnonideal {
|
||||||
/* ******************************************* */
|
/* ******************************************* */
|
||||||
/* **** CONVERGENCE FORCING SECTION ********** */
|
/* **** CONVERGENCE FORCING SECTION ********** */
|
||||||
/* ******************************************* */
|
/* ******************************************* */
|
||||||
vcs_dfe(molNum, 0, 0, 0, nspecies);
|
vcs_dfe(molNum, VCS_STATECALC_OLD, 0, 0, nspecies);
|
||||||
for (kspec = 0, s = 0.0; kspec < nspecies; ++kspec) {
|
for (kspec = 0, s = 0.0; kspec < nspecies; ++kspec) {
|
||||||
s += m_deltaMolNumSpecies[kspec] * m_feSpecies_curr[kspec];
|
s += m_deltaMolNumSpecies[kspec] * m_feSpecies_curr[kspec];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ int VCS_SOLVE::vcs_report(int iconv)
|
||||||
plogf("%14.7E ", log(ActCoeff[l]));
|
plogf("%14.7E ", log(ActCoeff[l]));
|
||||||
double tpmoles = m_tPhaseMoles_old[pid];
|
double tpmoles = m_tPhaseMoles_old[pid];
|
||||||
double phi = m_phasePhi[pid];
|
double phi = m_phasePhi[pid];
|
||||||
double eContrib = phi * Charge[l] * Faraday_dim;
|
double eContrib = phi * m_chargeSpecies[l] * Faraday_dim;
|
||||||
double lx = 0.0;
|
double lx = 0.0;
|
||||||
if (m_speciesUnknownType[l] == VCS_SPECIES_TYPE_INTERFACIALVOLTAGE) {
|
if (m_speciesUnknownType[l] == VCS_SPECIES_TYPE_INTERFACIALVOLTAGE) {
|
||||||
lx = 0.0;
|
lx = 0.0;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* @file vcs_rxnadj.cpp
|
* @file vcs_rxnadj.cpp
|
||||||
* routines for carrying out various line adjustments
|
* Routines for carrying out various adjustments to the reaction steps
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* $Id$
|
* $Id$
|
||||||
|
|
@ -10,27 +10,20 @@
|
||||||
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
|
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
|
||||||
* U.S. Government retains certain rights in this software.
|
* U.S. Government retains certain rights in this software.
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#include "vcs_solve.h"
|
#include "vcs_solve.h"
|
||||||
#include "vcs_internal.h"
|
#include "vcs_internal.h"
|
||||||
#include "vcs_VolPhase.h"
|
#include "vcs_VolPhase.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
namespace VCSnonideal {
|
namespace VCSnonideal {
|
||||||
|
|
||||||
/*****************************************************************************/
|
//! Calculates reaction adjustments using a full Hessian approximation
|
||||||
/*****************************************************************************/
|
/*!
|
||||||
/*****************************************************************************/
|
* Calculates reaction adjustments. This does what equation 6.4-16, p. 143
|
||||||
|
|
||||||
int VCS_SOLVE::vcs_rxn_adj_cg(void)
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* vcs_rxn_adj_cg:
|
|
||||||
*
|
|
||||||
* 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
|
* in Smith and Missen is suppose to do. However, a full matrix is
|
||||||
* formed and then solved via a conjugate gradient algorithm. No
|
* formed and then solved via a conjugate gradient algorithm. No
|
||||||
* preconditioning is done.
|
* preconditioning is done.
|
||||||
|
|
@ -49,494 +42,503 @@ int VCS_SOLVE::vcs_rxn_adj_cg(void)
|
||||||
*
|
*
|
||||||
* Special attention is taken to flag cases where the direction of the
|
* Special attention is taken to flag cases where the direction of the
|
||||||
* update is contrary to the steepest descent rule. This is an important
|
* 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
|
* attribute of the regular vcs algorithm. We don't want to violate this.
|
||||||
***************************************************************************/
|
*
|
||||||
{
|
* NOTE: currently this routine is not used.
|
||||||
int irxn, j;
|
|
||||||
int k = 0;
|
|
||||||
int kspec, soldel = 0;
|
|
||||||
double s, xx, dss;
|
|
||||||
double *dnPhase_irxn;
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
char ANOTE[128];
|
|
||||||
plogf(" "); for (j = 0; j < 77; j++) plogf("-");
|
|
||||||
plogf("\n --- Subroutine rxn_adj_cg() called\n");
|
|
||||||
plogf(" --- Species Moles Rxn_Adjustment | Comment\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Precalculation loop -> we calculate quantities based on
|
|
||||||
* loops over the number of species.
|
|
||||||
* We also evaluate whether the matrix is appropriate for
|
|
||||||
* this algorithm. If not, we bail out.
|
|
||||||
*/
|
*/
|
||||||
for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
|
int VCS_SOLVE::vcs_rxn_adj_cg() {
|
||||||
|
int irxn, j;
|
||||||
|
int k = 0;
|
||||||
|
int kspec, soldel = 0;
|
||||||
|
double s, xx, dss;
|
||||||
|
double *dnPhase_irxn;
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
sprintf(ANOTE,"Normal Calc");
|
char ANOTE[128];
|
||||||
|
plogf(" "); for (j = 0; j < 77; j++) plogf("-");
|
||||||
|
plogf("\n --- Subroutine rxn_adj_cg() called\n");
|
||||||
|
plogf(" --- Species Moles Rxn_Adjustment | Comment\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
kspec = ir[irxn];
|
/*
|
||||||
dnPhase_irxn = m_deltaMolNumPhase[irxn];
|
* Precalculation loop -> we calculate quantities based on
|
||||||
|
* loops over the number of species.
|
||||||
|
* We also evaluate whether the matrix is appropriate for
|
||||||
|
* this algorithm. If not, we bail out.
|
||||||
|
*/
|
||||||
|
for (irxn = 0; irxn < m_numRxnRdc; ++irxn) {
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
sprintf(ANOTE,"Normal Calc");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (m_molNumSpecies_old[kspec] == 0.0 && (! SSPhase[kspec])) {
|
kspec = ir[irxn];
|
||||||
/* *******************************************************************/
|
dnPhase_irxn = m_deltaMolNumPhase[irxn];
|
||||||
/* **** MULTISPECIES PHASE WITH total moles equal to zero ************/
|
|
||||||
/* *******************************************************************/
|
if (m_molNumSpecies_old[kspec] == 0.0 && (! SSPhase[kspec])) {
|
||||||
/*
|
/* *******************************************************************/
|
||||||
* HKM -> the statment below presupposes units in m_deltaGRxn_new[]. It probably
|
/* **** MULTISPECIES PHASE WITH total moles equal to zero ************/
|
||||||
* should be replaced with something more relativistic
|
/* *******************************************************************/
|
||||||
*/
|
|
||||||
if (m_deltaGRxn_new[irxn] < -1.0e-4) {
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
(void) sprintf(ANOTE, "MultSpec: come alive DG = %11.3E", m_deltaGRxn_new[irxn]);
|
|
||||||
#endif
|
|
||||||
m_deltaMolNumSpecies[kspec] = 1.0e-10;
|
|
||||||
spStatus[irxn] = VCS_SPECIES_MAJOR;
|
|
||||||
--(m_numRxnMinorZeroed);
|
|
||||||
} else {
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
(void) sprintf(ANOTE, "MultSpec: still dead DG = %11.3E", m_deltaGRxn_new[irxn]);
|
|
||||||
#endif
|
|
||||||
m_deltaMolNumSpecies[kspec] = 0.0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* ********************************************** */
|
|
||||||
/* **** REGULAR PROCESSING ********** */
|
|
||||||
/* ********************************************** */
|
|
||||||
/*
|
|
||||||
* First take care of cases where we want to bail out
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Don't bother if superconvergence has already been achieved
|
|
||||||
* in this mode.
|
|
||||||
*/
|
|
||||||
if (fabs(m_deltaGRxn_new[irxn]) <= m_tolmaj2) {
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
sprintf(ANOTE,"Skipped: converged DG = %11.3E\n", m_deltaGRxn_new[irxn]);
|
|
||||||
plogf(" --- "); plogf("%-12.12s", m_speciesName[kspec].c_str());
|
|
||||||
plogf(" %12.4E %12.4E | %s\n", m_molNumSpecies_old[kspec], m_deltaMolNumSpecies[kspec], ANOTE);
|
|
||||||
#endif
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Don't calculate for minor or nonexistent species if
|
|
||||||
* their values are to be decreasing anyway.
|
|
||||||
*/
|
|
||||||
if (spStatus[irxn] <= VCS_SPECIES_MINOR && m_deltaGRxn_new[irxn] >= 0.0) {
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
sprintf(ANOTE,"Skipped: IC = %3d and DG >0: %11.3E\n",
|
|
||||||
spStatus[irxn], m_deltaGRxn_new[irxn]);
|
|
||||||
plogf(" --- "); plogf("%-12.12s", m_speciesName[kspec].c_str());
|
|
||||||
plogf(" %12.4E %12.4E | %s\n", m_molNumSpecies_old[kspec],
|
|
||||||
m_deltaMolNumSpecies[kspec], ANOTE);
|
|
||||||
#endif
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Start of the regular processing
|
|
||||||
*/
|
|
||||||
if (SSPhase[kspec]) s = 0.0;
|
|
||||||
else s = 1.0 / m_molNumSpecies_old[kspec];
|
|
||||||
for (j = 0; j < m_numComponents; ++j) {
|
|
||||||
if (! SSPhase[j]) s += SQUARE(m_stoichCoeffRxnMatrix[irxn][j]) / m_molNumSpecies_old[j];
|
|
||||||
}
|
|
||||||
for (j = 0; j < m_numPhases; j++) {
|
|
||||||
if (! (VPhaseList[j])->SingleSpecies) {
|
|
||||||
if (m_tPhaseMoles_old[j] > 0.0)
|
|
||||||
s -= SQUARE(dnPhase_irxn[j]) / m_tPhaseMoles_old[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (s != 0.0) {
|
|
||||||
m_deltaMolNumSpecies[kspec] = -m_deltaGRxn_new[irxn] / s;
|
|
||||||
} else {
|
|
||||||
/* ************************************************************ */
|
|
||||||
/* **** REACTION IS ENTIRELY AMONGST SINGLE SPECIES PHASES **** */
|
|
||||||
/* **** DELETE ONE SOLID AND RECOMPUTE BASIS ********* */
|
|
||||||
/* ************************************************************ */
|
|
||||||
/*
|
/*
|
||||||
* Either the species L will disappear or one of the
|
* HKM -> the statment below presupposes units in m_deltaGRxn_new[]. It probably
|
||||||
* component single species phases will disappear. The sign
|
* should be replaced with something more relativistic
|
||||||
* of DG(I) will indicate which way the reaction will go.
|
|
||||||
* Then, we need to follow the reaction to see which species
|
|
||||||
* will zero out first.
|
|
||||||
*/
|
*/
|
||||||
if (m_deltaGRxn_new[irxn] > 0.0) {
|
if (m_deltaGRxn_new[irxn] < -1.0e-4) {
|
||||||
dss = m_molNumSpecies_old[kspec];
|
#ifdef DEBUG_MODE
|
||||||
k = kspec;
|
(void) sprintf(ANOTE, "MultSpec: come alive DG = %11.3E", m_deltaGRxn_new[irxn]);
|
||||||
for (j = 0; j < m_numComponents; ++j) {
|
#endif
|
||||||
if (m_stoichCoeffRxnMatrix[irxn][j] > 0.0) {
|
m_deltaMolNumSpecies[kspec] = 1.0e-10;
|
||||||
xx = m_molNumSpecies_old[j] / m_stoichCoeffRxnMatrix[irxn][j];
|
spStatus[irxn] = VCS_SPECIES_MAJOR;
|
||||||
if (xx < dss) {
|
--(m_numRxnMinorZeroed);
|
||||||
dss = xx;
|
|
||||||
k = j;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dss = -dss;
|
|
||||||
} else {
|
} else {
|
||||||
dss = 1.0e10;
|
#ifdef DEBUG_MODE
|
||||||
for (j = 0; j < m_numComponents; ++j) {
|
(void) sprintf(ANOTE, "MultSpec: still dead DG = %11.3E", m_deltaGRxn_new[irxn]);
|
||||||
if (m_stoichCoeffRxnMatrix[irxn][j] < 0.0) {
|
#endif
|
||||||
xx = -m_molNumSpecies_old[j] / m_stoichCoeffRxnMatrix[irxn][j];
|
m_deltaMolNumSpecies[kspec] = 0.0;
|
||||||
if (xx < dss) {
|
}
|
||||||
dss = xx;
|
} else {
|
||||||
k = j;
|
/* ********************************************** */
|
||||||
|
/* **** REGULAR PROCESSING ********** */
|
||||||
|
/* ********************************************** */
|
||||||
|
/*
|
||||||
|
* First take care of cases where we want to bail out
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Don't bother if superconvergence has already been achieved
|
||||||
|
* in this mode.
|
||||||
|
*/
|
||||||
|
if (fabs(m_deltaGRxn_new[irxn]) <= m_tolmaj2) {
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
sprintf(ANOTE,"Skipped: converged DG = %11.3E\n", m_deltaGRxn_new[irxn]);
|
||||||
|
plogf(" --- "); plogf("%-12.12s", m_speciesName[kspec].c_str());
|
||||||
|
plogf(" %12.4E %12.4E | %s\n", m_molNumSpecies_old[kspec], m_deltaMolNumSpecies[kspec], ANOTE);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Don't calculate for minor or nonexistent species if
|
||||||
|
* their values are to be decreasing anyway.
|
||||||
|
*/
|
||||||
|
if (spStatus[irxn] <= VCS_SPECIES_MINOR && m_deltaGRxn_new[irxn] >= 0.0) {
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
sprintf(ANOTE,"Skipped: IC = %3d and DG >0: %11.3E\n",
|
||||||
|
spStatus[irxn], m_deltaGRxn_new[irxn]);
|
||||||
|
plogf(" --- "); plogf("%-12.12s", m_speciesName[kspec].c_str());
|
||||||
|
plogf(" %12.4E %12.4E | %s\n", m_molNumSpecies_old[kspec],
|
||||||
|
m_deltaMolNumSpecies[kspec], ANOTE);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Start of the regular processing
|
||||||
|
*/
|
||||||
|
if (SSPhase[kspec]) s = 0.0;
|
||||||
|
else s = 1.0 / m_molNumSpecies_old[kspec];
|
||||||
|
for (j = 0; j < m_numComponents; ++j) {
|
||||||
|
if (! SSPhase[j]) s += SQUARE(m_stoichCoeffRxnMatrix[irxn][j]) / m_molNumSpecies_old[j];
|
||||||
|
}
|
||||||
|
for (j = 0; j < m_numPhases; j++) {
|
||||||
|
if (! (VPhaseList[j])->SingleSpecies) {
|
||||||
|
if (m_tPhaseMoles_old[j] > 0.0)
|
||||||
|
s -= SQUARE(dnPhase_irxn[j]) / m_tPhaseMoles_old[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (s != 0.0) {
|
||||||
|
m_deltaMolNumSpecies[kspec] = -m_deltaGRxn_new[irxn] / s;
|
||||||
|
} else {
|
||||||
|
/* ************************************************************ */
|
||||||
|
/* **** REACTION IS ENTIRELY AMONGST SINGLE SPECIES PHASES **** */
|
||||||
|
/* **** DELETE ONE SOLID AND RECOMPUTE BASIS ********* */
|
||||||
|
/* ************************************************************ */
|
||||||
|
/*
|
||||||
|
* Either the species L will disappear or one of the
|
||||||
|
* component single species phases will disappear. The sign
|
||||||
|
* of DG(I) will indicate which way the reaction will go.
|
||||||
|
* Then, we need to follow the reaction to see which species
|
||||||
|
* will zero out first.
|
||||||
|
*/
|
||||||
|
if (m_deltaGRxn_new[irxn] > 0.0) {
|
||||||
|
dss = m_molNumSpecies_old[kspec];
|
||||||
|
k = kspec;
|
||||||
|
for (j = 0; j < m_numComponents; ++j) {
|
||||||
|
if (m_stoichCoeffRxnMatrix[irxn][j] > 0.0) {
|
||||||
|
xx = m_molNumSpecies_old[j] / m_stoichCoeffRxnMatrix[irxn][j];
|
||||||
|
if (xx < dss) {
|
||||||
|
dss = xx;
|
||||||
|
k = j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dss = -dss;
|
||||||
|
} else {
|
||||||
|
dss = 1.0e10;
|
||||||
|
for (j = 0; j < m_numComponents; ++j) {
|
||||||
|
if (m_stoichCoeffRxnMatrix[irxn][j] < 0.0) {
|
||||||
|
xx = -m_molNumSpecies_old[j] / m_stoichCoeffRxnMatrix[irxn][j];
|
||||||
|
if (xx < dss) {
|
||||||
|
dss = xx;
|
||||||
|
k = j;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Here we adjust the mole fractions
|
|
||||||
* according to DSS and the stoichiometric array
|
|
||||||
* to take into account that we are eliminating
|
|
||||||
* the kth species. DSS contains the amount
|
|
||||||
* of moles of the kth species that needs to be
|
|
||||||
* added back into the component species.
|
|
||||||
*/
|
|
||||||
if (dss != 0.0) {
|
|
||||||
m_molNumSpecies_old[kspec] += dss;
|
|
||||||
m_tPhaseMoles_old[PhaseID[kspec]] += dss;
|
|
||||||
for (j = 0; j < m_numComponents; ++j) {
|
|
||||||
m_molNumSpecies_old[j] += dss * m_stoichCoeffRxnMatrix[irxn][j];
|
|
||||||
m_tPhaseMoles_old[PhaseID[j]] += dss * m_stoichCoeffRxnMatrix[irxn][j];
|
|
||||||
}
|
|
||||||
m_molNumSpecies_old[k] = 0.0;
|
|
||||||
m_tPhaseMoles_old[PhaseID[k]] = 0.0;
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
plogf(" --- vcs_st2 Special section to delete ");
|
|
||||||
plogf("%-12.12s", m_speciesName[k].c_str());
|
|
||||||
plogf("\n --- Immediate return - Restart iteration\n");
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* We need to immediately recompute the
|
* Here we adjust the mole fractions
|
||||||
* component basis, because we just zeroed
|
* according to DSS and the stoichiometric array
|
||||||
* it out.
|
* to take into account that we are eliminating
|
||||||
|
* the kth species. DSS contains the amount
|
||||||
|
* of moles of the kth species that needs to be
|
||||||
|
* added back into the component species.
|
||||||
*/
|
*/
|
||||||
if (k != kspec) soldel = 2;
|
if (dss != 0.0) {
|
||||||
else soldel = 1;
|
m_molNumSpecies_old[kspec] += dss;
|
||||||
return soldel;
|
m_tPhaseMoles_old[PhaseID[kspec]] += dss;
|
||||||
|
for (j = 0; j < m_numComponents; ++j) {
|
||||||
|
m_molNumSpecies_old[j] += dss * m_stoichCoeffRxnMatrix[irxn][j];
|
||||||
|
m_tPhaseMoles_old[PhaseID[j]] += dss * m_stoichCoeffRxnMatrix[irxn][j];
|
||||||
|
}
|
||||||
|
m_molNumSpecies_old[k] = 0.0;
|
||||||
|
m_tPhaseMoles_old[PhaseID[k]] = 0.0;
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
plogf(" --- vcs_st2 Special section to delete ");
|
||||||
|
plogf("%-12.12s", m_speciesName[k].c_str());
|
||||||
|
plogf("\n --- Immediate return - Restart iteration\n");
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* We need to immediately recompute the
|
||||||
|
* component basis, because we just zeroed
|
||||||
|
* it out.
|
||||||
|
*/
|
||||||
|
if (k != kspec) soldel = 2;
|
||||||
|
else soldel = 1;
|
||||||
|
return soldel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
} /* End of regular processing */
|
||||||
} /* End of regular processing */
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
plogf(" --- "); plogf("%-12.12s", m_speciesName[kspec].c_str());
|
plogf(" --- "); plogf("%-12.12s", m_speciesName[kspec].c_str());
|
||||||
plogf(" %12.4E %12.4E | %s\n", m_molNumSpecies_old[kspec],
|
plogf(" %12.4E %12.4E | %s\n", m_molNumSpecies_old[kspec],
|
||||||
m_deltaMolNumSpecies[kspec], ANOTE);
|
m_deltaMolNumSpecies[kspec], ANOTE);
|
||||||
#endif
|
#endif
|
||||||
} /* End of loop over non-component stoichiometric formation reactions */
|
} /* End of loop over non-component stoichiometric formation reactions */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* When we form the Hessian we must be careful to ensure that it
|
||||||
|
* is a symmetric positive definate matrix, still. This means zeroing
|
||||||
|
* out columns when we zero out rows as well.
|
||||||
|
* -> I suggest writing a small program to make sure of this
|
||||||
|
* property.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
plogf(" "); for (j = 0; j < 77; j++) plogf("-"); plogf("\n");
|
||||||
|
#endif
|
||||||
|
return soldel;
|
||||||
|
}
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
// Calculates the diagonal contribution to the Hessian due to
|
||||||
|
// the dependence of the activity coefficients on the mole numbers.
|
||||||
/*
|
/*
|
||||||
*
|
|
||||||
* When we form the Hessian we must be careful to ensure that it
|
|
||||||
* is a symmetric positive definate matrix, still. This means zeroing
|
|
||||||
* out columns when we zero out rows as well.
|
|
||||||
* -> I suggest writing a small program to make sure of this
|
|
||||||
* property.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
plogf(" "); for (j = 0; j < 77; j++) plogf("-"); plogf("\n");
|
|
||||||
#endif
|
|
||||||
return soldel;
|
|
||||||
} /* vcs_rxn_adj_cg() ********************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
double VCS_SOLVE::vcs_Hessian_diag_adj(int irxn, double hessianDiag_Ideal)
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
*
|
|
||||||
* vcs_actCoeff_diag_adj(irxn):
|
|
||||||
*
|
|
||||||
* 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)
|
* (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 increased positively to any degree.
|
||||||
* We allow the diagonal to be decreased to 1/3 of the ideal solution
|
* We allow the diagonal to be decreased to 1/3 of the ideal solution
|
||||||
* value, but no more -> it must remain positive.
|
* value, but no more -> it must remain positive.
|
||||||
**************************************************************************/
|
|
||||||
{
|
|
||||||
double diag = hessianDiag_Ideal;
|
|
||||||
double hessActCoef = vcs_Hessian_actCoeff_diag(irxn);
|
|
||||||
if (hessianDiag_Ideal <= 0.0) {
|
|
||||||
plogf("We shouldn't be here\n");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
if (hessActCoef >= 0.0) {
|
|
||||||
diag += hessActCoef;
|
|
||||||
} else if (fabs(hessActCoef) < 0.6666 * hessianDiag_Ideal) {
|
|
||||||
diag += hessActCoef;
|
|
||||||
} else {
|
|
||||||
diag -= 0.6666 * hessianDiag_Ideal;
|
|
||||||
}
|
|
||||||
return diag;
|
|
||||||
}
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
double VCS_SOLVE::vcs_Hessian_actCoeff_diag(int irxn)
|
|
||||||
|
|
||||||
/**************************************************************************
|
|
||||||
*
|
*
|
||||||
* vcs_Hessian_actCoeff_diag(irxn):
|
* NOTE: currently this routine is not used
|
||||||
*
|
*/
|
||||||
* Calculates the diagonal contribution to the Hessian due to
|
double VCS_SOLVE::vcs_Hessian_diag_adj(int irxn, double hessianDiag_Ideal) {
|
||||||
* the dependence of the activity coefficients on the mole numbers.
|
double diag = hessianDiag_Ideal;
|
||||||
|
double hessActCoef = vcs_Hessian_actCoeff_diag(irxn);
|
||||||
|
if (hessianDiag_Ideal <= 0.0) {
|
||||||
|
plogf("We shouldn't be here\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
if (hessActCoef >= 0.0) {
|
||||||
|
diag += hessActCoef;
|
||||||
|
} else if (fabs(hessActCoef) < 0.6666 * hessianDiag_Ideal) {
|
||||||
|
diag += hessActCoef;
|
||||||
|
} else {
|
||||||
|
diag -= 0.6666 * 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)
|
* (See framemaker notes, Eqn. 20 - VCS Equations document)
|
||||||
**************************************************************************/
|
*
|
||||||
{
|
* NOTE: currently this routine is not used
|
||||||
int kspec, k, l, kph;
|
|
||||||
double s;
|
|
||||||
double *sc_irxn;
|
|
||||||
kspec = ir[irxn];
|
|
||||||
kph = PhaseID[kspec];
|
|
||||||
sc_irxn = m_stoichCoeffRxnMatrix[irxn];
|
|
||||||
/*
|
|
||||||
* First the diagonal term of the Jacobian
|
|
||||||
*/
|
*/
|
||||||
s = dLnActCoeffdMolNum[kspec][kspec];
|
double VCS_SOLVE::vcs_Hessian_actCoeff_diag(int irxn)
|
||||||
/*
|
{
|
||||||
* Next, the other terms. Note this only a loop over the components
|
int kspec, k, l, kph;
|
||||||
* So, it's not too expensive to calculate.
|
double s;
|
||||||
*/
|
double *sc_irxn;
|
||||||
for (l = 0; l < m_numComponents; l++) {
|
kspec = ir[irxn];
|
||||||
if (!SSPhase[l]) {
|
kph = PhaseID[kspec];
|
||||||
for (k = 0; k < m_numComponents; ++k) {
|
sc_irxn = m_stoichCoeffRxnMatrix[irxn];
|
||||||
if (PhaseID[k] == PhaseID[l]) {
|
/*
|
||||||
s += sc_irxn[k] * sc_irxn[l] * dLnActCoeffdMolNum[k][l];
|
* First the diagonal term of the Jacobian
|
||||||
|
*/
|
||||||
|
s = dLnActCoeffdMolNum[kspec][kspec];
|
||||||
|
/*
|
||||||
|
* Next, the other terms. Note this only a loop over the components
|
||||||
|
* So, it's not too expensive to calculate.
|
||||||
|
*/
|
||||||
|
for (l = 0; l < m_numComponents; l++) {
|
||||||
|
if (!SSPhase[l]) {
|
||||||
|
for (k = 0; k < m_numComponents; ++k) {
|
||||||
|
if (PhaseID[k] == PhaseID[l]) {
|
||||||
|
s += sc_irxn[k] * sc_irxn[l] * dLnActCoeffdMolNum[k][l];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (kph == PhaseID[l]) {
|
||||||
|
s += sc_irxn[l] * (dLnActCoeffdMolNum[kspec][l] + dLnActCoeffdMolNum[l][kspec]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (kph == PhaseID[l]) {
|
}
|
||||||
s += sc_irxn[l] * (dLnActCoeffdMolNum[kspec][l] + dLnActCoeffdMolNum[l][kspec]);
|
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) {
|
||||||
|
/*
|
||||||
|
* Loop over all of the phases in the problem
|
||||||
|
*/
|
||||||
|
for (int iphase = 0; iphase < m_numPhases; iphase++) {
|
||||||
|
vcs_VolPhase *Vphase = VPhaseList[iphase];
|
||||||
|
/*
|
||||||
|
* We don't need to call single species phases;
|
||||||
|
*/
|
||||||
|
if (!Vphase->SingleSpecies) {
|
||||||
|
/*
|
||||||
|
* update the Ln Act Coeff jacobian entries with respect to the
|
||||||
|
* mole number of species in the phase
|
||||||
|
*/
|
||||||
|
Vphase->updateLnActCoeffJac(moleSpeciesVCS);
|
||||||
|
/*
|
||||||
|
* Download the resulting calculation into the full vector
|
||||||
|
* -> This scatter calculation is carried out in the
|
||||||
|
* vcs_VolPhase object.
|
||||||
|
*/
|
||||||
|
Vphase->sendToVCSLnActCoeffJac(dLnActCoeffdMolNum.baseDataAddr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return s;
|
/*****************************************************************************/
|
||||||
}
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
//! This function recalculates the deltaG for reaction, irxn
|
||||||
void VCS_SOLVE::vcs_CalcLnActCoeffJac(const double * const moleSpeciesVCS)
|
/*!
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*************************************************************************/
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Loop over all of the phases in the problem
|
|
||||||
*/
|
|
||||||
for (int iphase = 0; iphase < m_numPhases; iphase++) {
|
|
||||||
vcs_VolPhase *Vphase = VPhaseList[iphase];
|
|
||||||
/*
|
|
||||||
* We don't need to call single species phases;
|
|
||||||
*/
|
|
||||||
if (!Vphase->SingleSpecies) {
|
|
||||||
/*
|
|
||||||
* update the Ln Act Coeff jacobian entries with respect to the
|
|
||||||
* mole number of species in the phase
|
|
||||||
*/
|
|
||||||
Vphase->updateLnActCoeffJac(moleSpeciesVCS);
|
|
||||||
/*
|
|
||||||
* Download the resulting calculation into the full matrix
|
|
||||||
* -> This scatter calculation is carried out in the
|
|
||||||
* volume object.
|
|
||||||
*/
|
|
||||||
Vphase->sendToVCSLnActCoeffJac(dLnActCoeffdMolNum.baseDataAddr());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
double VCS_SOLVE::deltaG_Recalc_Rxn(int irxn, const double *const molNum,
|
|
||||||
double * const ac, double * const mu_i)
|
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
*
|
|
||||||
* deltaG_Recalc_Rxn
|
|
||||||
* 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
|
* given the mole numbers in molNum. It uses the temporary
|
||||||
* space mu_i, to hold the chemical potentials
|
* 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.
|
||||||
int kspec = irxn + m_numComponents;
|
*
|
||||||
int *pp_ptr = m_phaseParticipation[irxn];
|
* This function is used by the vcs_line_search algorithm() and
|
||||||
for (int iphase = 0; iphase < m_numPhases; iphase++) {
|
* should not be used widely due to the unknown state it leaves the
|
||||||
if (pp_ptr[iphase]) {
|
* system.
|
||||||
vcs_chemPotPhase(iphase, molNum, ac, mu_i);
|
*
|
||||||
|
* 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 diemsionless 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 irxn, const double *const molNum,
|
||||||
|
double * const ac, double * const mu_i) {
|
||||||
|
int kspec = irxn + m_numComponents;
|
||||||
|
int *pp_ptr = m_phaseParticipation[irxn];
|
||||||
|
for (int iphase = 0; iphase < m_numPhases; iphase++) {
|
||||||
|
if (pp_ptr[iphase]) {
|
||||||
|
vcs_chemPotPhase(iphase, molNum, ac, mu_i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
double deltaG = mu_i[kspec];
|
||||||
|
double *sc_irxn = m_stoichCoeffRxnMatrix[irxn];
|
||||||
|
for (int k = 0; k < m_numComponents; k++) {
|
||||||
|
deltaG += sc_irxn[k] * mu_i[k];
|
||||||
|
}
|
||||||
|
return deltaG;
|
||||||
}
|
}
|
||||||
double deltaG = mu_i[kspec];
|
/*****************************************************************************/
|
||||||
double *sc_irxn = m_stoichCoeffRxnMatrix[irxn];
|
|
||||||
for (int k = 0; k < m_numComponents; k++) {
|
|
||||||
deltaG += sc_irxn[k] * mu_i[k];
|
|
||||||
}
|
|
||||||
return deltaG;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
double VCS_SOLVE::vcs_line_search(int irxn, double dx_orig, char *ANOTE)
|
// 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 int irxn, const double dx_orig,
|
||||||
|
char * const ANOTE)
|
||||||
#else
|
#else
|
||||||
double VCS_SOLVE::vcs_line_search(int irxn, double dx_orig)
|
double VCS_SOLVE::vcs_line_search(const int irxn, cost double dx_orig)
|
||||||
#endif
|
#endif
|
||||||
/*************************************************************************
|
{
|
||||||
*
|
int its = 0;
|
||||||
* In this routine we carry out a rough line search algorithm
|
int k;
|
||||||
* to make sure that the m_deltaGRxn_new doesn't switch signs prematurely.
|
int kspec = ir[irxn];
|
||||||
*
|
const int MAXITS = 10;
|
||||||
*
|
double dx = dx_orig;
|
||||||
*************************************************************************/
|
double *sc_irxn = m_stoichCoeffRxnMatrix[irxn];
|
||||||
{
|
double *molNumBase = VCS_DATA_PTR(m_molNumSpecies_old);
|
||||||
int its = 0;
|
double *acBase = VCS_DATA_PTR(ActCoeff0);
|
||||||
int k;
|
double *ac = VCS_DATA_PTR(ActCoeff);
|
||||||
int kspec = ir[irxn];
|
double molSum = 0.0;
|
||||||
const int MAXITS = 10;
|
double slope;
|
||||||
double dx = dx_orig;
|
|
||||||
double *sc_irxn = m_stoichCoeffRxnMatrix[irxn];
|
|
||||||
double *molNumBase = VCS_DATA_PTR(m_molNumSpecies_old);
|
|
||||||
double *acBase = VCS_DATA_PTR(ActCoeff0);
|
|
||||||
double *ac = VCS_DATA_PTR(ActCoeff);
|
|
||||||
double molSum = 0.0;
|
|
||||||
double slope;
|
|
||||||
/*
|
|
||||||
* Calculate the deltaG value at the dx = 0.0 point
|
|
||||||
*/
|
|
||||||
double deltaGOrig = deltaG_Recalc_Rxn(irxn, molNumBase, acBase,
|
|
||||||
VCS_DATA_PTR(m_feSpecies_old));
|
|
||||||
double forig = fabs(deltaGOrig) + 1.0E-15;
|
|
||||||
if (deltaGOrig > 0.0) {
|
|
||||||
if (dx_orig > 0.0) {
|
|
||||||
dx = 0.0;
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
if (vcs_debug_print_lvl >= 2) {
|
|
||||||
//plogf(" --- %s :Warning possible error dx>0 dg > 0\n", SpName[kspec]);
|
|
||||||
}
|
|
||||||
sprintf(ANOTE,"Rxn reduced to zero step size in line search: dx>0 dg > 0");
|
|
||||||
#endif
|
|
||||||
return dx;
|
|
||||||
}
|
|
||||||
} else if (deltaGOrig < 0.0) {
|
|
||||||
if (dx_orig < 0.0) {
|
|
||||||
dx = 0.0;
|
|
||||||
#ifdef DEBUG_MODE
|
|
||||||
if (vcs_debug_print_lvl >= 2) {
|
|
||||||
//plogf(" --- %s :Warning possible error dx<0 dg < 0\n", SpName[kspec]);
|
|
||||||
}
|
|
||||||
sprintf(ANOTE,"Rxn reduced to zero step size in line search: dx<0 dg < 0");
|
|
||||||
#endif
|
|
||||||
return dx;
|
|
||||||
}
|
|
||||||
} else if (deltaGOrig == 0.0) {
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
if (dx_orig == 0.0) return 0.0;
|
|
||||||
|
|
||||||
vcs_dcopy(VCS_DATA_PTR(m_molNumSpecies_new), molNumBase, m_numSpeciesRdc);
|
|
||||||
molSum = molNumBase[kspec];
|
|
||||||
m_molNumSpecies_new[kspec] = molNumBase[kspec] + dx_orig;
|
|
||||||
for (k = 0; k < m_numComponents; k++) {
|
|
||||||
m_molNumSpecies_new[k] = molNumBase[k] + sc_irxn[k] * dx_orig;
|
|
||||||
molSum += molNumBase[k];
|
|
||||||
}
|
|
||||||
|
|
||||||
double deltaG1 = deltaG_Recalc_Rxn(irxn, VCS_DATA_PTR(m_molNumSpecies_new),
|
|
||||||
ac, VCS_DATA_PTR(m_feSpecies_new));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If deltaG hasn't switched signs when going the full distance
|
|
||||||
* then we are heading in the appropriate direction, and
|
|
||||||
* we should accept the current full step size
|
|
||||||
*/
|
|
||||||
if (deltaG1 * deltaGOrig > 0.0) {
|
|
||||||
dx = dx_orig;
|
|
||||||
goto finalize;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If we have decreased somewhat, the deltaG return after finding
|
|
||||||
* a better estimate for the line search.
|
|
||||||
*/
|
|
||||||
if (fabs(deltaG1) < 0.8*forig) {
|
|
||||||
if (deltaG1 * deltaGOrig < 0.0) {
|
|
||||||
slope = (deltaG1 - deltaGOrig) / dx_orig;
|
|
||||||
dx = -deltaGOrig / slope;
|
|
||||||
} else {
|
|
||||||
dx = dx_orig;
|
|
||||||
}
|
|
||||||
goto finalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx = dx_orig;
|
|
||||||
|
|
||||||
for (its = 0; its < MAXITS; its++) {
|
|
||||||
/*
|
/*
|
||||||
* Calculate the approximation to the total Gibbs free energy at
|
* Calculate the deltaG value at the dx = 0.0 point
|
||||||
* the dx *= 0.5 point
|
|
||||||
*/
|
*/
|
||||||
dx *= 0.5;
|
double deltaGOrig = deltaG_Recalc_Rxn(irxn, molNumBase, acBase,
|
||||||
m_molNumSpecies_new[kspec] = molNumBase[kspec] + dx;
|
VCS_DATA_PTR(m_feSpecies_old));
|
||||||
for (k = 0; k < m_numComponents; k++) {
|
double forig = fabs(deltaGOrig) + 1.0E-15;
|
||||||
m_molNumSpecies_new[k] = molNumBase[k] + sc_irxn[k] * dx;
|
if (deltaGOrig > 0.0) {
|
||||||
|
if (dx_orig > 0.0) {
|
||||||
|
dx = 0.0;
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
if (vcs_debug_print_lvl >= 2) {
|
||||||
|
//plogf(" --- %s :Warning possible error dx>0 dg > 0\n", SpName[kspec]);
|
||||||
|
}
|
||||||
|
sprintf(ANOTE,"Rxn reduced to zero step size in line search: dx>0 dg > 0");
|
||||||
|
#endif
|
||||||
|
return dx;
|
||||||
|
}
|
||||||
|
} else if (deltaGOrig < 0.0) {
|
||||||
|
if (dx_orig < 0.0) {
|
||||||
|
dx = 0.0;
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
if (vcs_debug_print_lvl >= 2) {
|
||||||
|
//plogf(" --- %s :Warning possible error dx<0 dg < 0\n", SpName[kspec]);
|
||||||
|
}
|
||||||
|
sprintf(ANOTE,"Rxn reduced to zero step size in line search: dx<0 dg < 0");
|
||||||
|
#endif
|
||||||
|
return dx;
|
||||||
|
}
|
||||||
|
} else if (deltaGOrig == 0.0) {
|
||||||
|
return 0.0;
|
||||||
}
|
}
|
||||||
double deltaG = deltaG_Recalc_Rxn(irxn, VCS_DATA_PTR(m_molNumSpecies_new),
|
if (dx_orig == 0.0) return 0.0;
|
||||||
ac, VCS_DATA_PTR(m_feSpecies_new));
|
|
||||||
|
vcs_dcopy(VCS_DATA_PTR(m_molNumSpecies_new), molNumBase, m_numSpeciesRdc);
|
||||||
|
molSum = molNumBase[kspec];
|
||||||
|
m_molNumSpecies_new[kspec] = molNumBase[kspec] + dx_orig;
|
||||||
|
for (k = 0; k < m_numComponents; k++) {
|
||||||
|
m_molNumSpecies_new[k] = molNumBase[k] + sc_irxn[k] * dx_orig;
|
||||||
|
molSum += molNumBase[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
double deltaG1 = deltaG_Recalc_Rxn(irxn, VCS_DATA_PTR(m_molNumSpecies_new),
|
||||||
|
ac, VCS_DATA_PTR(m_feSpecies_new));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If deltaG hasn't switched signs when going the full distance
|
* If deltaG hasn't switched signs when going the full distance
|
||||||
* then we are heading in the appropriate direction, and
|
* then we are heading in the appropriate direction, and
|
||||||
* we should accept the current step
|
* we should accept the current full step size
|
||||||
*/
|
*/
|
||||||
if (deltaG * deltaGOrig > 0.0) {
|
if (deltaG1 * deltaGOrig > 0.0) {
|
||||||
|
dx = dx_orig;
|
||||||
goto finalize;
|
goto finalize;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If we have decreased somewhat, the deltaG return after finding
|
* If we have decreased somewhat, the deltaG return after finding
|
||||||
* a better estimate for the line search.
|
* a better estimate for the line search.
|
||||||
*/
|
*/
|
||||||
if (fabs(deltaG) / forig < (1.0 - 0.1 * dx / dx_orig)) {
|
if (fabs(deltaG1) < 0.8*forig) {
|
||||||
if (deltaG * deltaGOrig < 0.0) {
|
if (deltaG1 * deltaGOrig < 0.0) {
|
||||||
slope = (deltaG - deltaGOrig) / dx;
|
slope = (deltaG1 - deltaGOrig) / dx_orig;
|
||||||
dx = -deltaGOrig / slope;
|
dx = -deltaGOrig / slope;
|
||||||
|
} else {
|
||||||
|
dx = dx_orig;
|
||||||
}
|
}
|
||||||
goto finalize;
|
goto finalize;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
finalize:
|
dx = dx_orig;
|
||||||
if (its >= MAXITS) {
|
|
||||||
|
for (its = 0; its < MAXITS; its++) {
|
||||||
|
/*
|
||||||
|
* Calculate the approximation to the total Gibbs free energy at
|
||||||
|
* the dx *= 0.5 point
|
||||||
|
*/
|
||||||
|
dx *= 0.5;
|
||||||
|
m_molNumSpecies_new[kspec] = molNumBase[kspec] + dx;
|
||||||
|
for (k = 0; k < m_numComponents; k++) {
|
||||||
|
m_molNumSpecies_new[k] = molNumBase[k] + sc_irxn[k] * dx;
|
||||||
|
}
|
||||||
|
double deltaG = deltaG_Recalc_Rxn(irxn, VCS_DATA_PTR(m_molNumSpecies_new),
|
||||||
|
ac, VCS_DATA_PTR(m_feSpecies_new));
|
||||||
|
/*
|
||||||
|
* If deltaG hasn't switched signs when going the full distance
|
||||||
|
* then we are heading in the appropriate direction, and
|
||||||
|
* we should accept the current step
|
||||||
|
*/
|
||||||
|
if (deltaG * deltaGOrig > 0.0) {
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* If we have decreased somewhat, the deltaG return after finding
|
||||||
|
* a better estimate for the line search.
|
||||||
|
*/
|
||||||
|
if (fabs(deltaG) / forig < (1.0 - 0.1 * dx / dx_orig)) {
|
||||||
|
if (deltaG * deltaGOrig < 0.0) {
|
||||||
|
slope = (deltaG - deltaGOrig) / dx;
|
||||||
|
dx = -deltaGOrig / slope;
|
||||||
|
}
|
||||||
|
goto finalize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
finalize:
|
||||||
|
if (its >= MAXITS) {
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
sprintf(ANOTE,"Rxn reduced to zero step size from %g to %g (MAXITS)",
|
sprintf(ANOTE,"Rxn reduced to zero step size from %g to %g (MAXITS)",
|
||||||
dx_orig, dx);
|
dx_orig, dx);
|
||||||
|
return dx;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
if (dx != dx_orig) {
|
||||||
|
sprintf(ANOTE,"Line Search reduced step size from %g to %g",
|
||||||
|
dx_orig, dx);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return dx;
|
return dx;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MODE
|
/*****************************************************************************/
|
||||||
if (dx != dx_orig) {
|
|
||||||
sprintf(ANOTE,"Line Search reduced step size from %g to %g",
|
|
||||||
dx_orig, dx);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return dx;
|
|
||||||
}
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
/*****************************************************************************/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -184,8 +184,8 @@ namespace VCSnonideal {
|
||||||
ActCoeff.resize(nspecies0, 1.0);
|
ActCoeff.resize(nspecies0, 1.0);
|
||||||
ActCoeff0.resize(nspecies0, 1.0);
|
ActCoeff0.resize(nspecies0, 1.0);
|
||||||
CurrPhAC.resize(nphase0, 0);
|
CurrPhAC.resize(nphase0, 0);
|
||||||
WtSpecies.resize(nspecies0, 0.0);
|
m_wtSpecies.resize(nspecies0, 0.0);
|
||||||
Charge.resize(nspecies0, 0.0);
|
m_chargeSpecies.resize(nspecies0, 0.0);
|
||||||
SpeciesThermo.resize(nspecies0, (VCS_SPECIES_THERMO *)0);
|
SpeciesThermo.resize(nspecies0, (VCS_SPECIES_THERMO *)0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -504,12 +504,12 @@ namespace VCSnonideal {
|
||||||
/*
|
/*
|
||||||
* Copy over the species molecular weights
|
* Copy over the species molecular weights
|
||||||
*/
|
*/
|
||||||
vcs_vdcopy(WtSpecies, pub->WtSpecies, nspecies);
|
vcs_vdcopy(m_wtSpecies, pub->WtSpecies, nspecies);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy over the charges
|
* Copy over the charges
|
||||||
*/
|
*/
|
||||||
vcs_vdcopy(Charge, pub->Charge, nspecies);
|
vcs_vdcopy(m_chargeSpecies, pub->Charge, nspecies);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Malloc and Copy the VCS_SPECIES_THERMO structures
|
* Malloc and Copy the VCS_SPECIES_THERMO structures
|
||||||
|
|
@ -726,7 +726,7 @@ namespace VCSnonideal {
|
||||||
* loop below starts at 1, not 0.
|
* loop below starts at 1, not 0.
|
||||||
*/
|
*/
|
||||||
int iSolvent = Vphase->IndSpecies[0];
|
int iSolvent = Vphase->IndSpecies[0];
|
||||||
double mnaught = WtSpecies[iSolvent] / 1000.;
|
double mnaught = m_wtSpecies[iSolvent] / 1000.;
|
||||||
for (int k = 1; k < Vphase->NVolSpecies; k++) {
|
for (int k = 1; k < Vphase->NVolSpecies; k++) {
|
||||||
int kspec = Vphase->IndSpecies[k];
|
int kspec = Vphase->IndSpecies[k];
|
||||||
SpecActConvention[kspec] = Vphase->ActivityConvention;
|
SpecActConvention[kspec] = Vphase->ActivityConvention;
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,16 @@ public:
|
||||||
*/
|
*/
|
||||||
void vcs_dfe(double const * const z, int kk, int ll, int lbot, int ltop);
|
void vcs_dfe(double const * const z, int kk, int ll, int lbot, int ltop);
|
||||||
|
|
||||||
void vcs_updateVP(int place);
|
//! This routine uploads the state of the system into all of the
|
||||||
|
//! vcs_VolumePhase objects in the current problem.
|
||||||
|
/*!
|
||||||
|
* @param vcsState Determines where to get the mole numbers from.
|
||||||
|
* - VCS_STATECALC_OLD -> from m_molNumSpecies_old
|
||||||
|
* - VCS_STATECALC_NEW -> from m_molNumSpecies_new
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void vcs_updateVP(const int vcsState);
|
||||||
|
|
||||||
int vcs_RxnStepSizes(void);
|
int vcs_RxnStepSizes(void);
|
||||||
|
|
||||||
//! Calculates the total number of moles of species in all phases.
|
//! Calculates the total number of moles of species in all phases.
|
||||||
|
|
@ -459,14 +468,74 @@ public:
|
||||||
*/
|
*/
|
||||||
void vcs_switch_elem_pos(int ipos, int jpos);
|
void vcs_switch_elem_pos(int ipos, int jpos);
|
||||||
|
|
||||||
int vcs_rxn_adj_cg(void);
|
//! Calculates reaction adjustments using a full Hessian approximation
|
||||||
double vcs_Hessian_diag_adj(int, double);
|
/*!
|
||||||
|
* 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_rxn_adj_cg(void);
|
||||||
|
|
||||||
|
//! 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_Hessian_diag_adj(int irxn, double hessianDiag_Ideal);
|
||||||
|
|
||||||
|
//! 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_Hessian_actCoeff_diag(int irxn);
|
double vcs_Hessian_actCoeff_diag(int irxn);
|
||||||
|
|
||||||
void vcs_CalcLnActCoeffJac(const double * const moleSpeciesVCS);
|
void vcs_CalcLnActCoeffJac(const double * const moleSpeciesVCS);
|
||||||
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
double vcs_line_search(int irxn, double dx_orig, char *ANOTE);
|
//! 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
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
double vcs_line_search(const int irxn, const double dx_orig,
|
||||||
|
char * const ANOTE);
|
||||||
#else
|
#else
|
||||||
double vcs_line_search(int irxn, double dx_orig);
|
double vcs_line_search(const int irxn, const double dx_orig);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -698,7 +767,34 @@ private:
|
||||||
|
|
||||||
|
|
||||||
void vcs_SSPhase(void);
|
void vcs_SSPhase(void);
|
||||||
double deltaG_Recalc_Rxn(int irxn, const double *const molNum,
|
|
||||||
|
//! 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.
|
||||||
|
*
|
||||||
|
* 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 diemsionless 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
|
||||||
|
*/
|
||||||
|
double deltaG_Recalc_Rxn(const int irxn, const double *const molNum,
|
||||||
double * const ac, double * const mu_i);
|
double * const ac, double * const mu_i);
|
||||||
void delete_memory();
|
void delete_memory();
|
||||||
|
|
||||||
|
|
@ -947,7 +1043,7 @@ public:
|
||||||
* -> Don't use this except for scaling
|
* -> Don't use this except for scaling
|
||||||
* purposes
|
* purposes
|
||||||
*/
|
*/
|
||||||
double m_totalMolNum;
|
double m_totalMolNum;
|
||||||
|
|
||||||
//! Total kmols of species in each phase
|
//! Total kmols of species in each phase
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -1155,16 +1251,16 @@ public:
|
||||||
*/
|
*/
|
||||||
std::vector<double> SpecLnMnaught;
|
std::vector<double> SpecLnMnaught;
|
||||||
|
|
||||||
//! Activity Coefficients for Species
|
//! Molar-based Activity Coefficients for Species
|
||||||
/*!
|
/*!
|
||||||
*
|
*
|
||||||
* Length = number of species
|
* Length = number of species
|
||||||
*/
|
*/
|
||||||
std::vector<double> ActCoeff;
|
std::vector<double> ActCoeff;
|
||||||
|
|
||||||
//! Activity Coefficients for Species
|
//! Molar-based Activity Coefficients for Species
|
||||||
/*!
|
/*!
|
||||||
*
|
* Molar based activity coeffients.
|
||||||
* Length = number of species
|
* Length = number of species
|
||||||
*/
|
*/
|
||||||
std::vector<double> ActCoeff0;
|
std::vector<double> ActCoeff0;
|
||||||
|
|
@ -1188,14 +1284,16 @@ public:
|
||||||
/*!
|
/*!
|
||||||
* units = kg/kmol
|
* units = kg/kmol
|
||||||
* length = number of species
|
* length = number of species
|
||||||
|
*
|
||||||
|
* note: this is a candidate for removal. I don't think we use it.
|
||||||
*/
|
*/
|
||||||
std::vector<double> WtSpecies;
|
std::vector<double> m_wtSpecies;
|
||||||
|
|
||||||
//! Charge of each species
|
//! Charge of each species
|
||||||
/*!
|
/*!
|
||||||
* Length = number of species
|
* Length = number of species
|
||||||
*/
|
*/
|
||||||
std::vector<double> Charge;
|
std::vector<double> m_chargeSpecies;
|
||||||
|
|
||||||
//! Vector of pointers to thermostructures which identify the model
|
//! Vector of pointers to thermostructures which identify the model
|
||||||
//! and parameters for evaluating the thermodynamic functions for that
|
//! and parameters for evaluating the thermodynamic functions for that
|
||||||
|
|
|
||||||
|
|
@ -270,16 +270,17 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *********************************************** */
|
|
||||||
/* **** EVALUATE TOTAL MOLES, GAS AND LIQUID ***** */
|
/*
|
||||||
/* *********************************************** */
|
* Evaluate the total moles of species in the problem
|
||||||
/* - Evaluate the total moles of gas and liquid */
|
*/
|
||||||
/* - These quantities are storred in the global variables */
|
|
||||||
vcs_tmoles();
|
vcs_tmoles();
|
||||||
/* ******************************************* */
|
|
||||||
/* **** EVALUATE ALL CHEMICAL POTENTIALS ***** */
|
/* ***************************************************************************** */
|
||||||
/* ******************************************* */
|
/* **** EVALUATE ALL CHEMICAL POTENTIALS AT THE OLD (CURRENT) MOLE NUMBERS ***** */
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 0, 0, m_numSpeciesRdc);
|
/* ***************************************************************************** */
|
||||||
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 0, 0, m_numSpeciesRdc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HKM -> If there was a machine estimate, we used to branch
|
* HKM -> If there was a machine estimate, we used to branch
|
||||||
* to the code segment which determined whether we needed a
|
* to the code segment which determined whether we needed a
|
||||||
|
|
@ -340,7 +341,7 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
vcs_elcorr(VCS_DATA_PTR(sm), VCS_DATA_PTR(wx));
|
vcs_elcorr(VCS_DATA_PTR(sm), VCS_DATA_PTR(wx));
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 0, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 0, 0, m_numSpeciesRdc);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
else {
|
else {
|
||||||
|
|
@ -355,6 +356,7 @@ namespace VCSnonideal {
|
||||||
vcs_deltag(0, false);
|
vcs_deltag(0, false);
|
||||||
iti = 0;
|
iti = 0;
|
||||||
goto L_MAINLOOP_ALL_SPECIES;
|
goto L_MAINLOOP_ALL_SPECIES;
|
||||||
|
|
||||||
/* ********************************************************* */
|
/* ********************************************************* */
|
||||||
/* **** SET INITIAL VALUES FOR ITERATION ******************* */
|
/* **** SET INITIAL VALUES FOR ITERATION ******************* */
|
||||||
/* **** EVALUATE REACTION ADJUSTMENTS ******************* */
|
/* **** EVALUATE REACTION ADJUSTMENTS ******************* */
|
||||||
|
|
@ -376,7 +378,7 @@ namespace VCSnonideal {
|
||||||
* We have already evaluated the major non-components
|
* We have already evaluated the major non-components
|
||||||
*/
|
*/
|
||||||
if (uptodate_minors == FALSE) {
|
if (uptodate_minors == FALSE) {
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 1, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 1, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(1, false);
|
vcs_deltag(1, false);
|
||||||
}
|
}
|
||||||
uptodate_minors = TRUE;
|
uptodate_minors = TRUE;
|
||||||
|
|
@ -454,27 +456,39 @@ namespace VCSnonideal {
|
||||||
* Zero out the net change in moles of multispecies phases
|
* Zero out the net change in moles of multispecies phases
|
||||||
*/
|
*/
|
||||||
vcs_dzero(VCS_DATA_PTR(m_deltaPhaseMoles), m_numPhases);
|
vcs_dzero(VCS_DATA_PTR(m_deltaPhaseMoles), m_numPhases);
|
||||||
/* **************************************************************** */
|
|
||||||
/* ***************** MAIN LOOP IN CALCULATION ******************** */
|
/*
|
||||||
/* **************************************************************** */
|
* Check on too many iterations.
|
||||||
|
* If we have too many iterations, Clean up and exit code even though we haven't
|
||||||
|
* converged. -> we have run out of iterations!
|
||||||
|
*/
|
||||||
|
if (m_VCount->Its > maxit) {
|
||||||
|
solveFail = -1;
|
||||||
|
goto L_RETURN_BLOCK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ********************************************************************** */
|
||||||
|
/* ***************** MAIN LOOP IN CALCULATION *************************** */
|
||||||
|
/* ***************** LOOP OVER IRXN TO DETERMINE STEP SIZE ************** */
|
||||||
|
/* ********************************************************************** */
|
||||||
/*
|
/*
|
||||||
* Loop through all of the reactions, irxn, pertaining to the
|
* Loop through all of the reactions, irxn, pertaining to the
|
||||||
* formation reaction for species kspec in canonical form.
|
* formation reaction for species kspec in canonical form.
|
||||||
*
|
*
|
||||||
* At the end of this loop, we will have a new estimate for the
|
* At the end of this loop, we will have a new estimate for the
|
||||||
* mole numbers wt[kspec] for all species consistent with an extent
|
* mole numbers for all species consistent with an extent
|
||||||
* of reaction, ds[kspec] for all noncomponent species formation
|
* of reaction for all noncomponent species formation
|
||||||
* reactions. We will have also ensured that all predicted
|
* reactions. We will have also ensured that all predicted
|
||||||
* non-component mole numbers are greater than zero.
|
* non-component mole numbers are greater than zero.
|
||||||
|
*
|
||||||
|
* Old_Solution New_Solution Description
|
||||||
|
* -----------------------------------------------------------------------------
|
||||||
|
* m_molNumSpecies_old[kspec] m_molNumSpecies_new[kspec] Species Mole Numbers
|
||||||
|
* m_deltaMolNumSpecies[kspec] Delta in the Species Mole Numbers
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
if (m_VCount->Its > maxit) {
|
|
||||||
solveFail = -1;
|
|
||||||
/*
|
|
||||||
* Clean up and exit code even though we haven't
|
|
||||||
* converged. -> we have run out of iterations!
|
|
||||||
*/
|
|
||||||
goto L_RETURN_BLOCK;
|
|
||||||
}
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
if (vcs_debug_print_lvl >= 2) {
|
if (vcs_debug_print_lvl >= 2) {
|
||||||
plogf(" --- Main Loop Treatment of each non-component species ");
|
plogf(" --- Main Loop Treatment of each non-component species ");
|
||||||
|
|
@ -493,10 +507,11 @@ namespace VCSnonideal {
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
ANOTE[0] = '\0';
|
ANOTE[0] = '\0';
|
||||||
#endif
|
#endif
|
||||||
/********************************************************************/
|
|
||||||
/********************** VOLTAGE SPECIES **************************/
|
|
||||||
/********************************************************************/
|
|
||||||
if (spStatus[irxn] == VCS_SPECIES_INTERFACIALVOLTAGE) {
|
if (spStatus[irxn] == VCS_SPECIES_INTERFACIALVOLTAGE) {
|
||||||
|
/********************************************************************/
|
||||||
|
/************************ VOLTAGE SPECIES ***************************/
|
||||||
|
/********************************************************************/
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
dx = minor_alt_calc(kspec, irxn, &soldel, ANOTE);
|
dx = minor_alt_calc(kspec, irxn, &soldel, ANOTE);
|
||||||
#else
|
#else
|
||||||
|
|
@ -505,7 +520,6 @@ namespace VCSnonideal {
|
||||||
m_deltaMolNumSpecies[kspec] = dx;
|
m_deltaMolNumSpecies[kspec] = dx;
|
||||||
}
|
}
|
||||||
else if (spStatus[irxn] < VCS_SPECIES_MINOR) {
|
else if (spStatus[irxn] < VCS_SPECIES_MINOR) {
|
||||||
|
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
/********************** ZEROED OUT SPECIES **************************/
|
/********************** ZEROED OUT SPECIES **************************/
|
||||||
/********************************************************************/
|
/********************************************************************/
|
||||||
|
|
@ -726,6 +740,7 @@ namespace VCSnonideal {
|
||||||
* Form a tentative value of the new species moles
|
* Form a tentative value of the new species moles
|
||||||
*/
|
*/
|
||||||
m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
|
m_molNumSpecies_new[kspec] = m_molNumSpecies_old[kspec] + dx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for non-positive mole fraction of major species.
|
* Check for non-positive mole fraction of major species.
|
||||||
* If we find one, we branch to a section below. Then,
|
* If we find one, we branch to a section below. Then,
|
||||||
|
|
@ -851,7 +866,7 @@ namespace VCSnonideal {
|
||||||
* set of reactions being considered. The set of reactions
|
* set of reactions being considered. The set of reactions
|
||||||
* is determined by the value of iti.
|
* is determined by the value of iti.
|
||||||
*/
|
*/
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, iti, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, iti, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(iti, false);
|
vcs_deltag(iti, false);
|
||||||
/*
|
/*
|
||||||
* Redefine the starting conditions for noncomponents
|
* Redefine the starting conditions for noncomponents
|
||||||
|
|
@ -902,6 +917,7 @@ namespace VCSnonideal {
|
||||||
m_deltaMolNumSpecies[kspec] = dx;
|
m_deltaMolNumSpecies[kspec] = dx;
|
||||||
|
|
||||||
} /* End of Loop on ic[irxn] -> the type of species */
|
} /* End of Loop on ic[irxn] -> the type of species */
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
/****** CALCULATE KMOLE NUMBER CHANGE FOR THE COMPONENT BASIS **********/
|
/****** CALCULATE KMOLE NUMBER CHANGE FOR THE COMPONENT BASIS **********/
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
@ -926,12 +942,12 @@ namespace VCSnonideal {
|
||||||
* Calculate the tentative change in the total number of
|
* Calculate the tentative change in the total number of
|
||||||
* moles in all of the phases
|
* moles in all of the phases
|
||||||
*/
|
*/
|
||||||
|
|
||||||
dnPhase_irxn = m_deltaMolNumPhase[irxn];
|
dnPhase_irxn = m_deltaMolNumPhase[irxn];
|
||||||
for (iph = 0; iph < m_numPhases; iph++) {
|
for (iph = 0; iph < m_numPhases; iph++) {
|
||||||
m_deltaPhaseMoles[iph] += dx * dnPhase_irxn[iph];
|
m_deltaPhaseMoles[iph] += dx * dnPhase_irxn[iph];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
checkDelta1(VCS_DATA_PTR(m_deltaMolNumSpecies), VCS_DATA_PTR(m_deltaPhaseMoles), kspec+1);
|
checkDelta1(VCS_DATA_PTR(m_deltaMolNumSpecies), VCS_DATA_PTR(m_deltaPhaseMoles), kspec+1);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -952,8 +968,9 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
L_MAIN_LOOP_END_NO_PRINT: ;
|
L_MAIN_LOOP_END_NO_PRINT: ;
|
||||||
#endif
|
#endif
|
||||||
/**************** END OF MAIN LOOP OVER FORMATION REACTIONS ************/
|
|
||||||
}
|
} /**************** END OF MAIN LOOP OVER FORMATION REACTIONS ************/
|
||||||
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
if (vcs_debug_print_lvl >= 2) {
|
if (vcs_debug_print_lvl >= 2) {
|
||||||
for (k = 0; k < m_numComponents; k++) {
|
for (k = 0; k < m_numComponents; k++) {
|
||||||
|
|
@ -966,6 +983,7 @@ namespace VCSnonideal {
|
||||||
plogendl();
|
plogendl();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
/*********** LIMIT REDUCTION OF BASIS SPECIES TO 99% *********************/
|
/*********** LIMIT REDUCTION OF BASIS SPECIES TO 99% *********************/
|
||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
@ -1050,8 +1068,8 @@ namespace VCSnonideal {
|
||||||
* we have only updated a subset of the W().
|
* we have only updated a subset of the W().
|
||||||
*/
|
*/
|
||||||
vcs_updateVP(1);
|
vcs_updateVP(1);
|
||||||
//vcs_dfe(VCS_DATA_PTR(wt), 1, iti, 0, m_numSpeciesTot);
|
//vcs_dfe(VCS_DATA_PTR(wt), VCS_STATECALC_NEW, iti, 0, m_numSpeciesTot);
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_new), 1, 0, 0, m_numSpeciesTot);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_new), VCS_STATECALC_NEW, 0, 0, m_numSpeciesTot);
|
||||||
/*
|
/*
|
||||||
* Evaluate DeltaG for all components if ITI=0, and for
|
* Evaluate DeltaG for all components if ITI=0, and for
|
||||||
* major components only if ITI NE 0
|
* major components only if ITI NE 0
|
||||||
|
|
@ -1063,7 +1081,7 @@ namespace VCSnonideal {
|
||||||
// Actually always need to calculate this
|
// Actually always need to calculate this
|
||||||
// or else nonprintouts get different results and sometimes
|
// or else nonprintouts get different results and sometimes
|
||||||
// fail in the line search algorithm -> Why is this?
|
// fail in the line search algorithm -> Why is this?
|
||||||
//vcs_dfe(VCS_DATA_PTR(wt), 1, 1, 0, m_numSpeciesRdc);
|
//vcs_dfe(VCS_DATA_PTR(wt), VCS_STATECALC_NEW, 1, 0, m_numSpeciesRdc);
|
||||||
//if (iti != 0) {
|
//if (iti != 0) {
|
||||||
// vcs_deltag(1, false);
|
// vcs_deltag(1, false);
|
||||||
//}
|
//}
|
||||||
|
|
@ -1279,7 +1297,7 @@ namespace VCSnonideal {
|
||||||
VCS_DATA_PTR(sm), VCS_DATA_PTR(ss), test,
|
VCS_DATA_PTR(sm), VCS_DATA_PTR(ss), test,
|
||||||
&usedZeroedSpecies);
|
&usedZeroedSpecies);
|
||||||
if (retn != VCS_SUCCESS) return retn;
|
if (retn != VCS_SUCCESS) return retn;
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 0, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 0, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(0, true);
|
vcs_deltag(0, true);
|
||||||
uptodate_minors = TRUE;
|
uptodate_minors = TRUE;
|
||||||
if (conv) {
|
if (conv) {
|
||||||
|
|
@ -1312,7 +1330,7 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
vcs_elcorr(VCS_DATA_PTR(sm), VCS_DATA_PTR(wx));
|
vcs_elcorr(VCS_DATA_PTR(sm), VCS_DATA_PTR(wx));
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 0, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 0, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(0, true);
|
vcs_deltag(0, true);
|
||||||
uptodate_minors = TRUE;
|
uptodate_minors = TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -1537,7 +1555,7 @@ namespace VCSnonideal {
|
||||||
* For this special case, we must reevaluate thermo functions
|
* For this special case, we must reevaluate thermo functions
|
||||||
*/
|
*/
|
||||||
if (iti != 0) {
|
if (iti != 0) {
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 0, kspec, kspec+1);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 0, kspec, kspec+1);
|
||||||
vcs_deltag(0, false);
|
vcs_deltag(0, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1618,7 +1636,7 @@ namespace VCSnonideal {
|
||||||
* for minor species, if needed.
|
* for minor species, if needed.
|
||||||
*/
|
*/
|
||||||
if (iti != 0) {
|
if (iti != 0) {
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 1, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 1, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(1, false);
|
vcs_deltag(1, false);
|
||||||
uptodate_minors = TRUE;
|
uptodate_minors = TRUE;
|
||||||
}
|
}
|
||||||
|
|
@ -1728,7 +1746,7 @@ namespace VCSnonideal {
|
||||||
/*
|
/*
|
||||||
* Go back to evaluate the total moles of gas and liquid.
|
* Go back to evaluate the total moles of gas and liquid.
|
||||||
*/
|
*/
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 0, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 0, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(0, false);
|
vcs_deltag(0, false);
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
|
@ -1818,7 +1836,7 @@ namespace VCSnonideal {
|
||||||
* for minor species and go back to do a full iteration
|
* for minor species and go back to do a full iteration
|
||||||
*/
|
*/
|
||||||
MajorSpeciesHaveConverged = true;
|
MajorSpeciesHaveConverged = true;
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 1, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 1, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(0, false);
|
vcs_deltag(0, false);
|
||||||
iti = 0;
|
iti = 0;
|
||||||
goto L_MAINLOOP_ALL_SPECIES;
|
goto L_MAINLOOP_ALL_SPECIES;
|
||||||
|
|
@ -1837,7 +1855,7 @@ namespace VCSnonideal {
|
||||||
* for minor species and go back to do a full iteration
|
* for minor species and go back to do a full iteration
|
||||||
*/
|
*/
|
||||||
MajorSpeciesHaveConverged = true;
|
MajorSpeciesHaveConverged = true;
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 1, 0, m_numSpeciesRdc);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 1, 0, m_numSpeciesRdc);
|
||||||
vcs_deltag(0, false);
|
vcs_deltag(0, false);
|
||||||
iti = 0;
|
iti = 0;
|
||||||
goto L_MAINLOOP_ALL_SPECIES;
|
goto L_MAINLOOP_ALL_SPECIES;
|
||||||
|
|
@ -2587,7 +2605,7 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), 0, 0, 0, m_numSpeciesTot);
|
vcs_dfe(VCS_DATA_PTR(m_molNumSpecies_old), VCS_STATECALC_OLD, 0, 0, m_numSpeciesTot);
|
||||||
vcs_deltag(0, true);
|
vcs_deltag(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2722,8 +2740,8 @@ namespace VCSnonideal {
|
||||||
* only step is being carried out, then we don't need to
|
* only step is being carried out, then we don't need to
|
||||||
* update the minor noncomponents.
|
* update the minor noncomponents.
|
||||||
*/
|
*/
|
||||||
// vcs_dfe(dptr, 1, iti, 0, m_numSpeciesRdc);
|
// vcs_dfe(dptr, VCS_STATECALC_NEW, iti, 0, m_numSpeciesRdc);
|
||||||
vcs_dfe(dptr, 1, 0, 0, m_numSpeciesRdc);
|
vcs_dfe(dptr, VCS_STATECALC_NEW, 0, 0, m_numSpeciesRdc);
|
||||||
/*
|
/*
|
||||||
* Evaluate DeltaG for all components if ITI=0, and for
|
* Evaluate DeltaG for all components if ITI=0, and for
|
||||||
* major components only if ITI NE 0
|
* major components only if ITI NE 0
|
||||||
|
|
@ -4058,26 +4076,25 @@ namespace VCSnonideal {
|
||||||
plogf("We have an inconsistency!\n");
|
plogf("We have an inconsistency!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
if (Charge[kspec] != -1.0) {
|
if (m_chargeSpecies[kspec] != -1.0) {
|
||||||
plogf("We have an unexpected situation!\n");
|
plogf("We have an unexpected situation!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
mu_i[kspec] = m_SSfeSpecies[kspec] + Charge[kspec] * Faraday_phi;
|
mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
|
||||||
} else {
|
} else {
|
||||||
if (SSPhase[kspec]) {
|
if (SSPhase[kspec]) {
|
||||||
mu_i[kspec] = m_SSfeSpecies[kspec] + Charge[kspec] * Faraday_phi;
|
mu_i[kspec] = m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
|
||||||
} else if (molNum[kspec] <= VCS_DELETE_MINORSPECIES_CUTOFF) {
|
} else if (molNum[kspec] <= VCS_DELETE_MINORSPECIES_CUTOFF) {
|
||||||
mu_i[kspec] = m_SSfeSpecies[kspec] + log(ac[kspec] * VCS_DELETE_MINORSPECIES_CUTOFF)
|
mu_i[kspec] = m_SSfeSpecies[kspec] + log(ac[kspec] * VCS_DELETE_MINORSPECIES_CUTOFF)
|
||||||
- tlogMoles - SpecLnMnaught[kspec] + Charge[kspec] * Faraday_phi;
|
- tlogMoles - SpecLnMnaught[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
|
||||||
} else {
|
} else {
|
||||||
mu_i[kspec] = m_SSfeSpecies[kspec] + log(ac[kspec] * molNum[kspec])
|
mu_i[kspec] = m_SSfeSpecies[kspec] + log(ac[kspec] * molNum[kspec])
|
||||||
- tlogMoles - SpecLnMnaught[kspec] + Charge[kspec] * Faraday_phi;
|
- tlogMoles - SpecLnMnaught[kspec] + m_chargeSpecies[kspec] * Faraday_phi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
// Calculalte the dimensionless chemical potentials of all species or
|
// Calculalte the dimensionless chemical potentials of all species or
|
||||||
|
|
@ -4105,7 +4122,7 @@ namespace VCSnonideal {
|
||||||
* Ideal Mixtures:
|
* Ideal Mixtures:
|
||||||
*
|
*
|
||||||
* m_feSpecies(I) = m_SSfeSpecies(I) + ln(z(I)) - ln(m_tPhaseMoles[iph])
|
* m_feSpecies(I) = m_SSfeSpecies(I) + ln(z(I)) - ln(m_tPhaseMoles[iph])
|
||||||
* + Charge[I] * Faraday_dim * m_phasePhi[iphase];
|
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
|
||||||
*
|
*
|
||||||
* ( This is equivalent to the adding the log of the
|
* ( This is equivalent to the adding the log of the
|
||||||
* mole fraction onto the standard chemical
|
* mole fraction onto the standard chemical
|
||||||
|
|
@ -4116,7 +4133,7 @@ namespace VCSnonideal {
|
||||||
*
|
*
|
||||||
* m_feSpecies(I) = m_SSfeSpecies(I)
|
* m_feSpecies(I) = m_SSfeSpecies(I)
|
||||||
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
|
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
|
||||||
* + Charge[I] * Faraday_dim * m_phasePhi[iphase];
|
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
|
||||||
*
|
*
|
||||||
* ( This is equivalent to the adding the log of the
|
* ( This is equivalent to the adding the log of the
|
||||||
* mole fraction multiplied by the activity coefficient
|
* mole fraction multiplied by the activity coefficient
|
||||||
|
|
@ -4130,7 +4147,7 @@ namespace VCSnonideal {
|
||||||
* m_feSpecies(I) = m_SSfeSpecies(I)
|
* m_feSpecies(I) = m_SSfeSpecies(I)
|
||||||
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
|
* + ln(ActCoeff[I] * z(I)) - ln(m_tPhaseMoles[iph])
|
||||||
* - ln(Mnaught * m_units)
|
* - ln(Mnaught * m_units)
|
||||||
* + Charge[I] * Faraday_dim * m_phasePhi[iphase];
|
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
|
||||||
*
|
*
|
||||||
* note: m_SSfeSpecies(I) is the molality based standard state.
|
* note: m_SSfeSpecies(I) is the molality based standard state.
|
||||||
* However, ActCoeff[I] is the molar based activity coefficient
|
* However, ActCoeff[I] is the molar based activity coefficient
|
||||||
|
|
@ -4142,7 +4159,7 @@ namespace VCSnonideal {
|
||||||
*
|
*
|
||||||
* m_feSpecies(I) = m_SSfeSpecies(I)
|
* m_feSpecies(I) = m_SSfeSpecies(I)
|
||||||
* + ln(ActCoeff_M[I] * m(I))
|
* + ln(ActCoeff_M[I] * m(I))
|
||||||
* + Charge[I] * Faraday_dim * m_phasePhi[iphase];
|
* + m_chargeSpecies[I] * Faraday_dim * m_phasePhi[iphase];
|
||||||
* where m[I] is the molality of the ith solute
|
* where m[I] is the molality of the ith solute
|
||||||
*
|
*
|
||||||
* m[I] = Xmol[I] / ( Xmol[N] * Mnaught * m_units)
|
* m[I] = Xmol[I] / ( Xmol[N] * Mnaught * m_units)
|
||||||
|
|
@ -4157,7 +4174,7 @@ namespace VCSnonideal {
|
||||||
*
|
*
|
||||||
* The chemical potential is calculated as:
|
* The chemical potential is calculated as:
|
||||||
*
|
*
|
||||||
* m_feSpecies(I)(I) = m_SSfeSpecies(I) + ln(ActCoeff[i](VCS_DELETE_MINORSPECIES_CUTOFF))
|
* m_feSpecies(I) = m_SSfeSpecies(I) + ln(ActCoeff[i](VCS_DELETE_MINORSPECIES_CUTOFF))
|
||||||
*
|
*
|
||||||
* Handling of "Species" Representing Interfacial Voltages
|
* Handling of "Species" Representing Interfacial Voltages
|
||||||
* ---------------------------------------------------------
|
* ---------------------------------------------------------
|
||||||
|
|
@ -4191,11 +4208,11 @@ namespace VCSnonideal {
|
||||||
* -> This can either be the current solution vector WT()
|
* -> This can either be the current solution vector WT()
|
||||||
* or the actual solution vector W()
|
* or the actual solution vector W()
|
||||||
*
|
*
|
||||||
* @param kk Determines whether z is old or new or tentative:
|
* @param kk Determines whether z is old or new or tmp:
|
||||||
* 1: Use the tentative values for the total number of
|
* VCS_STATECALC_NEW: Use the tentative values for the total number of
|
||||||
* moles in the phases, i.e., use TG1 instead of TG etc.
|
* moles in the phases, i.e., use TG1 instead of TG etc.
|
||||||
* 0: Use the base values of the total number of
|
* VCS_STATECALC_OLD: Use the base values of the total number of
|
||||||
* moles in each system.
|
* moles in each system.
|
||||||
*
|
*
|
||||||
* Also needed:
|
* Also needed:
|
||||||
* ff : standard state chemical potentials. These are the
|
* ff : standard state chemical potentials. These are the
|
||||||
|
|
@ -4211,6 +4228,14 @@ namespace VCSnonideal {
|
||||||
vcs_VolPhase *Vphase;
|
vcs_VolPhase *Vphase;
|
||||||
VCS_SPECIES_THERMO *st_ptr;
|
VCS_SPECIES_THERMO *st_ptr;
|
||||||
|
|
||||||
|
#ifdef DEBUG_MODE
|
||||||
|
if (kk != VCS_STATECALC_OLD && kk != VCS_STATECALC_NEW) {
|
||||||
|
plogf(" --- Subroutine vcs_dfe called with bad kk value: %d", kk);
|
||||||
|
plogendl();
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
if (vcs_debug_print_lvl >= 2) {
|
if (vcs_debug_print_lvl >= 2) {
|
||||||
if (ll == 0) {
|
if (ll == 0) {
|
||||||
|
|
@ -4225,11 +4250,11 @@ namespace VCSnonideal {
|
||||||
} else {
|
} else {
|
||||||
plogf(" --- Subroutine vcs_dfe called for components and majors");
|
plogf(" --- Subroutine vcs_dfe called for components and majors");
|
||||||
}
|
}
|
||||||
if (kk == 1) plogf(" using tentative solution\n");
|
if (kk == VCS_STATECALC_NEW) plogf(" using tentative solution");
|
||||||
else plogf("\n");
|
plogendl();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (kk <= 0) {
|
if (kk <= VCS_STATECALC_OLD) {
|
||||||
tPhMoles_ptr = VCS_DATA_PTR(m_tPhaseMoles_old);
|
tPhMoles_ptr = VCS_DATA_PTR(m_tPhaseMoles_old);
|
||||||
} else {
|
} else {
|
||||||
tPhMoles_ptr = VCS_DATA_PTR(m_tPhaseMoles_new);
|
tPhMoles_ptr = VCS_DATA_PTR(m_tPhaseMoles_new);
|
||||||
|
|
@ -4311,13 +4336,13 @@ namespace VCSnonideal {
|
||||||
plogf("We have an inconsistency!\n");
|
plogf("We have an inconsistency!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
if (Charge[kspec] != -1.0) {
|
if (m_chargeSpecies[kspec] != -1.0) {
|
||||||
plogf("We have an unexpected situation!\n");
|
plogf("We have an unexpected situation!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m_feSpecies_curr[kspec] =
|
m_feSpecies_curr[kspec] =
|
||||||
m_SSfeSpecies[kspec] + Charge[kspec] * Faraday_dim * m_phasePhi[iphase];
|
m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_dim * m_phasePhi[iphase];
|
||||||
} else {
|
} else {
|
||||||
if (SSPhase[kspec]) {
|
if (SSPhase[kspec]) {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
||||||
|
|
@ -4328,14 +4353,14 @@ namespace VCSnonideal {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec]
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec]
|
||||||
+ log(ActCoeff[kspec] * VCS_DELETE_MINORSPECIES_CUTOFF)
|
+ log(ActCoeff[kspec] * VCS_DELETE_MINORSPECIES_CUTOFF)
|
||||||
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
||||||
+ Charge[kspec] * Faraday_dim * m_phasePhi[iphase];
|
+ m_chargeSpecies[kspec] * Faraday_dim * m_phasePhi[iphase];
|
||||||
} else {
|
} else {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec] + log(ActCoeff[kspec] * z[kspec])
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec] + log(ActCoeff[kspec] * z[kspec])
|
||||||
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
||||||
+ Charge[kspec] * Faraday_dim * m_phasePhi[iphase];
|
+ m_chargeSpecies[kspec] * Faraday_dim * m_phasePhi[iphase];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4354,13 +4379,13 @@ namespace VCSnonideal {
|
||||||
plogf("We have an inconsistency!\n");
|
plogf("We have an inconsistency!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
if (Charge[kspec] != -1.0) {
|
if (m_chargeSpecies[kspec] != -1.0) {
|
||||||
plogf("We have an unexpected situation!\n");
|
plogf("We have an unexpected situation!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m_feSpecies_curr[kspec] =
|
m_feSpecies_curr[kspec] =
|
||||||
m_SSfeSpecies[kspec] + Charge[kspec] * Faraday_dim * m_phasePhi[iphase];
|
m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_dim * m_phasePhi[iphase];
|
||||||
} else {
|
} else {
|
||||||
if (SSPhase[kspec]) {
|
if (SSPhase[kspec]) {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
||||||
|
|
@ -4371,14 +4396,14 @@ namespace VCSnonideal {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec]
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec]
|
||||||
+ log(ActCoeff[kspec] * VCS_DELETE_MINORSPECIES_CUTOFF)
|
+ log(ActCoeff[kspec] * VCS_DELETE_MINORSPECIES_CUTOFF)
|
||||||
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
||||||
+ Charge[kspec] * Faraday_dim * m_phasePhi[iphase]; ;
|
+ m_chargeSpecies[kspec] * Faraday_dim * m_phasePhi[iphase]; ;
|
||||||
} else {
|
} else {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec] + log(ActCoeff[kspec] * z[kspec])
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec] + log(ActCoeff[kspec] * z[kspec])
|
||||||
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
- tlogMoles[PhaseID[kspec]] - SpecLnMnaught[kspec]
|
||||||
+ Charge[kspec] * Faraday_dim * m_phasePhi[iphase];
|
+ m_chargeSpecies[kspec] * Faraday_dim * m_phasePhi[iphase];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4398,13 +4423,13 @@ namespace VCSnonideal {
|
||||||
plogf("We have an inconsistency!\n");
|
plogf("We have an inconsistency!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
if (Charge[kspec] != -1.0) {
|
if (m_chargeSpecies[kspec] != -1.0) {
|
||||||
plogf("We have an unexpected situation!\n");
|
plogf("We have an unexpected situation!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m_feSpecies_curr[kspec] =
|
m_feSpecies_curr[kspec] =
|
||||||
m_SSfeSpecies[kspec] + Charge[kspec] * Faraday_dim * m_phasePhi[iphase]; ;
|
m_SSfeSpecies[kspec] + m_chargeSpecies[kspec] * Faraday_dim * m_phasePhi[iphase]; ;
|
||||||
} else {
|
} else {
|
||||||
if (SSPhase[kspec]) {
|
if (SSPhase[kspec]) {
|
||||||
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
m_feSpecies_curr[kspec] = m_SSfeSpecies[kspec];
|
||||||
|
|
@ -4434,7 +4459,6 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
#ifdef DEBUG_MODE
|
#ifdef DEBUG_MODE
|
||||||
|
|
@ -4472,7 +4496,6 @@ namespace VCSnonideal {
|
||||||
plogendl();
|
plogendl();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
// Calculate the norm of a deltaGibbs free energy vector
|
// Calculate the norm of a deltaGibbs free energy vector
|
||||||
|
|
@ -4495,7 +4518,6 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
return (std::sqrt(tmp / m_numRxnRdc));
|
return (std::sqrt(tmp / m_numRxnRdc));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
// Calculates the total number of moles of species in all phases.
|
// Calculates the total number of moles of species in all phases.
|
||||||
|
|
@ -4533,34 +4555,34 @@ namespace VCSnonideal {
|
||||||
}
|
}
|
||||||
m_totalMolNum = sum;
|
m_totalMolNum = sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void VCS_SOLVE::vcs_updateVP (int place)
|
// This routine uploads the state of the system into all of the
|
||||||
|
// vcs_VolPhase objects in the current problem.
|
||||||
/*************************************************************************
|
/*
|
||||||
* vcs_updateVP()
|
* @param vcsState Determines where to get the mole numbers from.
|
||||||
*
|
* - VCS_STATECALC_OLD -> from m_molNumSpecies_old
|
||||||
* This routine uploads the state of the system into all of the
|
* - VCS_STATECALC_NEW -> from m_molNumSpecies_new
|
||||||
* VolumePhase objects in the current problem.
|
*
|
||||||
* place
|
*/
|
||||||
* 0 -> from m_molNumSpecies_old
|
void VCS_SOLVE::vcs_updateVP(const int vcsState) {
|
||||||
* 1 -> from wt
|
|
||||||
*************************************************************************/
|
|
||||||
{
|
|
||||||
vcs_VolPhase *Vphase;
|
vcs_VolPhase *Vphase;
|
||||||
for (int i = 0; i < m_numPhases; i++) {
|
for (int i = 0; i < m_numPhases; i++) {
|
||||||
Vphase = VPhaseList[i];
|
Vphase = VPhaseList[i];
|
||||||
if (place == 0) {
|
if (vcsState == VCS_STATECALC_OLD) {
|
||||||
Vphase->setMolesFromVCSCheck(VCS_DATA_PTR(m_molNumSpecies_old),
|
Vphase->setMolesFromVCSCheck(VCS_DATA_PTR(m_molNumSpecies_old),
|
||||||
VCS_DATA_PTR(m_tPhaseMoles_old), i);
|
VCS_DATA_PTR(m_tPhaseMoles_old), i);
|
||||||
} else if (place == 1) {
|
} else if (vcsState == VCS_STATECALC_NEW) {
|
||||||
Vphase->setMolesFromVCSCheck(VCS_DATA_PTR(m_molNumSpecies_new),
|
Vphase->setMolesFromVCSCheck(VCS_DATA_PTR(m_molNumSpecies_new),
|
||||||
VCS_DATA_PTR(m_tPhaseMoles_new), i);
|
VCS_DATA_PTR(m_tPhaseMoles_new), i);
|
||||||
} else {
|
}
|
||||||
plogf("we shouldn't be here\n");
|
#ifdef DEBUG_MODE
|
||||||
|
else {
|
||||||
|
plogf("we shouldn't be here");
|
||||||
|
plogendl();
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4659,8 +4681,8 @@ namespace VCSnonideal {
|
||||||
SWAP(SpecLnMnaught[k1], SpecLnMnaught[k2], t1);
|
SWAP(SpecLnMnaught[k1], SpecLnMnaught[k2], t1);
|
||||||
SWAP(ActCoeff[k1], ActCoeff[k2], t1);
|
SWAP(ActCoeff[k1], ActCoeff[k2], t1);
|
||||||
SWAP(ActCoeff0[k1], ActCoeff0[k2], t1);
|
SWAP(ActCoeff0[k1], ActCoeff0[k2], t1);
|
||||||
SWAP(WtSpecies[k1], WtSpecies[k2], t1);
|
SWAP(m_wtSpecies[k1], m_wtSpecies[k2], t1);
|
||||||
SWAP(Charge[k1], Charge[k2], t1);
|
SWAP(m_chargeSpecies[k1], m_chargeSpecies[k2], t1);
|
||||||
SWAP(SpeciesThermo[k1], SpeciesThermo[k2], st_tmp);
|
SWAP(SpeciesThermo[k1], SpeciesThermo[k2], st_tmp);
|
||||||
SWAP(VolPM[k1], VolPM[k2], t1);
|
SWAP(VolPM[k1], VolPM[k2], t1);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue