//! @file TransportData.cpp // This file is part of Cantera. See License.txt in the top-level directory or // at http://www.cantera.org/license.txt for license and copyright information. #include "cantera/transport/TransportData.h" #include "cantera/thermo/Species.h" #include "cantera/base/ctexceptions.h" #include "cantera/base/stringUtils.h" #include "cantera/base/ctml.h" #include namespace Cantera { GasTransportData::GasTransportData() : diameter(0.0) , well_depth(0.0) , dipole(0.0) , polarizability(0.0) , rotational_relaxation(0.0) , acentric_factor(0.0) , dispersion_coefficient(0.0) , quadrupole_polarizability(0.0) { } GasTransportData::GasTransportData( const std::string& geometry_, double diameter_, double well_depth_, double dipole_, double polarizability_, double rot_relax, double acentric, double dispersion, double quad_polar) : geometry(geometry_) , diameter(diameter_) , well_depth(well_depth_) , dipole(dipole_) , polarizability(polarizability_) , rotational_relaxation(rot_relax) , acentric_factor(acentric) , dispersion_coefficient(dispersion) , quadrupole_polarizability(quad_polar) { } void GasTransportData::setCustomaryUnits( const std::string& geometry_, double diameter_, double well_depth_, double dipole_, double polarizability_, double rot_relax, double acentric, double dispersion, double quad_polar) { 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 dispersion_coefficient = 1e-50 * dispersion; // convert from Angstroms^5 to m^5 quadrupole_polarizability = 1e-50 * quad_polar; // convert from Angstroms^5 to m^5 } void GasTransportData::validate(const Species& sp) { double nAtoms = 0; for (const auto& elem : sp.composition) { if (!caseInsensitiveEquals(elem.first, "E")) { nAtoms += elem.second; } } if (geometry == "atom") { if (nAtoms > 1) { throw CanteraError("GasTransportData::validate", "invalid geometry for species '{}'. 'atom' specified, but " "species contains multiple atoms.", sp.name); } } else if (geometry == "linear") { if (nAtoms < 2) { throw CanteraError("GasTransportData::validate", "invalid geometry for species '{}'. 'linear' specified, but " "species does not contain multiple atoms.", sp.name); } } else if (geometry == "nonlinear") { if (nAtoms < 3) { throw CanteraError("GasTransportData::validate", "invalid geometry for species '{}'. 'nonlinear' specified, but " "species only contains {} atoms.", sp.name, nAtoms); } } else { throw CanteraError("GasTransportData::validate", "invalid geometry for species '{}': '{}'.", sp.name, geometry); } if (well_depth < 0.0) { throw CanteraError("GasTransportData::validate", "negative well depth for species '{}'.", sp.name); } if (diameter <= 0.0) { throw CanteraError("GasTransportData::validate", "negative or zero diameter for species '{}'.", sp.name); } if (dipole < 0.0) { throw CanteraError("GasTransportData::validate", "negative dipole moment for species '{}'.", sp.name); } if (polarizability < 0.0) { throw CanteraError("GasTransportData::validate", "negative polarizability for species '{}'.", sp.name); } if (rotational_relaxation < 0.0) { throw CanteraError("GasTransportData::validate", "negative rotation relaxation number for species '{}'.", sp.name); } if (dispersion_coefficient < 0.0) { throw CanteraError("GasTransportData::validate", "negative dispersion coefficient for species '{}'.", sp.name); } if (quadrupole_polarizability < 0.0) { throw CanteraError("GasTransportData::validate", "negative quadrupole polarizability for species '{}'.", sp.name); } } void setupGasTransportData(GasTransportData& tr, const XML_Node& tr_node) { std::string geometry, dummy; getString(tr_node, "geometry", geometry, dummy); double diam = getFloat(tr_node, "LJ_diameter"); double welldepth = getFloat(tr_node, "LJ_welldepth"); double dipole = 0.0; getOptionalFloat(tr_node, "dipoleMoment", dipole); double polar = 0.0; getOptionalFloat(tr_node, "polarizability", polar); double rot = 0.0; getOptionalFloat(tr_node, "rotRelax", rot); double acentric = 0.0; getOptionalFloat(tr_node, "acentric_factor", acentric); double dispersion = 0.0; getOptionalFloat(tr_node, "dispersion_coefficient", dispersion); double quad = 0.0; getOptionalFloat(tr_node, "quadrupole_polarizability", quad); tr.setCustomaryUnits(geometry, diam, welldepth, dipole, polar, rot, acentric, dispersion, quad); } void setupGasTransportData(GasTransportData& tr, const AnyMap& node) { std::string geometry = node["geometry"].asString(); double welldepth = node["well-depth"].asDouble(); double diameter = node["diameter"].asDouble(); double dipole = node.getDouble("dipole", 0.0); double polar = node.getDouble("polarizability", 0.0); double rot = node.getDouble("rotational-relaxation", 0.0); double acentric = node.getDouble("acentric-factor", 0.0); double dispersion = node.getDouble("dispersion-coefficient", 0.0); double quad = node.getDouble("quadrupole-polarizability", 0.0); tr.setCustomaryUnits(geometry, diameter, welldepth, dipole, polar, rot, acentric, dispersion, quad); tr.input = node; } shared_ptr newTransportData(const XML_Node& transport_node) { std::string model = transport_node["model"]; if (model == "gas_transport") { auto tr = make_shared(); setupGasTransportData(*tr, transport_node); return tr; } else { // Transport model not handled here return make_shared(); } } unique_ptr newTransportData(const AnyMap& node) { if (node.getString("model", "") == "gas") { unique_ptr tr(new GasTransportData()); setupGasTransportData(*tr, node); return unique_ptr(move(tr)); } else { // Transport model not handled here unique_ptr tr(new TransportData()); tr->input = node; return tr; } } }