Add case-sensitive/lowercase logic to Phase::species
Further: * revert unit tests to previous species definitions (some case mis-matches) * remove non-essential comments * opt to maintain case-sensitive species maps with lowercase as fallback
This commit is contained in:
parent
76dd997692
commit
717635d3e6
6 changed files with 60 additions and 49 deletions
|
|
@ -707,10 +707,6 @@ public:
|
|||
//! Return the Species object for the named species. Changes to this object
|
||||
//! do not affect the ThermoPhase object until the #modifySpecies function
|
||||
//! is called.
|
||||
/*!
|
||||
* @deprecated To be removed after Cantera 2.5. Replaceable with
|
||||
* Phase::species(size_t) via Phase::speciesIndex(std::string&).
|
||||
*/
|
||||
shared_ptr<Species> species(const std::string& name) const;
|
||||
|
||||
//! Return the Species object for species whose index is *k*. Changes to
|
||||
|
|
@ -809,15 +805,15 @@ protected:
|
|||
//! Flag determining behavior when adding species with an undefined element
|
||||
UndefElement::behavior m_undefinedElementBehavior;
|
||||
|
||||
//! Find lowercase species name in m_speciesIndices when case sensitive
|
||||
//! species names are not enforced. Raise exception if lowercase name
|
||||
//! is not unique.
|
||||
size_t findSpeciesLower(const std::string& nameStr) const;
|
||||
|
||||
//! Flag determining whether case sensitive species names are enforced
|
||||
bool m_caseSensitiveSpecies;
|
||||
|
||||
private:
|
||||
//! Find lowercase species name in m_speciesIndices when case sensitive
|
||||
//! species names are not enforced and a user specifies a non-canonical
|
||||
//! species name. Raise exception if lowercase name is not unique.
|
||||
size_t findSpeciesLower(const std::string& nameStr) const;
|
||||
|
||||
XML_Node* m_xml; //!< XML node containing the XML info for this phase
|
||||
|
||||
//! ID of the phase. This is the value of the ID attribute of the XML
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class TestThermoPhase(utilities.CanteraTest):
|
|||
self.assertEqual(list(X[0,:,0]), list(Y))
|
||||
|
||||
def test_setCompositionString(self):
|
||||
self.phase.X = 'H2:1.0, O2:1.0'
|
||||
self.phase.X = 'h2:1.0, o2:1.0'
|
||||
X = self.phase.X
|
||||
self.assertNear(X[0], 0.5)
|
||||
self.assertNear(X[3], 0.5)
|
||||
|
|
@ -161,7 +161,7 @@ class TestThermoPhase(utilities.CanteraTest):
|
|||
self.assertNear(Y[3], 0.75)
|
||||
|
||||
def test_getCompositionDict(self):
|
||||
self.phase.X = 'OH:1e-9, O2:0.4, AR:0.6'
|
||||
self.phase.X = 'oh:1e-9, O2:0.4, AR:0.6'
|
||||
self.assertEqual(len(self.phase.mole_fraction_dict(1e-7)), 2)
|
||||
self.assertEqual(len(self.phase.mole_fraction_dict()), 3)
|
||||
|
||||
|
|
@ -202,7 +202,7 @@ class TestThermoPhase(utilities.CanteraTest):
|
|||
self.phase.Y = {'H2':1.0, 'O2':'xx'}
|
||||
|
||||
def test_setCompositionSlice(self):
|
||||
self.phase['H2', 'O2'].X = 0.1, 0.9
|
||||
self.phase['h2', 'o2'].X = 0.1, 0.9
|
||||
X = self.phase.X
|
||||
self.assertNear(X[0], 0.1)
|
||||
self.assertNear(X[3], 0.9)
|
||||
|
|
@ -1257,7 +1257,7 @@ class TestMisc(utilities.CanteraTest):
|
|||
gas = ct.Solution('h2o2.xml')
|
||||
self.assertFalse(gas.case_sensitive_species_names)
|
||||
self.assertTrue(gas.species_index('h2') == 0)
|
||||
|
||||
|
||||
gas.case_sensitive_species_names = True
|
||||
self.assertTrue(gas.case_sensitive_species_names)
|
||||
with self.assertRaises(ValueError):
|
||||
|
|
|
|||
|
|
@ -183,7 +183,9 @@ size_t Phase::findSpeciesLower(const std::string& name) const
|
|||
loc = k.second;
|
||||
} else {
|
||||
throw CanteraError("Phase::findSpeciesLower",
|
||||
"Lowercase species name '{}' is not unique", nLower);
|
||||
"Lowercase species name '{}' is not unique. "
|
||||
"Set Phase::caseSensitiveSpecies to true to "
|
||||
"enforce case sensitive species names", nLower);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -193,23 +195,23 @@ size_t Phase::findSpeciesLower(const std::string& name) const
|
|||
size_t Phase::speciesIndex(const std::string& nameStr) const
|
||||
{
|
||||
size_t loc = npos;
|
||||
try {
|
||||
return m_speciesIndices.at(nameStr);
|
||||
} catch (std::out_of_range&) {
|
||||
if (!m_caseSensitiveSpecies) {
|
||||
loc = findSpeciesLower(nameStr);
|
||||
}
|
||||
std::map<std::string, size_t>::const_iterator it;
|
||||
|
||||
it = m_speciesIndices.find(nameStr);
|
||||
if (it != m_speciesIndices.end()) {
|
||||
return it->second;
|
||||
} else if (!m_caseSensitiveSpecies) {
|
||||
loc = findSpeciesLower(nameStr);
|
||||
}
|
||||
if (loc == npos && nameStr.find(':') != npos) {
|
||||
std::string pn;
|
||||
std::string sn = parseSpeciesName(nameStr, pn);
|
||||
if (pn == "" || pn == m_name || pn == m_id) {
|
||||
try {
|
||||
return m_speciesIndices.at(sn);
|
||||
} catch (std::out_of_range&) {
|
||||
if (!m_caseSensitiveSpecies) {
|
||||
return findSpeciesLower(sn);
|
||||
}
|
||||
it = m_speciesIndices.find(nameStr);
|
||||
if (it != m_speciesIndices.end()) {
|
||||
return it->second;
|
||||
} else if (!m_caseSensitiveSpecies) {
|
||||
return findSpeciesLower(sn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -320,20 +322,14 @@ void Phase::setMoleFractions_NoNorm(const doublereal* const x)
|
|||
void Phase::setMoleFractionsByName(const compositionMap& xMap)
|
||||
{
|
||||
vector_fp mf(m_kk, 0.0);
|
||||
|
||||
for (const auto& sp : xMap) {
|
||||
try {
|
||||
mf[m_speciesIndices.at(sp.first)] = sp.second;
|
||||
} catch (std::out_of_range&) {
|
||||
size_t loc = npos;
|
||||
if (!m_caseSensitiveSpecies) {
|
||||
loc = findSpeciesLower(sp.first);
|
||||
}
|
||||
if (loc == npos) {
|
||||
throw CanteraError("Phase::setMoleFractionsByName",
|
||||
"Unknown species '{}'", sp.first);
|
||||
} else {
|
||||
mf[loc] = sp.second;
|
||||
}
|
||||
size_t loc = speciesIndex(sp.first);
|
||||
if (loc != npos) {
|
||||
mf[loc] = sp.second;
|
||||
} else {
|
||||
throw CanteraError("Phase::setMoleFractionsByName",
|
||||
"Unknown species '{}'", sp.first);
|
||||
}
|
||||
}
|
||||
setMoleFractions(&mf[0]);
|
||||
|
|
@ -743,7 +739,6 @@ size_t Phase::addElement(const std::string& symbol, doublereal weight,
|
|||
}
|
||||
|
||||
bool Phase::addSpecies(shared_ptr<Species> spec) {
|
||||
// species names are case sensitive
|
||||
if (m_species.find(spec->name) != m_species.end()) {
|
||||
throw CanteraError("Phase::addSpecies",
|
||||
"Phase '{}' already contains a species named '{}'.",
|
||||
|
|
@ -849,13 +844,35 @@ void Phase::modifySpecies(size_t k, shared_ptr<Species> spec)
|
|||
invalidateCache();
|
||||
}
|
||||
|
||||
//! @deprecated To be removed after Cantera 2.5.
|
||||
shared_ptr<Species> Phase::species(const std::string& name) const
|
||||
{
|
||||
warn_deprecated("Phase::species(std::string&)",
|
||||
"To be removed after Cantera 2.5. "
|
||||
"Use Phase::species(size_t) instead.");
|
||||
return m_species.at(name);
|
||||
std::map<std::string, shared_ptr<Species> >::const_iterator it;
|
||||
|
||||
it = m_species.find(name);
|
||||
if (it != m_species.end()) {
|
||||
return it->second;
|
||||
} else if (!m_caseSensitiveSpecies) {
|
||||
std::string nLower = toLowerCopy(name);
|
||||
bool found = false;
|
||||
shared_ptr<Species> sp;
|
||||
for (const auto& k : m_species) {
|
||||
if (toLowerCopy(k.first) == nLower) {
|
||||
if (!found) {
|
||||
found = true;
|
||||
sp = k.second;
|
||||
} else {
|
||||
throw CanteraError("Phase::species",
|
||||
"Lowercase species name '{}' is not unique. "
|
||||
"Set Phase::caseSensitiveSpecies to true to "
|
||||
"enforce case sensitive species names", nLower);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sp;
|
||||
} else {
|
||||
throw CanteraError("Phase::setMassFractionsByName",
|
||||
"Unknown species '{}'", name);
|
||||
}
|
||||
}
|
||||
|
||||
shared_ptr<Species> Phase::species(size_t k) const
|
||||
|
|
|
|||
|
|
@ -710,8 +710,6 @@ vector<double> RedlichKwongMFTP::getCoeff(const std::string& iName)
|
|||
// based on crit properties T_c and P_c:
|
||||
for (size_t isp = 0; isp < nDatabase; isp++) {
|
||||
XML_Node& acNodeDoc = doc->child(isp);
|
||||
// not enforcing case sensitive species names as this is external
|
||||
// to CTI or YAML input files
|
||||
std::string iNameLower = toLowerCopy(iName);
|
||||
std::string dbName = toLowerCopy(acNodeDoc.attrib("name"));
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ TEST_F(TestThermoMethods, getMoleFractionsByName)
|
|||
EXPECT_DOUBLE_EQ(X["H2"], 0.3);
|
||||
EXPECT_DOUBLE_EQ(X["AR"], 0.5);
|
||||
|
||||
thermo->setMoleFractionsByName("OH:1e-9, O2:0.2, H2:0.3, AR:0.5");
|
||||
thermo->setMoleFractionsByName("OH:1e-9, O2:0.2, h2:0.3, AR:0.5");
|
||||
X = thermo->getMoleFractionsByName();
|
||||
EXPECT_EQ(X.size(), (size_t) 4);
|
||||
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ TEST_F(ConstructFromScratch, addUndefinedElements)
|
|||
ASSERT_EQ((size_t) 4, p.nSpecies());
|
||||
ASSERT_EQ((size_t) 3, p.nElements());
|
||||
ASSERT_EQ((size_t) 1, p.nAtoms(p.speciesIndex("CO2"), p.elementIndex("C")));
|
||||
ASSERT_EQ((size_t) 2, p.nAtoms(p.speciesIndex("CO2"), p.elementIndex("O")));
|
||||
ASSERT_EQ((size_t) 2, p.nAtoms(p.speciesIndex("co2"), p.elementIndex("O")));
|
||||
p.setMassFractionsByName("H2:0.5, CO2:0.5");
|
||||
ASSERT_DOUBLE_EQ(0.5, p.massFraction("CO2"));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue