*** empty log message ***
This commit is contained in:
parent
916c065a9f
commit
76526a6aa3
41 changed files with 2086 additions and 163 deletions
|
|
@ -728,6 +728,10 @@ extern "C" {
|
||||||
catch (CanteraError) { return -1; }
|
catch (CanteraError) { return -1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int DLL_EXPORT trans_setParameters(int n, int type, int k, double* d) {
|
||||||
|
try { trans(n)->setParameters(type, k, d); return 0;}
|
||||||
|
catch (CanteraError) { return -1; }
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------- Functions ---------------------------
|
//-------------------- Functions ---------------------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,7 @@ extern "C" {
|
||||||
int DLL_IMPORT trans_getMixDiffCoeffs(int n, int ld, double* d);
|
int DLL_IMPORT trans_getMixDiffCoeffs(int n, int ld, double* d);
|
||||||
int DLL_IMPORT trans_getBinDiffCoeffs(int n, int ld, double* d);
|
int DLL_IMPORT trans_getBinDiffCoeffs(int n, int ld, double* d);
|
||||||
int DLL_IMPORT trans_getMultiDiffCoeffs(int n, int ld, double* d);
|
int DLL_IMPORT trans_getMultiDiffCoeffs(int n, int ld, double* d);
|
||||||
|
int DLL_IMPORT trans_setParameters(int n, int type, int k, double* d);
|
||||||
|
|
||||||
int DLL_IMPORT import_phase(int nth, int nxml, char* id);
|
int DLL_IMPORT import_phase(int nth, int nxml, char* id);
|
||||||
int DLL_IMPORT import_kinetics(int nxml, char* id,
|
int DLL_IMPORT import_kinetics(int nxml, char* id,
|
||||||
|
|
|
||||||
5
Cantera/matlab/cantera/@Transport/setParameters.m
Normal file
5
Cantera/matlab/cantera/@Transport/setParameters.m
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
function setParameters(tr, type, k, p)
|
||||||
|
% SETPARAMETERS - set parameters.
|
||||||
|
%
|
||||||
|
v = trans_get(tr.id, 31, type, k, p);
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
function setThermalConductivity(tr, lam)
|
||||||
|
% SETTHERMALCONDUCTIVITY - Set the thermal conductivity.
|
||||||
|
%
|
||||||
|
% This method can only be used with transport models that
|
||||||
|
% support directly setting the value of the thermal
|
||||||
|
% conductivity.
|
||||||
|
%
|
||||||
|
setParameters(tr, 1, 0, lam);
|
||||||
|
|
||||||
|
|
@ -10,8 +10,8 @@ t0 = cputime; % record the starting time
|
||||||
% parameter values
|
% parameter values
|
||||||
p = oneatm; % pressure
|
p = oneatm; % pressure
|
||||||
tin = 300.0; % inlet temperature
|
tin = 300.0; % inlet temperature
|
||||||
mdot_o = 0.24; % air, kg/m^2/s
|
mdot_o = 0.72; % air, kg/m^2/s
|
||||||
mdot_f = 0.08; % fuel, kg/m^2/s
|
mdot_f = 0.24; % fuel, kg/m^2/s
|
||||||
|
|
||||||
rxnmech = 'gri30.xml'; % reaction mechanism file
|
rxnmech = 'gri30.xml'; % reaction mechanism file
|
||||||
transport = 'Mix'; % transport model
|
transport = 'Mix'; % transport model
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ void reportError();
|
||||||
mexErrMsgTxt("unknown Transport method");
|
mexErrMsgTxt("unknown Transport method");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (job < 30) {
|
else if (job < 30) {
|
||||||
nsp = getInt(prhs[3]);
|
nsp = getInt(prhs[3]);
|
||||||
plhs[0] = mxCreateNumericMatrix(nsp,nsp,mxDOUBLE_CLASS,mxREAL);
|
plhs[0] = mxCreateNumericMatrix(nsp,nsp,mxDOUBLE_CLASS,mxREAL);
|
||||||
|
|
@ -80,6 +81,25 @@ void reportError();
|
||||||
mexErrMsgTxt("unknown Transport method");
|
mexErrMsgTxt("unknown Transport method");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set parameters
|
||||||
|
else if (job < 40) {
|
||||||
|
double* params;
|
||||||
|
int typ, k;
|
||||||
|
switch (job) {
|
||||||
|
case 31:
|
||||||
|
typ = getInt(prhs[3]);
|
||||||
|
k = getInt(prhs[4]);
|
||||||
|
params = mxGetPr(prhs[5]);
|
||||||
|
iok = trans_setParameters(n, typ, k, params);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mexErrMsgTxt("unknown Transport method");
|
||||||
|
}
|
||||||
|
plhs[0] = mxCreateNumericMatrix(1,1,mxDOUBLE_CLASS,mxREAL);
|
||||||
|
h = mxGetPr(plhs[0]);
|
||||||
|
*h = double(iok);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
mexErrMsgTxt("unknown Transport method");
|
mexErrMsgTxt("unknown Transport method");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -404,7 +404,6 @@ class OneDim:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.setNewtonOptions(max_jac_age = self._opt['ts_jac_age'])
|
self.setNewtonOptions(max_jac_age = self._opt['ts_jac_age'])
|
||||||
print 'max jac age = ',self._opt['ts_jac_age']
|
|
||||||
|
|
||||||
if loglevel > 0:
|
if loglevel > 0:
|
||||||
print_heading('Begin time integration.\n\n')
|
print_heading('Begin time integration.\n\n')
|
||||||
|
|
|
||||||
34
Cantera/python/Cantera/SolidTransport.py
Normal file
34
Cantera/python/Cantera/SolidTransport.py
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
"""
|
||||||
|
Transport properties for solids.
|
||||||
|
|
||||||
|
This class implements a simple model for the diffusion coefficients and
|
||||||
|
the thermal conductivity of a solid. The diffusion coefficients have
|
||||||
|
modified Arrhenius form, and the thermal conductivity is constant.
|
||||||
|
All parameters are user-specified, not computed from a physical model.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
>>> tr = SolidTransport(solid_phase)
|
||||||
|
>>> tr.setThermalConductivity(0.5) # W/m/K
|
||||||
|
>>> tr.setDiffCoeff(species = "OxygenIon", A = 2.0, n = 0.0, E = 700.0)
|
||||||
|
|
||||||
|
Note that the diffusion coefficient is computed from D = A * T^n *
|
||||||
|
exp(-E/t) in m^2/s. Diffusion coefficients for unspecified species are
|
||||||
|
set to zero.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
from Cantera.Transport import Transport
|
||||||
|
|
||||||
|
class SolidTransport(Transport):
|
||||||
|
def __init__(self, phase = None):
|
||||||
|
Transport.__init__(self, model = "Solid", phase = phase)
|
||||||
|
|
||||||
|
def setThermalConductivity(self, lamb):
|
||||||
|
self.setParameters(1, 0, [lamb, 0.0])
|
||||||
|
|
||||||
|
def setDiffCoeff(self, species = "", A = 0.0, n = 0.0, E = 0.0):
|
||||||
|
k = self._phase.speciesIndex(species)
|
||||||
|
self.setParameters(0, k, [A, n, E])
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import _cantera
|
import _cantera
|
||||||
|
from Numeric import asarray
|
||||||
|
|
||||||
class Transport:
|
class Transport:
|
||||||
|
|
||||||
|
|
@ -80,5 +81,10 @@ class Transport:
|
||||||
|
|
||||||
def multiDiffCoeffs(self):
|
def multiDiffCoeffs(self):
|
||||||
return _cantera.tran_multiDiffCoeffs(self.__tr_id,
|
return _cantera.tran_multiDiffCoeffs(self.__tr_id,
|
||||||
self.trnsp)
|
self.trnsp)
|
||||||
|
|
||||||
|
def setParameters(self, type, k, params):
|
||||||
|
return _cantera.tran_setParameters(self.__tr_id,
|
||||||
|
type, k, asarray(params))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
46
Cantera/python/Cantera/solid.py
Normal file
46
Cantera/python/Cantera/solid.py
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
|
||||||
|
import string
|
||||||
|
import os
|
||||||
|
|
||||||
|
from constants import *
|
||||||
|
from ThermoPhase import ThermoPhase
|
||||||
|
from Kinetics import Kinetics
|
||||||
|
from SolidTransport import SolidTransport
|
||||||
|
import XML
|
||||||
|
import _cantera
|
||||||
|
|
||||||
|
class Solid(ThermoPhase, Kinetics, SolidTransport):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, src="", root=None):
|
||||||
|
|
||||||
|
self.ckin = 0
|
||||||
|
self._owner = 0
|
||||||
|
self.verbose = 1
|
||||||
|
|
||||||
|
# get the 'phase' element
|
||||||
|
s = XML.find_XML(src=src, root=root, name="phase")
|
||||||
|
|
||||||
|
# get the equation of state model
|
||||||
|
ThermoPhase.__init__(self, xml_phase=s)
|
||||||
|
|
||||||
|
# get the kinetics model
|
||||||
|
Kinetics.__init__(self, xml_phase=s, phases=[self])
|
||||||
|
|
||||||
|
SolidTransport.__init__(self, phase=self)
|
||||||
|
|
||||||
|
#self.setState_TP(300.0, OneAtm)
|
||||||
|
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return _cantera.phase_report(self._phase_id, self.verbose)
|
||||||
|
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
SolidTransport.__del__(self)
|
||||||
|
Kinetics.__del__(self)
|
||||||
|
ThermoPhase.__del__(self)
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from solution import Solution
|
from solution import Solution
|
||||||
|
|
||||||
def Solid(import_file="", id="",
|
def Solid(src="",
|
||||||
kmodel=1, transport=None):
|
kmodel=1, transport=None):
|
||||||
return Solution(import_file=import_file,
|
return Solution(import_file=import_file,
|
||||||
thermo_db="",
|
thermo_db="",
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,21 @@ py_transport_delete(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
py_setParameters(PyObject *self, PyObject *args) {
|
||||||
|
int n, k, typ;
|
||||||
|
PyObject* parray;
|
||||||
|
if (!PyArg_ParseTuple(args, "iiiO:py_setParameters",
|
||||||
|
&n, &typ, &k, &parray)) return NULL;
|
||||||
|
|
||||||
|
PyArrayObject* a = (PyArrayObject*)parray;
|
||||||
|
double* xd = (double*)a->data;
|
||||||
|
int ok = trans_setParameters(n, typ, k, xd);
|
||||||
|
if (ok < 0) return reportError(ok);
|
||||||
|
return Py_BuildValue("i",ok);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyObject*
|
static PyObject*
|
||||||
py_viscosity(PyObject *self, PyObject *args) {
|
py_viscosity(PyObject *self, PyObject *args) {
|
||||||
int n;
|
int n;
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ static PyMethodDef ct_methods[] = {
|
||||||
{"tran_binaryDiffCoeffs", py_binaryDiffCoeffs, METH_VARARGS},
|
{"tran_binaryDiffCoeffs", py_binaryDiffCoeffs, METH_VARARGS},
|
||||||
{"tran_mixDiffCoeffs", py_mixDiffCoeffs, METH_VARARGS},
|
{"tran_mixDiffCoeffs", py_mixDiffCoeffs, METH_VARARGS},
|
||||||
{"tran_multiDiffCoeffs", py_multiDiffCoeffs, METH_VARARGS},
|
{"tran_multiDiffCoeffs", py_multiDiffCoeffs, METH_VARARGS},
|
||||||
|
{"tran_setParameters", py_setParameters, METH_VARARGS},
|
||||||
|
|
||||||
{"get_Cantera_Error", ct_get_cantera_error, METH_VARARGS},
|
{"get_Cantera_Error", ct_get_cantera_error, METH_VARARGS},
|
||||||
{"ct_print", ct_print, METH_VARARGS},
|
{"ct_print", ct_print, METH_VARARGS},
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,12 @@
|
||||||
|
|
||||||
namespace Cantera {
|
namespace Cantera {
|
||||||
|
|
||||||
ImplicitSurfChem::ImplicitSurfChem(SurfKinetics& kin)
|
ImplicitSurfChem::ImplicitSurfChem(InterfaceKinetics& kin)
|
||||||
: FuncEval(), m_kin(&kin), m_integ(0),
|
: FuncEval(), m_kin(&kin), m_integ(0),
|
||||||
m_atol(1.e-15), m_rtol(1.e-7), m_maxstep(0.0)
|
m_atol(1.e-14), m_rtol(1.e-7), m_maxstep(0.0)
|
||||||
{
|
{
|
||||||
m_integ = new CVodeInt;
|
m_integ = new CVodeInt;
|
||||||
m_surf = &kin.sphase();
|
m_surf = (SurfPhase*)&kin.thermo(kin.nPhases()-1);
|
||||||
|
|
||||||
// use backward differencing, with a full Jacobian computed
|
// use backward differencing, with a full Jacobian computed
|
||||||
// numerically, and use a Newton linear iterator
|
// numerically, and use a Newton linear iterator
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Cantera {
|
||||||
m_integ->setProblemType(DENSE + NOJAC);
|
m_integ->setProblemType(DENSE + NOJAC);
|
||||||
m_integ->setIterator(Newton_Iter);
|
m_integ->setIterator(Newton_Iter);
|
||||||
m_nsp = m_surf->nSpecies();
|
m_nsp = m_surf->nSpecies();
|
||||||
m_work.resize(m_kin->nTotal());
|
m_work.resize(m_kin->nTotalSpecies());
|
||||||
}
|
}
|
||||||
|
|
||||||
// overloaded method of FuncEval. Called by the integrator to
|
// overloaded method of FuncEval. Called by the integrator to
|
||||||
|
|
@ -69,11 +69,14 @@ namespace Cantera {
|
||||||
doublereal rs0 = 1.0/m_surf->siteDensity();
|
doublereal rs0 = 1.0/m_surf->siteDensity();
|
||||||
m_kin->getNetProductionRates(m_work.begin());
|
m_kin->getNetProductionRates(m_work.begin());
|
||||||
int k;
|
int k;
|
||||||
int kbulk = m_kin->nTotal() - m_nsp;
|
int kbulk = m_kin->nTotalSpecies() - m_nsp;
|
||||||
doublereal sum = 0.0;
|
doublereal sum = 0.0;
|
||||||
for (k = 0; k < m_nsp; k++) {
|
for (k = 1; k < m_nsp; k++) {
|
||||||
ydot[k] = m_work[kbulk + k] * rs0 * m_surf->size(k);
|
ydot[k] = m_work[kbulk + k] * rs0 * m_surf->size(k);
|
||||||
|
sum -= ydot[k];
|
||||||
}
|
}
|
||||||
|
//if (sum < 0.0) sum = 0.0;
|
||||||
|
ydot[0] = sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@
|
||||||
|
|
||||||
#include "FuncEval.h"
|
#include "FuncEval.h"
|
||||||
#include "CVode.h"
|
#include "CVode.h"
|
||||||
#include "surfKinetics.h"
|
#include "InterfaceKinetics.h"
|
||||||
|
#include "SurfPhase.h"
|
||||||
|
|
||||||
namespace Cantera {
|
namespace Cantera {
|
||||||
|
|
||||||
|
|
@ -37,7 +38,7 @@ namespace Cantera {
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
ImplicitSurfChem(SurfKinetics& kin);
|
ImplicitSurfChem(InterfaceKinetics& kin);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -90,8 +91,8 @@ namespace Cantera {
|
||||||
*/
|
*/
|
||||||
void updateState(doublereal* y);
|
void updateState(doublereal* y);
|
||||||
|
|
||||||
SurfacePhase* m_surf;
|
SurfPhase* m_surf;
|
||||||
SurfKinetics* m_kin;
|
InterfaceKinetics* m_kin;
|
||||||
int m_nsp;
|
int m_nsp;
|
||||||
Integrator* m_integ; // pointer to integrator
|
Integrator* m_integ; // pointer to integrator
|
||||||
doublereal m_atol, m_rtol; // tolerances
|
doublereal m_atol, m_rtol; // tolerances
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ namespace Cantera {
|
||||||
void SurfPhase::
|
void SurfPhase::
|
||||||
setElectricPotential(doublereal V) {
|
setElectricPotential(doublereal V) {
|
||||||
for (int k = 0; k < m_kk; k++) {
|
for (int k = 0; k < m_kk; k++) {
|
||||||
m_pe[k] = charge(k)*Faraday;
|
m_pe[k] = charge(k)*Faraday*V;
|
||||||
}
|
}
|
||||||
_updateThermo(true);
|
_updateThermo(true);
|
||||||
}
|
}
|
||||||
|
|
@ -125,7 +125,7 @@ namespace Cantera {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfPhase::
|
void SurfPhase::
|
||||||
getCoverages(doublereal* theta) {
|
getCoverages(doublereal* theta) const {
|
||||||
getConcentrations(theta);
|
getConcentrations(theta);
|
||||||
for (int k = 0; k < m_kk; k++) {
|
for (int k = 0; k < m_kk; k++) {
|
||||||
theta[k] *= size(k)/m_n0;
|
theta[k] *= size(k)/m_n0;
|
||||||
|
|
@ -147,7 +147,7 @@ namespace Cantera {
|
||||||
m_s0[k] *= GasConstant;
|
m_s0[k] *= GasConstant;
|
||||||
m_cp0[k] *= GasConstant;
|
m_cp0[k] *= GasConstant;
|
||||||
deltaE = m_pe[k];
|
deltaE = m_pe[k];
|
||||||
m_h0[k] += deltaE;
|
//m_h0[k] += deltaE;
|
||||||
m_mu0[k] = m_h0[k] - tnow*m_s0[k];
|
m_mu0[k] = m_h0[k] - tnow*m_s0[k];
|
||||||
}
|
}
|
||||||
m_tlast = tnow;
|
m_tlast = tnow;
|
||||||
|
|
@ -166,6 +166,7 @@ namespace Cantera {
|
||||||
InterfaceKinetics(thermo_t* thermo) :
|
InterfaceKinetics(thermo_t* thermo) :
|
||||||
Kinetics(thermo),
|
Kinetics(thermo),
|
||||||
m_kk(0),
|
m_kk(0),
|
||||||
|
m_redo_rates(false),
|
||||||
m_nirrev(0),
|
m_nirrev(0),
|
||||||
m_nrev(0),
|
m_nrev(0),
|
||||||
m_finalized(false)
|
m_finalized(false)
|
||||||
|
|
@ -177,12 +178,14 @@ namespace Cantera {
|
||||||
void InterfaceKinetics::
|
void InterfaceKinetics::
|
||||||
_update_rates_T() {
|
_update_rates_T() {
|
||||||
doublereal T = thermo().temperature();
|
doublereal T = thermo().temperature();
|
||||||
if (T != m_kdata->m_temp) {
|
if (T != m_kdata->m_temp || m_redo_rates) {
|
||||||
doublereal logT = log(T);
|
doublereal logT = log(T);
|
||||||
m_rates.update(T, logT, m_kdata->m_rfn.begin());
|
m_rates.update(T, logT, m_kdata->m_rfn.begin());
|
||||||
|
correctElectronTransferRates(m_kdata->m_rfn.begin());
|
||||||
m_kdata->m_temp = T;
|
m_kdata->m_temp = T;
|
||||||
updateKc();
|
updateKc();
|
||||||
m_kdata->m_ROP_ok = false;
|
m_kdata->m_ROP_ok = false;
|
||||||
|
m_redo_rates = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -212,10 +215,14 @@ namespace Cantera {
|
||||||
doublereal rrt = 1.0/rt;
|
doublereal rrt = 1.0/rt;
|
||||||
int np = nPhases();
|
int np = nPhases();
|
||||||
for (n = 0; n < np; n++) {
|
for (n = 0; n < np; n++) {
|
||||||
|
// cout << n << "start = " << m_start[n] << endl;
|
||||||
thermo(n).getStandardChemPotentials(m_mu0.begin() + m_start[n]);
|
thermo(n).getStandardChemPotentials(m_mu0.begin() + m_start[n]);
|
||||||
nsp = thermo(n).nSpecies();
|
nsp = thermo(n).nSpecies();
|
||||||
for (k = 0; k < nsp; k++) {
|
for (k = 0; k < nsp; k++) {
|
||||||
|
//cout << ik << "mu0 = " << m_mu0[ik] << endl;
|
||||||
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
||||||
|
m_mu0[ik] += Faraday * m_phi[n] * thermo(n).charge(k);
|
||||||
|
//cout << ik << "mu0 = " << m_mu0[ik] << endl;
|
||||||
ik++;
|
ik++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -228,7 +235,9 @@ namespace Cantera {
|
||||||
|
|
||||||
for (i = 0; i < m_nrev; i++) {
|
for (i = 0; i < m_nrev; i++) {
|
||||||
irxn = m_revindex[i];
|
irxn = m_revindex[i];
|
||||||
|
//cout << "rev " << irxn << " " << m_rkc[irxn] << endl;
|
||||||
m_rkc[irxn] = exp(m_rkc[irxn]*rrt);
|
m_rkc[irxn] = exp(m_rkc[irxn]*rrt);
|
||||||
|
//cout << "rev " << irxn << " " << m_rkc[irxn] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = 0; i != m_nirrev; ++i) {
|
for(i = 0; i != m_nirrev; ++i) {
|
||||||
|
|
@ -251,7 +260,14 @@ namespace Cantera {
|
||||||
thermo(n).getStandardChemPotentials(m_mu0.begin() + m_start[n]);
|
thermo(n).getStandardChemPotentials(m_mu0.begin() + m_start[n]);
|
||||||
nsp = thermo(n).nSpecies();
|
nsp = thermo(n).nSpecies();
|
||||||
for (k = 0; k < nsp; k++) {
|
for (k = 0; k < nsp; k++) {
|
||||||
|
//cout << thermo(n).id() << " " << thermo(n).speciesName(k)
|
||||||
|
// << " " << m_mu0[ik] << endl;
|
||||||
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
||||||
|
m_mu0[ik] += Faraday * m_phi[n] * thermo(n).charge(k);
|
||||||
|
//if (thermo(n).charge(k) != 0.0) {
|
||||||
|
// cout << thermo(n).id() << " " << thermo(n).speciesName(k)
|
||||||
|
// << " " << m_phi[n] << " " << thermo(n).charge(k) << endl;
|
||||||
|
//}
|
||||||
ik++;
|
ik++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -268,6 +284,41 @@ namespace Cantera {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the equilibrium constants of all reactions, whether
|
||||||
|
* reversible or not.
|
||||||
|
*/
|
||||||
|
void InterfaceKinetics::correctElectronTransferRates(doublereal* kf) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
int n, nsp, k, ik=0;
|
||||||
|
doublereal rt = GasConstant*thermo(0).temperature();
|
||||||
|
doublereal rrt = 1.0/rt;
|
||||||
|
int np = nPhases();
|
||||||
|
for (n = 0; n < np; n++) {
|
||||||
|
nsp = thermo(n).nSpecies();
|
||||||
|
for (k = 0; k < nsp; k++) {
|
||||||
|
m_pot[ik] = Faraday*thermo(n).charge(k)*m_phi[n];
|
||||||
|
ik++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fill(m_rwork.begin(), m_rwork.begin() + m_ii, 0.0);
|
||||||
|
m_reactantStoich.decrementReactions(m_pot.begin(), m_rwork.begin());
|
||||||
|
m_revProductStoich.incrementReactions(m_pot.begin(), m_rwork.begin());
|
||||||
|
m_irrevProductStoich.incrementReactions(m_pot.begin(), m_rwork.begin());
|
||||||
|
doublereal eamod, ea;
|
||||||
|
for (i = 0; i < m_ii; i++) {
|
||||||
|
//loc = m_index[i].second;
|
||||||
|
//if (loc >= 0) {
|
||||||
|
// const Arrhenius& r = m_rates.rateCoeff(m_index[i].second);
|
||||||
|
// ea = GasConstant*r.activationEnergy_R();
|
||||||
|
eamod = 0.5*m_rwork[i];
|
||||||
|
if (m_index[i].second >= 0) kf[i] *= exp(-eamod*rrt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InterfaceKinetics::updateROP() {
|
void InterfaceKinetics::updateROP() {
|
||||||
|
|
||||||
_update_rates_T();
|
_update_rates_T();
|
||||||
|
|
@ -312,7 +363,6 @@ namespace Cantera {
|
||||||
m_kdata->m_ROP_ok = true;
|
m_kdata->m_ROP_ok = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void InterfaceKinetics::
|
void InterfaceKinetics::
|
||||||
addReaction(const ReactionData& r) {
|
addReaction(const ReactionData& r) {
|
||||||
|
|
||||||
|
|
@ -436,9 +486,12 @@ namespace Cantera {
|
||||||
m_prxn.resize(m_kk);
|
m_prxn.resize(m_kk);
|
||||||
m_conc.resize(m_kk);
|
m_conc.resize(m_kk);
|
||||||
m_mu0.resize(m_kk);
|
m_mu0.resize(m_kk);
|
||||||
|
m_pot.resize(m_kk, 0.0);
|
||||||
|
m_phi.resize(np,0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InterfaceKinetics::finalize() {
|
void InterfaceKinetics::finalize() {
|
||||||
|
m_rwork.resize(nReactions());
|
||||||
m_finalized = true;
|
m_finalized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,11 @@ namespace Cantera {
|
||||||
|
|
||||||
virtual int ID() { return cInterfaceKinetics; }
|
virtual int ID() { return cInterfaceKinetics; }
|
||||||
|
|
||||||
|
void setElectricPotential(int n, doublereal V) {
|
||||||
|
m_phi[n] = V;
|
||||||
|
m_redo_rates = true;
|
||||||
|
}
|
||||||
|
|
||||||
virtual doublereal reactantStoichCoeff(int k, int i) const {
|
virtual doublereal reactantStoichCoeff(int k, int i) const {
|
||||||
return m_rrxn[k][i];
|
return m_rrxn[k][i];
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +158,7 @@ namespace Cantera {
|
||||||
< m_revindex.end()) return true;
|
< m_revindex.end()) return true;
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
|
void correctElectronTransferRates(doublereal* kf);
|
||||||
void _update_rates_T();
|
void _update_rates_T();
|
||||||
void _update_rates_C();
|
void _update_rates_C();
|
||||||
|
|
||||||
|
|
@ -162,7 +167,8 @@ namespace Cantera {
|
||||||
int m_kk;
|
int m_kk;
|
||||||
|
|
||||||
Rate1<Arrhenius> m_rates;
|
Rate1<Arrhenius> m_rates;
|
||||||
|
bool m_redo_rates;
|
||||||
|
|
||||||
mutable map<int, pair<int, int> > m_index;
|
mutable map<int, pair<int, int> > m_index;
|
||||||
|
|
||||||
vector<int> m_irrev;
|
vector<int> m_irrev;
|
||||||
|
|
@ -191,6 +197,9 @@ namespace Cantera {
|
||||||
|
|
||||||
vector_fp m_conc;
|
vector_fp m_conc;
|
||||||
vector_fp m_mu0;
|
vector_fp m_mu0;
|
||||||
|
vector_fp m_phi;
|
||||||
|
vector_fp m_pot;
|
||||||
|
vector_fp m_rwork;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,18 @@ namespace Cantera {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thermo_t& speciesPhase(string nm) {
|
||||||
|
int np = m_thermo.size();
|
||||||
|
int k;
|
||||||
|
string id;
|
||||||
|
for (int n = 0; n < np; n++) {
|
||||||
|
k = thermo(n).speciesIndex(nm);
|
||||||
|
if (k >= 0) return thermo(n);
|
||||||
|
}
|
||||||
|
throw CanteraError("speciesPhase", "unknown species "+nm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepare to add reactions.
|
* Prepare to add reactions.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -26,13 +26,13 @@ BASE = Elements.o Constituents.o stringUtils.o misc.o importCTML.o plots.o
|
||||||
xml.o Phase.o DenseMatrix.o ctml.o funcs.o ctvector.o phasereport.o
|
xml.o Phase.o DenseMatrix.o ctml.o funcs.o ctvector.o phasereport.o
|
||||||
|
|
||||||
# thermodynamic properties
|
# thermodynamic properties
|
||||||
THERMO = $(BASE) ThermoPhase.o IdealGasPhase.o ConstDensityThermo.o SpeciesThermoFactory.o ThermoFactory.o
|
THERMO = $(BASE) ThermoPhase.o IdealGasPhase.o ConstDensityThermo.o SolidCompound.o SpeciesThermoFactory.o ThermoFactory.o
|
||||||
|
|
||||||
# homogeneous kinetics
|
# homogeneous kinetics
|
||||||
KINETICS = GRI_30_Kinetics.o KineticsFactory.o GasKinetics.o FalloffFactory.o GasKineticsWriter.o $(THERMO)
|
KINETICS = GRI_30_Kinetics.o KineticsFactory.o GasKinetics.o FalloffFactory.o GasKineticsWriter.o $(THERMO)
|
||||||
|
|
||||||
# heterogeneous kinetics
|
# heterogeneous kinetics
|
||||||
HETEROKIN = InterfaceKinetics.o $(THERMO)
|
HETEROKIN = InterfaceKinetics.o ImplicitSurfChem.o $(THERMO)
|
||||||
|
|
||||||
# support for importing from Chemkin-compatible reaction mechanisms
|
# support for importing from Chemkin-compatible reaction mechanisms
|
||||||
CK = $(KINETICS)
|
CK = $(KINETICS)
|
||||||
|
|
|
||||||
84
Cantera/src/MetalPhase.h
Normal file
84
Cantera/src/MetalPhase.h
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @file MetalPhase.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Author$
|
||||||
|
* $Date$
|
||||||
|
* $Revision$
|
||||||
|
*
|
||||||
|
* Copyright 2003 California Institute of Technology
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CT_METALPHASE_H
|
||||||
|
#define CT_METALPHASE_H
|
||||||
|
|
||||||
|
//#include "ct_defs.h"
|
||||||
|
#include "mix_defs.h"
|
||||||
|
#include "ThermoPhase.h"
|
||||||
|
#include "SpeciesThermo.h"
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup thermoprops
|
||||||
|
*
|
||||||
|
* Class MetalPhase represents electrons in a metal.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class MetalPhase : public ThermoPhase {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
MetalPhase() {}
|
||||||
|
|
||||||
|
virtual ~MetalPhase() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equation of state flag.
|
||||||
|
*/
|
||||||
|
virtual int eosType() const { return cMetal; }
|
||||||
|
|
||||||
|
virtual doublereal enthalpy_mole() const { return 0.0; }
|
||||||
|
virtual doublereal intEnergy_mole() const { return 0.0; }
|
||||||
|
virtual doublereal entropy_mole() const { return 0.0; }
|
||||||
|
virtual doublereal gibbs_mole() const { return 0.0; }
|
||||||
|
virtual doublereal cp_mole() const { return 0.0; }
|
||||||
|
virtual doublereal cv_mole() const { return 0.0; }
|
||||||
|
|
||||||
|
virtual void getChemPotentials(doublereal* mu) const {
|
||||||
|
mu[0] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void getStandardChemPotentials(doublereal* mu0) const {
|
||||||
|
mu0[0] = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void getActivityConcentrations(doublereal* c) const {
|
||||||
|
c[0] = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual doublereal standardConcentration(int k=0) const {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual doublereal logStandardConc(int k=0) const {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -78,6 +78,10 @@ namespace Cantera {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const R& rateCoeff(int loc) const {
|
||||||
|
return m_rates[loc];
|
||||||
|
}
|
||||||
|
|
||||||
void update_C(const doublereal* c) {
|
void update_C(const doublereal* c) {
|
||||||
TYPENAME_KEYWORD vector<R>::iterator b = m_rates.begin();
|
TYPENAME_KEYWORD vector<R>::iterator b = m_rates.begin();
|
||||||
TYPENAME_KEYWORD vector<R>::iterator e = m_rates.end();
|
TYPENAME_KEYWORD vector<R>::iterator e = m_rates.end();
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ namespace Cantera {
|
||||||
s << ");" << endl;
|
s << ");" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
doublereal activationEnergy_R() const {
|
||||||
|
return m_E;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
doublereal m_logA, m_b, m_E;
|
doublereal m_logA, m_b, m_E;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
50
Cantera/src/SolidCompound.cpp
Normal file
50
Cantera/src/SolidCompound.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @file IdealGasPhase.cpp
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning(disable:4786)
|
||||||
|
#pragma warning(disable:4503)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ct_defs.h"
|
||||||
|
#include "mix_defs.h"
|
||||||
|
#include "SolidCompound.h"
|
||||||
|
#include "SpeciesThermo.h"
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
void SolidCompound::initThermo() {
|
||||||
|
m_kk = nSpecies();
|
||||||
|
if (m_kk > 1) {
|
||||||
|
throw CanteraError("initThermo",
|
||||||
|
"solid compounds may only contain one species.");
|
||||||
|
}
|
||||||
|
doublereal tmin = m_spthermo->minTemp();
|
||||||
|
doublereal tmax = m_spthermo->maxTemp();
|
||||||
|
if (tmin > 0.0) m_tmin = tmin;
|
||||||
|
if (tmax > 0.0) m_tmax = tmax;
|
||||||
|
m_p0 = refPressure();
|
||||||
|
|
||||||
|
int leng = m_kk;
|
||||||
|
m_h0_RT.resize(leng);
|
||||||
|
m_cp0_R.resize(leng);
|
||||||
|
m_s0_R.resize(leng);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SolidCompound::_updateThermo() const {
|
||||||
|
doublereal tnow = temperature();
|
||||||
|
if (m_tlast != tnow) {
|
||||||
|
m_spthermo->update(tnow, m_cp0_R.begin(), m_h0_RT.begin(),
|
||||||
|
m_s0_R.begin());
|
||||||
|
m_tlast = tnow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
187
Cantera/src/SolidCompound.h
Normal file
187
Cantera/src/SolidCompound.h
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @file SolidPhase.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Author$
|
||||||
|
* $Date$
|
||||||
|
* $Revision$
|
||||||
|
*
|
||||||
|
* Copyright 2001 California Institute of Technology
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CT_SOLIDPHASE_H
|
||||||
|
#define CT_SOLIDPHASE_H
|
||||||
|
|
||||||
|
//#include "ct_defs.h"
|
||||||
|
#include "mix_defs.h"
|
||||||
|
#include "ThermoPhase.h"
|
||||||
|
#include "SpeciesThermo.h"
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup thermoprops
|
||||||
|
*
|
||||||
|
* Class IdealGasPhase represents low-density gases that obey the
|
||||||
|
* ideal gas equation of state. It derives from class ThermoPhase,
|
||||||
|
* and overloads the virtual methods defined there with ones that
|
||||||
|
* use expressions appropriate for ideal gas mixtures.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class SolidCompound : public ThermoPhase {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SolidCompound(): m_tlast(-1.0), m_tmin(0.0), m_tmax(0.0),
|
||||||
|
m_press(OneAtm), m_p0(OneAtm) {}
|
||||||
|
|
||||||
|
virtual ~SolidCompound() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equation of state flag. Returns the value cIdealGas, defined
|
||||||
|
* in mix_defs.h.
|
||||||
|
*/
|
||||||
|
virtual int eosType() const { return cSolidCompound; }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Molar Thermodynamic Properties
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Molar enthalpy. Units: J/kmol.
|
||||||
|
*/
|
||||||
|
virtual doublereal enthalpy_mole() const {
|
||||||
|
double hh = intEnergy_mole() + m_press / molarDensity();
|
||||||
|
return hh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Molar internal energy. J/kmol.
|
||||||
|
*/
|
||||||
|
virtual doublereal intEnergy_mole() const {
|
||||||
|
_updateThermo();
|
||||||
|
// cout << "intEnergy: " << m_h0_RT[0] << " " << m_p0/molarDensity()
|
||||||
|
// << endl;
|
||||||
|
return GasConstant * temperature() * m_h0_RT[0]
|
||||||
|
- m_p0 / molarDensity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Molar entropy. Units: J/kmol/K.
|
||||||
|
*/
|
||||||
|
virtual doublereal entropy_mole() const {
|
||||||
|
_updateThermo();
|
||||||
|
//cout << "s/r = " << m_s0_R[0] << endl;
|
||||||
|
return GasConstant * m_s0_R[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual doublereal gibbs_mole() const {
|
||||||
|
return enthalpy_mole() - temperature() * entropy_mole();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Molar heat capacity at constant pressure. Units: J/kmol/K.
|
||||||
|
*/
|
||||||
|
virtual doublereal cp_mole() const {
|
||||||
|
_updateThermo();
|
||||||
|
return GasConstant * m_cp0_R[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Molar heat capacity at constant volume. Units: J/kmol/K.
|
||||||
|
*/
|
||||||
|
virtual doublereal cv_mole() const {
|
||||||
|
return cp_mole();
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Mechanical Equation of State
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pressure. Units: Pa.
|
||||||
|
*/
|
||||||
|
virtual doublereal pressure() const {
|
||||||
|
return m_press;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the pressure at constant temperature. Units: Pa.
|
||||||
|
*/
|
||||||
|
virtual void setPressure(doublereal p) {
|
||||||
|
m_press = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void getChemPotentials(doublereal* mu) const {
|
||||||
|
mu[0] = gibbs_mole();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void getStandardChemPotentials(doublereal* mu0) const {
|
||||||
|
mu0[0] = gibbs_mole();
|
||||||
|
//cout << m_h0_RT[0] << " " << m_s0_R[0] << endl;
|
||||||
|
//cout << "std chem pot = " << mu0[0] << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the array of generalized
|
||||||
|
* concentrations. For a solid compound, there is only one
|
||||||
|
* species, and the generalized concentration is 1.0.
|
||||||
|
*/
|
||||||
|
virtual void getActivityConcentrations(doublereal* c) const {
|
||||||
|
c[0] = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The standard concentration. This is defined as the concentration
|
||||||
|
* by which the generalized concentration is normalized to produce
|
||||||
|
* the activity.
|
||||||
|
*/
|
||||||
|
virtual doublereal standardConcentration(int k=0) const {
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual doublereal logStandardConc(int k=0) const {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void initThermo();
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
int m_kk;
|
||||||
|
doublereal m_tmin, m_tmax, m_p0, m_press;
|
||||||
|
|
||||||
|
mutable doublereal m_tlast;
|
||||||
|
mutable array_fp m_h0_RT;
|
||||||
|
mutable array_fp m_cp0_R;
|
||||||
|
mutable array_fp m_s0_R;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void _updateThermo() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace Cantera {
|
||||||
void setSiteDensity(doublereal n0);
|
void setSiteDensity(doublereal n0);
|
||||||
void setElectricPotential(doublereal V);
|
void setElectricPotential(doublereal V);
|
||||||
void setCoverages(const doublereal* theta);
|
void setCoverages(const doublereal* theta);
|
||||||
void getCoverages(doublereal* theta);
|
void getCoverages(doublereal* theta) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,19 @@
|
||||||
#include "IdealGasPhase.h"
|
#include "IdealGasPhase.h"
|
||||||
#include "ConstDensityThermo.h"
|
#include "ConstDensityThermo.h"
|
||||||
#include "SurfPhase.h"
|
#include "SurfPhase.h"
|
||||||
|
#include "MetalPhase.h"
|
||||||
|
#include "SolidCompound.h"
|
||||||
#include "importCTML.h"
|
#include "importCTML.h"
|
||||||
|
|
||||||
namespace Cantera {
|
namespace Cantera {
|
||||||
|
|
||||||
ThermoFactory* ThermoFactory::__factory = 0;
|
ThermoFactory* ThermoFactory::__factory = 0;
|
||||||
|
|
||||||
static int ntypes = 3;
|
static int ntypes = 5;
|
||||||
static string _types[] = {"IdealGas", "Incompressible", "Surface"};
|
static string _types[] = {"IdealGas", "Incompressible",
|
||||||
static int _itypes[] = {cIdealGas, cIncompressible, cSurf};
|
"Surface", "Metal", "SolidCompound"};
|
||||||
|
static int _itypes[] = {cIdealGas, cIncompressible,
|
||||||
|
cSurf, cMetal, cSolidCompound};
|
||||||
|
|
||||||
|
|
||||||
ThermoPhase* ThermoFactory::newThermoPhase(string model) {
|
ThermoPhase* ThermoFactory::newThermoPhase(string model) {
|
||||||
|
|
@ -55,6 +59,14 @@ namespace Cantera {
|
||||||
th = new SurfPhase;
|
th = new SurfPhase;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cMetal:
|
||||||
|
th = new MetalPhase;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cSolidCompound:
|
||||||
|
th = new SolidCompound;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw CanteraError("newThermo",
|
throw CanteraError("newThermo",
|
||||||
"newThermo: unknown equation of state: "+model);
|
"newThermo: unknown equation of state: "+model);
|
||||||
|
|
@ -99,22 +111,23 @@ namespace Cantera {
|
||||||
switch (ieos) {
|
switch (ieos) {
|
||||||
|
|
||||||
case cIdealGas:
|
case cIdealGas:
|
||||||
// Ideal gas
|
|
||||||
th = new IdealGasPhase;
|
th = new IdealGasPhase;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cIncompressible:
|
case cIncompressible:
|
||||||
// getFloats(eos,d);
|
|
||||||
//dens = d["density"];
|
|
||||||
th = new ConstDensityThermo;
|
th = new ConstDensityThermo;
|
||||||
//th->setParameters(1, &dens);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cSurf:
|
case cSurf:
|
||||||
//getFloats(eos,d);
|
|
||||||
//dens = d["site_density"];
|
|
||||||
th = new SurfPhase;
|
th = new SurfPhase;
|
||||||
//th->setParameters(1, &dens);
|
break;
|
||||||
|
|
||||||
|
case cMetal:
|
||||||
|
th = new MetalPhase;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cSolidCompound:
|
||||||
|
th = new SolidCompound;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -122,8 +135,10 @@ namespace Cantera {
|
||||||
"newThermo: unknown equation of state: "+eostype);
|
"newThermo: unknown equation of state: "+eostype);
|
||||||
}
|
}
|
||||||
th->setSpeciesThermo(spthermo);
|
th->setSpeciesThermo(spthermo);
|
||||||
|
|
||||||
// import the phase specification
|
// import the phase specification
|
||||||
importPhase(node, th);
|
importPhase(node, th);
|
||||||
|
|
||||||
return th;
|
return th;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ using namespace std;
|
||||||
#include "ReactionData.h"
|
#include "ReactionData.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "stringUtils.h"
|
#include "stringUtils.h"
|
||||||
|
#include "GasKineticsWriter.h"
|
||||||
|
|
||||||
#include "xml.h"
|
#include "xml.h"
|
||||||
#include "ctml.h"
|
#include "ctml.h"
|
||||||
|
|
@ -40,6 +41,8 @@ using namespace ctml;
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
GasKineticsWriter* writer = 0;
|
||||||
|
|
||||||
namespace Cantera {
|
namespace Cantera {
|
||||||
|
|
||||||
typedef vector<XML_Node*> nodeset_t;
|
typedef vector<XML_Node*> nodeset_t;
|
||||||
|
|
@ -191,15 +194,15 @@ namespace Cantera {
|
||||||
* Define a map and get all of the floats in the
|
* Define a map and get all of the floats in the
|
||||||
* current XML species block
|
* current XML species block
|
||||||
*/
|
*/
|
||||||
map<string, double> fd;
|
//map<string, double> fd;
|
||||||
getFloats(s, fd);
|
//getFloats(s, fd);
|
||||||
|
doublereal chrg = 0.0;
|
||||||
|
if (s.hasChild("charge")) chrg = getFloat(s, "charge");
|
||||||
|
doublereal sz = 1.0;
|
||||||
|
if (s.hasChild("size")) sz = getFloat(s, "size");
|
||||||
|
|
||||||
/*
|
|
||||||
* Set a default for the size parameter to one
|
|
||||||
*/
|
|
||||||
if (fd["size"] == 0.0) fd["size"] = 1.0;
|
|
||||||
p.addUniqueSpecies(s["name"], ecomp.begin(),
|
p.addUniqueSpecies(s["name"], ecomp.begin(),
|
||||||
fd["charge"], fd["size"]);
|
chrg, sz);
|
||||||
|
|
||||||
// get thermo
|
// get thermo
|
||||||
XML_Node& thermo = s.child("thermo");
|
XML_Node& thermo = s.child("thermo");
|
||||||
|
|
@ -391,7 +394,8 @@ namespace Cantera {
|
||||||
vector_fp coeff(3);
|
vector_fp coeff(3);
|
||||||
getArrhenius(c, order, coeff[0], coeff[1], coeff[2]);
|
getArrhenius(c, order, coeff[0], coeff[1], coeff[2]);
|
||||||
if (order == 0) order = nr;
|
if (order == 0) order = nr;
|
||||||
if (order == nr || rdata.reactionType == THREE_BODY_RXN)
|
if (order == nr || rdata.reactionType == THREE_BODY_RXN
|
||||||
|
|| rdata.reactionType == ELEMENTARY_RXN)
|
||||||
chigh = coeff;
|
chigh = coeff;
|
||||||
else if (order == nr + 1) clow = coeff;
|
else if (order == nr + 1) clow = coeff;
|
||||||
else {
|
else {
|
||||||
|
|
@ -401,6 +405,15 @@ namespace Cantera {
|
||||||
"wrong Arrhenius coeff order");
|
"wrong Arrhenius coeff order");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// else if (nm == "Stick") {
|
||||||
|
// vector_fp coeff(3);
|
||||||
|
// string spname = c["species"];
|
||||||
|
// ThermoPhase& th = kin.speciesPhase(spname);
|
||||||
|
// int isp = th.speciesIndex(spname);
|
||||||
|
// double mw = th.molecularWeights()[isp];
|
||||||
|
// cbar = sqrt((8.0*GasConstant)/(Pi*mw));
|
||||||
|
//
|
||||||
|
// }
|
||||||
else if (nm == "falloff") {
|
else if (nm == "falloff") {
|
||||||
getFalloff(c, rdata);
|
getFalloff(c, rdata);
|
||||||
}
|
}
|
||||||
|
|
@ -501,11 +514,21 @@ namespace Cantera {
|
||||||
"wrong equation of state type");
|
"wrong equation of state type");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (eos["model"] == "SolidCompound") {
|
||||||
|
if (th->eosType() == cSolidCompound) {
|
||||||
|
doublereal rho = getFloat(eos, "density", "-");
|
||||||
|
th->setDensity(rho);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw CanteraError("importCTML",
|
||||||
|
"wrong equation of state type");
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (eos["model"] == "Surface") {
|
else if (eos["model"] == "Surface") {
|
||||||
if (th->eosType() == cSurf) {
|
if (th->eosType() == cSurf) {
|
||||||
map<string, doublereal> d;
|
//map<string, doublereal> d;
|
||||||
//getFloats(eos, d);
|
//getFloats(eos, d);
|
||||||
doublereal n = fpValue(eos("site_density"));
|
doublereal n = getFloat(eos, "site_density", "-");
|
||||||
th->setParameters(1, &n);
|
th->setParameters(1, &n);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -685,12 +708,16 @@ namespace Cantera {
|
||||||
|
|
||||||
getRateCoefficient(r.child("rateCoeff"), kin, rdata);
|
getRateCoefficient(r.child("rateCoeff"), kin, rdata);
|
||||||
kin.addReaction(rdata);
|
kin.addReaction(rdata);
|
||||||
|
//if (writer) writer->addReaction(rdata);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool installReactionArrays(XML_Node& p, Kinetics& kin,
|
bool installReactionArrays(XML_Node& p, Kinetics& kin,
|
||||||
string default_phase) {
|
string default_phase) {
|
||||||
|
|
||||||
|
writer = new GasKineticsWriter;
|
||||||
|
|
||||||
vector<XML_Node*> rarrays;
|
vector<XML_Node*> rarrays;
|
||||||
int itot = 0;
|
int itot = 0;
|
||||||
p.getChildren("reactionArray",rarrays);
|
p.getChildren("reactionArray",rarrays);
|
||||||
|
|
@ -738,6 +765,12 @@ namespace Cantera {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kin.finalize();
|
kin.finalize();
|
||||||
|
ofstream fwrite("mech.cpp");
|
||||||
|
//writer->writeGetNetProductionRates(cout, kin.nTotalSpecies(),
|
||||||
|
// kin.nReactions());
|
||||||
|
fwrite.close();
|
||||||
|
delete writer;
|
||||||
|
writer = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@ namespace Cantera {
|
||||||
const int cIdealGas = 1;
|
const int cIdealGas = 1;
|
||||||
const int cIncompressible = 2;
|
const int cIncompressible = 2;
|
||||||
const int cSurf = 3;
|
const int cSurf = 3;
|
||||||
|
const int cMetal = 4;
|
||||||
|
const int cSolidCompound = 5;
|
||||||
|
|
||||||
// kinetic manager types
|
// kinetic manager types
|
||||||
const int cGasKinetics = 2;
|
const int cGasKinetics = 2;
|
||||||
|
|
|
||||||
|
|
@ -107,10 +107,10 @@ namespace Cantera {
|
||||||
m_nv = nv;
|
m_nv = nv;
|
||||||
m_max.resize(m_nv, 0.0);
|
m_max.resize(m_nv, 0.0);
|
||||||
m_min.resize(m_nv, 0.0);
|
m_min.resize(m_nv, 0.0);
|
||||||
m_rtol_ss.resize(m_nv, 0.0);
|
m_rtol_ss.resize(m_nv, 1.0e-8);
|
||||||
m_atol_ss.resize(m_nv, 0.0);
|
m_atol_ss.resize(m_nv, 1.0e-15);
|
||||||
m_rtol_ts.resize(m_nv, 0.0);
|
m_rtol_ts.resize(m_nv, 1.0e-8);
|
||||||
m_atol_ts.resize(m_nv, 0.0);
|
m_atol_ts.resize(m_nv, 1.0e-15);
|
||||||
m_points = np;
|
m_points = np;
|
||||||
m_z.resize(np, 0.0);
|
m_z.resize(np, 0.0);
|
||||||
m_slast.resize(m_nv * m_points, 0.0);
|
m_slast.resize(m_nv * m_points, 0.0);
|
||||||
|
|
|
||||||
|
|
@ -97,14 +97,17 @@ namespace Cantera {
|
||||||
const doublereal* step, OneDim& r) const {
|
const doublereal* step, OneDim& r) const {
|
||||||
doublereal f, sum = 0.0;//, fmx = 0.0;
|
doublereal f, sum = 0.0;//, fmx = 0.0;
|
||||||
int n;
|
int n;
|
||||||
int nd = r.nDomains();
|
int nd = r.nDomains();
|
||||||
for (n = 0; n < nd; n++) {
|
for (n = 0; n < nd; n++) {
|
||||||
f = norm_square(x + r.start(n), step + r.start(n),
|
f = norm_square(x + r.start(n), step + r.start(n),
|
||||||
r.domain(n));
|
r.domain(n));
|
||||||
sum += f;
|
sum += f;
|
||||||
// if (f > fmx) fmx = f;
|
// cout << "n = " << n << " f = " << f << endl;
|
||||||
}
|
}
|
||||||
|
//cout << "sum = " << sum << endl;
|
||||||
|
//cout << "r.size() = " << r.size() << endl;
|
||||||
sum /= r.size();
|
sum /= r.size();
|
||||||
|
//cout << "sum = " << sum << " " << sqrt(sum) << endl;
|
||||||
return sqrt(sum);
|
return sqrt(sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,7 +124,11 @@ namespace Cantera {
|
||||||
for (n = 0; n < sz; n++) {
|
for (n = 0; n < sz; n++) {
|
||||||
step[n] = -step[n];
|
step[n] = -step[n];
|
||||||
}
|
}
|
||||||
|
jac.solve(sz, step, step);
|
||||||
|
|
||||||
|
#undef DEBUG_STEP
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
|
bool ok = false;
|
||||||
Domain1D* d;
|
Domain1D* d;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
for (n = 0; n < sz; n++) {
|
for (n = 0; n < sz; n++) {
|
||||||
|
|
@ -132,10 +139,10 @@ namespace Cantera {
|
||||||
r.pointDomain(n)->componentName(n - d->loc() - nvd*pt)
|
r.pointDomain(n)->componentName(n - d->loc() - nvd*pt)
|
||||||
<< " " << x[n] << " " << step[n] << endl;
|
<< " " << x[n] << " " << step[n] << endl;
|
||||||
}
|
}
|
||||||
if (!ok) throw "not ok";
|
//if (!ok) throw "not ok";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
jac.solve(sz, step, step);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -336,9 +336,9 @@ namespace Cantera {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//else {
|
else {
|
||||||
// throw CanteraError("refine","keepPoint is false at m = "+int2str(m));
|
throw CanteraError("refine","keepPoint is false at m = "+int2str(m));
|
||||||
//}
|
}
|
||||||
}
|
}
|
||||||
dsize.push_back(znew.size() - nstart);
|
dsize.push_back(znew.size() - nstart);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
634
Cantera/src/oneD/Solid1D.cpp
Normal file
634
Cantera/src/oneD/Solid1D.cpp
Normal file
|
|
@ -0,0 +1,634 @@
|
||||||
|
/**
|
||||||
|
* @file Solid.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Author$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 2003 California Institute of Technology
|
||||||
|
|
||||||
|
|
||||||
|
// turn off warnings under Windows
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning(disable:4786)
|
||||||
|
#pragma warning(disable:4503)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "Solid1D.h"
|
||||||
|
#include "../ArrayViewer.h"
|
||||||
|
#include "ctml.h"
|
||||||
|
#include "MultiJac.h"
|
||||||
|
|
||||||
|
using namespace ctml;
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
|
||||||
|
int Solid1D::c_T_loc = 0;
|
||||||
|
int Solid1D::c_phi_loc = 1;
|
||||||
|
int Solid1D::c_Y_loc = 2;
|
||||||
|
|
||||||
|
|
||||||
|
Solid1D::Solid1D(ThermoPhase* ph, int nsp, int points) :
|
||||||
|
Domain1D(nsp+1, points),
|
||||||
|
m_nsp(nsp),
|
||||||
|
m_thermo(0),
|
||||||
|
m_kin(0),
|
||||||
|
m_trans(0),
|
||||||
|
m_jac(0),
|
||||||
|
m_ok(false),
|
||||||
|
{
|
||||||
|
m_type = cSolidType;
|
||||||
|
|
||||||
|
m_points = points;
|
||||||
|
m_thermo = ph;
|
||||||
|
|
||||||
|
if (ph == 0) return; // used to create a dummy object
|
||||||
|
|
||||||
|
int nsp2 = m_thermo->nSpecies();
|
||||||
|
if (nsp2 != m_nsp) {
|
||||||
|
m_nsp = nsp2;
|
||||||
|
Domain1D::resize(m_nsp+1, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// make a local copy of the species molecular weight vector
|
||||||
|
m_wt = m_thermo->molecularWeights();
|
||||||
|
|
||||||
|
m_nv = m_nsp + 1;
|
||||||
|
|
||||||
|
// turn off the energy equation at all points
|
||||||
|
m_do_energy.resize(m_points,false);
|
||||||
|
m_do_gauss.resize(m_points,false);
|
||||||
|
m_do_species.resize(m_nsp,false);
|
||||||
|
|
||||||
|
m_diff.resize(m_nsp*m_points);
|
||||||
|
m_flux.resize(m_nsp,m_points);
|
||||||
|
m_wdot.resize(m_nsp,m_points, 0.0);
|
||||||
|
m_ybar.resize(m_nsp);
|
||||||
|
|
||||||
|
|
||||||
|
//-------------- default solution bounds --------------------
|
||||||
|
|
||||||
|
vector_fp vmin(m_nv), vmax(m_nv);
|
||||||
|
|
||||||
|
// temperature bounds
|
||||||
|
vmin[c_T_loc] = 200.0;
|
||||||
|
vmax[c_T_loc]= 1.e9;
|
||||||
|
|
||||||
|
// mass fraction bounds
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
vmin[c_Y_loc + k] = -1.0e-5;
|
||||||
|
vmax[c_Y_loc + k] = 1.0e5;
|
||||||
|
}
|
||||||
|
setBounds(vmin.size(), vmin.begin(), vmax.size(), vmax.begin());
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------- default error tolerances ----------------
|
||||||
|
vector_fp rtol(m_nv, 1.0e-8);
|
||||||
|
vector_fp atol(m_nv, 1.0e-15);
|
||||||
|
setTolerances(rtol.size(), rtol.begin(), atol.size(), atol.begin(),false);
|
||||||
|
setTolerances(rtol.size(), rtol.begin(), atol.size(), atol.begin(),true);
|
||||||
|
|
||||||
|
//-------------------- grid refinement -------------------------
|
||||||
|
m_refiner->setActive(c_T_loc, false);
|
||||||
|
|
||||||
|
vector_fp gr;
|
||||||
|
for (int ng = 0; ng < m_points; ng++) gr.push_back(1.0*ng/m_points);
|
||||||
|
setupGrid(m_points, gr.begin());
|
||||||
|
setID("solid");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the grid size. Called after grid refinement.
|
||||||
|
*/
|
||||||
|
void Solid1D::resize(int points) {
|
||||||
|
Domain1D::resize(m_nv, points);
|
||||||
|
|
||||||
|
m_rho.resize(m_points, 0.0);
|
||||||
|
m_wtm.resize(m_points, 0.0);
|
||||||
|
m_cp.resize(m_points, 0.0);
|
||||||
|
m_tcon.resize(m_points, 0.0);
|
||||||
|
m_cdens.resize(m_points, 0.0);
|
||||||
|
m_diff.resize(m_nsp*m_points);
|
||||||
|
|
||||||
|
m_flux.resize(m_nsp,m_points);
|
||||||
|
m_wdot.resize(m_nsp,m_points, 0.0);
|
||||||
|
|
||||||
|
m_do_energy.resize(m_points,false);
|
||||||
|
m_do_gauss.resize(m_points,false);
|
||||||
|
m_do_species.resize(m_nsp,false);
|
||||||
|
|
||||||
|
m_fixedtemp.resize(m_points);
|
||||||
|
m_fixedphi.resize(m_points);
|
||||||
|
|
||||||
|
m_dz.resize(m_points-1);
|
||||||
|
m_z.resize(m_points);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Solid1D::setupGrid(int n, const doublereal* z) {
|
||||||
|
resize(n);
|
||||||
|
int j;
|
||||||
|
m_z[0] = z[0];
|
||||||
|
for (j = 1; j < m_points; j++) {
|
||||||
|
m_z[j] = z[j];
|
||||||
|
m_dz[j-1] = m_z[j] - m_z[j-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a transport manager.
|
||||||
|
*/
|
||||||
|
void Solid1D::setTransport(Transport& trans) {
|
||||||
|
m_trans = &trans;
|
||||||
|
|
||||||
|
if (m_trans->model() != cSolidTransport) {
|
||||||
|
throw CanteraError("setTransport","unknown transport model.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the solid object state to be consistent with the solution at
|
||||||
|
* point j.
|
||||||
|
*/
|
||||||
|
void Solid1D::setThermoState(const doublereal* x,int j) {
|
||||||
|
m_thermo->setTemperature(T(x,j));
|
||||||
|
m_thermo->setElectricPotential(phi(x,j));
|
||||||
|
const doublereal* yy = x + m_nv*j + 1;
|
||||||
|
m_thermo->setMassFractions_NoNorm(yy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the state to be consistent with the solution at the
|
||||||
|
* midpoint between j and j + 1.
|
||||||
|
*/
|
||||||
|
void Solid1D::setStateAtMidpoint(const doublereal* x,int j) {
|
||||||
|
m_thermo->setTemperature(0.5*(T(x,j)+T(x,j+1)));
|
||||||
|
m_thermo->setElectricPotential(0.5*(phi(x,j)+phi(x,j+1)));
|
||||||
|
const doublereal* yyj = x + m_nv*j + 1;
|
||||||
|
const doublereal* yyjp = x + m_nv*(j+1) + 1;
|
||||||
|
for (int k = 0; k < m_nsp; k++)
|
||||||
|
m_ybar[k] = 0.5*(yyj[k] + yyjp[k]);
|
||||||
|
m_thermo->setMassFractions_NoNorm(m_ybar.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Solid1D::eval(int jg, doublereal* xg,
|
||||||
|
doublereal* rg, integer* diagg, doublereal rdt) {
|
||||||
|
|
||||||
|
// if evaluating a Jacobian, and the global point is outside
|
||||||
|
// the domain of influence for this domain, then skip
|
||||||
|
// evaluating the residual
|
||||||
|
if (jg >=0 && (jg < firstPoint() - 1 || jg > lastPoint() + 1)) return;
|
||||||
|
|
||||||
|
// if evaluating a Jacobian, compute the steady-state residual
|
||||||
|
if (jg >= 0) rdt = 0.0;
|
||||||
|
|
||||||
|
// start of local part of global arrays
|
||||||
|
doublereal* x = xg + loc();
|
||||||
|
doublereal* rsd = rg + loc();
|
||||||
|
integer* diag = diagg + loc();
|
||||||
|
|
||||||
|
int jmin, jmax, jpt;
|
||||||
|
jpt = jg - firstPoint();
|
||||||
|
|
||||||
|
if (jg < 0) { // evaluate all points
|
||||||
|
jmin = 0;
|
||||||
|
jmax = m_points - 1;
|
||||||
|
}
|
||||||
|
else { // evaluate points for Jacobian
|
||||||
|
jmin = max(jpt-1, 0);
|
||||||
|
jmax = min(jpt+1,m_points-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// properties are computed for grid points from j0 to j1
|
||||||
|
int j0 = max(jmin-1,0);
|
||||||
|
int j1 = min(jmax+1,m_points-1);
|
||||||
|
|
||||||
|
|
||||||
|
int j, k;
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------
|
||||||
|
// update properties
|
||||||
|
//-----------------------------------------------------
|
||||||
|
|
||||||
|
// thermodynamic properties only if a Jacobian is
|
||||||
|
// not being evaluated
|
||||||
|
if (jpt < 0)
|
||||||
|
updateThermo(x, j0, j1);
|
||||||
|
|
||||||
|
// update transport properties only if a Jacobian is
|
||||||
|
// not being evaluated
|
||||||
|
if (jpt < 0)
|
||||||
|
updateTransport(x, j0, j1);
|
||||||
|
|
||||||
|
// update the species diffusive mass fluxes whether or not a
|
||||||
|
// Jacobian is being evaluated
|
||||||
|
updateDiffFluxes(x, j0, j1);
|
||||||
|
|
||||||
|
for (j = j0; j <= j1; j++) {
|
||||||
|
setThermoState(j);
|
||||||
|
m_cdens[j] = m_thermo->chargeDensity();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------
|
||||||
|
// evaluate the residual equations at all required
|
||||||
|
// grid points
|
||||||
|
//----------------------------------------------------
|
||||||
|
|
||||||
|
for (j = jmin; j <= jmax; j++) {
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
// left boundary
|
||||||
|
//----------------------------------------------
|
||||||
|
|
||||||
|
if (j == 0) {
|
||||||
|
rsd[index(c_T_loc,0)] = T(x,0);
|
||||||
|
rsd[index(c_phi_loc,0)] = phi(x,0);
|
||||||
|
|
||||||
|
// The default boundary condition for species is zero
|
||||||
|
// flux. However, the boundary object may modify
|
||||||
|
// this.
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
rsd[index(c_Y_loc + k, 0)] = - m_flux(k,0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
//
|
||||||
|
// right boundary
|
||||||
|
//
|
||||||
|
//----------------------------------------------
|
||||||
|
|
||||||
|
else if (j == m_points - 1) {
|
||||||
|
rsd[index(c_T_loc,j)] = T(x,j);
|
||||||
|
rsd[index(c_phi_loc,j)] = phi(x,j);
|
||||||
|
doublereal sum = 0.0;
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
sum += Y(x,k,j);
|
||||||
|
rsd[index(k+c_Y_loc,j)] = m_flux(k,j-1);
|
||||||
|
}
|
||||||
|
rsd[index(c_Y_loc,j)] = 1.0 - sum;
|
||||||
|
diag[index(c_Y_loc,j)] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
// interior points
|
||||||
|
//------------------------------------------
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// Species equations
|
||||||
|
//
|
||||||
|
// \rho u dY_k/dz + dJ_k/dz + M_k\omega_k
|
||||||
|
//
|
||||||
|
//-------------------------------------------------
|
||||||
|
getWdot(x,j);
|
||||||
|
|
||||||
|
doublereal convec, diffus;
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
diffus = 2.0*(m_flux(k,j) - m_flux(k,j-1))
|
||||||
|
/(z(j+1) - z(j-1));
|
||||||
|
rsd[index(c_Y_loc + k, j)]
|
||||||
|
= (m_wt[k]*(wdot(k,j) )
|
||||||
|
- diffus)/m_rho[j]
|
||||||
|
- rdt*(Y(x,k,j) - Y_prev(k,j));
|
||||||
|
diag[index(c_Y_loc + k, j)] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------
|
||||||
|
// energy equation
|
||||||
|
//-----------------------------------------------
|
||||||
|
|
||||||
|
if (m_do_energy[j]) {
|
||||||
|
|
||||||
|
rsd[index(c_T_loc, j)] = - divHeatFlux(x,j);
|
||||||
|
rsd[index(c_T_loc, j)] /= (m_rho[j]*m_cp[j]);
|
||||||
|
|
||||||
|
rsd[index(c_T_loc, j)] -= rdt*(T(x,j) - T_prev(j));
|
||||||
|
diag[index(c_T_loc, j)] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
// Gauss's equation
|
||||||
|
//----------------------------------------------
|
||||||
|
rsd[index(c_phi_loc, j)] = m_cdens[j] - divDisplCurr(x,j);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// residual equations if the energy or species equations
|
||||||
|
// are disabled
|
||||||
|
|
||||||
|
if (!m_do_energy[j]) {
|
||||||
|
rsd[index(c_T_loc, j)] = T(x,j) - T_fixed(j);
|
||||||
|
diag[index(c_T_loc, j)] = 0;
|
||||||
|
}
|
||||||
|
if (!m_do_gauss[j]) {
|
||||||
|
rsd[index(c_phi_loc, j)] = phi(x,j) - phi_fixed(j);
|
||||||
|
diag[index(c_phi_loc, j)] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the transport properties at grid points in the range
|
||||||
|
* from j0 to j1, based on solution x.
|
||||||
|
*/
|
||||||
|
void Surf1D::updateTransport(doublereal* x,int j0, int j1) {
|
||||||
|
int j;
|
||||||
|
for (j = j0; j < j1; j++) {
|
||||||
|
setStateAtMidpoint(x,j);
|
||||||
|
m_trans->getMixDiffCoeffs(m_diff.begin() + j*m_nsp);
|
||||||
|
m_tcon[j] = m_trans->thermalConductivity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the solution.
|
||||||
|
*/
|
||||||
|
void Solid1D::showSolution(const doublereal* x) {
|
||||||
|
int nn = m_nv/5;
|
||||||
|
int i, j, n;
|
||||||
|
char* buf = new char[100];
|
||||||
|
|
||||||
|
// The mean molecular weight is needed to convert
|
||||||
|
updateThermo(x, 0, m_points-1);
|
||||||
|
|
||||||
|
for (i = 0; i < nn; i++) {
|
||||||
|
drawline();
|
||||||
|
sprintf(buf, "\n z ");
|
||||||
|
writelog(buf);
|
||||||
|
for (n = 0; n < 5; n++) {
|
||||||
|
sprintf(buf, " %10s ",componentName(i*5 + n).c_str());
|
||||||
|
writelog(buf);
|
||||||
|
}
|
||||||
|
drawline();
|
||||||
|
for (j = 0; j < m_points; j++) {
|
||||||
|
sprintf(buf, "\n %10.4g ",m_z[j]);
|
||||||
|
writelog(buf);
|
||||||
|
for (n = 0; n < 5; n++) {
|
||||||
|
sprintf(buf, " %10.4g ",component(x, i*5+n,j));
|
||||||
|
writelog(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writelog("\n");
|
||||||
|
}
|
||||||
|
int nrem = m_nv - 5*nn;
|
||||||
|
drawline();
|
||||||
|
sprintf(buf, "\n z ");
|
||||||
|
writelog(buf);
|
||||||
|
for (n = 0; n < nrem; n++) {
|
||||||
|
sprintf(buf, " %10s ", componentName(nn*5 + n).c_str());
|
||||||
|
writelog(buf);
|
||||||
|
}
|
||||||
|
drawline();
|
||||||
|
for (j = 0; j < m_points; j++) {
|
||||||
|
sprintf(buf, "\n %10.4g ",m_z[j]);
|
||||||
|
writelog(buf);
|
||||||
|
for (n = 0; n < nrem; n++) {
|
||||||
|
sprintf(buf, " %10.4g ",component(x, nn*5+n,j));
|
||||||
|
writelog(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writelog("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the diffusive mass fluxes.
|
||||||
|
*/
|
||||||
|
void Solid1D::updateDiffFluxes(const doublereal* x, int j0, int j1) {
|
||||||
|
int j, k, m;
|
||||||
|
doublereal sum, wtm, rho, dz, gradlogT, s;
|
||||||
|
doublereal dphidz, a1;
|
||||||
|
for (j = j0; j < j1; j++) {
|
||||||
|
sum = 0.0;
|
||||||
|
wtm = m_wtm[j];
|
||||||
|
rho = density(j);
|
||||||
|
dz = z(j+1) - z(j);
|
||||||
|
dphidz = (phi(x,j+1) - phi(x,j))/dz;
|
||||||
|
a1 = rho*Faraday*dphidz/(GasConstant * T(x,j));
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
m_flux(k,j) = m_wt[k]*(rho*m_diff[k+m_nsp*j]/wtm);
|
||||||
|
m_flux(k,j) *= (X(x,k,j) - X(x,k,j+1))/dz;
|
||||||
|
m_flux(k,j) += a1*0.5*(Y(x,k,j)
|
||||||
|
+ Y(x,k,j+1))*m_diff[k+m_nsp*j]*m_charge[k];
|
||||||
|
sum -= m_flux(k,j);
|
||||||
|
}
|
||||||
|
for (k = 0; k < m_nsp; k++) m_flux(k,j) += Y(x,k,j)*sum;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Solid1D::outputTEC(ostream &s, const doublereal* x,
|
||||||
|
string title, int zone) {
|
||||||
|
int j,k;
|
||||||
|
s << "TITLE = \"" + title + "\"" << endl;
|
||||||
|
s << "VARIABLES = \"Z (m)\"" << endl;
|
||||||
|
s << "\"T (K)\"" << endl;
|
||||||
|
s << "\"phi (V)\"" << endl;
|
||||||
|
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
s << "\"" << m_thermo->speciesName(k) << "\"" << endl;
|
||||||
|
}
|
||||||
|
s << "ZONE T=\"c" << zone << "\"" << endl;
|
||||||
|
s << " I=" << m_points << ",J=1,K=1,F=POINT" << endl;
|
||||||
|
s << "DT=(SINGLE SINGLE";
|
||||||
|
for (k = 0; k < m_nsp; k++) s << " SINGLE";
|
||||||
|
s << " )" << endl;
|
||||||
|
for (j = 0; j < m_points; j++) {
|
||||||
|
s << z(j) << " ";
|
||||||
|
for (k = 0; k < m_nv; k++) {
|
||||||
|
s << component(x, k, j) << " ";
|
||||||
|
}
|
||||||
|
s << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string Solid1D::componentName(int n) const {
|
||||||
|
switch(n) {
|
||||||
|
case c_T_loc: return "T";
|
||||||
|
case c_phi_loc: return "phi";
|
||||||
|
default:
|
||||||
|
if (n >= (int) 1 && n < (int) (c_Y_loc + m_nsp)) {
|
||||||
|
return m_thermo->speciesName(n - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return "<unknown>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Solid1D::restore(XML_Node& dom, doublereal* soln) {
|
||||||
|
|
||||||
|
vector<string> ignored;
|
||||||
|
int nsp = m_thermo->nSpecies();
|
||||||
|
vector_int did_species(nsp, 0);
|
||||||
|
|
||||||
|
vector<XML_Node*> str;
|
||||||
|
dom.getChildren("string",str);
|
||||||
|
int nstr = str.size();
|
||||||
|
for (int istr = 0; istr < nstr; istr++) {
|
||||||
|
XML_Node& nd = *str[istr];
|
||||||
|
writelog(nd["title"]+": "+nd.value()+"\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
map<string, double> params;
|
||||||
|
getFloats(dom, params);
|
||||||
|
|
||||||
|
vector<XML_Node*> d;
|
||||||
|
dom.child("grid_data").getChildren("floatArray",d);
|
||||||
|
int nd = d.size();
|
||||||
|
|
||||||
|
vector_fp x;
|
||||||
|
int n, np, j, ks, k;
|
||||||
|
string nm;
|
||||||
|
bool readgrid = false, wrote_header = false;
|
||||||
|
for (n = 0; n < nd; n++) {
|
||||||
|
XML_Node& fa = *d[n];
|
||||||
|
nm = fa["title"];
|
||||||
|
if (nm == "z") {
|
||||||
|
getFloatArray(fa,x,false);
|
||||||
|
np = x.size();
|
||||||
|
writelog("Grid contains "+int2str(np)+
|
||||||
|
" points.\n");
|
||||||
|
readgrid = true;
|
||||||
|
|
||||||
|
// note that setupGrid also resizes the domain.
|
||||||
|
setupGrid(np, x.begin());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!readgrid) {
|
||||||
|
throw CanteraError("Solid1D::restore",
|
||||||
|
"domain contains no grid points.");
|
||||||
|
}
|
||||||
|
|
||||||
|
writelog("Importing datasets:\n");
|
||||||
|
for (n = 0; n < nd; n++) {
|
||||||
|
XML_Node& fa = *d[n];
|
||||||
|
nm = fa["title"];
|
||||||
|
getFloatArray(fa,x,false);
|
||||||
|
if (nm == "z") {
|
||||||
|
; // already read grid
|
||||||
|
}
|
||||||
|
else if (nm == "T") {
|
||||||
|
writelog("temperature ");
|
||||||
|
if ((int) x.size() == np) {
|
||||||
|
for (j = 0; j < np; j++)
|
||||||
|
soln[index(c_T_loc,j)] = x[j];
|
||||||
|
|
||||||
|
// For fixed-temperature simulations, use the imported temperature profile by default.
|
||||||
|
// If this is not desired, call setFixedTempProfile *after* restoring the solution.
|
||||||
|
vector_fp zz(np);
|
||||||
|
for (int jj = 0; jj < np; jj++) zz[jj] = (grid(jj) - zmin())/(zmax() - zmin());
|
||||||
|
setFixedTempProfile(zz, x);
|
||||||
|
}
|
||||||
|
else goto error;
|
||||||
|
}
|
||||||
|
else if (nm == "phi") {
|
||||||
|
writelog("potential ");
|
||||||
|
if ((int) x.size() == np) {
|
||||||
|
for (j = 0; j < np; j++)
|
||||||
|
soln[index(c_phi_loc,j)] = x[j];
|
||||||
|
}
|
||||||
|
else goto error;
|
||||||
|
}
|
||||||
|
else if (m_thermo->speciesIndex(nm) >= 0) {
|
||||||
|
writelog(nm+" ");
|
||||||
|
if ((int) x.size() == np) {
|
||||||
|
k = m_thermo->speciesIndex(nm);
|
||||||
|
did_species[k] = 1;
|
||||||
|
for (j = 0; j < np; j++)
|
||||||
|
soln[index(k+c_Y_loc,j)] = x[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ignored.push_back(nm);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ignored.size() != 0) {
|
||||||
|
writelog("\n\n");
|
||||||
|
writelog("Ignoring datasets:\n");
|
||||||
|
int nn = ignored.size();
|
||||||
|
for (int n = 0; n < nn; n++) {
|
||||||
|
writelog(ignored[n]+" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ks = 0; ks < nsp; ks++) {
|
||||||
|
if (did_species[ks] == 0) {
|
||||||
|
if (!wrote_header) {
|
||||||
|
writelog("Missing data for species:\n");
|
||||||
|
wrote_header = true;
|
||||||
|
}
|
||||||
|
writelog(m_thermo->speciesName(ks)+" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
error:
|
||||||
|
throw CanteraError("Solid1D::restore","Data size error");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Solid1D::save(XML_Node& o, doublereal* sol) {
|
||||||
|
int k;
|
||||||
|
|
||||||
|
ArrayViewer soln(m_nv, m_points, sol + loc());
|
||||||
|
|
||||||
|
XML_Node& flow = (XML_Node&)o.addChild("domain");
|
||||||
|
flow.addAttribute("type",flowType());
|
||||||
|
flow.addAttribute("id",m_id);
|
||||||
|
flow.addAttribute("points",m_points);
|
||||||
|
flow.addAttribute("components",m_nv);
|
||||||
|
|
||||||
|
if (m_desc != "") addString(flow,"description",m_desc);
|
||||||
|
XML_Node& gv = flow.addChild("grid_data");
|
||||||
|
addFloatArray(gv,"z",m_z.size(),m_z.begin(),
|
||||||
|
"m","length");
|
||||||
|
vector_fp x(soln.nColumns());
|
||||||
|
|
||||||
|
soln.getRow(c_T_loc,x.begin());
|
||||||
|
addFloatArray(gv,"T",x.size(),x.begin(),"K","temperature",0.0);
|
||||||
|
|
||||||
|
soln.getRow(c_phi_loc,x.begin());
|
||||||
|
addFloatArray(gv,"phi",x.size(),x.begin(),"V","potential",0.0);
|
||||||
|
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
soln.getRow(c_Y_loc+k,x.begin());
|
||||||
|
addFloatArray(gv,m_thermo->speciesName(k),
|
||||||
|
x.size(),x.begin(),"","massFraction",0.0,1.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Solid1D::setJac(MultiJac* jac) {
|
||||||
|
m_jac = jac;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
402
Cantera/src/oneD/Solid1D.h
Normal file
402
Cantera/src/oneD/Solid1D.h
Normal file
|
|
@ -0,0 +1,402 @@
|
||||||
|
§/**
|
||||||
|
* @file Solid1D.h
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* $Author$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 2001 California Institute of Technology
|
||||||
|
|
||||||
|
#ifndef CT_SOLID1D_H
|
||||||
|
#define CT_SOLID1D_H
|
||||||
|
|
||||||
|
#include "../transport/TransportBase.h"
|
||||||
|
#include "Domain1D.h"
|
||||||
|
#include "../Array.h"
|
||||||
|
#include "../sort.h"
|
||||||
|
#include "../ThermoPhase.h"
|
||||||
|
#include "../Kinetics.h"
|
||||||
|
#include "../funcs.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
class MultiJac;
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------
|
||||||
|
// Class Solid1D
|
||||||
|
//-----------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class for one-dimensional reacting solids with current
|
||||||
|
* transport. This class implements the one-dimensional
|
||||||
|
* similarity solution for a chemically-reacting, axisymmetric,
|
||||||
|
* stagnation-point flow.
|
||||||
|
*/
|
||||||
|
class Solid1D : public Domain1D {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------
|
||||||
|
// constants
|
||||||
|
//------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offsets of solution components in the solution array.
|
||||||
|
*/
|
||||||
|
const unsigned int c_phi_loc; // electric potential
|
||||||
|
const unsigned int c_T_loc; // temperature
|
||||||
|
const unsigned int c_C_loc; // concentrations
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
// construction and destruction
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
// Constructor.
|
||||||
|
Solid1D(ThermoPhase* ph = 0, int nsp = 1, int points = 1);
|
||||||
|
|
||||||
|
/// Destructor.
|
||||||
|
virtual ~Solid1D(){}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Problem Specification
|
||||||
|
*/
|
||||||
|
//@{
|
||||||
|
|
||||||
|
virtual void setupGrid(int n, const doublereal* z);
|
||||||
|
|
||||||
|
thermo_t& phase() { return *m_thermo; }
|
||||||
|
kinetics_t& kinetics() { return *m_kin; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the thermo manager.
|
||||||
|
*/
|
||||||
|
void setThermo(thermo_t& th) {
|
||||||
|
m_thermo = &th;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// set the kinetics manager
|
||||||
|
void setKinetics(kinetics_t& kin) { m_kin = &kin; }
|
||||||
|
|
||||||
|
/// set the transport manager
|
||||||
|
void setTransport(Transport& trans);
|
||||||
|
|
||||||
|
virtual void setState(int point, const doublereal* state) {
|
||||||
|
setTemperature(point, state[c_T_loc]);
|
||||||
|
setElectricPotential(point, state[c_phi_loc);
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
setConcentration(point, k, state[c_C_loc+k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual void _getInitialSoln(doublereal* x) {
|
||||||
|
int k, j;
|
||||||
|
for (j = 0; j < m_points; j++) {
|
||||||
|
x[index(c_T_loc,j)] = T_fixed(j);
|
||||||
|
x[index(c_phi_loc,j)] = phi_fixed(j);
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
x[index(c_C_loc+k,j)] = C_fixed(k,j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void _finalize(const doublereal* x) {
|
||||||
|
int k, j;
|
||||||
|
doublereal zz, tt;
|
||||||
|
int nz = m_zfix.size();
|
||||||
|
bool e = m_do_energy[0];
|
||||||
|
for (j = 0; j < m_points; j++) {
|
||||||
|
if (e || nz == 0)
|
||||||
|
setTemperature(j, T(x, j));
|
||||||
|
else {
|
||||||
|
zz = (z(j) - z(0))/(z(m_points - 1) - z(0));
|
||||||
|
tt = linearInterp(zz, m_zfix, m_tfix);
|
||||||
|
setTemperature(j, tt);
|
||||||
|
}
|
||||||
|
setElectricPotential(j, phi(x,j));
|
||||||
|
for (k = 0; k < m_nsp; k++) {
|
||||||
|
setConcentration(j, k, C(x, k, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e) solveEnergyEqn();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setFixedTempProfile(vector_fp& zfixed, vector_fp& tfixed) {
|
||||||
|
m_zfix = zfixed;
|
||||||
|
m_tfix = tfixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the temperature fixed point at grid point j, and
|
||||||
|
* disable the energy equation so that the solution will be
|
||||||
|
* held to this value.
|
||||||
|
*/
|
||||||
|
void setTemperature(int j, doublereal t) {
|
||||||
|
m_fixedtemp[j] = t;
|
||||||
|
m_do_energy[j] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the electric potential fixed point at grid point j, and
|
||||||
|
* disable Gauss's equation so that the solution will be
|
||||||
|
* held to this value.
|
||||||
|
*/
|
||||||
|
void setElectricPotential(int j, doublereal phi) {
|
||||||
|
m_fixedphi[j] = phi;
|
||||||
|
m_do_gauss[j] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the mass fraction fixed point for species k at grid
|
||||||
|
* point j, and disable the species equation so that the
|
||||||
|
* solution will be held to this value.
|
||||||
|
*/
|
||||||
|
void setConcentration(int j, int k, doublereal c) {
|
||||||
|
m_fixedc(k,j) = c;
|
||||||
|
m_do_species[k] = true; // false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fixed temperature value at point j.
|
||||||
|
*/
|
||||||
|
doublereal T_fixed(int j) const {return m_fixedtemp[j];}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fixed potential value at point j.
|
||||||
|
*/
|
||||||
|
doublereal phi_fixed(int j) const {return m_fixedphi[j];}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The fixed mass fraction value of species k at point j.
|
||||||
|
*/
|
||||||
|
doublereal C_fixed(int k, int j) const {return m_fixedc(k,j);}
|
||||||
|
|
||||||
|
virtual string componentName(int n) const;
|
||||||
|
|
||||||
|
void setDielectricConstant(doublereal e) { m_eps = e; }
|
||||||
|
doublereal dielectricConstant() { return e; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a Tecplot zone corresponding to the current solution.
|
||||||
|
* May be called multiple times to generate animation.
|
||||||
|
*/
|
||||||
|
void outputTEC(ostream &s, const doublereal* x,
|
||||||
|
string title, int zone);
|
||||||
|
|
||||||
|
virtual void showSolution(const doublereal* x);
|
||||||
|
|
||||||
|
virtual void save(XML_Node& o, doublereal* sol);
|
||||||
|
|
||||||
|
virtual void restore(XML_Node& dom, doublereal* soln);
|
||||||
|
|
||||||
|
// overloaded in subclasses
|
||||||
|
virtual string solidType() { return "<none>"; }
|
||||||
|
|
||||||
|
void solveEnergyEqn(int j=-1) {
|
||||||
|
if (j < 0)
|
||||||
|
for (int i = 0; i < m_points; i++)
|
||||||
|
m_do_energy[i] = true;
|
||||||
|
else
|
||||||
|
m_do_energy[j] = true;
|
||||||
|
m_refiner->setActive(c_T_loc, true);
|
||||||
|
needJacUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixTemperature(int j=-1) {
|
||||||
|
if (j < 0)
|
||||||
|
for (int i = 0; i < m_points; i++) {
|
||||||
|
m_do_energy[i] = false;
|
||||||
|
}
|
||||||
|
else m_do_energy[j] = false;
|
||||||
|
m_refiner->setActive(c_T_loc, false);
|
||||||
|
needJacUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void solveGaussEqn(int j=-1) {
|
||||||
|
if (j < 0)
|
||||||
|
for (int i = 0; i < m_points; i++)
|
||||||
|
m_do_gauss[i] = true;
|
||||||
|
else
|
||||||
|
m_do_gauss[j] = true;
|
||||||
|
m_refiner->setActive(c_phi_loc, true);
|
||||||
|
needJacUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixElectricPotential(int j=-1) {
|
||||||
|
if (j < 0)
|
||||||
|
for (int i = 0; i < m_points; i++) {
|
||||||
|
m_do_gauss[i] = false;
|
||||||
|
}
|
||||||
|
else m_do_gauss[j] = false;
|
||||||
|
m_refiner->setActive(c_phi_loc, false);
|
||||||
|
needJacUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool doSpecies(int k) { return m_do_species[k]; }
|
||||||
|
bool doEnergy(int j) { return m_do_energy[j]; }
|
||||||
|
bool doGauss(int j) { return m_do_gauss[j]; }
|
||||||
|
|
||||||
|
void solveSpecies(int k=-1) {
|
||||||
|
if (k == -1) {
|
||||||
|
for (int i = 0; i < m_nsp; i++)
|
||||||
|
m_do_species[i] = true;
|
||||||
|
}
|
||||||
|
else m_do_species[k] = true;
|
||||||
|
needJacUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fixSpecies(int k=-1) {
|
||||||
|
if (k == -1) {
|
||||||
|
for (int i = 0; i < m_nsp; i++)
|
||||||
|
m_do_species[i] = false;
|
||||||
|
}
|
||||||
|
else m_do_species[k] = false;
|
||||||
|
needJacUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void resize(int points);
|
||||||
|
|
||||||
|
void setJac(MultiJac* jac);
|
||||||
|
void setThermoState(const doublereal* x,int j);
|
||||||
|
void setStateAtMidpoint(const doublereal* x,int j);
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
doublereal component(const doublereal* x, int i, int j) const {
|
||||||
|
doublereal xx = x[index(i,j)];
|
||||||
|
return xx;
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal wdot(int k, int j) const {return m_wdot(k,j);}
|
||||||
|
|
||||||
|
/// write the net production rates at point j into array m_wdot
|
||||||
|
void getWdot(doublereal* x,int j) {
|
||||||
|
setThermoState(x,j);
|
||||||
|
m_kin->getNetProductionRates(&m_wdot(0,j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* update the thermodynamic properties from point
|
||||||
|
* j0 to point j1 (inclusive), based on solution x.
|
||||||
|
*/
|
||||||
|
void updateThermo(const doublereal* x, int j0, int j1) {
|
||||||
|
int j;
|
||||||
|
for (j = j0; j <= j1; j++) {
|
||||||
|
setThermoState(x,j);
|
||||||
|
m_cp[j] = m_thermo->cp_mass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------
|
||||||
|
// solution components
|
||||||
|
//--------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
doublereal T(const doublereal* x,int j) const {
|
||||||
|
return x[index(c_T_loc, j)];
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal& T(doublereal* x,int j) {return x[index(c_T_loc, j)];}
|
||||||
|
|
||||||
|
doublereal T_prev(int j) const {return prevSoln(c_T_loc, j);}
|
||||||
|
|
||||||
|
doublereal C(const doublereal* x,int k, int j) const {
|
||||||
|
return x[index(c_C_loc + k, j)];
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal& C(doublereal* x,int k, int j) {
|
||||||
|
return x[index(c_C_loc + k, j)];
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal C_prev(int k, int j) const {
|
||||||
|
return prevSoln(c_C_loc + k, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal flux(int k, int j) const {
|
||||||
|
return m_flux(k, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal phi(doublereal* x, j) {
|
||||||
|
return x[index(c_phi_loc, j)];
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal divHeatFlux(const doublereal* x, int j) const {
|
||||||
|
doublereal c1 = m_tcon[j-1]*(T(x,j) - T(x,j-1));
|
||||||
|
doublereal c2 = m_tcon[j]*(T(x,j+1) - T(x,j));
|
||||||
|
return -2.0*(c2/(z(j+1) - z(j)) - c1/(z(j) - z(j-1)))/(z(j+1) - z(j-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
doublereal divDisplCurr(const doublereal* x, int j) const {
|
||||||
|
doublereal c1 = (phi(x,j) - phi(x,j-1));
|
||||||
|
doublereal c2 = (phi(x,j+1) - phi(x,j));
|
||||||
|
return -2.0*m_eps*epsilon_0*
|
||||||
|
(c2/(z(j+1) - z(j)) - c1/(z(j) - z(j-1)))/(z(j+1) - z(j-1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateDiffFluxes(const doublereal* x, int j0, int j1);
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
//
|
||||||
|
// member data
|
||||||
|
//
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
doublereal m_eps // relative dielectric constant
|
||||||
|
|
||||||
|
// grid parameters
|
||||||
|
vector_fp m_dz;
|
||||||
|
|
||||||
|
// mixture thermo properties
|
||||||
|
vector_fp m_cdens;
|
||||||
|
|
||||||
|
// transport properties
|
||||||
|
vector_fp m_tcon;
|
||||||
|
vector_fp m_diff;
|
||||||
|
Array2D m_flux;
|
||||||
|
|
||||||
|
// production rates
|
||||||
|
Array2D m_wdot;
|
||||||
|
|
||||||
|
int m_nsp;
|
||||||
|
|
||||||
|
thermo_t* m_thermo;
|
||||||
|
kinetics_t* m_kin;
|
||||||
|
Transport* m_trans;
|
||||||
|
|
||||||
|
MultiJac* m_jac;
|
||||||
|
|
||||||
|
bool m_ok;
|
||||||
|
|
||||||
|
// flags
|
||||||
|
vector<bool> m_do_energy;
|
||||||
|
vector<bool> m_do_species;
|
||||||
|
vector<bool> m_do_gauss;
|
||||||
|
|
||||||
|
// fixed T and Y values
|
||||||
|
Array2D m_fixedy;
|
||||||
|
Array2D m_fixedphi;
|
||||||
|
vector_fp m_fixedtemp;
|
||||||
|
vector_fp m_zfix;
|
||||||
|
vector_fp m_tfix;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
vector_fp m_cbar;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -58,10 +58,10 @@ namespace Cantera {
|
||||||
m_nv = m_domain->nComponents();
|
m_nv = m_domain->nComponents();
|
||||||
|
|
||||||
// check consistency
|
// check consistency
|
||||||
if (n != m_domain->nPoints()) return -1;
|
if (n != m_domain->nPoints()) throw CanteraError("analyze","inconsistent");
|
||||||
|
|
||||||
|
|
||||||
if (n >= m_npmax) return 0;
|
if (n >= m_npmax) throw CanteraError("analyze","max points");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* find locations where cell size ratio is too large.
|
* find locations where cell size ratio is too large.
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Cantera {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
for (int i = 0; i < m_nv; i++) {
|
for (int i = 0; i < m_nv; i++) {
|
||||||
//cout << i << " " << m_nv << " " << m_active[i] << endl;
|
cout << i << " " << m_nv << " " << m_active[i] << endl;
|
||||||
if (m_active[i]) {
|
if (m_active[i]) {
|
||||||
name = m_domain->componentName(i);
|
name = m_domain->componentName(i);
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@ namespace Cantera {
|
||||||
m_c[name] = 1;
|
m_c[name] = 1;
|
||||||
if (int(m_loc.size()) + n > m_npmax) goto done;
|
if (int(m_loc.size()) + n > m_npmax) goto done;
|
||||||
}
|
}
|
||||||
if (r >= 0.0) {
|
if (r >= -1.0) {
|
||||||
m_keep[j] = 1;
|
m_keep[j] = 1;
|
||||||
m_keep[j+1] = 1;
|
m_keep[j+1] = 1;
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +155,7 @@ namespace Cantera {
|
||||||
m_loc[j+1] = 1;
|
m_loc[j+1] = 1;
|
||||||
if (int(m_loc.size()) + n > m_npmax) goto done;
|
if (int(m_loc.size()) + n > m_npmax) goto done;
|
||||||
}
|
}
|
||||||
if (r >= 0.0) {
|
if (r >= -1.0) {
|
||||||
m_keep[j+1] = 1;
|
m_keep[j+1] = 1;
|
||||||
}
|
}
|
||||||
//cout << "at point " << j << " slope r = "
|
//cout << "at point " << j << " slope r = "
|
||||||
|
|
|
||||||
84
Cantera/src/transport/SolidTransport.cpp
Normal file
84
Cantera/src/transport/SolidTransport.cpp
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @file SolidTransport.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Author$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*/
|
||||||
|
|
||||||
|
// copyright 2003 California Institute of Technology
|
||||||
|
|
||||||
|
|
||||||
|
// turn off warnings under Windows
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning(disable:4786)
|
||||||
|
#pragma warning(disable:4503)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "SolidTransport.h"
|
||||||
|
|
||||||
|
#include "utilities.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
//////////////////// class SolidTransport methods //////////////
|
||||||
|
|
||||||
|
SolidTransport::SolidTransport() {}
|
||||||
|
|
||||||
|
void SolidTransport::setParameters(int n, int k, double* p) {
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
m_sp.push_back(k);
|
||||||
|
m_Adiff.push_back(p[0]);
|
||||||
|
m_Ndiff.push_back(p[1]);
|
||||||
|
m_Ediff.push_back(p[2]);
|
||||||
|
m_nmobile = m_sp.size();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
m_lam = p[0];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************************
|
||||||
|
*
|
||||||
|
* Public methods
|
||||||
|
*
|
||||||
|
*********************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
void SolidTransport::getMobilities(doublereal* mobil) {
|
||||||
|
int k;
|
||||||
|
getMixDiffCoeffs(mobil);
|
||||||
|
doublereal t = m_thermo->temperature();
|
||||||
|
int nsp = m_thermo->nSpecies();
|
||||||
|
doublereal c1 = ElectronCharge / (Boltzmann * t);
|
||||||
|
for (k = 0; k < nsp; k++) {
|
||||||
|
mobil[k] *= c1 * m_thermo->charge(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
doublereal SolidTransport::thermalConductivity() {
|
||||||
|
return m_lam;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SolidTransport::getMixDiffCoeffs(doublereal* d) {
|
||||||
|
doublereal temp = m_thermo->temperature();
|
||||||
|
int nsp = m_thermo->nSpecies();
|
||||||
|
int k;
|
||||||
|
for (k = 0; k < nsp; k++) d[k] = 0.0;
|
||||||
|
for (k = 0; k < m_nmobile; k++) {
|
||||||
|
d[m_sp[k]] =
|
||||||
|
m_Adiff[k] * pow(temp, m_Ndiff[k]) * exp(-m_Ediff[k]/temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
Cantera/src/transport/SolidTransport.h
Normal file
81
Cantera/src/transport/SolidTransport.h
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @file SolidTransport.h
|
||||||
|
* Header file defining class SolidTransport
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Author$
|
||||||
|
* $Revision$
|
||||||
|
* $Date$
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Copyright 2003 California Institute of Technology
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CT_SOLIDTRAN_H
|
||||||
|
#define CT_SOLIDTRAN_H
|
||||||
|
|
||||||
|
|
||||||
|
// turn off warnings under Windows
|
||||||
|
#ifdef WIN32
|
||||||
|
#pragma warning(disable:4786)
|
||||||
|
#pragma warning(disable:4503)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// STL includes
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <numeric>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// Cantera includes
|
||||||
|
#include "TransportBase.h"
|
||||||
|
#include "../DenseMatrix.h"
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class SolidTransport implements transport
|
||||||
|
* properties for solids.
|
||||||
|
*/
|
||||||
|
class SolidTransport : public Transport {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~SolidTransport() {}
|
||||||
|
|
||||||
|
virtual int model() { return cSolidTransport; }
|
||||||
|
|
||||||
|
virtual doublereal thermalConductivity();
|
||||||
|
virtual void getMixDiffCoeffs(doublereal* d);
|
||||||
|
virtual void getMobilities(doublereal* mobil);
|
||||||
|
virtual void setParameters(int n, int k, doublereal* p);
|
||||||
|
|
||||||
|
friend class TransportFactory;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// default constructor
|
||||||
|
SolidTransport();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int m_nmobile; // number of mobile species
|
||||||
|
vector_fp m_Adiff;
|
||||||
|
vector_fp m_Ndiff;
|
||||||
|
vector_fp m_Ediff;
|
||||||
|
vector_int m_sp;
|
||||||
|
doublereal m_lam;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ namespace Cantera {
|
||||||
if (units == "") return 1.0;
|
if (units == "") return 1.0;
|
||||||
doublereal f = 1.0, fctr;
|
doublereal f = 1.0, fctr;
|
||||||
int tsize;
|
int tsize;
|
||||||
string u = units, tok;
|
string u = units, tok, tsub;
|
||||||
int k;
|
int k;
|
||||||
char action = '-';
|
char action = '-';
|
||||||
while (1 > 0) {
|
while (1 > 0) {
|
||||||
|
|
@ -33,18 +33,22 @@ namespace Cantera {
|
||||||
tok = u;
|
tok = u;
|
||||||
tsize = tok.size();
|
tsize = tok.size();
|
||||||
if (tok[tsize - 1] == '2') {
|
if (tok[tsize - 1] == '2') {
|
||||||
fctr = m_u[tok.substr(0,tsize-2)];
|
tsub = tok.substr(0,tsize-1);
|
||||||
|
fctr = m_u[tsub];
|
||||||
fctr *= fctr;
|
fctr *= fctr;
|
||||||
}
|
}
|
||||||
else if (tok[tsize - 1] == '3') {
|
else if (tok[tsize - 1] == '3') {
|
||||||
fctr = m_u[tok.substr(0,tsize-2)];
|
tsub = tok.substr(0,tsize-1);
|
||||||
|
fctr = m_u[tsub];
|
||||||
fctr *= fctr*fctr;
|
fctr *= fctr*fctr;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
tsub = tok;
|
||||||
fctr = m_u[tok];
|
fctr = m_u[tok];
|
||||||
|
}
|
||||||
|
|
||||||
if (fctr == 0)
|
if (fctr == 0)
|
||||||
throw CanteraError("toSI","unknown unit: "+tok);
|
throw CanteraError("toSI","unknown unit: "+tsub);
|
||||||
if (action == '-') f *= fctr;
|
if (action == '-') f *= fctr;
|
||||||
else if (action == '/') f /= fctr;
|
else if (action == '/') f /= fctr;
|
||||||
if (k < 0) break;
|
if (k < 0) break;
|
||||||
|
|
|
||||||
|
|
@ -1,100 +1,101 @@
|
||||||
<ctml>
|
<ctml>
|
||||||
<elementData caseSensitive="no">
|
<elementData caseSensitive="no">
|
||||||
<element name="H", atomicWt = " 1.00794"/>
|
<element name="H", atomicWt = "1.00794"/>
|
||||||
<element name="D", atomicWt = " 2.0 "/>
|
<element name="D", atomicWt = "2.0"/>
|
||||||
<element name="Tr", atomicWt = " 3.0 "/>
|
<element name="Tr", atomicWt = "3.0"/>
|
||||||
<element name="He", atomicWt = " 4.002602"/>
|
<element name="He", atomicWt = "4.002602"/>
|
||||||
<element name="Li", atomicWt = " 6.941 "/>
|
<element name="Li", atomicWt = "6.941"/>
|
||||||
<element name="Be", atomicWt = " 9.012182"/>
|
<element name="Be", atomicWt = "9.012182"/>
|
||||||
<element name="B", atomicWt = " 10.811 "/>
|
<element name="B", atomicWt = "10.811"/>
|
||||||
<element name="C", atomicWt = " 12.011 "/>
|
<element name="C", atomicWt = "12.011"/>
|
||||||
<element name="N", atomicWt = " 14.00674"/>
|
<element name="N", atomicWt = "14.00674"/>
|
||||||
<element name="O", atomicWt = " 15.9994 "/>
|
<element name="O", atomicWt = "15.9994"/>
|
||||||
<element name="F", atomicWt = " 18.9984032"/>
|
<element name="F", atomicWt = "18.9984032"/>
|
||||||
<element name="Ne", atomicWt = " 20.1797 "/>
|
<element name="Ne", atomicWt = "20.1797"/>
|
||||||
<element name="Na", atomicWt = " 22.98977"/>
|
<element name="Na", atomicWt = "22.98977"/>
|
||||||
<element name="Mg", atomicWt = " 24.3050 "/>
|
<element name="Mg", atomicWt = "24.3050"/>
|
||||||
<element name="Al", atomicWt = " 26.98154"/>
|
<element name="Al", atomicWt = "26.98154"/>
|
||||||
<element name="Si", atomicWt = " 28.0855 "/>
|
<element name="Si", atomicWt = "28.0855"/>
|
||||||
<element name="P", atomicWt = " 30.97376"/>
|
<element name="P", atomicWt = "30.97376"/>
|
||||||
<element name="S", atomicWt = " 32.066 "/>
|
<element name="S", atomicWt = "32.066"/>
|
||||||
<element name="Cl", atomicWt = " 35.4527 "/>
|
<element name="Cl", atomicWt = "35.4527"/>
|
||||||
<element name="Ar", atomicWt = " 39.948 "/>
|
<element name="Ar", atomicWt = "39.948"/>
|
||||||
<element name="K", atomicWt = " 39.0983 "/>
|
<element name="K", atomicWt = "39.0983"/>
|
||||||
<element name="Ca", atomicWt = " 40.078 "/>
|
<element name="Ca", atomicWt = "40.078"/>
|
||||||
<element name="Sc", atomicWt = " 44.95591"/>
|
<element name="Sc", atomicWt = "44.95591"/>
|
||||||
<element name="Ti", atomicWt = " 47.88 "/>
|
<element name="Ti", atomicWt = "47.88"/>
|
||||||
<element name="V", atomicWt = " 50.9415 "/>
|
<element name="V", atomicWt = "50.9415"/>
|
||||||
<element name="Cr", atomicWt = " 51.9961 "/>
|
<element name="Cr", atomicWt = "51.9961"/>
|
||||||
<element name="Mn", atomicWt = " 54.9381 "/>
|
<element name="Mn", atomicWt = "54.9381"/>
|
||||||
<element name="Fe", atomicWt = " 55.847 "/>
|
<element name="Fe", atomicWt = "55.847"/>
|
||||||
<element name="Co", atomicWt = " 58.9332 "/>
|
<element name="Co", atomicWt = "58.9332"/>
|
||||||
<element name="Ni", atomicWt = " 58.69 "/>
|
<element name="Ni", atomicWt = "58.69"/>
|
||||||
<element name="Cu", atomicWt = " 63.546 "/>
|
<element name="Cu", atomicWt = "63.546"/>
|
||||||
<element name="Zn", atomicWt = " 65.39 "/>
|
<element name="Zn", atomicWt = "65.39"/>
|
||||||
<element name="Ga", atomicWt = " 69.723 "/>
|
<element name="Ga", atomicWt = "69.723"/>
|
||||||
<element name="Ge", atomicWt = " 72.61 "/>
|
<element name="Ge", atomicWt = "72.61"/>
|
||||||
<element name="As", atomicWt = " 74.92159"/>
|
<element name="As", atomicWt = "74.92159"/>
|
||||||
<element name="Se", atomicWt = " 78.96 "/>
|
<element name="Se", atomicWt = "78.96"/>
|
||||||
<element name="Br", atomicWt = " 79.904 "/>
|
<element name="Br", atomicWt = "79.904"/>
|
||||||
<element name="Kr", atomicWt = " 83.80 "/>
|
<element name="Kr", atomicWt = "83.80"/>
|
||||||
<element name="Rb", atomicWt = " 85.4678 "/>
|
<element name="Rb", atomicWt = "85.4678"/>
|
||||||
<element name="Sr", atomicWt = " 87.62 "/>
|
<element name="Sr", atomicWt = "87.62"/>
|
||||||
<element name="Y", atomicWt = " 88.90585"/>
|
<element name="Y", atomicWt = "88.90585"/>
|
||||||
<element name="Zr", atomicWt = " 91.224 "/>
|
<element name="Zr", atomicWt = "91.224"/>
|
||||||
<element name="Nb", atomicWt = " 92.90638"/>
|
<element name="Nb", atomicWt = "92.90638"/>
|
||||||
<element name="Mo", atomicWt = " 95.94 "/>
|
<element name="Mo", atomicWt = "95.94 "/>
|
||||||
<element name="Tc", atomicWt = " 97.9072 "/>
|
<element name="Tc", atomicWt = "97.9072"/>
|
||||||
<element name="Ru", atomicWt = " 101.07 "/>
|
<element name="Ru", atomicWt = "101.07"/>
|
||||||
<element name="Rh", atomicWt = " 102.9055 "/>
|
<element name="Rh", atomicWt = "102.9055"/>
|
||||||
<element name="Pd", atomicWt = " 106.42 "/>
|
<element name="Pd", atomicWt = "106.42"/>
|
||||||
<element name="Ag", atomicWt = " 107.8682 "/>
|
<element name="Ag", atomicWt = "107.8682"/>
|
||||||
<element name="Cd", atomicWt = " 112.411 "/>
|
<element name="Cd", atomicWt = "112.411"/>
|
||||||
<element name="In", atomicWt = " 114.82 "/>
|
<element name="In", atomicWt = "114.82"/>
|
||||||
<element name="Sn", atomicWt = " 118.710 "/>
|
<element name="Sn", atomicWt = "118.710"/>
|
||||||
<element name="Sb", atomicWt = " 121.75 "/>
|
<element name="Sb", atomicWt = "121.75"/>
|
||||||
<element name="Te", atomicWt = " 127.6 "/>
|
<element name="Te", atomicWt = "127.6"/>
|
||||||
<element name="I", atomicWt = " 126.90447"/>
|
<element name="I", atomicWt = " 126.90447"/>
|
||||||
<element name="Xe", atomicWt = " 131.29 "/>
|
<element name="Xe", atomicWt = "131.29"/>
|
||||||
<element name="Cs", atomicWt = " 132.90543"/>
|
<element name="Cs", atomicWt = "132.90543"/>
|
||||||
<element name="Ba", atomicWt = " 137.327 "/>
|
<element name="Ba", atomicWt = "137.327"/>
|
||||||
<element name="La", atomicWt = " 138.9055 "/>
|
<element name="La", atomicWt = "138.9055"/>
|
||||||
<element name="Ce", atomicWt = " 140.115 "/>
|
<element name="Ce", atomicWt = "140.115"/>
|
||||||
<element name="Pr", atomicWt = " 140.90765"/>
|
<element name="Pr", atomicWt = "140.90765"/>
|
||||||
<element name="Nd", atomicWt = " 144.24 "/>
|
<element name="Nd", atomicWt = "144.24"/>
|
||||||
<element name="Pm", atomicWt = " 144.9127 "/>
|
<element name="Pm", atomicWt = "144.9127"/>
|
||||||
<element name="Sm", atomicWt = " 150.36 "/>
|
<element name="Sm", atomicWt = "150.36 "/>
|
||||||
<element name="Eu", atomicWt = " 151.965 "/>
|
<element name="Eu", atomicWt = "151.965"/>
|
||||||
<element name="Gd", atomicWt = " 157.25 "/>
|
<element name="Gd", atomicWt = "157.25"/>
|
||||||
<element name="Tb", atomicWt = " 158.92534"/>
|
<element name="Tb", atomicWt = "158.92534"/>
|
||||||
<element name="Dy", atomicWt = " 162.50 "/>
|
<element name="Dy", atomicWt = "162.50"/>
|
||||||
<element name="Ho", atomicWt = " 164.93032"/>
|
<element name="Ho", atomicWt = "164.93032"/>
|
||||||
<element name="Er", atomicWt = " 167.26 "/>
|
<element name="Er", atomicWt = "167.26"/>
|
||||||
<element name="Tm", atomicWt = " 168.93421"/>
|
<element name="Tm", atomicWt = "168.93421"/>
|
||||||
<element name="Yb", atomicWt = " 173.04 "/>
|
<element name="Yb", atomicWt = "173.04"/>
|
||||||
<element name="Lu", atomicWt = " 174.967 "/>
|
<element name="Lu", atomicWt = "174.967"/>
|
||||||
<element name="Hf", atomicWt = " 178.49 "/>
|
<element name="Hf", atomicWt = "178.49"/>
|
||||||
<element name="Ta", atomicWt = " 180.9479 "/>
|
<element name="Ta", atomicWt = "180.9479"/>
|
||||||
<element name="W", atomicWt = " 183.85 "/>
|
<element name="W", atomicWt = "183.85"/>
|
||||||
<element name="Re", atomicWt = " 186.207 "/>
|
<element name="Re", atomicWt = "186.207"/>
|
||||||
<element name="Os", atomicWt = " 190.2 "/>
|
<element name="Os", atomicWt = "190.2"/>
|
||||||
<element name="Ir", atomicWt = " 192.22 "/>
|
<element name="Ir", atomicWt = "192.22"/>
|
||||||
<element name="Pt", atomicWt = " 195.08 "/>
|
<element name="Pt", atomicWt = "195.08"/>
|
||||||
<element name="Au", atomicWt = " 196.96654"/>
|
<element name="Au", atomicWt = "196.96654"/>
|
||||||
<element name="Hg", atomicWt = " 200.59 "/>
|
<element name="Hg", atomicWt = "200.59"/>
|
||||||
<element name="Ti", atomicWt = " 204.3833 "/>
|
<element name="Ti", atomicWt = "204.3833"/>
|
||||||
<element name="Pb", atomicWt = " 207.2 "/>
|
<element name="Pb", atomicWt = "207.2"/>
|
||||||
<element name="Bi", atomicWt = " 208.98037"/>
|
<element name="Bi", atomicWt = "208.98037"/>
|
||||||
<element name="Po", atomicWt = " 208.9824 "/>
|
<element name="Po", atomicWt = "208.9824"/>
|
||||||
<element name="At", atomicWt = " 209.9871 "/>
|
<element name="At", atomicWt = "209.9871"/>
|
||||||
<element name="Rn", atomicWt = " 222.0176 "/>
|
<element name="Rn", atomicWt = "222.0176"/>
|
||||||
<element name="Fr", atomicWt = " 223.0197 "/>
|
<element name="Fr", atomicWt = "223.0197"/>
|
||||||
<element name="Ra", atomicWt = " 226.0254 "/>
|
<element name="Ra", atomicWt = "226.0254"/>
|
||||||
<element name="Ac", atomicWt = " 227.0279 "/>
|
<element name="Ac", atomicWt = "227.0279"/>
|
||||||
<element name="Th", atomicWt = " 232.0381 "/>
|
<element name="Th", atomicWt = "232.0381"/>
|
||||||
<element name="Pa", atomicWt = " 231.03588"/>
|
<element name="Pa", atomicWt = "231.03588"/>
|
||||||
<element name="U", atomicWt = " 238.0508 "/>
|
<element name="U", atomicWt = "238.0508"/>
|
||||||
<element name="Np", atomicWt = " 237.0482 "/>
|
<element name="Np", atomicWt = "237.0482"/>
|
||||||
<element name="Pu", atomicWt = " 244.0482 "/>
|
<element name="Pu", atomicWt = "244.0482"/>
|
||||||
|
<element name="E", atomicWt = "0.000545"/>
|
||||||
</elementData>
|
</elementData>
|
||||||
</ctml>
|
</ctml>
|
||||||
|
|
|
||||||
60
examples/cxx/flame1.cpp
Normal file
60
examples/cxx/flame1.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
|
||||||
|
#include "Cantera.h"
|
||||||
|
#include "IdealGasMix.h"
|
||||||
|
#include "transport.h"
|
||||||
|
|
||||||
|
main() {
|
||||||
|
|
||||||
|
// create the gas object
|
||||||
|
|
||||||
|
IdealGasMix gas("gri30.xml");
|
||||||
|
doublereal temp = 500.0;
|
||||||
|
doublereal pres = 2.0*OneAtm;
|
||||||
|
gas.setState_TPX(temp, pres, "CH4:1.0, O2:2.0, N2:7.52");
|
||||||
|
|
||||||
|
// create a transport manager that implements
|
||||||
|
// mixture-averaged transport properties
|
||||||
|
|
||||||
|
Transport* tr = newTransportMgr("Mix", &gas);
|
||||||
|
|
||||||
|
|
||||||
|
//============= build each domain ========================
|
||||||
|
|
||||||
|
|
||||||
|
//-------- step 1: create the stagnation flow -------------
|
||||||
|
|
||||||
|
StFlow flow(&gas);
|
||||||
|
|
||||||
|
// create an initial grid
|
||||||
|
doublereal z[] = {0.0, 0.05, 0.1, 0.15, 0.2};
|
||||||
|
flow.setupGrid(5, z);
|
||||||
|
|
||||||
|
// specify the objects to use to compute kinetic rates and
|
||||||
|
// transport properties
|
||||||
|
flow.setKinetics(&gas);
|
||||||
|
flow.setTransport(&tr);
|
||||||
|
|
||||||
|
flow.setPressure(0.05*OneAtm);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------- step 2: create the inlet -----------------------
|
||||||
|
|
||||||
|
Inlet1D inlet;
|
||||||
|
inlet.setMoleFractions("CH4:1, O2:2, N2:7.52");
|
||||||
|
inlet.setMdot(0.1);
|
||||||
|
|
||||||
|
|
||||||
|
//------- step 3: create the surface ---------------------
|
||||||
|
|
||||||
|
Surf1D surf;
|
||||||
|
|
||||||
|
//=================== create the container and insert the domains =====
|
||||||
|
|
||||||
|
vector<Resid1D*> domains;
|
||||||
|
domains.push_back(inlet);
|
||||||
|
domains.push_back(flow);
|
||||||
|
domains.push_back(surf);
|
||||||
|
|
||||||
|
OneDim flamesim(domains);
|
||||||
|
}
|
||||||
53
include/Interface.h
Normal file
53
include/Interface.h
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#ifndef CXX_INTERFACE
|
||||||
|
#define CXX_INTERFACE
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "kernel/SurfPhase.h"
|
||||||
|
#include "kernel/InterfaceKinetics.h"
|
||||||
|
#include "kernel/importCTML.h"
|
||||||
|
|
||||||
|
namespace Cantera {
|
||||||
|
|
||||||
|
class Interface :
|
||||||
|
public SurfPhase, public InterfaceKinetics
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Interface(string infile, string id, vector<ThermoPhase*> phases)
|
||||||
|
: m_ok(false), m_r(0) {
|
||||||
|
string path = findInputFile(infile);
|
||||||
|
ifstream fin(path.c_str());
|
||||||
|
if (!fin) {
|
||||||
|
throw CanteraError("Interface","could not open "
|
||||||
|
+path+" for reading.");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_r = new XML_Node("-");
|
||||||
|
m_r->build(fin);
|
||||||
|
|
||||||
|
XML_Node* x = find_XML("", m_r, id, "", "");
|
||||||
|
if (!x)
|
||||||
|
throw CanteraError("Interface","error in find_XML");
|
||||||
|
|
||||||
|
importPhase(*x, this);
|
||||||
|
phases.push_back(this);
|
||||||
|
importKinetics(*x, phases, this);
|
||||||
|
m_ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~Interface() {}
|
||||||
|
|
||||||
|
bool operator!() { return !m_ok;}
|
||||||
|
bool ready() { return m_ok; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_ok;
|
||||||
|
XML_Node* m_r;
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "kernel/oneD/Sim1D.h"
|
#include "kernel/oneD/Sim1D.h"
|
||||||
#include "kernel/oneD/OneDim.h"
|
#include "kernel/oneD/OneDim.h"
|
||||||
#include "kernel/oneD/Resid1D.h"
|
#include "kernel/oneD/Domain1D.h"
|
||||||
#include "kernel/oneD/Inlet1D.h"
|
#include "kernel/oneD/Inlet1D.h"
|
||||||
#include "kernel/oneD/MultiNewton.h"
|
#include "kernel/oneD/MultiNewton.h"
|
||||||
#include "kernel/oneD/MultiJac.h"
|
#include "kernel/oneD/MultiJac.h"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue