Updates to the LatticeSolidPhase object.
This object is not ready for primetime.
This commit is contained in:
parent
fba698e890
commit
6e9d490dc1
4 changed files with 466 additions and 228 deletions
|
|
@ -1,7 +1,11 @@
|
|||
/**
|
||||
*
|
||||
* @file LatticeSolidPhase.cpp
|
||||
*
|
||||
* @file LatticeSolidPhase.h
|
||||
* Definitions for a simple thermodynamics model of a bulk solid phase
|
||||
* derived from %ThermoPhase,
|
||||
* assuming an ideal solution model based on a lattice of solid atoms
|
||||
* (see \ref thermoprops and class \link Cantera::LatticeSolidPhase LatticeSolidPhase\endlink).
|
||||
*/
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
|
@ -10,39 +14,53 @@
|
|||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#ifdef WITH_LATTICE_SOLID
|
||||
|
||||
#include "ct_defs.h"
|
||||
#ifdef WITH_LATTICE_SOLID
|
||||
|
||||
#include "mix_defs.h"
|
||||
#include "LatticeSolidPhase.h"
|
||||
#include "LatticePhase.h"
|
||||
#include "SpeciesThermo.h"
|
||||
#include "ThermoFactory.h"
|
||||
//#include "importCTML.h"
|
||||
|
||||
#include <string>
|
||||
using namespace std;
|
||||
|
||||
using namespace std;
|
||||
//======================================================================================================================
|
||||
namespace Cantera {
|
||||
|
||||
|
||||
//====================================================================================================================
|
||||
// Base empty constructor
|
||||
LatticeSolidPhase::LatticeSolidPhase() :
|
||||
m_tlast(0.0)
|
||||
m_mm(0),
|
||||
m_kk(0),
|
||||
m_tlast(0.0),
|
||||
m_press(-1.0),
|
||||
m_molar_density(0.0),
|
||||
m_nlattice(0),
|
||||
m_lattice(0),
|
||||
m_x(0)
|
||||
{
|
||||
}
|
||||
|
||||
//====================================================================================================================
|
||||
// Copy Constructor
|
||||
/*
|
||||
* @param right Object to be copied
|
||||
*/
|
||||
LatticeSolidPhase::LatticeSolidPhase(const LatticeSolidPhase &right) :
|
||||
m_tlast(0.0)
|
||||
m_mm(0),
|
||||
m_kk(0),
|
||||
m_tlast(0.0),
|
||||
m_press(-1.0),
|
||||
m_molar_density(0.0),
|
||||
m_nlattice(0),
|
||||
m_lattice(0),
|
||||
m_x(0)
|
||||
{
|
||||
*this = operator=(right);
|
||||
}
|
||||
|
||||
//====================================================================================================================
|
||||
// Assignment operator
|
||||
/*
|
||||
* @param right Object to be copied
|
||||
|
|
@ -51,21 +69,26 @@ namespace Cantera {
|
|||
LatticeSolidPhase::operator=(const LatticeSolidPhase& right) {
|
||||
if (&right != this) {
|
||||
ThermoPhase::operator=(right);
|
||||
m_mm = right.m_mm;
|
||||
m_kk = right.m_kk;
|
||||
m_tlast = right.m_tlast;
|
||||
m_press = right.m_press;
|
||||
m_mm = right.m_mm;
|
||||
m_kk = right.m_kk;
|
||||
m_tlast = right.m_tlast;
|
||||
m_press = right.m_press;
|
||||
m_molar_density = right.m_molar_density;
|
||||
m_nlattice = right.m_nlattice;
|
||||
m_x = right.m_x;
|
||||
m_nlattice = right.m_nlattice;
|
||||
deepStdVectorPointerCopy<LatticePhase>(right.m_lattice, m_lattice);
|
||||
m_x = right.m_x;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! Destructor
|
||||
//====================================================================================================================
|
||||
// Destructor
|
||||
LatticeSolidPhase::~LatticeSolidPhase() {
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
delete m_lattice[n];
|
||||
m_lattice[n] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//====================================================================================================================
|
||||
// Duplication function
|
||||
/*
|
||||
* This virtual function is used to create a duplicate of the
|
||||
|
|
@ -78,7 +101,7 @@ namespace Cantera {
|
|||
LatticeSolidPhase *igp = new LatticeSolidPhase(*this);
|
||||
return (ThermoPhase *) igp;
|
||||
}
|
||||
|
||||
//====================================================================================================================
|
||||
doublereal LatticeSolidPhase::
|
||||
enthalpy_mole() const {
|
||||
_updateThermo();
|
||||
|
|
@ -90,200 +113,249 @@ namespace Cantera {
|
|||
}
|
||||
return sum/molarDensity();
|
||||
}
|
||||
|
||||
doublereal LatticeSolidPhase::intEnergy_mole() const {
|
||||
_updateThermo();
|
||||
doublereal ndens, sum = 0.0;
|
||||
int n;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->intEnergy_mole();
|
||||
}
|
||||
return sum/molarDensity();
|
||||
//====================================================================================================================
|
||||
doublereal LatticeSolidPhase::intEnergy_mole() const {
|
||||
_updateThermo();
|
||||
doublereal ndens, sum = 0.0;
|
||||
int n;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->intEnergy_mole();
|
||||
}
|
||||
|
||||
doublereal LatticeSolidPhase::entropy_mole() const {
|
||||
_updateThermo();
|
||||
doublereal ndens, sum = 0.0;
|
||||
int n;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->entropy_mole();
|
||||
}
|
||||
return sum/molarDensity();
|
||||
return sum/molarDensity();
|
||||
}
|
||||
//====================================================================================================================
|
||||
doublereal LatticeSolidPhase::entropy_mole() const {
|
||||
_updateThermo();
|
||||
doublereal ndens, sum = 0.0;
|
||||
int n;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->entropy_mole();
|
||||
}
|
||||
|
||||
doublereal LatticeSolidPhase::gibbs_mole() const {
|
||||
_updateThermo();
|
||||
doublereal ndens, sum = 0.0;
|
||||
int n;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->gibbs_mole();
|
||||
}
|
||||
return sum/molarDensity();
|
||||
return sum/molarDensity();
|
||||
}
|
||||
//====================================================================================================================
|
||||
doublereal LatticeSolidPhase::gibbs_mole() const {
|
||||
_updateThermo();
|
||||
doublereal ndens, sum = 0.0;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->gibbs_mole();
|
||||
}
|
||||
|
||||
doublereal LatticeSolidPhase::cp_mole() const {
|
||||
_updateThermo();
|
||||
doublereal ndens, sum = 0.0;
|
||||
int n;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->cp_mole();
|
||||
}
|
||||
return sum/molarDensity();
|
||||
return sum/molarDensity();
|
||||
}
|
||||
//====================================================================================================================
|
||||
doublereal LatticeSolidPhase::cp_mole() const {
|
||||
_updateThermo();
|
||||
doublereal sum = 0.0;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
doublereal ndens = m_lattice[n]->molarDensity();
|
||||
sum += ndens * m_lattice[n]->cp_mole();
|
||||
}
|
||||
|
||||
void LatticeSolidPhase::getActivityConcentrations(doublereal* c) const {
|
||||
_updateThermo();
|
||||
int n;
|
||||
int strt = 0;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
m_lattice[n]->getMoleFractions(c+strt);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
return sum/molarDensity();
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::getActivityConcentrations(doublereal* c) const {
|
||||
_updateThermo();
|
||||
int strt = 0;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
m_lattice[n]->getMoleFractions(c+strt);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::getActivityCoefficients(doublereal* ac) const {
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
ac[k] = 1.0;
|
||||
}
|
||||
}
|
||||
//====================================================================================================================
|
||||
doublereal LatticeSolidPhase::standardConcentration(int k) const {
|
||||
return 1.0;
|
||||
}
|
||||
//====================================================================================================================
|
||||
doublereal LatticeSolidPhase::logStandardConc(int k) const {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void LatticeSolidPhase::getActivityCoefficients(doublereal* ac) const {
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
ac[k] = 1.0;
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::setMoleFractions(const doublereal* x) {
|
||||
int nsp, strt = 0;
|
||||
doublereal sum = 0.0;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
nsp = m_lattice[n]->nSpecies();
|
||||
m_lattice[n]->setMoleFractions(x+strt);
|
||||
for (int k = 0; k < nsp; k++) {
|
||||
sum += x[strt + k];
|
||||
}
|
||||
strt += nsp;
|
||||
}
|
||||
for (int k = 0; k < strt; k++) {
|
||||
m_x[k] = x[k] / sum;
|
||||
}
|
||||
State::setMoleFractions(DATA_PTR(m_x));
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::getMoleFractions(doublereal* x) const {
|
||||
int nsp, strt = 0;
|
||||
State::getMoleFractions(x);
|
||||
doublereal sum;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
nsp = m_lattice[n]->nSpecies();
|
||||
sum = 0.0;
|
||||
for (int k = 0; k < nsp; k++) {
|
||||
sum += (x + strt)[k];
|
||||
}
|
||||
for (int k = 0; k < nsp; k++) {
|
||||
(x + strt)[k] /= sum;
|
||||
}
|
||||
/*
|
||||
* At this point we can check against the mole fraction vector of the underlying LatticePhase objects and
|
||||
* get the same answer.
|
||||
*/
|
||||
#ifdef DEBUG_MODE
|
||||
m_lattice[n]->getMoleFractions(&(m_x[strt]));
|
||||
for (int k = 0; k < nsp; k++) {
|
||||
if (fabs((x + strt)[k] - m_x[strt+k]) > 1.0E-14) {
|
||||
throw CanteraError("LatticeSolidPhase::getMoleFractions()",
|
||||
"internal error");
|
||||
}
|
||||
}
|
||||
|
||||
doublereal LatticeSolidPhase::standardConcentration(int k) const {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
doublereal LatticeSolidPhase::logStandardConc(int k) const {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
void LatticeSolidPhase::getChemPotentials(doublereal* mu) const {
|
||||
_updateThermo();
|
||||
int n;
|
||||
int strt = 0;
|
||||
double dratio;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
dratio = m_lattice[n]->molarDensity()/molarDensity();
|
||||
m_lattice[n]->getChemPotentials(mu+strt);
|
||||
scale(mu + strt, mu + strt + m_lattice[n]->nSpecies(), mu + strt, dratio);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
}
|
||||
|
||||
void LatticeSolidPhase::getStandardChemPotentials(doublereal* mu0) const {
|
||||
_updateThermo();
|
||||
int n;
|
||||
int strt = 0;
|
||||
double dratio;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
dratio = m_lattice[n]->molarDensity()/molarDensity();
|
||||
m_lattice[n]->getStandardChemPotentials(mu0+strt);
|
||||
scale(mu0 + strt, mu0 + strt + m_lattice[n]->nSpecies(), mu0 + strt, dratio);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
}
|
||||
|
||||
void LatticeSolidPhase::initThermo() {
|
||||
m_kk = nSpecies();
|
||||
m_mm = nElements();
|
||||
m_x.resize(m_kk);
|
||||
int n, nsp, k, loc = 0;
|
||||
doublereal ndens;
|
||||
m_molar_density = 0.0;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
nsp = m_lattice[n]->nSpecies();
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_x[loc] = ndens * m_lattice[n]->moleFraction(k);
|
||||
loc++;
|
||||
}
|
||||
m_molar_density += ndens;
|
||||
}
|
||||
setMoleFractions(DATA_PTR(m_x));
|
||||
|
||||
// const vector<string>& spnames = speciesNames();
|
||||
// int n, k, kl, namesize;
|
||||
// int nl = m_sitedens.size();
|
||||
// string s;
|
||||
// m_lattice.resize(m_kk,-1);
|
||||
// vector_fp conc(m_kk, 0.0);
|
||||
|
||||
// compositionMap xx;
|
||||
// for (n = 0; n < nl; n++) {
|
||||
// for (k = 0; k < m_kk; k++) {
|
||||
// xx[speciesName(k)] = -1.0;
|
||||
// }
|
||||
// parseCompString(m_sp[n], xx);
|
||||
// for (k = 0; k < m_kk; k++) {
|
||||
// if (xx[speciesName(k)] != -1.0) {
|
||||
// conc[k] = m_sitedens[n]*xx[speciesName(k)];
|
||||
// m_lattice[k] = n;
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
// for (k = 0; k < m_kk; k++) {
|
||||
// if (m_lattice[k] == -1) {
|
||||
// throw CanteraError("LatticeSolidPhase::"
|
||||
// "setParametersFromXML","Species "+speciesName(k)
|
||||
// +" not a member of any lattice.");
|
||||
// }
|
||||
// }
|
||||
// setMoleFractions(DATA_PTR(conc));
|
||||
}
|
||||
|
||||
|
||||
void LatticeSolidPhase::_updateThermo() const {
|
||||
doublereal tnow = temperature();
|
||||
// if (fabs(molarDensity() - m_molar_density)/m_molar_density > 0.0001) {
|
||||
// throw CanteraError("_updateThermo","molar density changed from "
|
||||
// +fp2str(m_molar_density)+" to "+fp2str(molarDensity()));
|
||||
//}
|
||||
if (m_tlast != tnow) {
|
||||
int n;
|
||||
getMoleFractions(DATA_PTR(m_x));
|
||||
int strt = 0;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
m_lattice[n]->setTemperature(tnow);
|
||||
m_lattice[n]->setMoleFractions(DATA_PTR(m_x) + strt);
|
||||
m_lattice[n]->setPressure(m_press);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
m_tlast = tnow;
|
||||
}
|
||||
}
|
||||
|
||||
void LatticeSolidPhase::setLatticeMoleFractions(int nn,
|
||||
string x) {
|
||||
m_lattice[nn]->setMoleFractionsByName(x);
|
||||
int n, k, loc=0, nsp;
|
||||
doublereal ndens;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
nsp = m_lattice[n]->nSpecies();
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_x[loc] = ndens * m_lattice[n]->moleFraction(k);
|
||||
loc++;
|
||||
}
|
||||
}
|
||||
setMoleFractions(DATA_PTR(m_x));
|
||||
}
|
||||
|
||||
void LatticeSolidPhase::setParametersFromXML(const XML_Node& eosdata) {
|
||||
eosdata._require("model","LatticeSolid");
|
||||
XML_Node& la = eosdata.child("LatticeArray");
|
||||
vector<XML_Node*> lattices;
|
||||
la.getChildren("phase",lattices);
|
||||
int n;
|
||||
int nl = lattices.size();
|
||||
m_nlattice = nl;
|
||||
for (n = 0; n < nl; n++) {
|
||||
XML_Node& i = *lattices[n];
|
||||
m_lattice.push_back((LatticePhase*)newPhase(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
strt += nsp;
|
||||
}
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::getChemPotentials(doublereal* mu) const {
|
||||
_updateThermo();
|
||||
int strt = 0;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
doublereal dratio = m_lattice[n]->molarDensity()/molarDensity();
|
||||
m_lattice[n]->getChemPotentials(mu+strt);
|
||||
scale(mu + strt, mu + strt + m_lattice[n]->nSpecies(), mu + strt, dratio);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::getStandardChemPotentials(doublereal* mu0) const {
|
||||
_updateThermo();
|
||||
int strt = 0;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
doublereal dratio = m_lattice[n]->molarDensity()/molarDensity();
|
||||
m_lattice[n]->getStandardChemPotentials(mu0+strt);
|
||||
scale(mu0 + strt, mu0 + strt + m_lattice[n]->nSpecies(), mu0 + strt, dratio);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::initThermo() {
|
||||
m_kk = nSpecies();
|
||||
m_mm = nElements();
|
||||
m_x.resize(m_kk);
|
||||
int nsp, k, loc = 0;
|
||||
doublereal ndens;
|
||||
m_molar_density = 0.0;
|
||||
for (int n = 0; n < m_nlattice; n++) {
|
||||
nsp = m_lattice[n]->nSpecies();
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_x[loc] = ndens * m_lattice[n]->moleFraction(k);
|
||||
loc++;
|
||||
}
|
||||
m_molar_density += ndens;
|
||||
}
|
||||
setMoleFractions(DATA_PTR(m_x));
|
||||
|
||||
// const vector<string>& spnames = speciesNames();
|
||||
// int n, k, kl, namesize;
|
||||
// int nl = m_sitedens.size();
|
||||
// string s;
|
||||
// m_lattice.resize(m_kk,-1);
|
||||
// vector_fp conc(m_kk, 0.0);
|
||||
|
||||
// compositionMap xx;
|
||||
// for (n = 0; n < nl; n++) {
|
||||
// for (k = 0; k < m_kk; k++) {
|
||||
// xx[speciesName(k)] = -1.0;
|
||||
// }
|
||||
// parseCompString(m_sp[n], xx);
|
||||
// for (k = 0; k < m_kk; k++) {
|
||||
// if (xx[speciesName(k)] != -1.0) {
|
||||
// conc[k] = m_sitedens[n]*xx[speciesName(k)];
|
||||
// m_lattice[k] = n;
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
// for (k = 0; k < m_kk; k++) {
|
||||
// if (m_lattice[k] == -1) {
|
||||
// throw CanteraError("LatticeSolidPhase::"
|
||||
// "setParametersFromXML","Species "+speciesName(k)
|
||||
// +" not a member of any lattice.");
|
||||
// }
|
||||
// }
|
||||
// setMoleFractions(DATA_PTR(conc));
|
||||
}
|
||||
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::_updateThermo() const {
|
||||
doublereal tnow = temperature();
|
||||
// if (fabs(molarDensity() - m_molar_density)/m_molar_density > 0.0001) {
|
||||
// throw CanteraError("_updateThermo","molar density changed from "
|
||||
// +fp2str(m_molar_density)+" to "+fp2str(molarDensity()));
|
||||
//}
|
||||
if (m_tlast != tnow) {
|
||||
int n;
|
||||
getMoleFractions(DATA_PTR(m_x));
|
||||
int strt = 0;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
m_lattice[n]->setTemperature(tnow);
|
||||
m_lattice[n]->setMoleFractions(DATA_PTR(m_x) + strt);
|
||||
m_lattice[n]->setPressure(m_press);
|
||||
strt += m_lattice[n]->nSpecies();
|
||||
}
|
||||
m_tlast = tnow;
|
||||
}
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::setLatticeMoleFractions(int nn, std::string x) {
|
||||
m_lattice[nn]->setMoleFractionsByName(x);
|
||||
int n, k, loc=0, nsp;
|
||||
doublereal ndens;
|
||||
for (n = 0; n < m_nlattice; n++) {
|
||||
nsp = m_lattice[n]->nSpecies();
|
||||
ndens = m_lattice[n]->molarDensity();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_x[loc] = ndens * m_lattice[n]->moleFraction(k);
|
||||
loc++;
|
||||
}
|
||||
}
|
||||
setMoleFractions(DATA_PTR(m_x));
|
||||
}
|
||||
//====================================================================================================================
|
||||
void LatticeSolidPhase::setParametersFromXML(const XML_Node& eosdata) {
|
||||
eosdata._require("model","LatticeSolid");
|
||||
XML_Node& la = eosdata.child("LatticeArray");
|
||||
std::vector<XML_Node*> lattices;
|
||||
la.getChildren("phase",lattices);
|
||||
int n;
|
||||
int nl = lattices.size();
|
||||
m_nlattice = nl;
|
||||
for (n = 0; n < nl; n++) {
|
||||
XML_Node& i = *lattices[n];
|
||||
m_lattice.push_back((LatticePhase*)newPhase(i));
|
||||
}
|
||||
}
|
||||
//====================================================================================================================
|
||||
|
||||
|
||||
doublereal LatticeSolidPhase::err(std::string msg) const {
|
||||
throw CanteraError("LatticeSolidPhase","Unimplemented " + msg);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
} // End namespace Cantera
|
||||
//======================================================================================================================
|
||||
#endif // End #define WITH_LATTICE_SOLID
|
||||
//======================================================================================================================
|
||||
|
|
|
|||
|
|
@ -27,19 +27,44 @@
|
|||
#include "mix_defs.h"
|
||||
#include "ThermoPhase.h"
|
||||
#include "SpeciesThermo.h"
|
||||
#include "LatticePhase.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
class LatticePhase;
|
||||
|
||||
//! Additive combination of lattice phases
|
||||
//! A phase that is comprised of an additive combination of other lattice phases
|
||||
/*!
|
||||
* This is the main way Cantera describes semiconductors and other solid phases.
|
||||
* This Thermophase object calculates its properties as a sum over other LatticePhase objects. Each of the %LatticePhase
|
||||
* objects is a ThermoPhase object by itself.
|
||||
*
|
||||
* The sum over the LatticePhase objects is carried out by weighting each LatticePhase object
|
||||
* value with the molarDensity of the LatticePhase. Then the resulting quantity is divided by
|
||||
* the molar density of the total compound. The LatticeSolidPhase object therefore only contains a
|
||||
* listing of the number of Lattice Phases
|
||||
* that comprises the solid and it contains a value for the molar density of the entire mixture.
|
||||
*
|
||||
* Let's take FeS2 as an example, which may be thought of as a combination of two lattices: Fe and S lattice.
|
||||
* The Fe sublattice has a molar density of 1 gmol cm-3. The S sublattice has a molar density of 2 gmol cm-3.
|
||||
* We then define the LatticeSolidPhase object as having a nominal composition of FeS2, and having a
|
||||
* molar density of 1 gmol cm-3. All quantities pertaining to the FeS2 compound will be have weights
|
||||
* associated with the sublattices. The Fe sublattice will have a weight of 1.0 associated with it. The
|
||||
* S sublattice will have a weight of 2.0 associated with it.
|
||||
*
|
||||
* Currently, the molar density is set to a constant.
|
||||
*
|
||||
* The results from this LatticeSolidPhase model reduces to the LatticePhase model when there is one
|
||||
* lattice phase and the molar densities of the sublattice and the molar density within the LatticeSolidPhase
|
||||
* have the same values.
|
||||
*
|
||||
* The mole fraction vector has been redefined within the LatticeSolidPhase object. The mole fractions sum
|
||||
* to one within each of the individual lattice phases. The routine getMoleFraction() and setMoleFraction()
|
||||
* have been redefined to use this convention.
|
||||
*
|
||||
*/
|
||||
class LatticeSolidPhase : public ThermoPhase {
|
||||
class LatticeSolidPhase : public ThermoPhase {
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -77,41 +102,166 @@ namespace Cantera {
|
|||
*/
|
||||
virtual int eosType() const { return cLatticeSolid; }
|
||||
|
||||
//! This method returns the convention used in specification
|
||||
//! of the standard state, of which there are currently two,
|
||||
//! temperature based, and variable pressure based.
|
||||
/*!
|
||||
* All of the thermo is determined by slave %ThermoPhase routines.
|
||||
*/
|
||||
virtual int standardStateConvention() const {
|
||||
return cSS_CONVENTION_SLAVE;
|
||||
}
|
||||
|
||||
//! Return the Molar Enthalpy. Units: J/kmol.
|
||||
/*!
|
||||
* For an ideal solution,
|
||||
* \f[
|
||||
* \hat h(T,P) = \sum_k X_k \hat h^0_k(T),
|
||||
* \f]
|
||||
* and is a function only of temperature.
|
||||
* The standard-state pure-species Enthalpies
|
||||
* \f$ \hat h^0_k(T) \f$ are computed by the species thermodynamic
|
||||
* property manager.
|
||||
* The molar enthalpy is determined by the following formula, where \f$ C_n \f$ is the
|
||||
* lattice molar density of the nth lattice, and \f$ C_T \f$ is the molar density
|
||||
* of the solid compound.
|
||||
*
|
||||
* \see SpeciesThermo
|
||||
* \f[
|
||||
* \tilde h(T,P) = \frac{\sum_n C_n \tilde h_n(T,P) }{C_T},
|
||||
* \f]
|
||||
*
|
||||
* \f$ \tilde h_n(T,P) \f$ is the enthalpy of the n<SUP>th</SUP> lattice.
|
||||
*
|
||||
* units J/kmol
|
||||
*/
|
||||
virtual doublereal enthalpy_mole() const;
|
||||
|
||||
|
||||
//! Return the Molar Internal Energy. Units: J/kmol.
|
||||
/*!
|
||||
* The molar internal energy is determined by the following formula, where \f$ C_n \f$ is the
|
||||
* lattice molar density of the nth lattice, and \f$ C_T \f$ is the molar density
|
||||
* of the solid compound.
|
||||
*
|
||||
* \f[
|
||||
* \tilde u(T,P) = \frac{\sum_n C_n \tilde u_n(T,P) }{C_T},
|
||||
* \f]
|
||||
*
|
||||
* \f$ \tilde u_n(T,P) \f$ is the internal energy of the n<SUP>th</SUP> lattice.
|
||||
*
|
||||
* units J/kmol
|
||||
*/
|
||||
virtual doublereal intEnergy_mole() const;
|
||||
|
||||
//! Return the Molar Entropy. Units: J/kmol/K.
|
||||
/*!
|
||||
* The molar entropy is determined by the following formula, where \f$ C_n \f$ is the
|
||||
* lattice molar density of the nth lattice, and \f$ C_T \f$ is the molar density
|
||||
* of the solid compound.
|
||||
*
|
||||
* \f[
|
||||
* \tilde s(T,P) = \frac{\sum_n C_n \tilde s_n(T,P) }{C_T},
|
||||
* \f]
|
||||
*
|
||||
* \f$ \tilde s_n(T,P) \f$ is the molar entropy of the n<SUP>th</SUP> lattice.
|
||||
*
|
||||
* units J/kmol/K
|
||||
*/
|
||||
virtual doublereal entropy_mole() const;
|
||||
|
||||
//! Return the Molar Enthalpy. Units: J/kmol.
|
||||
/*!
|
||||
* The molar enthalpy is determined by the following formula, where \f$ C_n \f$ is the
|
||||
* lattice molar density of the nth lattice, and \f$ C_T \f$ is the molar density
|
||||
* of the solid compound.
|
||||
*
|
||||
* \f[
|
||||
* \tilde h(T,P) = \frac{\sum_n C_n \tilde h_n(T,P) }{C_T},
|
||||
* \f]
|
||||
*
|
||||
* \f$ \tilde h_n(T,P) \f$ is the enthalpy of the n<SUP>th</SUP> lattice.
|
||||
*
|
||||
* units J/kmol
|
||||
*/
|
||||
virtual doublereal gibbs_mole() const;
|
||||
|
||||
//! Return the constant pressure heat capacity. Units: J/kmol/K
|
||||
/*!
|
||||
* The molar constant pressure heat capacity is determined by the following formula, where \f$ C_n \f$ is the
|
||||
* lattice molar density of the nth lattice, and \f$ C_T \f$ is the molar density
|
||||
* of the solid compound.
|
||||
*
|
||||
* \f[
|
||||
* \tilde c_{p,n}(T,P) = \frac{\sum_n C_n \tilde c_{p,n}(T,P) }{C_T},
|
||||
* \f]
|
||||
*
|
||||
* \f$ \tilde c_{p,n}(T,P) \f$ is the heat capacity of the n<SUP>th</SUP> lattice.
|
||||
*
|
||||
* units J/kmol/K
|
||||
*/
|
||||
virtual doublereal cp_mole() const;
|
||||
|
||||
//! Return the constant volume heat capacity. Units: J/kmol/K
|
||||
/*!
|
||||
* The molar constant volume heat capacity is determined by the following formula, where \f$ C_n \f$ is the
|
||||
* lattice molar density of the nth lattice, and \f$ C_T \f$ is the molar density
|
||||
* of the solid compound.
|
||||
*
|
||||
* \f[
|
||||
* \tilde c_{v,n}(T,P) = \frac{\sum_n C_n \tilde c_{v,n}(T,P) }{C_T},
|
||||
* \f]
|
||||
*
|
||||
* \f$ \tilde c_{v,n}(T,P) \f$ is the heat capacity of the n<SUP>th</SUP> lattice.
|
||||
*
|
||||
* units J/kmol/K
|
||||
*/
|
||||
virtual doublereal cv_mole() const {
|
||||
return cp_mole();
|
||||
}
|
||||
|
||||
//! Report the Pressure. Units: Pa.
|
||||
/*!
|
||||
* This method simply returns the storred pressure value.
|
||||
*/
|
||||
virtual doublereal pressure() const {
|
||||
return m_press;
|
||||
}
|
||||
|
||||
//! Set the pressure at constant temperature. Units: Pa.
|
||||
/*!
|
||||
*
|
||||
* @param p Pressure (units - Pa)
|
||||
*/
|
||||
virtual void setPressure(doublereal p) {
|
||||
m_press = p;
|
||||
setMolarDensity(m_molar_density);
|
||||
}
|
||||
virtual void setMoleFractions(const doublereal *x);
|
||||
virtual void getMoleFractions(doublereal *x) const;
|
||||
|
||||
doublereal moleFraction(const int k) const {
|
||||
return err("not implemented");
|
||||
}
|
||||
|
||||
|
||||
void getMassFractions(doublereal* const y) const {
|
||||
err("not implemented");
|
||||
}
|
||||
doublereal massFraction(const int k) const {
|
||||
return err("not implemented");
|
||||
}
|
||||
|
||||
virtual void setMassFractions(const doublereal *y) {
|
||||
err("not implemented");
|
||||
}
|
||||
virtual void setMassFractions_NoNorm(const doublereal* const y) {
|
||||
err("not implemented");
|
||||
}
|
||||
|
||||
void getConcentrations(doublereal* const c) const {
|
||||
err("not implemented");
|
||||
}
|
||||
|
||||
doublereal concentration(int k) const {
|
||||
return err("not implemented");
|
||||
}
|
||||
|
||||
virtual void setConcentrations(const doublereal* const conc) {
|
||||
err("not implemented");
|
||||
}
|
||||
|
||||
|
||||
virtual void getActivityConcentrations(doublereal* c) const;
|
||||
|
||||
|
|
@ -145,6 +295,15 @@ namespace Cantera {
|
|||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
//! error routine
|
||||
/*!
|
||||
* @param msg Message
|
||||
*
|
||||
* @return nothing
|
||||
*/
|
||||
doublereal err(std::string msg) const;
|
||||
|
||||
protected:
|
||||
|
||||
int m_mm;
|
||||
|
|
@ -164,5 +323,6 @@ namespace Cantera {
|
|||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // #ifdef WITH_LATTICE_SOLID
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ namespace Cantera {
|
|||
|
||||
// Perform any required subclass-specific initialization
|
||||
// that requires the XML phase object
|
||||
string id = "";
|
||||
std::string id = "";
|
||||
th->initThermoXML(phase, id);
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -37,9 +37,11 @@ namespace Cantera {
|
|||
*/
|
||||
//@{
|
||||
//! Standard state uses the molar convention
|
||||
const int cSS_CONVENTION_TEMPERATURE = 0;
|
||||
const int cSS_CONVENTION_TEMPERATURE = 0;
|
||||
//! Standard state uses the molality convention
|
||||
const int cSS_CONVENTION_VPSS = 1;
|
||||
const int cSS_CONVENTION_VPSS = 1;
|
||||
//! Standard state thermodynamics is obtained from slave %ThermoPhase objects
|
||||
const int cSS_CONVENTION_SLAVE = 2;
|
||||
//@}
|
||||
|
||||
|
||||
|
|
@ -1085,6 +1087,10 @@ namespace Cantera {
|
|||
*
|
||||
* - Variable Pressure and Temperature -based activities
|
||||
* cSS_CONVENTION_VPSS 1
|
||||
*
|
||||
* - Thermodynamics is set via slave ThermoPhase objects with
|
||||
* nothing being carried out at this %ThermoPhase object level
|
||||
* cSS_CONVENTION_SLAVE 2
|
||||
*/
|
||||
virtual int standardStateConvention() const;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue