[Transport] Add gas phase transport parameters to Species objects

This commit is contained in:
Ray Speth 2015-01-08 23:36:22 +00:00
parent 5f33f426b8
commit 8022e9e01e
5 changed files with 231 additions and 1 deletions

View file

@ -4,11 +4,13 @@
#define CT_SPECIES_H
#include "cantera/base/ct_defs.h"
#include "cantera/base/smart_ptr.h"
namespace Cantera
{
class SpeciesThermoInterpType;
class TransportData;
//! Contains data about a single chemical species
/*!
@ -49,6 +51,8 @@ public:
//! The effective size [m] of the species
double size;
shared_ptr<TransportData> transport;
protected:
//! Thermodynamic data for the species
SpeciesThermoInterpType* thermo_;

View file

@ -0,0 +1,76 @@
//! @file TransportData.h
#ifndef CT_TRANSPORTDATA_H
#define CT_TRANSPORTDATA_H
#include "cantera/base/ct_defs.h"
namespace Cantera
{
class Species;
//! Base class for transport data for a single species
class TransportData
{
public:
TransportData() {}
explicit TransportData(const std::string& name);
virtual ~TransportData() {}
virtual void validate(const Species& species) {}
//! The name of the species
std::string name;
};
//! Transport data for a single gas-phase species which can be used in
//! mixture-averaged or multicomponent transport models.
class GasTransportData : public TransportData
{
public:
GasTransportData();
GasTransportData(const std::string& name, const std::string& geometry,
double diameter, double well_depth, double dipole=0.0,
double polarizability=0.0, double rot_relax=0.0,
double acentric=0.0);
//! Set the parameters using "customary" units: diameter in Angstroms, well
//! depth in Kelvin, dipole in Debye, and polarizability in Angstroms^3.
//! These are the units used in in CK-style input files.
void setCustomaryUnits(const std::string& name, const std::string& geometry,
double diameter, double well_depth, double dipole=0.0,
double polarizability=0.0, double rot_relax=0.0,
double acentric=0.0);
virtual void validate(const Species& species);
//! A string specifying the molecular geometry. One of `atom`, `linear`, or
//! `nonlinear`.
std::string geometry;
//! The Lennard-Jones collision diameter [m]
double diameter;
//! The Lennard-Jones well depth [J]
double well_depth;
//! The permanent dipole moment of the molecule [Coulomb-m]. Default 0.0.
double dipole;
//! The polarizability of the molecule [m^3]. Default 0.0.
double polarizability;
//! The rotational relaxation number (the number of collisions it takes to
//! equilibrate the rotational degrees of freedom with the temperature).
//! Default 0.0.
double rotational_relaxation;
// Pitzer's acentric factor [dimensionless]. Default 0.0.
double acentric_factor;
};
}
#endif

View file

@ -35,6 +35,7 @@ Species::Species(const Species& other)
, composition(other.composition)
, charge(other.charge)
, size(other.size)
, transport(other.transport)
{
if (other.thermo_) {
thermo_ = other.thermo_->duplMyselfAsSpeciesThermoInterpType();
@ -52,6 +53,7 @@ Species& Species::operator=(const Species& other)
composition = other.composition;
charge = other.charge;
size = other.size;
transport = other.transport;
delete thermo_;
if (other.thermo_) {
thermo_ = other.thermo_->duplMyselfAsSpeciesThermoInterpType();

View file

@ -52,6 +52,8 @@
#include "cantera/thermo/MixedSolventElectrolyte.h"
#include "cantera/thermo/IdealSolnGasVPSS.h"
#include "cantera/transport/TransportData.h"
#include "cantera/base/stringUtils.h"
using namespace std;
@ -621,7 +623,37 @@ bool installSpecies(size_t k, const XML_Node& s, thermo_t& th,
vp_ptr->createInstallPDSS(k, s, phaseNode_ptr);
} else {
SpeciesThermoInterpType* st = newSpeciesThermoInterpType(s);
th.addSpecies(Species(s["name"], comp_map, st, chrg, sz));
Species sp(s["name"], comp_map, st, chrg, sz);
// Read gas-phase transport data, if provided
if (s.hasChild("transport") &&
s.child("transport")["model"] == "gas_transport") {
XML_Node& tr = s.child("transport");
string geometry, dummy;
getString(tr, "geometry", geometry, dummy);
double diam = getFloat(tr, "LJ_diameter");
double welldepth = getFloat(tr, "LJ_welldepth");
double dipole = 0.0;
getOptionalFloat(tr, "dipoleMoment", dipole);
double polar = 0.0;
getOptionalFloat(tr, "polarizability", polar);
double rot = 0.0;
getOptionalFloat(tr, "rotRelax", rot);
double acentric = 0.0;
getOptionalFloat(tr, "acentric_factor", acentric);
GasTransportData* gastran = new GasTransportData;
gastran->setCustomaryUnits(sp.name, geometry, diam, welldepth,
dipole, polar, rot, acentric);
sp.transport.reset(gastran);
gastran->validate(sp);
}
th.addSpecies(sp);
}
return true;

View file

@ -0,0 +1,116 @@
//! @file TransportData.cpp
#include "cantera/transport/TransportData.h"
#include "cantera/thermo/Species.h"
#include "cantera/base/ctexceptions.h"
#include "cantera/base/stringUtils.h"
namespace Cantera
{
TransportData::TransportData(const std::string& name_)
: name(name_)
{
}
GasTransportData::GasTransportData()
: diameter(0.0)
, well_depth(0.0)
, dipole(0.0)
, polarizability(0.0)
, rotational_relaxation(0.0)
, acentric_factor(0.0)
{
}
GasTransportData::GasTransportData(
const std::string& name_, const std::string& geometry_,
double diameter_, double well_depth_, double dipole_,
double polarizability_, double rot_relax, double acentric)
: TransportData(name_)
, geometry(geometry_)
, diameter(diameter_)
, well_depth(well_depth_)
, dipole(dipole_)
, polarizability(polarizability_)
, rotational_relaxation(rot_relax)
, acentric_factor(acentric)
{
}
void GasTransportData::setCustomaryUnits(
const std::string& name_, const std::string& geometry_,
double diameter_, double well_depth_, double dipole_,
double polarizability_, double rot_relax, double acentric)
{
name = name_;
geometry = geometry_;
diameter = 1e-10 * diameter_; // convert from Angstroms to m
well_depth = Boltzmann * well_depth_; // convert from K to J
dipole = 1e-21 / lightSpeed * dipole_; // convert from Debye to Coulomb-m
polarizability = 1e-30 * polarizability_; // convert from Angstroms^3 to m^3
rotational_relaxation = rot_relax; // pure number
acentric_factor = acentric; // dimensionless
}
void GasTransportData::validate(const Species& sp)
{
double nAtoms = 0;
for (compositionMap::const_iterator iter = sp.composition.begin();
iter != sp.composition.end();
++iter) {
nAtoms += iter->second;
}
if (geometry == "atom") {
if (nAtoms != 1) {
throw CanteraError("GasTransportData::validate",
"invalid geometry for species '" + name + "'. 'atom' specified,"
" but species contains multiple atoms.");
}
} else if (geometry == "linear") {
if (nAtoms == 1) {
throw CanteraError("GasTransportData::validate",
"invalid geometry for species '" + name + "'. 'linear'"
" specified, but species only contains one atom.");
}
} else if (geometry == "nonlinear") {
if (nAtoms < 3) {
throw CanteraError("GasTransportData::validate",
"invalid geometry for species '" + name + "'. 'nonlinear'"
" specified, but species only contains " + fp2str(nAtoms) +
" atoms.");
}
} else {
throw CanteraError("GasTransportData::validate",
"invalid geometry for species '" + name + "': '" +
geometry + "'.");
}
if (well_depth < 0.0) {
throw CanteraError("GasTransportData::validate",
"negative well depth for species '" + name + "'.");
}
if (diameter <= 0.0) {
throw CanteraError("GasTransportData::validate",
"negative or zero diameter for species '" + name + "'.");
}
if (dipole < 0.0) {
throw CanteraError("GasTransportData::validate",
"negative dipole moment for species '" + name + "'.");
}
if (polarizability < 0.0) {
throw CanteraError("GasTransportData::validate",
"negative polarizability for species '" + name + "'.");
}
if (rotational_relaxation < 0.0) {
throw CanteraError("GasTransportData::validate",
"negative rotation relaxation number for species '" + name + "'");
}
}
}