diff --git a/include/cantera/transport/TransportFactory.h b/include/cantera/transport/TransportFactory.h index f095a19e8..7ff10948c 100644 --- a/include/cantera/transport/TransportFactory.h +++ b/include/cantera/transport/TransportFactory.h @@ -174,6 +174,7 @@ private: * instance of TransportParams containing the transport data for * these species read from the file. * + * @param thermo The phase with species corresponding to the transport data * @param xspecies Vector of pointers to species XML_Node databases. * @param log reference to an XML_Node that will contain the log (unused) * @param names vector of species names that must be filled in with valid transport parameters @@ -181,7 +182,7 @@ private: * for the species listed in names (in the order of their listing * in names). */ - void getTransportData(const std::vector &xspecies, + void getTransportData(const ThermoPhase& thermo, const std::vector &xspecies, XML_Node& log, const std::vector& names, GasTransportParams& tr); diff --git a/interfaces/cython/cantera/test/test_transport.py b/interfaces/cython/cantera/test/test_transport.py index d7fcc7960..090469737 100644 --- a/interfaces/cython/cantera/test/test_transport.py +++ b/interfaces/cython/cantera/test/test_transport.py @@ -43,6 +43,53 @@ class TestTransport(utilities.CanteraTest): self.assertTrue(all(self.phase.multi_diff_coeffs.flat >= 0.0)) self.assertTrue(all(self.phase.thermal_diff_coeffs.flat != 0.0)) +class TestTransportGeometryFlags(utilities.CanteraTest): + phase_data = """ +units(length="cm", time="s", quantity="mol", act_energy="cal/mol") + +ideal_gas(name="test", + elements="O H", + species="H2 H H2O", + initial_state=state(temperature=300.0, pressure=OneAtm), + transport='Mix' +) + +species(name="H2", + atoms=" H:2 ", + thermo=const_cp(t0=1000, h0=51.7, s0=19.5, cp0=8.41), + transport=gas_transport( + geom="{H2}", + diam=2.92, well_depth=38.00, polar=0.79, rot_relax=280.00) +) + +species(name="H", + atoms=" H:1 ", + thermo=const_cp(t0=1000, h0=51.7, s0=19.5, cp0=8.41), + transport=gas_transport( + geom="{H}", + diam=2.05, well_depth=145.00) +) +species(name="H2O", + atoms=" H:2 O:1 ", + thermo=const_cp(t0=1000, h0=51.7, s0=19.5, cp0=8.41), + transport=gas_transport( + geom="{H2O}", + diam=2.60, well_depth=572.40, dipole=1.84, rot_relax=4.00) +) +""" + def test_bad_geometry(self): + ct.Solution(source=self.phase_data.format(H='atom', + H2='linear', + H2O='nonlinear')) + bad = [{'H':'linear', 'H2':'linear', 'H2O':'nonlinear'}, + {'H':'nonlinear', 'H2':'linear', 'H2O':'nonlinear'}, + {'H':'atom', 'H2':'atom', 'H2O':'nonlinear'}, + {'H':'atom', 'H2':'nonlinear', 'H2O':'nonlinear'}, + {'H':'atom', 'H2':'linear', 'H2O':'atom'}] + for geoms in bad: + with self.assertRaises(RuntimeError): + ct.Solution(source=self.phase_data.format(**geoms)) + class TestDustyGas(utilities.CanteraTest): def setUp(self): diff --git a/src/transport/TransportFactory.cpp b/src/transport/TransportFactory.cpp index e86437be7..9d284a92b 100644 --- a/src/transport/TransportFactory.cpp +++ b/src/transport/TransportFactory.cpp @@ -437,7 +437,7 @@ void TransportFactory::setupMM(const std::vector &transport_dat tr.w_ac.resize(nsp); XML_Node root, log; - getTransportData(transport_database, log, tr.thermo->speciesNames(), tr); + getTransportData(*thermo, transport_database, log, tr.thermo->speciesNames(), tr); for (size_t i = 0; i < nsp; i++) { tr.poly[i].resize(nsp); @@ -687,7 +687,7 @@ void TransportFactory::fitCollisionIntegrals(GasTransportParams& tr, } } -void TransportFactory::getTransportData(const std::vector &xspecies, +void TransportFactory::getTransportData(const ThermoPhase& thermo, const std::vector &xspecies, XML_Node& log, const std::vector &names, GasTransportParams& tr) { std::map speciesIndices; @@ -713,14 +713,32 @@ void TransportFactory::getTransportData(const std::vector &xspe // parameters are converted to SI units before storing + double nAtoms = 0; + size_t kSpec = thermo.speciesIndex(sp["name"]); + for (size_t m = 0; m < thermo.nElements(); m++) { + nAtoms += thermo.nAtoms(kSpec, m); + } + // Molecular geometry; rotational heat capacity / R XML_Node* geomNode = ctml::getByTitle(node, "geometry"); std::string geom = (geomNode) ? geomNode->value() : ""; if (geom == "atom") { + if (nAtoms != 1) { + throw TransportDBError(i, "invalid geometry. 'atom' specified," + " but species contains multiple atoms."); + } tr.crot[j] = 0.0; } else if (geom == "linear") { + if (nAtoms == 1) { + throw TransportDBError(i, "invalid geometry. 'linear' specified," + " but species only contains one atom."); + } tr.crot[j] = 1.0; } else if (geom == "nonlinear") { + if (nAtoms < 3) { + throw TransportDBError(i, "invalid geometry. 'nonlinear' specified," + " but species only contains " + fp2str(nAtoms) + " atoms."); + } tr.crot[j] = 1.5; } else { throw TransportDBError(i, "invalid geometry");