mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
Make use of C++17 structured bindings to improve readability
This commit is contained in:
parent
a6196d3744
commit
56c3a077f7
@ -87,8 +87,8 @@ AnyValue& AnyValue::operator=(const std::unordered_map<std::string, T> items) {
|
|||||||
*m_value = AnyMap();
|
*m_value = AnyMap();
|
||||||
m_equals = eq_comparer<AnyMap>;
|
m_equals = eq_comparer<AnyMap>;
|
||||||
AnyMap& dest = as<AnyMap>();
|
AnyMap& dest = as<AnyMap>();
|
||||||
for (const auto& item : items) {
|
for (const auto& [key, value] : items) {
|
||||||
dest[item.first] = item.second;
|
dest[key] = value;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -98,8 +98,8 @@ AnyValue& AnyValue::operator=(const std::map<std::string, T> items) {
|
|||||||
*m_value = AnyMap();
|
*m_value = AnyMap();
|
||||||
m_equals = eq_comparer<AnyMap>;
|
m_equals = eq_comparer<AnyMap>;
|
||||||
AnyMap& dest = as<AnyMap>();
|
AnyMap& dest = as<AnyMap>();
|
||||||
for (const auto& item : items) {
|
for (const auto& [key, value] : items) {
|
||||||
dest[item.first] = item.second;
|
dest[key] = value;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -107,8 +107,8 @@ public:
|
|||||||
void updateFromStruct(const BlowersMaselData& shared_data) {
|
void updateFromStruct(const BlowersMaselData& shared_data) {
|
||||||
if (shared_data.ready) {
|
if (shared_data.ready) {
|
||||||
m_deltaH_R = 0.;
|
m_deltaH_R = 0.;
|
||||||
for (const auto& item : m_stoich_coeffs) {
|
for (const auto& [k, multiplier] : m_stoich_coeffs) {
|
||||||
m_deltaH_R += shared_data.partialMolarEnthalpies[item.first] * item.second;
|
m_deltaH_R += shared_data.partialMolarEnthalpies[k] * multiplier;
|
||||||
}
|
}
|
||||||
m_deltaH_R /= GasConstant;
|
m_deltaH_R /= GasConstant;
|
||||||
}
|
}
|
||||||
|
@ -237,8 +237,11 @@ protected:
|
|||||||
double m_deltaPotential_RT; //!< Normalized electric potential energy change
|
double m_deltaPotential_RT; //!< Normalized electric potential energy change
|
||||||
double m_deltaGibbs0_RT; //!< Normalized standard state Gibbs free energy change
|
double m_deltaGibbs0_RT; //!< Normalized standard state Gibbs free energy change
|
||||||
double m_prodStandardConcentrations; //!< Products of standard concentrations
|
double m_prodStandardConcentrations; //!< Products of standard concentrations
|
||||||
std::map<size_t, size_t> m_indices; //!< Map holding indices of coverage species
|
|
||||||
std::vector<std::string> m_cov; //!< Vector holding names of coverage species
|
//! Map from coverage dependencies stored in this object to the index of the
|
||||||
|
//! coverage species in the Kinetics object
|
||||||
|
map<size_t, size_t> m_indices;
|
||||||
|
vector<string> m_cov; //!< Vector holding names of coverage species
|
||||||
vector_fp m_ac; //!< Vector holding coverage-specific exponential dependence
|
vector_fp m_ac; //!< Vector holding coverage-specific exponential dependence
|
||||||
vector_fp m_ec; //!< Vector holding coverage-specific activation energy dependence
|
vector_fp m_ec; //!< Vector holding coverage-specific activation energy dependence
|
||||||
vector_fp m_mc; //!< Vector holding coverage-specific power-law exponents
|
vector_fp m_mc; //!< Vector holding coverage-specific power-law exponents
|
||||||
|
@ -65,8 +65,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void getRateConstants(double* kf) override {
|
virtual void getRateConstants(double* kf) override {
|
||||||
for (auto& rxn : m_rxn_rates) {
|
for (auto& [iRxn, rate] : m_rxn_rates) {
|
||||||
kf[rxn.first] = rxn.second.evalFromStruct(m_shared);
|
kf[iRxn] = rate.evalFromStruct(m_shared);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,8 +172,8 @@ protected:
|
|||||||
template <typename T=RateType,
|
template <typename T=RateType,
|
||||||
typename std::enable_if<has_ddT<T>::value, bool>::type = true>
|
typename std::enable_if<has_ddT<T>::value, bool>::type = true>
|
||||||
void _process_ddT(double* rop, const double* kf, double deltaT) {
|
void _process_ddT(double* rop, const double* kf, double deltaT) {
|
||||||
for (const auto& rxn : m_rxn_rates) {
|
for (const auto& [iRxn, rate] : m_rxn_rates) {
|
||||||
rop[rxn.first] *= rxn.second.ddTScaledFromStruct(m_shared);
|
rop[iRxn] *= rate.ddTScaledFromStruct(m_shared);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,10 +188,10 @@ protected:
|
|||||||
_update();
|
_update();
|
||||||
|
|
||||||
// apply numerical derivative
|
// apply numerical derivative
|
||||||
for (auto& rxn : m_rxn_rates) {
|
for (auto& [iRxn, rate] : m_rxn_rates) {
|
||||||
if (kf[rxn.first] != 0.) {
|
if (kf[iRxn] != 0.) {
|
||||||
double k1 = rxn.second.evalFromStruct(m_shared);
|
double k1 = rate.evalFromStruct(m_shared);
|
||||||
rop[rxn.first] *= dTinv * (k1 / kf[rxn.first] - 1.);
|
rop[iRxn] *= dTinv * (k1 / kf[iRxn] - 1.);
|
||||||
} // else not needed: derivative is already zero
|
} // else not needed: derivative is already zero
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,13 +209,13 @@ protected:
|
|||||||
m_shared.perturbThirdBodies(deltaM);
|
m_shared.perturbThirdBodies(deltaM);
|
||||||
_update();
|
_update();
|
||||||
|
|
||||||
for (auto& rxn : m_rxn_rates) {
|
for (auto& [iRxn, rate] : m_rxn_rates) {
|
||||||
if (kf[rxn.first] != 0. && m_shared.conc_3b[rxn.first] > 0.) {
|
if (kf[iRxn] != 0. && m_shared.conc_3b[iRxn] > 0.) {
|
||||||
double k1 = rxn.second.evalFromStruct(m_shared);
|
double k1 = rate.evalFromStruct(m_shared);
|
||||||
rop[rxn.first] *= dMinv * (k1 / kf[rxn.first] - 1.);
|
rop[iRxn] *= dMinv * (k1 / kf[iRxn] - 1.);
|
||||||
rop[rxn.first] /= m_shared.conc_3b[rxn.first];
|
rop[iRxn] /= m_shared.conc_3b[iRxn];
|
||||||
} else {
|
} else {
|
||||||
rop[rxn.first] = 0.;
|
rop[iRxn] = 0.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,8 +232,8 @@ protected:
|
|||||||
// do not overwrite existing entries
|
// do not overwrite existing entries
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const auto& rxn : m_rxn_rates) {
|
for (const auto& [iRxn, rate] : m_rxn_rates) {
|
||||||
rop[rxn.first] = 0.;
|
rop[iRxn] = 0.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,10 +246,10 @@ protected:
|
|||||||
m_shared.perturbPressure(deltaP);
|
m_shared.perturbPressure(deltaP);
|
||||||
_update();
|
_update();
|
||||||
|
|
||||||
for (auto& rxn : m_rxn_rates) {
|
for (auto& [iRxn, rate] : m_rxn_rates) {
|
||||||
if (kf[rxn.first] != 0.) {
|
if (kf[iRxn] != 0.) {
|
||||||
double k1 = rxn.second.evalFromStruct(m_shared);
|
double k1 = rate.evalFromStruct(m_shared);
|
||||||
rop[rxn.first] *= dPinv * (k1 / kf[rxn.first] - 1.);
|
rop[iRxn] *= dPinv * (k1 / kf[iRxn] - 1.);
|
||||||
} // else not needed: derivative is already zero
|
} // else not needed: derivative is already zero
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,8 +262,8 @@ protected:
|
|||||||
template <typename T=RateType, typename D=DataType,
|
template <typename T=RateType, typename D=DataType,
|
||||||
typename std::enable_if<!has_ddP<D>::value, bool>::type = true>
|
typename std::enable_if<!has_ddP<D>::value, bool>::type = true>
|
||||||
void _process_ddP(double* rop, const double* kf, double deltaP) {
|
void _process_ddP(double* rop, const double* kf, double deltaP) {
|
||||||
for (const auto& rxn : m_rxn_rates) {
|
for (const auto& [iRxn, rate] : m_rxn_rates) {
|
||||||
rop[rxn.first] = 0.;
|
rop[iRxn] = 0.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +278,9 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
doublereal m_flxmax;
|
doublereal m_flxmax;
|
||||||
std::map<size_t, std::map<size_t, Path*> > m_paths;
|
std::map<size_t, std::map<size_t, Path*> > m_paths;
|
||||||
std::map<size_t, SpeciesNode*> m_nodes;
|
|
||||||
|
//! map of species index to SpeciesNode
|
||||||
|
map<size_t, SpeciesNode*> m_nodes;
|
||||||
std::vector<Path*> m_pathlist;
|
std::vector<Path*> m_pathlist;
|
||||||
std::vector<std::string> m_include;
|
std::vector<std::string> m_include;
|
||||||
std::vector<std::string> m_exclude;
|
std::vector<std::string> m_exclude;
|
||||||
|
@ -32,13 +32,13 @@ public:
|
|||||||
|
|
||||||
m_species.emplace_back();
|
m_species.emplace_back();
|
||||||
m_eff.emplace_back();
|
m_eff.emplace_back();
|
||||||
for (const auto& eff : efficiencies) {
|
for (const auto& [k, efficiency] : efficiencies) {
|
||||||
AssertTrace(eff.first != npos);
|
AssertTrace(k != npos);
|
||||||
m_species.back().push_back(eff.first);
|
m_species.back().push_back(k);
|
||||||
m_eff.back().push_back(eff.second - default_efficiency);
|
m_eff.back().push_back(efficiency - default_efficiency);
|
||||||
m_efficiencyList.emplace_back(
|
m_efficiencyList.emplace_back(
|
||||||
static_cast<int>(rxnNumber),
|
static_cast<int>(rxnNumber),
|
||||||
static_cast<int>(eff.first), eff.second - default_efficiency);
|
static_cast<int>(k), efficiency - default_efficiency);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,9 +282,7 @@ YAML::Emitter& operator<<(YAML::Emitter& out, const AnyMap& rhs)
|
|||||||
out << YAML::Flow;
|
out << YAML::Flow;
|
||||||
out << YAML::BeginMap;
|
out << YAML::BeginMap;
|
||||||
size_t width = 15;
|
size_t width = 15;
|
||||||
for (const auto& item : rhs.ordered()) {
|
for (const auto& [name, value] : rhs.ordered()) {
|
||||||
const auto& name = item.first;
|
|
||||||
const auto& value = item.second;
|
|
||||||
string valueStr;
|
string valueStr;
|
||||||
bool foundType = true;
|
bool foundType = true;
|
||||||
if (value.is<double>()) {
|
if (value.is<double>()) {
|
||||||
@ -319,9 +317,9 @@ YAML::Emitter& operator<<(YAML::Emitter& out, const AnyMap& rhs)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
out << YAML::BeginMap;
|
out << YAML::BeginMap;
|
||||||
for (const auto& item : rhs.ordered()) {
|
for (const auto& [key, value] : rhs.ordered()) {
|
||||||
out << item.first;
|
out << key;
|
||||||
out << item.second;
|
out << value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out << YAML::EndMap;
|
out << YAML::EndMap;
|
||||||
@ -1121,18 +1119,18 @@ void AnyValue::applyUnits(shared_ptr<UnitSystem>& units)
|
|||||||
} else {
|
} else {
|
||||||
// Merge with a child units declaration
|
// Merge with a child units declaration
|
||||||
auto& childUnits = item["units"].as<AnyMap>();
|
auto& childUnits = item["units"].as<AnyMap>();
|
||||||
for (auto& jtem : deltaUnits) {
|
for (auto& [dimension, unit] : deltaUnits) {
|
||||||
if (!childUnits.hasKey(jtem.first)) {
|
if (!childUnits.hasKey(dimension)) {
|
||||||
childUnits[jtem.first] = jtem.second;
|
childUnits[dimension] = unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (item.hasKey("__units__")) {
|
} else if (item.hasKey("__units__")) {
|
||||||
// Merge with a child units declaration
|
// Merge with a child units declaration
|
||||||
auto& childUnits = item["__units__"].as<AnyMap>();
|
auto& childUnits = item["__units__"].as<AnyMap>();
|
||||||
for (auto& jtem : deltaUnits) {
|
for (auto& [dimension, unit] : deltaUnits) {
|
||||||
if (!childUnits.hasKey(jtem.first)) {
|
if (!childUnits.hasKey(dimension)) {
|
||||||
childUnits[jtem.first] = jtem.second;
|
childUnits[dimension] = unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1416,9 +1414,9 @@ void AnyMap::clear()
|
|||||||
|
|
||||||
void AnyMap::update(const AnyMap& other, bool keepExisting)
|
void AnyMap::update(const AnyMap& other, bool keepExisting)
|
||||||
{
|
{
|
||||||
for (const auto& item : other) {
|
for (const auto& [key, value] : other) {
|
||||||
if (!keepExisting || !hasKey(item.first)) {
|
if (!keepExisting || !hasKey(key)) {
|
||||||
(*this)[item.first] = item.second;
|
(*this)[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1452,8 +1450,8 @@ std::set<std::string> AnyMap::keys() const
|
|||||||
void AnyMap::propagateMetadata(shared_ptr<AnyMap>& metadata)
|
void AnyMap::propagateMetadata(shared_ptr<AnyMap>& metadata)
|
||||||
{
|
{
|
||||||
m_metadata = metadata;
|
m_metadata = metadata;
|
||||||
for (auto& item : m_data) {
|
for (auto& [name, value] : m_data) {
|
||||||
item.second.propagateMetadata(m_metadata);
|
value.propagateMetadata(m_metadata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1484,8 +1482,8 @@ void AnyMap::copyMetadata(const AnyMap& other)
|
|||||||
m_metadata = make_shared<AnyMap>();
|
m_metadata = make_shared<AnyMap>();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& item : *other.m_metadata) {
|
for (const auto& [key, value] : *other.m_metadata) {
|
||||||
(*m_metadata)[item.first] = item.second;
|
(*m_metadata)[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
propagateMetadata(m_metadata);
|
propagateMetadata(m_metadata);
|
||||||
@ -1593,14 +1591,14 @@ AnyMap::OrderedProxy::OrderedProxy(const AnyMap& data)
|
|||||||
std::unique_lock<std::mutex> lock(yaml_field_order_mutex);
|
std::unique_lock<std::mutex> lock(yaml_field_order_mutex);
|
||||||
if (AnyMap::s_headFields.count(itemType)) {
|
if (AnyMap::s_headFields.count(itemType)) {
|
||||||
for (const auto& key : AnyMap::s_headFields[itemType]) {
|
for (const auto& key : AnyMap::s_headFields[itemType]) {
|
||||||
for (auto& item : m_ordered) {
|
for (auto& [order, item] : m_ordered) {
|
||||||
if (item.first.first >= 0) {
|
if (order.first >= 0) {
|
||||||
// This and following items come from an input file and
|
// This and following items come from an input file and
|
||||||
// should not be re-ordered
|
// should not be re-ordered
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (item.second->first == key) {
|
if (item->first == key) {
|
||||||
item.first.second = --head;
|
order.second = --head;
|
||||||
order_changed = true;
|
order_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1608,14 +1606,14 @@ AnyMap::OrderedProxy::OrderedProxy(const AnyMap& data)
|
|||||||
}
|
}
|
||||||
if (AnyMap::s_tailFields.count(itemType)) {
|
if (AnyMap::s_tailFields.count(itemType)) {
|
||||||
for (const auto& key : AnyMap::s_tailFields[itemType]) {
|
for (const auto& key : AnyMap::s_tailFields[itemType]) {
|
||||||
for (auto& item : m_ordered) {
|
for (auto& [order, item] : m_ordered) {
|
||||||
if (item.first.first >= 0) {
|
if (order.first >= 0) {
|
||||||
// This and following items come from an input file and
|
// This and following items come from an input file and
|
||||||
// should not be re-ordered
|
// should not be re-ordered
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (item.second->first == key) {
|
if (item->first == key) {
|
||||||
item.first.second = ++tail;
|
order.second = ++tail;
|
||||||
order_changed = true;
|
order_changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1650,14 +1648,14 @@ bool AnyMap::operator==(const AnyMap& other) const
|
|||||||
{
|
{
|
||||||
// First, make sure that 'other' has all of the non-hidden keys that are in
|
// First, make sure that 'other' has all of the non-hidden keys that are in
|
||||||
// this map
|
// this map
|
||||||
for (auto& item : *this) {
|
for (auto& [key, value] : *this) {
|
||||||
if (!other.hasKey(item.first)) {
|
if (!other.hasKey(key)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Then check for equality, using the non-hidden keys from 'other'
|
// Then check for equality, using the non-hidden keys from 'other'
|
||||||
for (auto & item : other) {
|
for (auto & [key, value] : other) {
|
||||||
if (!hasKey(item.first) || item.second != at(item.first)) {
|
if (!hasKey(key) || value != at(key)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1685,16 +1683,16 @@ void AnyMap::applyUnits(shared_ptr<UnitSystem>& units) {
|
|||||||
} else {
|
} else {
|
||||||
m_units = units;
|
m_units = units;
|
||||||
}
|
}
|
||||||
for (auto& item : m_data) {
|
for (auto& [name, item] : m_data) {
|
||||||
item.second.applyUnits(m_units);
|
item.applyUnits(m_units);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnyMap::setUnits(const UnitSystem& units)
|
void AnyMap::setUnits(const UnitSystem& units)
|
||||||
{
|
{
|
||||||
if (hasKey("__units__")) {
|
if (hasKey("__units__")) {
|
||||||
for (const auto& item : units.getDelta(*m_units)) {
|
for (const auto& [dimension, value] : units.getDelta(*m_units)) {
|
||||||
m_data["__units__"][item.first] = item.second;
|
m_data["__units__"][dimension] = value;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_data["__units__"] = units.getDelta(*m_units);
|
m_data["__units__"] = units.getDelta(*m_units);
|
||||||
@ -1779,13 +1777,13 @@ AnyMap AnyMap::fromYamlFile(const std::string& name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate an AnyMap from the YAML file and store it in the cache
|
// Generate an AnyMap from the YAML file and store it in the cache
|
||||||
auto& cache_item = s_cache[fullName];
|
auto& [cache_item, cache_time] = s_cache[fullName];
|
||||||
cache_item.second = mtime;
|
cache_time = mtime;
|
||||||
try {
|
try {
|
||||||
YAML::Node node = YAML::LoadFile(fullName);
|
YAML::Node node = YAML::LoadFile(fullName);
|
||||||
cache_item.first = node.as<AnyMap>();
|
cache_item = node.as<AnyMap>();
|
||||||
cache_item.first.setMetadata("filename", AnyValue(fullName));
|
cache_item.setMetadata("filename", AnyValue(fullName));
|
||||||
cache_item.first.applyUnits();
|
cache_item.applyUnits();
|
||||||
} catch (YAML::Exception& err) {
|
} catch (YAML::Exception& err) {
|
||||||
s_cache.erase(fullName);
|
s_cache.erase(fullName);
|
||||||
AnyMap fake;
|
AnyMap fake;
|
||||||
@ -1796,14 +1794,14 @@ AnyMap AnyMap::fromYamlFile(const std::string& name,
|
|||||||
s_cache.erase(fullName);
|
s_cache.erase(fullName);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
cache_item.first["__file__"] = fullName;
|
cache_item["__file__"] = fullName;
|
||||||
|
|
||||||
if (cache_item.first.hasKey("deprecated")) {
|
if (cache_item.hasKey("deprecated")) {
|
||||||
warn_deprecated(fullName, cache_item.first["deprecated"].asString());
|
warn_deprecated(fullName, cache_item["deprecated"].asString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a copy of the AnyMap
|
// Return a copy of the AnyMap
|
||||||
return cache_item.first;
|
return cache_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AnyMap::toYamlString() const
|
std::string AnyMap::toYamlString() const
|
||||||
|
@ -318,13 +318,12 @@ shared_ptr<Solution> newSolution(const AnyMap& phaseNode,
|
|||||||
|
|
||||||
// save root-level information (YAML header)
|
// save root-level information (YAML header)
|
||||||
AnyMap header;
|
AnyMap header;
|
||||||
for (const auto& item : rootNode.ordered()) {
|
for (const auto& [key, value] : rootNode.ordered()) {
|
||||||
std::string key = item.first;
|
|
||||||
if (key == "phases") {
|
if (key == "phases") {
|
||||||
// header ends with "phases" field
|
// header ends with "phases" field
|
||||||
break;
|
break;
|
||||||
} else if (key != "units") {
|
} else if (key != "units") {
|
||||||
header[key] = item.second;
|
header[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sol->header() = header;
|
sol->header() = header;
|
||||||
|
@ -174,8 +174,8 @@ std::map<std::string, double> SolutionArray::getAuxiliary(size_t index)
|
|||||||
{
|
{
|
||||||
setIndex(index);
|
setIndex(index);
|
||||||
std::map<std::string, double> out;
|
std::map<std::string, double> out;
|
||||||
for (auto& item : m_extra) {
|
for (auto& [key, value] : m_extra) {
|
||||||
out[item.first] = item.second[m_index];
|
out[key] = value[m_index];
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -233,10 +233,8 @@ void SolutionArray::writeEntry(const std::string& fname, const std::string& id,
|
|||||||
|
|
||||||
const auto& nativeState = m_sol->thermo()->nativeState();
|
const auto& nativeState = m_sol->thermo()->nativeState();
|
||||||
size_t nSpecies = m_sol->thermo()->nSpecies();
|
size_t nSpecies = m_sol->thermo()->nSpecies();
|
||||||
for (auto& state : nativeState) {
|
for (auto& [name, offset] : nativeState) {
|
||||||
std::string name = state.first;
|
|
||||||
if (name == "X" || name == "Y") {
|
if (name == "X" || name == "Y") {
|
||||||
size_t offset = state.second;
|
|
||||||
std::vector<vector_fp> prop;
|
std::vector<vector_fp> prop;
|
||||||
for (size_t i = 0; i < m_size; i++) {
|
for (size_t i = 0; i < m_size; i++) {
|
||||||
size_t first = offset + i * m_stride;
|
size_t first = offset + i * m_stride;
|
||||||
@ -250,8 +248,8 @@ void SolutionArray::writeEntry(const std::string& fname, const std::string& id,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& extra : m_extra) {
|
for (auto& [name, value] : m_extra) {
|
||||||
file.writeVector(id, extra.first, extra.second);
|
file.writeVector(id, name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,8 +281,8 @@ void SolutionArray::writeEntry(AnyMap& root, const std::string& id)
|
|||||||
data["points"] = int(m_size);
|
data["points"] = int(m_size);
|
||||||
data.update(m_meta);
|
data.update(m_meta);
|
||||||
|
|
||||||
for (auto& extra : m_extra) {
|
for (auto& [name, value] : m_extra) {
|
||||||
data[extra.first] = extra.second;
|
data[name] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto phase = m_sol->thermo();
|
auto phase = m_sol->thermo();
|
||||||
@ -313,13 +311,12 @@ void SolutionArray::writeEntry(AnyMap& root, const std::string& id)
|
|||||||
}
|
}
|
||||||
} else if (m_size > 1) {
|
} else if (m_size > 1) {
|
||||||
std::vector<std::string> components;
|
std::vector<std::string> components;
|
||||||
for (auto& extra : m_extra) {
|
for (auto& [name, value] : m_extra) {
|
||||||
components.push_back(extra.first);
|
components.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& nativeState = phase->nativeState();
|
const auto& nativeState = phase->nativeState();
|
||||||
for (auto& state : nativeState) {
|
for (auto& [name, offset] : nativeState) {
|
||||||
std::string name = state.first;
|
|
||||||
if (name == "X" || name == "Y") {
|
if (name == "X" || name == "Y") {
|
||||||
for (auto& spc : phase->speciesNames()) {
|
for (auto& spc : phase->speciesNames()) {
|
||||||
data[spc] = getComponent(spc);
|
data[spc] = getComponent(spc);
|
||||||
@ -399,9 +396,9 @@ AnyMap SolutionArray::readHeader(const AnyMap& root, const std::string& id)
|
|||||||
{
|
{
|
||||||
auto sub = locateField(root, id);
|
auto sub = locateField(root, id);
|
||||||
AnyMap header;
|
AnyMap header;
|
||||||
for (const auto& item : sub) {
|
for (const auto& [name, value] : sub) {
|
||||||
if (!sub[item.first].is<AnyMap>()) {
|
if (!sub[name].is<AnyMap>()) {
|
||||||
header[item.first] = item.second;
|
header[name] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return header;
|
return header;
|
||||||
@ -471,8 +468,8 @@ std::set<std::string> SolutionArray::stateProperties(
|
|||||||
{
|
{
|
||||||
std::set<std::string> states;
|
std::set<std::string> states;
|
||||||
if (mode == "native") {
|
if (mode == "native") {
|
||||||
for (const auto& item : m_sol->thermo()->nativeState()) {
|
for (const auto& [name, offset] : m_sol->thermo()->nativeState()) {
|
||||||
states.insert(alias ? aliasMap.at(item.first) : item.first);
|
states.insert(alias ? aliasMap.at(name) : name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const auto& m : mode) {
|
for (const auto& m : mode) {
|
||||||
@ -490,10 +487,9 @@ void SolutionArray::readEntry(const std::string& fname, const std::string& id)
|
|||||||
file.checkGroup(id);
|
file.checkGroup(id);
|
||||||
m_meta = file.readAttributes(id, true);
|
m_meta = file.readAttributes(id, true);
|
||||||
|
|
||||||
auto contents = file.contents(id);
|
auto [size, names] = file.contents(id);
|
||||||
m_size = contents.first;
|
m_size = size;
|
||||||
m_data.resize(m_size * m_stride, 0.);
|
m_data.resize(m_size * m_stride, 0.);
|
||||||
std::set<std::string> names = contents.second;
|
|
||||||
|
|
||||||
if (m_size == 0) {
|
if (m_size == 0) {
|
||||||
return;
|
return;
|
||||||
@ -520,10 +516,8 @@ void SolutionArray::readEntry(const std::string& fname, const std::string& id)
|
|||||||
const auto& nativeStates = m_sol->thermo()->nativeState();
|
const auto& nativeStates = m_sol->thermo()->nativeState();
|
||||||
if (mode == "native") {
|
if (mode == "native") {
|
||||||
// native state can be written directly into data storage
|
// native state can be written directly into data storage
|
||||||
for (const auto& item : nativeStates) {
|
for (const auto& [name, offset] : nativeStates) {
|
||||||
std::string name = item.first;
|
|
||||||
if (name == "X" || name == "Y") {
|
if (name == "X" || name == "Y") {
|
||||||
size_t offset = item.second;
|
|
||||||
auto prop = file.readMatrix(id, name, m_size, nSpecies);
|
auto prop = file.readMatrix(id, name, m_size, nSpecies);
|
||||||
for (size_t i = 0; i < m_size; i++) {
|
for (size_t i = 0; i < m_size; i++) {
|
||||||
std::copy(prop[i].begin(), prop[i].end(),
|
std::copy(prop[i].begin(), prop[i].end(),
|
||||||
@ -631,14 +625,12 @@ void SolutionArray::readEntry(const AnyMap& root, const std::string& id)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// legacy YAML format does not provide for list of components
|
// legacy YAML format does not provide for list of components
|
||||||
for (const auto& item : sub) {
|
for (const auto& [name, value] : sub) {
|
||||||
const std::string& name = item.first;
|
|
||||||
const AnyValue& value = item.second;
|
|
||||||
if (value.is<std::vector<double>>()) {
|
if (value.is<std::vector<double>>()) {
|
||||||
const vector_fp& data = value.as<std::vector<double>>();
|
const vector_fp& data = value.as<std::vector<double>>();
|
||||||
if (data.size() == m_size) {
|
if (data.size() == m_size) {
|
||||||
setComponent(name, data, true);
|
setComponent(name, data, true);
|
||||||
exclude.insert(item.first);
|
exclude.insert(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -648,11 +640,11 @@ void SolutionArray::readEntry(const AnyMap& root, const std::string& id)
|
|||||||
const auto& nativeState = m_sol->thermo()->nativeState();
|
const auto& nativeState = m_sol->thermo()->nativeState();
|
||||||
std::set<std::string> props = {};
|
std::set<std::string> props = {};
|
||||||
std::set<std::string> missingProps = {};
|
std::set<std::string> missingProps = {};
|
||||||
for (const auto& item : nativeState) {
|
for (const auto& [name, offset] : nativeState) {
|
||||||
if (exclude.count(item.first)) {
|
if (exclude.count(name)) {
|
||||||
props.insert(item.first);
|
props.insert(name);
|
||||||
} else {
|
} else {
|
||||||
missingProps.insert(item.first);
|
missingProps.insert(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,9 +668,9 @@ void SolutionArray::readEntry(const AnyMap& root, const std::string& id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add meta data
|
// add meta data
|
||||||
for (const auto& item : sub) {
|
for (const auto& [name, value] : sub) {
|
||||||
if (!exclude.count(item.first)) {
|
if (!exclude.count(name)) {
|
||||||
m_meta[item.first] = item.second;
|
m_meta[name] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_meta.erase("points");
|
m_meta.erase("points");
|
||||||
|
@ -221,65 +221,65 @@ AnyMap Storage::readAttributes(const std::string& id, bool recursive) const
|
|||||||
|
|
||||||
void writeH5Attributes(h5::Group sub, const AnyMap& meta)
|
void writeH5Attributes(h5::Group sub, const AnyMap& meta)
|
||||||
{
|
{
|
||||||
for (auto& item : meta) {
|
for (auto& [name, item] : meta) {
|
||||||
if (sub.hasAttribute(item.first)) {
|
if (sub.hasAttribute(name)) {
|
||||||
throw NotImplementedError("writeH5Attributes",
|
throw NotImplementedError("writeH5Attributes",
|
||||||
"Unable to overwrite existing Attribute '{}'", item.first);
|
"Unable to overwrite existing Attribute '{}'", name);
|
||||||
}
|
}
|
||||||
if (item.second.is<double>()) {
|
if (item.is<double>()) {
|
||||||
double value = item.second.asDouble();
|
double value = item.asDouble();
|
||||||
h5::Attribute attr = sub.createAttribute<double>(
|
h5::Attribute attr = sub.createAttribute<double>(
|
||||||
item.first, h5::DataSpace::From(value));
|
name, h5::DataSpace::From(value));
|
||||||
attr.write(value);
|
attr.write(value);
|
||||||
} else if (item.second.is<int>() || item.second.is<long int>()) {
|
} else if (item.is<int>() || item.is<long int>()) {
|
||||||
int value = item.second.asInt();
|
int value = item.asInt();
|
||||||
h5::Attribute attr = sub.createAttribute<int>(
|
h5::Attribute attr = sub.createAttribute<int>(
|
||||||
item.first, h5::DataSpace::From(value));
|
name, h5::DataSpace::From(value));
|
||||||
attr.write(value);
|
attr.write(value);
|
||||||
} else if (item.second.is<std::string>()) {
|
} else if (item.is<string>()) {
|
||||||
std::string value = item.second.asString();
|
string value = item.asString();
|
||||||
h5::Attribute attr = sub.createAttribute<std::string>(
|
h5::Attribute attr = sub.createAttribute<string>(
|
||||||
item.first, h5::DataSpace::From(value));
|
name, h5::DataSpace::From(value));
|
||||||
attr.write(value);
|
attr.write(value);
|
||||||
} else if (item.second.is<bool>()) {
|
} else if (item.is<bool>()) {
|
||||||
bool bValue = item.second.asBool();
|
bool bValue = item.asBool();
|
||||||
H5Boolean value = bValue ? H5Boolean::TRUE : H5Boolean::FALSE;
|
H5Boolean value = bValue ? H5Boolean::TRUE : H5Boolean::FALSE;
|
||||||
h5::Attribute attr = sub.createAttribute<H5Boolean>(
|
h5::Attribute attr = sub.createAttribute<H5Boolean>(
|
||||||
item.first, h5::DataSpace::From(value));
|
name, h5::DataSpace::From(value));
|
||||||
attr.write(value);
|
attr.write(value);
|
||||||
} else if (item.second.is<std::vector<double>>()) {
|
} else if (item.is<vector<double>>()) {
|
||||||
auto values = item.second.as<std::vector<double>>();
|
auto values = item.as<vector<double>>();
|
||||||
h5::Attribute attr = sub.createAttribute<double>(
|
h5::Attribute attr = sub.createAttribute<double>(
|
||||||
item.first, h5::DataSpace::From(values));
|
name, h5::DataSpace::From(values));
|
||||||
attr.write(values);
|
attr.write(values);
|
||||||
} else if (item.second.is<std::vector<int>>()) {
|
} else if (item.is<vector<int>>()) {
|
||||||
auto values = item.second.as<std::vector<int>>();
|
auto values = item.as<vector<int>>();
|
||||||
h5::Attribute attr = sub.createAttribute<int>(
|
h5::Attribute attr = sub.createAttribute<int>(
|
||||||
item.first, h5::DataSpace::From(values));
|
name, h5::DataSpace::From(values));
|
||||||
attr.write(values);
|
attr.write(values);
|
||||||
} else if (item.second.is<std::vector<std::string>>()) {
|
} else if (item.is<vector<string>>()) {
|
||||||
auto values = item.second.as<std::vector<std::string>>();
|
auto values = item.as<vector<string>>();
|
||||||
h5::Attribute attr = sub.createAttribute<std::string>(
|
h5::Attribute attr = sub.createAttribute<string>(
|
||||||
item.first, h5::DataSpace::From(values));
|
name, h5::DataSpace::From(values));
|
||||||
attr.write(values);
|
attr.write(values);
|
||||||
} else if (item.second.is<std::vector<bool>>()) {
|
} else if (item.is<vector<bool>>()) {
|
||||||
auto bValue = item.second.as<std::vector<bool>>();
|
auto bValue = item.as<vector<bool>>();
|
||||||
std::vector<H5Boolean> values;
|
vector<H5Boolean> values;
|
||||||
for (auto b : bValue) {
|
for (auto b : bValue) {
|
||||||
values.push_back(b ? H5Boolean::TRUE : H5Boolean::FALSE);
|
values.push_back(b ? H5Boolean::TRUE : H5Boolean::FALSE);
|
||||||
}
|
}
|
||||||
h5::Attribute attr = sub.createAttribute<H5Boolean>(
|
h5::Attribute attr = sub.createAttribute<H5Boolean>(
|
||||||
item.first, h5::DataSpace::From(values));
|
name, h5::DataSpace::From(values));
|
||||||
attr.write(values);
|
attr.write(values);
|
||||||
} else if (item.second.is<AnyMap>()) {
|
} else if (item.is<AnyMap>()) {
|
||||||
// step into recursion
|
// step into recursion
|
||||||
auto value = item.second.as<AnyMap>();
|
auto value = item.as<AnyMap>();
|
||||||
auto grp = sub.createGroup(item.first);
|
auto grp = sub.createGroup(name);
|
||||||
writeH5Attributes(grp, value);
|
writeH5Attributes(grp, value);
|
||||||
} else {
|
} else {
|
||||||
throw NotImplementedError("writeH5Attributes",
|
throw NotImplementedError("writeH5Attributes",
|
||||||
"Unable to write attribute '{}' with type '{}'",
|
"Unable to write attribute '{}' with type '{}'",
|
||||||
item.first, item.second.type_str());
|
name, item.type_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,22 +255,22 @@ std::string Units::str(bool skip_unity) const
|
|||||||
|
|
||||||
std::string num = "";
|
std::string num = "";
|
||||||
std::string den = "";
|
std::string den = "";
|
||||||
for (auto const& dim : dims) {
|
for (auto const& [dimension, exponent] : dims) {
|
||||||
int rounded = (int)round(dim.second);
|
int rounded = (int)round(exponent);
|
||||||
if (dim.second == 0.) {
|
if (exponent == 0.) {
|
||||||
// skip
|
// skip
|
||||||
} else if (dim.second == 1.) {
|
} else if (exponent == 1.) {
|
||||||
num.append(fmt::format(" * {}", dim.first));
|
num.append(fmt::format(" * {}", dimension));
|
||||||
} else if (dim.second == -1.) {
|
} else if (exponent == -1.) {
|
||||||
den.append(fmt::format(" / {}", dim.first));
|
den.append(fmt::format(" / {}", dimension));
|
||||||
} else if (dim.second == rounded && rounded > 0) {
|
} else if (exponent == rounded && rounded > 0) {
|
||||||
num.append(fmt::format(" * {}^{}", dim.first, rounded));
|
num.append(fmt::format(" * {}^{}", dimension, rounded));
|
||||||
} else if (dim.second == rounded) {
|
} else if (exponent == rounded) {
|
||||||
den.append(fmt::format(" / {}^{}", dim.first, -rounded));
|
den.append(fmt::format(" / {}^{}", dimension, -rounded));
|
||||||
} else if (dim.second > 0) {
|
} else if (exponent > 0) {
|
||||||
num.append(fmt::format(" * {}^{}", dim.first, dim.second));
|
num.append(fmt::format(" * {}^{}", dimension, exponent));
|
||||||
} else {
|
} else {
|
||||||
den.append(fmt::format(" / {}^{}", dim.first, -dim.second));
|
den.append(fmt::format(" / {}^{}", dimension, -exponent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,9 +373,9 @@ void UnitStack::join(double exponent)
|
|||||||
void UnitStack::update(const Units& units, double exponent)
|
void UnitStack::update(const Units& units, double exponent)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto& item : stack) {
|
for (auto& [current_unit, current_exp] : stack) {
|
||||||
if (item.first == units) {
|
if (current_unit == units) {
|
||||||
item.second += exponent;
|
current_exp += exponent;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -391,11 +391,11 @@ Units UnitStack::product() const
|
|||||||
return Units(0.);
|
return Units(0.);
|
||||||
}
|
}
|
||||||
Units out = Units(1.);
|
Units out = Units(1.);
|
||||||
for (auto& item : stack) {
|
for (auto& [units, exponent] : stack) {
|
||||||
if (item.second == 1) {
|
if (exponent == 1) {
|
||||||
out *= item.first;
|
out *= units;
|
||||||
} else {
|
} else {
|
||||||
out *= item.first.pow(item.second);
|
out *= units.pow(exponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
@ -430,8 +430,8 @@ std::map<std::string, std::string> UnitSystem::defaults() const
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Overwrite entries that have conversion factors
|
// Overwrite entries that have conversion factors
|
||||||
for (const auto& defaults : m_defaults) {
|
for (const auto& [dimension, default_unit] : m_defaults) {
|
||||||
units[defaults.first] = defaults.second;
|
units[dimension] = default_unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activation energy follows specified energy and quantity units
|
// Activation energy follows specified energy and quantity units
|
||||||
@ -490,45 +490,44 @@ void UnitSystem::setDefaults(std::initializer_list<std::string> units)
|
|||||||
|
|
||||||
void UnitSystem::setDefaults(const std::map<std::string, std::string>& units)
|
void UnitSystem::setDefaults(const std::map<std::string, std::string>& units)
|
||||||
{
|
{
|
||||||
for (const auto& item : units) {
|
for (const auto& [dimension, name] : units) {
|
||||||
auto& name = item.first;
|
Units unit(name);
|
||||||
Units unit(item.second);
|
if (dimension == "mass" && unit.convertible(knownUnits.at("kg"))) {
|
||||||
if (name == "mass" && unit.convertible(knownUnits.at("kg"))) {
|
|
||||||
m_mass_factor = unit.factor();
|
m_mass_factor = unit.factor();
|
||||||
m_defaults["mass"] = item.second;
|
m_defaults["mass"] = name;
|
||||||
} else if (name == "length" && unit.convertible(knownUnits.at("m"))) {
|
} else if (dimension == "length" && unit.convertible(knownUnits.at("m"))) {
|
||||||
m_length_factor = unit.factor();
|
m_length_factor = unit.factor();
|
||||||
m_defaults["length"] = item.second;
|
m_defaults["length"] = name;
|
||||||
} else if (name == "time" && unit.convertible(knownUnits.at("s"))) {
|
} else if (dimension == "time" && unit.convertible(knownUnits.at("s"))) {
|
||||||
m_time_factor = unit.factor();
|
m_time_factor = unit.factor();
|
||||||
m_defaults["time"] = item.second;
|
m_defaults["time"] = name;
|
||||||
} else if (name == "temperature" && unit.convertible(knownUnits.at("K"))) {
|
} else if (dimension == "temperature" && unit.convertible(knownUnits.at("K"))) {
|
||||||
// do nothing - no other temperature scales are supported
|
// do nothing - no other temperature scales are supported
|
||||||
if (unit.factor() != 1.) {
|
if (unit.factor() != 1.) {
|
||||||
throw CanteraError("UnitSystem::setDefaults", "Temperature scales "
|
throw CanteraError("UnitSystem::setDefaults", "Temperature scales "
|
||||||
"with non-unity conversion factor from Kelvin are not supported.");
|
"with non-unity conversion factor from Kelvin are not supported.");
|
||||||
}
|
}
|
||||||
} else if (name == "current" && unit.convertible(knownUnits.at("A"))) {
|
} else if (dimension == "current" && unit.convertible(knownUnits.at("A"))) {
|
||||||
// do nothing - no other current scales are supported
|
// do nothing - no other current scales are supported
|
||||||
if (unit.factor() != 1.) {
|
if (unit.factor() != 1.) {
|
||||||
throw CanteraError("UnitSystem::setDefaults", "Current scales "
|
throw CanteraError("UnitSystem::setDefaults", "Current scales "
|
||||||
"with non-unity conversion factor from Ampere are not supported.");
|
"with non-unity conversion factor from Ampere are not supported.");
|
||||||
}
|
}
|
||||||
} else if (name == "quantity" && unit.convertible(knownUnits.at("kmol"))) {
|
} else if (dimension == "quantity" && unit.convertible(knownUnits.at("kmol"))) {
|
||||||
m_quantity_factor = unit.factor();
|
m_quantity_factor = unit.factor();
|
||||||
m_defaults["quantity"] = item.second;
|
m_defaults["quantity"] = name;
|
||||||
} else if (name == "pressure" && unit.convertible(knownUnits.at("Pa"))) {
|
} else if (dimension == "pressure" && unit.convertible(knownUnits.at("Pa"))) {
|
||||||
m_pressure_factor = unit.factor();
|
m_pressure_factor = unit.factor();
|
||||||
m_defaults["pressure"] = item.second;
|
m_defaults["pressure"] = name;
|
||||||
} else if (name == "energy" && unit.convertible(knownUnits.at("J"))) {
|
} else if (dimension == "energy" && unit.convertible(knownUnits.at("J"))) {
|
||||||
m_energy_factor = unit.factor();
|
m_energy_factor = unit.factor();
|
||||||
m_defaults["energy"] = item.second;
|
m_defaults["energy"] = name;
|
||||||
} else if (name == "activation-energy") {
|
} else if (dimension == "activation-energy") {
|
||||||
// handled separately to allow override
|
// handled separately to allow override
|
||||||
} else {
|
} else {
|
||||||
throw CanteraError("UnitSystem::setDefaults",
|
throw CanteraError("UnitSystem::setDefaults",
|
||||||
"Unable to set default unit for '{}' to '{}' ({}).",
|
"Unable to set default unit for '{}' to '{}' ({}).",
|
||||||
name, item.second, unit.str());
|
dimension, name, unit.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (units.find("activation-energy") != units.end()) {
|
if (units.find("activation-energy") != units.end()) {
|
||||||
@ -636,13 +635,13 @@ double UnitSystem::convert(const AnyValue& v, const std::string& dest) const
|
|||||||
double UnitSystem::convert(const AnyValue& v, const Units& dest) const
|
double UnitSystem::convert(const AnyValue& v, const Units& dest) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto val_units = split_unit(v);
|
auto [value, units] = split_unit(v);
|
||||||
if (val_units.second.empty()) {
|
if (units.empty()) {
|
||||||
// Just a value, so convert using default units
|
// Just a value, so convert using default units
|
||||||
return convertTo(val_units.first, dest);
|
return convertTo(value, dest);
|
||||||
} else {
|
} else {
|
||||||
// Both source and destination units are explicit
|
// Both source and destination units are explicit
|
||||||
return convert(val_units.first, Units(val_units.second), dest);
|
return convert(value, Units(units), dest);
|
||||||
}
|
}
|
||||||
} catch (CanteraError& err) {
|
} catch (CanteraError& err) {
|
||||||
throw InputFileError("UnitSystem::convert", v, err.getMessage());
|
throw InputFileError("UnitSystem::convert", v, err.getMessage());
|
||||||
@ -738,13 +737,13 @@ double UnitSystem::convertActivationEnergy(const AnyValue& v,
|
|||||||
const std::string& dest) const
|
const std::string& dest) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
auto val_units = split_unit(v);
|
auto [value, units] = split_unit(v);
|
||||||
if (val_units.second.empty()) {
|
if (units.empty()) {
|
||||||
// Just a value, so convert using default units
|
// Just a value, so convert using default units
|
||||||
return convertActivationEnergyTo(val_units.first, dest);
|
return convertActivationEnergyTo(value, dest);
|
||||||
} else {
|
} else {
|
||||||
// Both source and destination units are explicit
|
// Both source and destination units are explicit
|
||||||
return convertActivationEnergy(val_units.first, val_units.second, dest);
|
return convertActivationEnergy(value, units, dest);
|
||||||
}
|
}
|
||||||
} catch (CanteraError& err) {
|
} catch (CanteraError& err) {
|
||||||
throw InputFileError(
|
throw InputFileError(
|
||||||
|
@ -82,10 +82,9 @@ std::string YamlWriter::toYamlString() const
|
|||||||
// Add remaining header information, ignoring obsolete information
|
// Add remaining header information, ignoring obsolete information
|
||||||
std::set<std::string> exclude = {
|
std::set<std::string> exclude = {
|
||||||
"description", "generator", "cantera-version", "git-commit", "date"};
|
"description", "generator", "cantera-version", "git-commit", "date"};
|
||||||
for (const auto& item : m_header) {
|
for (const auto& [key, value] : m_header) {
|
||||||
std::string key = item.first;
|
|
||||||
if (!exclude.count(key)) {
|
if (!exclude.count(key)) {
|
||||||
output[key] = item.second;
|
output[key] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,9 +156,9 @@ std::string YamlWriter::toYamlString() const
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool match = false;
|
bool match = false;
|
||||||
for (auto& group : phaseGroups) {
|
for (auto& [canonicalPhase, dependentPhases] : phaseGroups) {
|
||||||
if (allReactions[group.first] == allReactions[name]) {
|
if (allReactions[canonicalPhase] == allReactions[name]) {
|
||||||
group.second.push_back(name);
|
dependentPhases.push_back(name);
|
||||||
allReactions.erase(name);
|
allReactions.erase(name);
|
||||||
match = true;
|
match = true;
|
||||||
break;
|
break;
|
||||||
@ -174,15 +173,15 @@ std::string YamlWriter::toYamlString() const
|
|||||||
if (phaseGroups.size() == 1) {
|
if (phaseGroups.size() == 1) {
|
||||||
output["reactions"] = std::move(allReactions[phaseGroups.begin()->first]);
|
output["reactions"] = std::move(allReactions[phaseGroups.begin()->first]);
|
||||||
} else {
|
} else {
|
||||||
for (const auto& group : phaseGroups) {
|
for (const auto& [canonicalPhase, dependentPhases] : phaseGroups) {
|
||||||
std::string groupName;
|
std::string groupName;
|
||||||
for (auto& name : group.second) {
|
for (auto& name : dependentPhases) {
|
||||||
groupName += name + "-";
|
groupName += name + "-";
|
||||||
}
|
}
|
||||||
groupName += "reactions";
|
groupName += "reactions";
|
||||||
output[groupName] = std::move(allReactions[group.first]);
|
output[groupName] = std::move(allReactions[canonicalPhase]);
|
||||||
|
|
||||||
for (auto& name : group.second) {
|
for (auto& name : dependentPhases) {
|
||||||
AnyMap& phaseDef = output["phases"].getMapWhere("name", name);
|
AnyMap& phaseDef = output["phases"].getMapWhere("name", name);
|
||||||
phaseDef["reactions"] = std::vector<std::string>{groupName};
|
phaseDef["reactions"] = std::vector<std::string>{groupName};
|
||||||
}
|
}
|
||||||
|
@ -602,8 +602,7 @@ void MultiPhaseEquil::computeN()
|
|||||||
std::vector<std::pair<double, size_t> > moleFractions(m_nsp);
|
std::vector<std::pair<double, size_t> > moleFractions(m_nsp);
|
||||||
for (size_t k = 0; k < m_nsp; k++) {
|
for (size_t k = 0; k < m_nsp; k++) {
|
||||||
// use -Xk to generate reversed sort order
|
// use -Xk to generate reversed sort order
|
||||||
moleFractions[k].first = - m_mix->speciesMoles(m_species[k]);
|
moleFractions[k] = {-m_mix->speciesMoles(m_species[k]), k};
|
||||||
moleFractions[k].second = k;
|
|
||||||
}
|
}
|
||||||
std::sort(moleFractions.begin(), moleFractions.end());
|
std::sort(moleFractions.begin(), moleFractions.end());
|
||||||
for (size_t k = 0; k < m_nsp; k++) {
|
for (size_t k = 0; k < m_nsp; k++) {
|
||||||
|
@ -76,11 +76,11 @@ double BlowersMaselRate::ddTScaledFromStruct(const BlowersMaselData& shared_data
|
|||||||
void BlowersMaselRate::setContext(const Reaction& rxn, const Kinetics& kin)
|
void BlowersMaselRate::setContext(const Reaction& rxn, const Kinetics& kin)
|
||||||
{
|
{
|
||||||
m_stoich_coeffs.clear();
|
m_stoich_coeffs.clear();
|
||||||
for (const auto& sp : rxn.reactants) {
|
for (const auto& [name, stoich] : rxn.reactants) {
|
||||||
m_stoich_coeffs.emplace_back(kin.kineticsSpeciesIndex(sp.first), -sp.second);
|
m_stoich_coeffs.emplace_back(kin.kineticsSpeciesIndex(name), -stoich);
|
||||||
}
|
}
|
||||||
for (const auto& sp : rxn.products) {
|
for (const auto& [name, stoich] : rxn.products) {
|
||||||
m_stoich_coeffs.emplace_back(kin.kineticsSpeciesIndex(sp.first), sp.second);
|
m_stoich_coeffs.emplace_back(kin.kineticsSpeciesIndex(name), stoich);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,11 +124,11 @@ bool BulkKinetics::addReaction(shared_ptr<Reaction> r, bool resize)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
double dn = 0.0;
|
double dn = 0.0;
|
||||||
for (const auto& sp : r->products) {
|
for (const auto& [name, stoich] : r->products) {
|
||||||
dn += sp.second;
|
dn += stoich;
|
||||||
}
|
}
|
||||||
for (const auto& sp : r->reactants) {
|
for (const auto& [name, stoich] : r->reactants) {
|
||||||
dn -= sp.second;
|
dn -= stoich;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dn.push_back(dn);
|
m_dn.push_back(dn);
|
||||||
@ -174,14 +174,14 @@ bool BulkKinetics::addReaction(shared_ptr<Reaction> r, bool resize)
|
|||||||
void BulkKinetics::addThirdBody(shared_ptr<Reaction> r)
|
void BulkKinetics::addThirdBody(shared_ptr<Reaction> r)
|
||||||
{
|
{
|
||||||
std::map<size_t, double> efficiencies;
|
std::map<size_t, double> efficiencies;
|
||||||
for (const auto& eff : r->thirdBody()->efficiencies) {
|
for (const auto& [name, efficiency] : r->thirdBody()->efficiencies) {
|
||||||
size_t k = kineticsSpeciesIndex(eff.first);
|
size_t k = kineticsSpeciesIndex(name);
|
||||||
if (k != npos) {
|
if (k != npos) {
|
||||||
efficiencies[k] = eff.second;
|
efficiencies[k] = efficiency;
|
||||||
} else if (!m_skipUndeclaredThirdBodies) {
|
} else if (!m_skipUndeclaredThirdBodies) {
|
||||||
throw CanteraError("BulkKinetics::addThirdBody", "Found "
|
throw CanteraError("BulkKinetics::addThirdBody", "Found third-body"
|
||||||
"third-body efficiency for undefined species '" + eff.first +
|
" efficiency for undefined species '{}' while adding reaction '{}'",
|
||||||
"' while adding reaction '" + r->equation() + "'");
|
name, r->equation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_multi_concm.install(nReactions() - 1, efficiencies,
|
m_multi_concm.install(nReactions() - 1, efficiencies,
|
||||||
|
@ -417,13 +417,13 @@ bool InterfaceKinetics::addReaction(shared_ptr<Reaction> r_base, bool resize)
|
|||||||
m_rxnPhaseIsReactant.emplace_back(nPhases(), false);
|
m_rxnPhaseIsReactant.emplace_back(nPhases(), false);
|
||||||
m_rxnPhaseIsProduct.emplace_back(nPhases(), false);
|
m_rxnPhaseIsProduct.emplace_back(nPhases(), false);
|
||||||
|
|
||||||
for (const auto& sp : r_base->reactants) {
|
for (const auto& [name, stoich] : r_base->reactants) {
|
||||||
size_t k = kineticsSpeciesIndex(sp.first);
|
size_t k = kineticsSpeciesIndex(name);
|
||||||
size_t p = speciesPhaseIndex(k);
|
size_t p = speciesPhaseIndex(k);
|
||||||
m_rxnPhaseIsReactant[i][p] = true;
|
m_rxnPhaseIsReactant[i][p] = true;
|
||||||
}
|
}
|
||||||
for (const auto& sp : r_base->products) {
|
for (const auto& [name, stoich] : r_base->products) {
|
||||||
size_t k = kineticsSpeciesIndex(sp.first);
|
size_t k = kineticsSpeciesIndex(name);
|
||||||
size_t p = speciesPhaseIndex(k);
|
size_t p = speciesPhaseIndex(k);
|
||||||
m_rxnPhaseIsProduct[i][p] = true;
|
m_rxnPhaseIsProduct[i][p] = true;
|
||||||
}
|
}
|
||||||
|
@ -145,20 +145,20 @@ void InterfaceRateBase::setCoverageDependencies(const AnyMap& dependencies,
|
|||||||
m_ac.clear();
|
m_ac.clear();
|
||||||
m_ec.clear();
|
m_ec.clear();
|
||||||
m_mc.clear();
|
m_mc.clear();
|
||||||
for (const auto& item : dependencies) {
|
for (const auto& [species, coeffs] : dependencies) {
|
||||||
double a, E, m;
|
double a, E, m;
|
||||||
if (item.second.is<AnyMap>()) {
|
if (coeffs.is<AnyMap>()) {
|
||||||
auto& cov_map = item.second.as<AnyMap>();
|
auto& cov_map = coeffs.as<AnyMap>();
|
||||||
a = cov_map["a"].asDouble();
|
a = cov_map["a"].asDouble();
|
||||||
m = cov_map["m"].asDouble();
|
m = cov_map["m"].asDouble();
|
||||||
E = units.convertActivationEnergy(cov_map["E"], "K");
|
E = units.convertActivationEnergy(cov_map["E"], "K");
|
||||||
} else {
|
} else {
|
||||||
auto& cov_vec = item.second.asVector<AnyValue>(3);
|
auto& cov_vec = coeffs.asVector<AnyValue>(3);
|
||||||
a = cov_vec[0].asDouble();
|
a = cov_vec[0].asDouble();
|
||||||
m = cov_vec[1].asDouble();
|
m = cov_vec[1].asDouble();
|
||||||
E = units.convertActivationEnergy(cov_vec[2], "K");
|
E = units.convertActivationEnergy(cov_vec[2], "K");
|
||||||
}
|
}
|
||||||
addCoverageDependence(item.first, a, m, E);
|
addCoverageDependence(species, a, m, E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,18 +229,18 @@ void InterfaceRateBase::updateFromStruct(const InterfaceData& shared_data) {
|
|||||||
m_acov = 0.0;
|
m_acov = 0.0;
|
||||||
m_ecov = 0.0;
|
m_ecov = 0.0;
|
||||||
m_mcov = 0.0;
|
m_mcov = 0.0;
|
||||||
for (auto& item : m_indices) {
|
for (auto& [iCov, iKin] : m_indices) {
|
||||||
m_acov += m_ac[item.first] * shared_data.coverages[item.second];
|
m_acov += m_ac[iCov] * shared_data.coverages[iKin];
|
||||||
m_ecov += m_ec[item.first] * shared_data.coverages[item.second];
|
m_ecov += m_ec[iCov] * shared_data.coverages[iKin];
|
||||||
m_mcov += m_mc[item.first] * shared_data.logCoverages[item.second];
|
m_mcov += m_mc[iCov] * shared_data.logCoverages[iKin];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update change in electrical potential energy
|
// Update change in electrical potential energy
|
||||||
if (m_chargeTransfer) {
|
if (m_chargeTransfer) {
|
||||||
m_deltaPotential_RT = 0.;
|
m_deltaPotential_RT = 0.;
|
||||||
for (const auto& ch : m_netCharges) {
|
for (const auto& [iPhase, netCharge] : m_netCharges) {
|
||||||
m_deltaPotential_RT +=
|
m_deltaPotential_RT +=
|
||||||
shared_data.electricPotentials[ch.first] * ch.second;
|
shared_data.electricPotentials[iPhase] * netCharge;
|
||||||
}
|
}
|
||||||
m_deltaPotential_RT /= GasConstant * shared_data.temperature;
|
m_deltaPotential_RT /= GasConstant * shared_data.temperature;
|
||||||
}
|
}
|
||||||
@ -249,12 +249,12 @@ void InterfaceRateBase::updateFromStruct(const InterfaceData& shared_data) {
|
|||||||
if (m_exchangeCurrentDensityFormulation) {
|
if (m_exchangeCurrentDensityFormulation) {
|
||||||
m_deltaGibbs0_RT = 0.;
|
m_deltaGibbs0_RT = 0.;
|
||||||
m_prodStandardConcentrations = 1.;
|
m_prodStandardConcentrations = 1.;
|
||||||
for (const auto& item : m_stoichCoeffs) {
|
for (const auto& [k, stoich] : m_stoichCoeffs) {
|
||||||
m_deltaGibbs0_RT +=
|
m_deltaGibbs0_RT +=
|
||||||
shared_data.standardChemPotentials[item.first] * item.second;
|
shared_data.standardChemPotentials[k] * stoich;
|
||||||
if (item.second > 0.) {
|
if (stoich > 0.) {
|
||||||
m_prodStandardConcentrations *=
|
m_prodStandardConcentrations *=
|
||||||
shared_data.standardConcentrations[item.first];
|
shared_data.standardConcentrations[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_deltaGibbs0_RT /= GasConstant * shared_data.temperature;
|
m_deltaGibbs0_RT /= GasConstant * shared_data.temperature;
|
||||||
@ -271,19 +271,19 @@ void InterfaceRateBase::setContext(const Reaction& rxn, const Kinetics& kin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_stoichCoeffs.clear();
|
m_stoichCoeffs.clear();
|
||||||
for (const auto& sp : rxn.reactants) {
|
for (const auto& [name, stoich] : rxn.reactants) {
|
||||||
m_stoichCoeffs.emplace_back(kin.kineticsSpeciesIndex(sp.first), -sp.second);
|
m_stoichCoeffs.emplace_back(kin.kineticsSpeciesIndex(name), -stoich);
|
||||||
}
|
}
|
||||||
for (const auto& sp : rxn.products) {
|
for (const auto& [name, stoich] : rxn.products) {
|
||||||
m_stoichCoeffs.emplace_back(kin.kineticsSpeciesIndex(sp.first), sp.second);
|
m_stoichCoeffs.emplace_back(kin.kineticsSpeciesIndex(name), stoich);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_netCharges.clear();
|
m_netCharges.clear();
|
||||||
for (const auto& sp : m_stoichCoeffs) {
|
for (const auto& [k, stoich] : m_stoichCoeffs) {
|
||||||
size_t n = kin.speciesPhaseIndex(sp.first);
|
size_t n = kin.speciesPhaseIndex(k);
|
||||||
size_t start = kin.kineticsSpeciesIndex(0, n);
|
size_t start = kin.kineticsSpeciesIndex(0, n);
|
||||||
double charge = kin.thermo(n).charge(sp.first - start);
|
double charge = kin.thermo(n).charge(k - start);
|
||||||
m_netCharges.emplace_back(n, Faraday * charge * sp.second);
|
m_netCharges.emplace_back(n, Faraday * charge * stoich);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,15 +334,15 @@ void StickingCoverage::setContext(const Reaction& rxn, const Kinetics& kin)
|
|||||||
// Identify the sticking species if not explicitly given
|
// Identify the sticking species if not explicitly given
|
||||||
std::vector<std::string> gasSpecies;
|
std::vector<std::string> gasSpecies;
|
||||||
std::vector<std::string> anySpecies;
|
std::vector<std::string> anySpecies;
|
||||||
for (const auto& sp : rxn.reactants) {
|
for (const auto& [name, stoich] : rxn.reactants) {
|
||||||
size_t iPhase = kin.speciesPhaseIndex(kin.kineticsSpeciesIndex(sp.first));
|
size_t iPhase = kin.speciesPhaseIndex(kin.kineticsSpeciesIndex(name));
|
||||||
if (iPhase != iInterface) {
|
if (iPhase != iInterface) {
|
||||||
// Non-interface species. There should be exactly one of these
|
// Non-interface species. There should be exactly one of these
|
||||||
// (either in gas phase or other phase)
|
// (either in gas phase or other phase)
|
||||||
if (kin.thermo(iPhase).phaseOfMatter() == "gas") {
|
if (kin.thermo(iPhase).phaseOfMatter() == "gas") {
|
||||||
gasSpecies.push_back(sp.first);
|
gasSpecies.push_back(name);
|
||||||
}
|
}
|
||||||
anySpecies.push_back(sp.first);
|
anySpecies.push_back(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gasSpecies.size() == 1) {
|
if (gasSpecies.size() == 1) {
|
||||||
@ -367,11 +367,11 @@ void StickingCoverage::setContext(const Reaction& rxn, const Kinetics& kin)
|
|||||||
double surface_order = 0.0;
|
double surface_order = 0.0;
|
||||||
double multiplier = 1.0;
|
double multiplier = 1.0;
|
||||||
// Adjust the A-factor
|
// Adjust the A-factor
|
||||||
for (const auto& sp : rxn.reactants) {
|
for (const auto& [name, stoich] : rxn.reactants) {
|
||||||
size_t iPhase = kin.speciesPhaseIndex(kin.kineticsSpeciesIndex(sp.first));
|
size_t iPhase = kin.speciesPhaseIndex(kin.kineticsSpeciesIndex(name));
|
||||||
const ThermoPhase& p = kin.thermo(iPhase);
|
const ThermoPhase& p = kin.thermo(iPhase);
|
||||||
size_t k = p.speciesIndex(sp.first);
|
size_t k = p.speciesIndex(name);
|
||||||
if (sp.first == sticking_species) {
|
if (name == sticking_species) {
|
||||||
multiplier *= sqrt(GasConstant / (2 * Pi * p.molecularWeight(k)));
|
multiplier *= sqrt(GasConstant / (2 * Pi * p.molecularWeight(k)));
|
||||||
} else {
|
} else {
|
||||||
// Non-sticking species. Convert from coverages used in the
|
// Non-sticking species. Convert from coverages used in the
|
||||||
@ -380,7 +380,7 @@ void StickingCoverage::setContext(const Reaction& rxn, const Kinetics& kin)
|
|||||||
// the dependence on the site density is incorporated when the
|
// the dependence on the site density is incorporated when the
|
||||||
// rate constant is evaluated, since we don't assume that the
|
// rate constant is evaluated, since we don't assume that the
|
||||||
// site density is known at this time.
|
// site density is known at this time.
|
||||||
double order = getValue(rxn.orders, sp.first, sp.second);
|
double order = getValue(rxn.orders, name, stoich);
|
||||||
if (&p == &surf) {
|
if (&p == &surf) {
|
||||||
multiplier *= pow(surf.size(k), order);
|
multiplier *= pow(surf.size(k), order);
|
||||||
surface_order += order;
|
surface_order += order;
|
||||||
|
@ -135,15 +135,15 @@ std::pair<size_t, size_t> Kinetics::checkDuplicates(bool throw_err) const
|
|||||||
Reaction& R = *m_reactions[i];
|
Reaction& R = *m_reactions[i];
|
||||||
net_stoich.emplace_back();
|
net_stoich.emplace_back();
|
||||||
std::map<int, double>& net = net_stoich.back();
|
std::map<int, double>& net = net_stoich.back();
|
||||||
for (const auto& sp : R.reactants) {
|
for (const auto& [name, stoich] : R.reactants) {
|
||||||
int k = static_cast<int>(kineticsSpeciesIndex(sp.first));
|
int k = static_cast<int>(kineticsSpeciesIndex(name));
|
||||||
key += k*(k+1);
|
key += k*(k+1);
|
||||||
net[-1 -k] -= sp.second;
|
net[-1 -k] -= stoich;
|
||||||
}
|
}
|
||||||
for (const auto& sp : R.products) {
|
for (const auto& [name, stoich] : R.products) {
|
||||||
int k = static_cast<int>(kineticsSpeciesIndex(sp.first));
|
int k = static_cast<int>(kineticsSpeciesIndex(name));
|
||||||
key += k*(k+1);
|
key += k*(k+1);
|
||||||
net[1+k] += sp.second;
|
net[1+k] += stoich;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare this reaction to others with similar participants
|
// Compare this reaction to others with similar participants
|
||||||
@ -214,11 +214,11 @@ double Kinetics::checkDuplicateStoich(std::map<int, double>& r1,
|
|||||||
std::map<int, double>& r2) const
|
std::map<int, double>& r2) const
|
||||||
{
|
{
|
||||||
std::unordered_set<int> keys; // species keys (k+1 or -k-1)
|
std::unordered_set<int> keys; // species keys (k+1 or -k-1)
|
||||||
for (auto& r : r1) {
|
for (auto& [speciesKey, stoich] : r1) {
|
||||||
keys.insert(r.first);
|
keys.insert(speciesKey);
|
||||||
}
|
}
|
||||||
for (auto& r : r2) {
|
for (auto& [speciesKey, stoich] : r2) {
|
||||||
keys.insert(r.first);
|
keys.insert(speciesKey);
|
||||||
}
|
}
|
||||||
int k1 = r1.begin()->first;
|
int k1 = r1.begin()->first;
|
||||||
// check for duplicate written in the same direction
|
// check for duplicate written in the same direction
|
||||||
@ -667,26 +667,26 @@ bool Kinetics::addReaction(shared_ptr<Reaction> r, bool resize)
|
|||||||
// the coefficient for species rk[i]
|
// the coefficient for species rk[i]
|
||||||
vector_fp rstoich, pstoich;
|
vector_fp rstoich, pstoich;
|
||||||
|
|
||||||
for (const auto& sp : r->reactants) {
|
for (const auto& [name, stoich] : r->reactants) {
|
||||||
rk.push_back(kineticsSpeciesIndex(sp.first));
|
rk.push_back(kineticsSpeciesIndex(name));
|
||||||
rstoich.push_back(sp.second);
|
rstoich.push_back(stoich);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& sp : r->products) {
|
for (const auto& [name, stoich] : r->products) {
|
||||||
pk.push_back(kineticsSpeciesIndex(sp.first));
|
pk.push_back(kineticsSpeciesIndex(name));
|
||||||
pstoich.push_back(sp.second);
|
pstoich.push_back(stoich);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The default order for each reactant is its stoichiometric coefficient,
|
// The default order for each reactant is its stoichiometric coefficient,
|
||||||
// which can be overridden by entries in the Reaction.orders map. rorder[i]
|
// which can be overridden by entries in the Reaction.orders map. rorder[i]
|
||||||
// is the order for species rk[i].
|
// is the order for species rk[i].
|
||||||
vector_fp rorder = rstoich;
|
vector_fp rorder = rstoich;
|
||||||
for (const auto& sp : r->orders) {
|
for (const auto& [name, order] : r->orders) {
|
||||||
size_t k = kineticsSpeciesIndex(sp.first);
|
size_t k = kineticsSpeciesIndex(name);
|
||||||
// Find the index of species k within rk
|
// Find the index of species k within rk
|
||||||
auto rloc = std::find(rk.begin(), rk.end(), k);
|
auto rloc = std::find(rk.begin(), rk.end(), k);
|
||||||
if (rloc != rk.end()) {
|
if (rloc != rk.end()) {
|
||||||
rorder[rloc - rk.begin()] = sp.second;
|
rorder[rloc - rk.begin()] = order;
|
||||||
} else {
|
} else {
|
||||||
// If the reaction order involves a non-reactant species, add an
|
// If the reaction order involves a non-reactant species, add an
|
||||||
// extra term to the reactants with zero stoichiometry so that the
|
// extra term to the reactants with zero stoichiometry so that the
|
||||||
@ -694,7 +694,7 @@ bool Kinetics::addReaction(shared_ptr<Reaction> r, bool resize)
|
|||||||
// reaction rate.
|
// reaction rate.
|
||||||
rk.push_back(k);
|
rk.push_back(k);
|
||||||
rstoich.push_back(0.0);
|
rstoich.push_back(0.0);
|
||||||
rorder.push_back(sp.second);
|
rorder.push_back(order);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -774,14 +774,12 @@ double Kinetics::reactionEnthalpy(const Composition& reactants, const Compositio
|
|||||||
thermo(n).getPartialMolarEnthalpies(&hk[m_start[n]]);
|
thermo(n).getPartialMolarEnthalpies(&hk[m_start[n]]);
|
||||||
}
|
}
|
||||||
double rxn_deltaH = 0;
|
double rxn_deltaH = 0;
|
||||||
for (const auto& product : products) {
|
for (const auto& [name, stoich] : products) {
|
||||||
size_t k = kineticsSpeciesIndex(product.first);
|
size_t k = kineticsSpeciesIndex(name);
|
||||||
double stoich = product.second;
|
|
||||||
rxn_deltaH += hk[k] * stoich;
|
rxn_deltaH += hk[k] * stoich;
|
||||||
}
|
}
|
||||||
for (const auto& reactant : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
size_t k = kineticsSpeciesIndex(reactant.first);
|
size_t k = kineticsSpeciesIndex(name);
|
||||||
double stoich = reactant.second;
|
|
||||||
rxn_deltaH -= hk[k] * stoich;
|
rxn_deltaH -= hk[k] * stoich;
|
||||||
}
|
}
|
||||||
return rxn_deltaH;
|
return rxn_deltaH;
|
||||||
|
@ -92,10 +92,10 @@ void PlogRate::getParameters(AnyMap& rateNode, const Units& rate_units) const
|
|||||||
// object not fully set up
|
// object not fully set up
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (const auto& r : getRates()) {
|
for (const auto& [pressure, rate] : getRates()) {
|
||||||
AnyMap rateNode_;
|
AnyMap rateNode_;
|
||||||
rateNode_["P"].setQuantity(r.first, "Pa");
|
rateNode_["P"].setQuantity(pressure, "Pa");
|
||||||
r.second.getRateParameters(rateNode_);
|
rate.getRateParameters(rateNode_);
|
||||||
rateList.push_back(std::move(rateNode_));
|
rateList.push_back(std::move(rateNode_));
|
||||||
}
|
}
|
||||||
rateNode["rate-constants"] = std::move(rateList);
|
rateNode["rate-constants"] = std::move(rateList);
|
||||||
@ -109,8 +109,8 @@ void PlogRate::setRates(const std::multimap<double, ArrheniusRate>& rates)
|
|||||||
m_valid = !rates.empty();
|
m_valid = !rates.empty();
|
||||||
rates_.reserve(rates.size());
|
rates_.reserve(rates.size());
|
||||||
// Insert intermediate pressures
|
// Insert intermediate pressures
|
||||||
for (const auto& rate : rates) {
|
for (const auto& [pressure, rate] : rates) {
|
||||||
double logp = std::log(rate.first);
|
double logp = std::log(pressure);
|
||||||
if (pressures_.empty() || pressures_.rbegin()->first != logp) {
|
if (pressures_.empty() || pressures_.rbegin()->first != logp) {
|
||||||
// starting a new group
|
// starting a new group
|
||||||
pressures_[logp] = {j, j+1};
|
pressures_[logp] = {j, j+1};
|
||||||
@ -120,7 +120,7 @@ void PlogRate::setRates(const std::multimap<double, ArrheniusRate>& rates)
|
|||||||
}
|
}
|
||||||
|
|
||||||
j++;
|
j++;
|
||||||
rates_.push_back(rate.second);
|
rates_.push_back(rate);
|
||||||
}
|
}
|
||||||
if (!m_valid) {
|
if (!m_valid) {
|
||||||
// ensure that reaction rate can be evaluated (but returns NaN)
|
// ensure that reaction rate can be evaluated (but returns NaN)
|
||||||
|
@ -40,8 +40,8 @@ Reaction::Reaction(const Composition& reactants_,
|
|||||||
|
|
||||||
// set flags ensuring correct serialization output
|
// set flags ensuring correct serialization output
|
||||||
bool count = 0;
|
bool count = 0;
|
||||||
for (const auto& reac : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
if (products.count(reac.first)) {
|
if (products.count(name)) {
|
||||||
count = true;
|
count = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -107,21 +107,19 @@ Reaction::Reaction(const AnyMap& node, const Kinetics& kin)
|
|||||||
void Reaction::check()
|
void Reaction::check()
|
||||||
{
|
{
|
||||||
if (!allow_nonreactant_orders) {
|
if (!allow_nonreactant_orders) {
|
||||||
for (const auto& order : orders) {
|
for (const auto& [name, order] : orders) {
|
||||||
if (reactants.find(order.first) == reactants.end()) {
|
if (reactants.find(name) == reactants.end()) {
|
||||||
throw InputFileError("Reaction::validate", input,
|
throw InputFileError("Reaction::validate", input,
|
||||||
"Reaction order specified for non-reactant species '{}'",
|
"Reaction order specified for non-reactant species '{}'", name);
|
||||||
order.first);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!allow_negative_orders) {
|
if (!allow_negative_orders) {
|
||||||
for (const auto& order : orders) {
|
for (const auto& [name, order] : orders) {
|
||||||
if (order.second < 0.0) {
|
if (order < 0.0) {
|
||||||
throw InputFileError("Reaction::validate", input,
|
throw InputFileError("Reaction::validate", input,
|
||||||
"Negative reaction order specified for species '{}'",
|
"Negative reaction order specified for species '{}'", name);
|
||||||
order.first);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -222,9 +220,9 @@ void Reaction::setParameters(const AnyMap& node, const Kinetics& kin)
|
|||||||
setEquation(node["equation"].asString(), &kin);
|
setEquation(node["equation"].asString(), &kin);
|
||||||
// Non-stoichiometric reaction orders
|
// Non-stoichiometric reaction orders
|
||||||
if (node.hasKey("orders")) {
|
if (node.hasKey("orders")) {
|
||||||
for (const auto& order : node["orders"].asMap<double>()) {
|
for (const auto& [name, order] : node["orders"].asMap<double>()) {
|
||||||
orders[order.first] = order.second;
|
orders[name] = order;
|
||||||
if (kin.kineticsSpeciesIndex(order.first) == npos) {
|
if (kin.kineticsSpeciesIndex(name) == npos) {
|
||||||
setValid(false);
|
setValid(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,15 +353,15 @@ void Reaction::setEquation(const std::string& equation, const Kinetics* kin)
|
|||||||
std::string third_body;
|
std::string third_body;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
size_t countM = 0;
|
size_t countM = 0;
|
||||||
for (const auto& reac : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
// detect explicitly specified collision partner
|
// detect explicitly specified collision partner
|
||||||
if (products.count(reac.first)) {
|
if (products.count(name)) {
|
||||||
third_body = reac.first;
|
third_body = name;
|
||||||
size_t generic = third_body == "M"
|
size_t generic = third_body == "M"
|
||||||
|| third_body == "(+M)" || third_body == "(+ M)";
|
|| third_body == "(+M)" || third_body == "(+ M)";
|
||||||
count++;
|
count++;
|
||||||
countM += generic;
|
countM += generic;
|
||||||
if (reac.second > 1 && products[third_body] > 1) {
|
if (stoich > 1 && products[third_body] > 1) {
|
||||||
count++;
|
count++;
|
||||||
countM += generic;
|
countM += generic;
|
||||||
}
|
}
|
||||||
@ -435,19 +433,19 @@ void Reaction::setEquation(const std::string& equation, const Kinetics* kin)
|
|||||||
size_t nprod = 0;
|
size_t nprod = 0;
|
||||||
|
|
||||||
// ensure that all reactants have integer stoichiometric coefficients
|
// ensure that all reactants have integer stoichiometric coefficients
|
||||||
for (const auto& reac : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
if (trunc(reac.second) != reac.second) {
|
if (trunc(stoich) != stoich) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nreac += static_cast<size_t>(reac.second);
|
nreac += static_cast<size_t>(stoich);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure that all products have integer stoichiometric coefficients
|
// ensure that all products have integer stoichiometric coefficients
|
||||||
for (const auto& prod : products) {
|
for (const auto& [name, stoich] : products) {
|
||||||
if (trunc(prod.second) != prod.second) {
|
if (trunc(stoich) != stoich) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nprod += static_cast<size_t>(prod.second);
|
nprod += static_cast<size_t>(stoich);
|
||||||
}
|
}
|
||||||
|
|
||||||
// either reactant or product side involves exactly three species
|
// either reactant or product side involves exactly three species
|
||||||
@ -520,22 +518,22 @@ UnitStack Reaction::calculateRateCoeffUnits(const Kinetics& kin)
|
|||||||
rate_units.join(1.);
|
rate_units.join(1.);
|
||||||
rate_units.update(Units(1.0, 0, 0, -1), 1.);
|
rate_units.update(Units(1.0, 0, 0, -1), 1.);
|
||||||
|
|
||||||
for (const auto& order : orders) {
|
for (const auto& [name, order] : orders) {
|
||||||
const auto& phase = kin.speciesPhase(order.first);
|
const auto& phase = kin.speciesPhase(name);
|
||||||
// Account for specified reaction orders
|
// Account for specified reaction orders
|
||||||
rate_units.update(phase.standardConcentrationUnits(), -order.second);
|
rate_units.update(phase.standardConcentrationUnits(), -order);
|
||||||
}
|
}
|
||||||
for (const auto& stoich : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
// Order for each reactant is the reactant stoichiometric coefficient,
|
// Order for each reactant is the reactant stoichiometric coefficient,
|
||||||
// unless already overridden by user-specified orders
|
// unless already overridden by user-specified orders
|
||||||
if (stoich.first == "M" || ba::starts_with(stoich.first, "(+")) {
|
if (name == "M" || ba::starts_with(name, "(+")) {
|
||||||
// calculateRateCoeffUnits may be called before these pseudo-species
|
// calculateRateCoeffUnits may be called before these pseudo-species
|
||||||
// have been stripped from the reactants
|
// have been stripped from the reactants
|
||||||
continue;
|
continue;
|
||||||
} else if (orders.find(stoich.first) == orders.end()) {
|
} else if (orders.find(name) == orders.end()) {
|
||||||
const auto& phase = kin.speciesPhase(stoich.first);
|
const auto& phase = kin.speciesPhase(name);
|
||||||
// Account for each reactant species
|
// Account for each reactant species
|
||||||
rate_units.update(phase.standardConcentrationUnits(), -stoich.second);
|
rate_units.update(phase.standardConcentrationUnits(), -stoich);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,9 +548,9 @@ UnitStack Reaction::calculateRateCoeffUnits(const Kinetics& kin)
|
|||||||
void updateUndeclared(std::vector<std::string>& undeclared,
|
void updateUndeclared(std::vector<std::string>& undeclared,
|
||||||
const Composition& comp, const Kinetics& kin)
|
const Composition& comp, const Kinetics& kin)
|
||||||
{
|
{
|
||||||
for (const auto& sp: comp) {
|
for (const auto& [name, stoich]: comp) {
|
||||||
if (kin.kineticsSpeciesIndex(sp.first) == npos) {
|
if (kin.kineticsSpeciesIndex(name) == npos) {
|
||||||
undeclared.emplace_back(sp.first);
|
undeclared.emplace_back(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -562,19 +560,17 @@ void Reaction::checkBalance(const Kinetics& kin) const
|
|||||||
Composition balr, balp;
|
Composition balr, balp;
|
||||||
|
|
||||||
// iterate over products and reactants
|
// iterate over products and reactants
|
||||||
for (const auto& sp : products) {
|
for (const auto& [name, stoich] : products) {
|
||||||
const ThermoPhase& ph = kin.speciesPhase(sp.first);
|
const ThermoPhase& ph = kin.speciesPhase(name);
|
||||||
size_t k = ph.speciesIndex(sp.first);
|
size_t k = ph.speciesIndex(name);
|
||||||
double stoich = sp.second;
|
|
||||||
for (size_t m = 0; m < ph.nElements(); m++) {
|
for (size_t m = 0; m < ph.nElements(); m++) {
|
||||||
balr[ph.elementName(m)] = 0.0; // so that balr contains all species
|
balr[ph.elementName(m)] = 0.0; // so that balr contains all species
|
||||||
balp[ph.elementName(m)] += stoich * ph.nAtoms(k, m);
|
balp[ph.elementName(m)] += stoich * ph.nAtoms(k, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& sp : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
const ThermoPhase& ph = kin.speciesPhase(sp.first);
|
const ThermoPhase& ph = kin.speciesPhase(name);
|
||||||
size_t k = ph.speciesIndex(sp.first);
|
size_t k = ph.speciesIndex(name);
|
||||||
double stoich = sp.second;
|
|
||||||
for (size_t m = 0; m < ph.nElements(); m++) {
|
for (size_t m = 0; m < ph.nElements(); m++) {
|
||||||
balr[ph.elementName(m)] += stoich * ph.nAtoms(k, m);
|
balr[ph.elementName(m)] += stoich * ph.nAtoms(k, m);
|
||||||
}
|
}
|
||||||
@ -582,8 +578,7 @@ void Reaction::checkBalance(const Kinetics& kin) const
|
|||||||
|
|
||||||
std::string msg;
|
std::string msg;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
for (const auto& el : balr) {
|
for (const auto& [elem, balance] : balr) {
|
||||||
const std::string& elem = el.first;
|
|
||||||
double elemsum = balr[elem] + balp[elem];
|
double elemsum = balr[elem] + balp[elem];
|
||||||
double elemdiff = fabs(balp[elem] - balr[elem]);
|
double elemdiff = fabs(balp[elem] - balr[elem]);
|
||||||
if (elemsum > 0.0 && elemdiff / elemsum > 1e-4) {
|
if (elemsum > 0.0 && elemdiff / elemsum > 1e-4) {
|
||||||
@ -607,16 +602,16 @@ void Reaction::checkBalance(const Kinetics& kin) const
|
|||||||
double reac_sites = 0.0;
|
double reac_sites = 0.0;
|
||||||
double prod_sites = 0.0;
|
double prod_sites = 0.0;
|
||||||
auto& surf = dynamic_cast<const SurfPhase&>(kin.thermo(kin.reactionPhaseIndex()));
|
auto& surf = dynamic_cast<const SurfPhase&>(kin.thermo(kin.reactionPhaseIndex()));
|
||||||
for (const auto& reactant : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
size_t k = surf.speciesIndex(reactant.first);
|
size_t k = surf.speciesIndex(name);
|
||||||
if (k != npos) {
|
if (k != npos) {
|
||||||
reac_sites += reactant.second * surf.size(k);
|
reac_sites += stoich * surf.size(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto& product : products) {
|
for (const auto& [name, stoich] : products) {
|
||||||
size_t k = surf.speciesIndex(product.first);
|
size_t k = surf.speciesIndex(name);
|
||||||
if (k != npos) {
|
if (k != npos) {
|
||||||
prod_sites += product.second * surf.size(k);
|
prod_sites += stoich * surf.size(k);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fabs(reac_sites - prod_sites) > 1e-5 * (reac_sites + prod_sites)) {
|
if (fabs(reac_sites - prod_sites) > 1e-5 * (reac_sites + prod_sites)) {
|
||||||
@ -677,19 +672,19 @@ bool Reaction::usesElectrochemistry(const Kinetics& kin) const
|
|||||||
vector_fp e_counter(kin.nPhases(), 0.0);
|
vector_fp e_counter(kin.nPhases(), 0.0);
|
||||||
|
|
||||||
// Find the number of electrons in the products for each phase
|
// Find the number of electrons in the products for each phase
|
||||||
for (const auto& sp : products) {
|
for (const auto& [name, stoich] : products) {
|
||||||
size_t kkin = kin.kineticsSpeciesIndex(sp.first);
|
size_t kkin = kin.kineticsSpeciesIndex(name);
|
||||||
size_t i = kin.speciesPhaseIndex(kkin);
|
size_t i = kin.speciesPhaseIndex(kkin);
|
||||||
size_t kphase = kin.thermo(i).speciesIndex(sp.first);
|
size_t kphase = kin.thermo(i).speciesIndex(name);
|
||||||
e_counter[i] += sp.second * kin.thermo(i).charge(kphase);
|
e_counter[i] += stoich * kin.thermo(i).charge(kphase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subtract the number of electrons in the reactants for each phase
|
// Subtract the number of electrons in the reactants for each phase
|
||||||
for (const auto& sp : reactants) {
|
for (const auto& [name, stoich] : reactants) {
|
||||||
size_t kkin = kin.kineticsSpeciesIndex(sp.first);
|
size_t kkin = kin.kineticsSpeciesIndex(name);
|
||||||
size_t i = kin.speciesPhaseIndex(kkin);
|
size_t i = kin.speciesPhaseIndex(kkin);
|
||||||
size_t kphase = kin.thermo(i).speciesIndex(sp.first);
|
size_t kphase = kin.thermo(i).speciesIndex(name);
|
||||||
e_counter[i] -= sp.second * kin.thermo(i).charge(kphase);
|
e_counter[i] -= stoich * kin.thermo(i).charge(kphase);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the electrons change phases then the reaction is electrochemical
|
// If the electrons change phases then the reaction is electrochemical
|
||||||
|
@ -62,12 +62,12 @@ void Path::writeLabel(ostream& s, doublereal threshold)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
doublereal v;
|
doublereal v;
|
||||||
for (const auto& label : m_label) {
|
for (const auto& [species, value] : m_label) {
|
||||||
v = label.second/m_total;
|
v = value / m_total;
|
||||||
if (m_label.size() == 1) {
|
if (m_label.size() == 1) {
|
||||||
s << label.first << "\\l";
|
s << species << "\\l";
|
||||||
} else if (v > threshold) {
|
} else if (v > threshold) {
|
||||||
s << label.first;
|
s << species;
|
||||||
int percent = int(100*v + 0.5);
|
int percent = int(100*v + 0.5);
|
||||||
if (percent < 100) {
|
if (percent < 100) {
|
||||||
s << " (" << percent << "%)\\l";
|
s << " (" << percent << "%)\\l";
|
||||||
@ -105,8 +105,8 @@ ReactionPathDiagram::ReactionPathDiagram()
|
|||||||
ReactionPathDiagram::~ReactionPathDiagram()
|
ReactionPathDiagram::~ReactionPathDiagram()
|
||||||
{
|
{
|
||||||
// delete the nodes
|
// delete the nodes
|
||||||
for (const auto& node : m_nodes) {
|
for (const auto& [k, node] : m_nodes) {
|
||||||
delete node.second;
|
delete node;
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the paths
|
// delete the paths
|
||||||
@ -125,10 +125,10 @@ vector_int ReactionPathDiagram::reactions()
|
|||||||
}
|
}
|
||||||
m_rxns.clear();
|
m_rxns.clear();
|
||||||
for (size_t i = 0; i < nPaths(); i++) {
|
for (size_t i = 0; i < nPaths(); i++) {
|
||||||
for (const auto& rxn : path(i)->reactionMap()) {
|
for (const auto& [iRxn, flux] : path(i)->reactionMap()) {
|
||||||
double flxratio = rxn.second/flmax;
|
double flxratio = flux / flmax;
|
||||||
if (flxratio > threshold) {
|
if (flxratio > threshold) {
|
||||||
m_rxns.insert(rxn.first);
|
m_rxns.insert(iRxn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,9 +364,9 @@ void ReactionPathDiagram::exportToDot(ostream& s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
s.precision(2);
|
s.precision(2);
|
||||||
for (const auto& node : m_nodes) {
|
for (const auto& [kSpecies, node] : m_nodes) {
|
||||||
if (node.second->visible) {
|
if (node->visible) {
|
||||||
s << "s" << node.first << " [ fontname=\""+m_font+"\", label=\"" << node.second->name
|
s << "s" << kSpecies << " [ fontname=\""+m_font+"\", label=\"" << node->name
|
||||||
<< "\"];" << endl;
|
<< "\"];" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,9 +160,9 @@ AnyMap legacyH5(shared_ptr<SolutionArray> arr, const AnyMap& header={})
|
|||||||
{"emissivity-left", "emissivity_left"},
|
{"emissivity-left", "emissivity_left"},
|
||||||
{"emissivity-right", "emissivity_right"},
|
{"emissivity-right", "emissivity_right"},
|
||||||
};
|
};
|
||||||
for (const auto& item : meta_pairs) {
|
for (const auto& [newName, oldName] : meta_pairs) {
|
||||||
if (meta.hasKey(item.second)) {
|
if (meta.hasKey(oldName)) {
|
||||||
out[item.first] = meta[item.second];
|
out[newName] = meta[oldName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,9 +172,9 @@ AnyMap legacyH5(shared_ptr<SolutionArray> arr, const AnyMap& header={})
|
|||||||
{"transient-reltol", "transient_reltol"},
|
{"transient-reltol", "transient_reltol"},
|
||||||
{"steady-reltol", "steady_reltol"},
|
{"steady-reltol", "steady_reltol"},
|
||||||
};
|
};
|
||||||
for (const auto& item : tol_pairs) {
|
for (const auto& [newName, oldName] : tol_pairs) {
|
||||||
if (meta.hasKey(item.second)) {
|
if (meta.hasKey(oldName)) {
|
||||||
out["tolerances"][item.first] = meta[item.second];
|
out["tolerances"][newName] = meta[oldName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,9 +194,9 @@ AnyMap legacyH5(shared_ptr<SolutionArray> arr, const AnyMap& header={})
|
|||||||
{"Soret-enabled", "soret_enabled"},
|
{"Soret-enabled", "soret_enabled"},
|
||||||
{"species-enabled", "species_enabled"},
|
{"species-enabled", "species_enabled"},
|
||||||
};
|
};
|
||||||
for (const auto& item : header_pairs) {
|
for (const auto& [newName, oldName] : header_pairs) {
|
||||||
if (header.hasKey(item.second)) {
|
if (header.hasKey(oldName)) {
|
||||||
out[item.first] = header[item.second];
|
out[newName] = header[oldName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,9 +208,9 @@ AnyMap legacyH5(shared_ptr<SolutionArray> arr, const AnyMap& header={})
|
|||||||
// {"grid-min", "???"}, // missing
|
// {"grid-min", "???"}, // missing
|
||||||
{"max-points", "max_grid_points"},
|
{"max-points", "max_grid_points"},
|
||||||
};
|
};
|
||||||
for (const auto& item : refiner_pairs) {
|
for (const auto& [newName, oldName] : refiner_pairs) {
|
||||||
if (header.hasKey(item.second)) {
|
if (header.hasKey(oldName)) {
|
||||||
out["refine-criteria"][item.first] = header[item.second];
|
out["refine-criteria"][newName] = header[oldName];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,8 +304,8 @@ void LatticeSolidPhase::initThermo()
|
|||||||
{
|
{
|
||||||
if (m_input.hasKey("composition")) {
|
if (m_input.hasKey("composition")) {
|
||||||
compositionMap composition = m_input["composition"].asMap<double>();
|
compositionMap composition = m_input["composition"].asMap<double>();
|
||||||
for (auto& item : composition) {
|
for (auto& [name, stoich] : composition) {
|
||||||
AnyMap& node = m_rootNode["phases"].getMapWhere("name", item.first);
|
AnyMap& node = m_rootNode["phases"].getMapWhere("name", name);
|
||||||
addLattice(newThermo(node, m_rootNode));
|
addLattice(newThermo(node, m_rootNode));
|
||||||
}
|
}
|
||||||
setLatticeStoichiometry(composition);
|
setLatticeStoichiometry(composition);
|
||||||
|
@ -49,13 +49,12 @@ void Mu0Poly::setParameters(double h0, const std::map<double, double>& T_mu)
|
|||||||
// Distribute the data into the internal arrays, and find the index of the
|
// Distribute the data into the internal arrays, and find the index of the
|
||||||
// point at 298.15 K.
|
// point at 298.15 K.
|
||||||
size_t iT298 = npos;
|
size_t iT298 = npos;
|
||||||
for (const auto& row : T_mu) {
|
for (const auto& [T1, mu] : T_mu) {
|
||||||
double T1 = row.first;
|
|
||||||
if (T1 == 298.15) {
|
if (T1 == 298.15) {
|
||||||
iT298 = m_t0_int.size();
|
iT298 = m_t0_int.size();
|
||||||
}
|
}
|
||||||
m_t0_int.push_back(T1);
|
m_t0_int.push_back(T1);
|
||||||
m_mu0_R_int.push_back(row.second / GasConstant);
|
m_mu0_R_int.push_back(mu / GasConstant);
|
||||||
}
|
}
|
||||||
if (iT298 == npos) {
|
if (iT298 == npos) {
|
||||||
throw CanteraError("Mu0Poly::setParameters",
|
throw CanteraError("Mu0Poly::setParameters",
|
||||||
|
@ -96,9 +96,8 @@ void MultiSpeciesThermo::update(doublereal t, doublereal* cp_R,
|
|||||||
const std::vector<index_STIT>& species = iter->second;
|
const std::vector<index_STIT>& species = iter->second;
|
||||||
double* tpoly = &jter->second[0];
|
double* tpoly = &jter->second[0];
|
||||||
species[0].second->updateTemperaturePoly(t, tpoly);
|
species[0].second->updateTemperaturePoly(t, tpoly);
|
||||||
for (size_t k = 0; k < species.size(); k++) {
|
for (auto& [i, spthermo] : species) {
|
||||||
size_t i = species[k].first;
|
spthermo->updateProperties(tpoly, cp_R+i, h_RT+i, s_R+i);
|
||||||
species[k].second->updateProperties(tpoly, cp_R+i, h_RT+i, s_R+i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,8 +161,8 @@ doublereal MultiSpeciesThermo::refPressure(size_t k) const
|
|||||||
SpeciesThermoInterpType* MultiSpeciesThermo::provideSTIT(size_t k)
|
SpeciesThermoInterpType* MultiSpeciesThermo::provideSTIT(size_t k)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const std::pair<int, size_t>& loc = m_speciesLoc.at(k);
|
auto& [iParam, jSpecies] = m_speciesLoc.at(k);
|
||||||
return m_sp.at(loc.first)[loc.second].second.get();
|
return m_sp.at(iParam)[jSpecies].second.get();
|
||||||
} catch (std::out_of_range&) {
|
} catch (std::out_of_range&) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -172,8 +171,8 @@ SpeciesThermoInterpType* MultiSpeciesThermo::provideSTIT(size_t k)
|
|||||||
const SpeciesThermoInterpType* MultiSpeciesThermo::provideSTIT(size_t k) const
|
const SpeciesThermoInterpType* MultiSpeciesThermo::provideSTIT(size_t k) const
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
const std::pair<int, size_t>& loc = m_speciesLoc.at(k);
|
auto& [iParam, jSpecies] = m_speciesLoc.at(k);
|
||||||
return m_sp.at(loc.first)[loc.second].second.get();
|
return m_sp.at(iParam)[jSpecies].second.get();
|
||||||
} catch (std::out_of_range&) {
|
} catch (std::out_of_range&) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -91,14 +91,14 @@ void Nasa9PolyMultiTempRegion::setParameters(const std::map<double, vector_fp>&
|
|||||||
{
|
{
|
||||||
m_regionPts.clear();
|
m_regionPts.clear();
|
||||||
m_lowerTempBounds.clear();
|
m_lowerTempBounds.clear();
|
||||||
for (const auto& region : regions) {
|
for (const auto& [Tmin, coeffs] : regions) {
|
||||||
m_lowerTempBounds.push_back(region.first);
|
m_lowerTempBounds.push_back(Tmin);
|
||||||
Nasa9Poly1* poly = new Nasa9Poly1;
|
Nasa9Poly1* poly = new Nasa9Poly1;
|
||||||
poly->setRefPressure(refPressure());
|
poly->setRefPressure(refPressure());
|
||||||
poly->setMinTemp(region.first);
|
poly->setMinTemp(Tmin);
|
||||||
poly->setParameters(region.second);
|
poly->setParameters(coeffs);
|
||||||
if (!m_regionPts.empty()) {
|
if (!m_regionPts.empty()) {
|
||||||
m_regionPts.back()->setMaxTemp(region.first);
|
m_regionPts.back()->setMaxTemp(Tmin);
|
||||||
}
|
}
|
||||||
m_regionPts.emplace_back(poly);
|
m_regionPts.emplace_back(poly);
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,8 @@ void PDSS_IonsFromNeutral::initThermo()
|
|||||||
setSpecialSpecies();
|
setSpecialSpecies();
|
||||||
}
|
}
|
||||||
if (m_input.hasKey("multipliers")) {
|
if (m_input.hasKey("multipliers")) {
|
||||||
for (const auto& item : m_input["multipliers"].asMap<double>()) {
|
for (const auto& [species, multiplier] : m_input["multipliers"].asMap<double>()) {
|
||||||
setNeutralSpeciesMultiplier(item.first, item.second);
|
setNeutralSpeciesMultiplier(species, multiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,9 +66,9 @@ void PDSS_IonsFromNeutral::initThermo()
|
|||||||
m_minTemp = neutralMoleculePhase_->minTemp();
|
m_minTemp = neutralMoleculePhase_->minTemp();
|
||||||
m_maxTemp = neutralMoleculePhase_->maxTemp();
|
m_maxTemp = neutralMoleculePhase_->maxTemp();
|
||||||
tmpNM.resize(neutralMoleculePhase_->nSpecies());
|
tmpNM.resize(neutralMoleculePhase_->nSpecies());
|
||||||
for (auto multiplier : neutralSpeciesMultipliers_) {
|
for (auto [species, multiplier] : neutralSpeciesMultipliers_) {
|
||||||
idNeutralMoleculeVec.push_back( neutralMoleculePhase_->speciesIndex(multiplier.first));
|
idNeutralMoleculeVec.push_back(neutralMoleculePhase_->speciesIndex(species));
|
||||||
factorVec.push_back(multiplier.second);
|
factorVec.push_back(multiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,9 +347,9 @@ void PengRobinson::initThermo()
|
|||||||
AnyMap critPropsDb;
|
AnyMap critPropsDb;
|
||||||
std::unordered_map<std::string, AnyMap*> dbSpecies;
|
std::unordered_map<std::string, AnyMap*> dbSpecies;
|
||||||
|
|
||||||
for (auto& item : m_species) {
|
for (auto& [name, species] : m_species) {
|
||||||
auto& data = item.second->input;
|
auto& data = species->input;
|
||||||
size_t k = speciesIndex(item.first);
|
size_t k = speciesIndex(name);
|
||||||
if (m_a_coeffs(k, k) != 0.0) {
|
if (m_a_coeffs(k, k) != 0.0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -366,16 +366,16 @@ void PengRobinson::initThermo()
|
|||||||
double b = eos.convert("b", "m^3/kmol");
|
double b = eos.convert("b", "m^3/kmol");
|
||||||
// unitless acentric factor:
|
// unitless acentric factor:
|
||||||
double w = eos["acentric-factor"].asDouble();
|
double w = eos["acentric-factor"].asDouble();
|
||||||
setSpeciesCoeffs(item.first, a0, b, w);
|
setSpeciesCoeffs(name, a0, b, w);
|
||||||
foundCoeffs = true;
|
foundCoeffs = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eos.hasKey("binary-a")) {
|
if (eos.hasKey("binary-a")) {
|
||||||
AnyMap& binary_a = eos["binary-a"].as<AnyMap>();
|
AnyMap& binary_a = eos["binary-a"].as<AnyMap>();
|
||||||
const UnitSystem& units = binary_a.units();
|
const UnitSystem& units = binary_a.units();
|
||||||
for (auto& item2 : binary_a) {
|
for (auto& [name2, coeff] : binary_a) {
|
||||||
double a0 = units.convert(item2.second, "Pa*m^6/kmol^2");
|
double a0 = units.convert(coeff, "Pa*m^6/kmol^2");
|
||||||
setBinaryCoeffs(item.first, item2.first, a0);
|
setBinaryCoeffs(name, name2, a0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (foundCoeffs) {
|
if (foundCoeffs) {
|
||||||
@ -402,7 +402,7 @@ void PengRobinson::initThermo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All names in critical-properties.yaml are upper case
|
// All names in critical-properties.yaml are upper case
|
||||||
auto ucName = boost::algorithm::to_upper_copy(item.first);
|
auto ucName = boost::algorithm::to_upper_copy(name);
|
||||||
if (dbSpecies.count(ucName)) {
|
if (dbSpecies.count(ucName)) {
|
||||||
auto& spec = *dbSpecies.at(ucName);
|
auto& spec = *dbSpecies.at(ucName);
|
||||||
auto& critProps = spec["critical-parameters"].as<AnyMap>();
|
auto& critProps = spec["critical-parameters"].as<AnyMap>();
|
||||||
@ -417,11 +417,11 @@ void PengRobinson::initThermo()
|
|||||||
if (!isnan(Tc)) {
|
if (!isnan(Tc)) {
|
||||||
double a = omega_a * std::pow(GasConstant * Tc, 2) / Pc;
|
double a = omega_a * std::pow(GasConstant * Tc, 2) / Pc;
|
||||||
double b = omega_b * GasConstant * Tc / Pc;
|
double b = omega_b * GasConstant * Tc / Pc;
|
||||||
setSpeciesCoeffs(item.first, a, b, omega_ac);
|
setSpeciesCoeffs(name, a, b, omega_ac);
|
||||||
} else {
|
} else {
|
||||||
throw InputFileError("PengRobinson::initThermo", data,
|
throw InputFileError("PengRobinson::initThermo", data,
|
||||||
"No Peng-Robinson model parameters or critical properties found for "
|
"No Peng-Robinson model parameters or critical properties found for "
|
||||||
"species '{}'", item.first);
|
"species '{}'", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,8 +456,8 @@ void PengRobinson::getSpeciesParameters(const std::string& name,
|
|||||||
auto& eosNode = speciesNode["equation-of-state"].getMapWhere(
|
auto& eosNode = speciesNode["equation-of-state"].getMapWhere(
|
||||||
"model", "Peng-Robinson", true);
|
"model", "Peng-Robinson", true);
|
||||||
AnyMap bin_a;
|
AnyMap bin_a;
|
||||||
for (const auto& item : m_binaryParameters.at(name)) {
|
for (const auto& [species, coeff] : m_binaryParameters.at(name)) {
|
||||||
bin_a[item.first].setQuantity(item.second, "Pa*m^6/kmol^2");
|
bin_a[species].setQuantity(coeff, "Pa*m^6/kmol^2");
|
||||||
}
|
}
|
||||||
eosNode["binary-a"] = std::move(bin_a);
|
eosNode["binary-a"] = std::move(bin_a);
|
||||||
}
|
}
|
||||||
@ -593,11 +593,11 @@ double PengRobinson::densSpinodalLiquid() const
|
|||||||
};
|
};
|
||||||
|
|
||||||
boost::uintmax_t maxiter = 100;
|
boost::uintmax_t maxiter = 100;
|
||||||
std::pair<double, double> vv = bmt::toms748_solve(
|
auto [lower, upper] = bmt::toms748_solve(
|
||||||
resid, Vroot[0], Vroot[1], bmt::eps_tolerance<double>(48), maxiter);
|
resid, Vroot[0], Vroot[1], bmt::eps_tolerance<double>(48), maxiter);
|
||||||
|
|
||||||
double mmw = meanMolecularWeight();
|
double mmw = meanMolecularWeight();
|
||||||
return mmw / (0.5 * (vv.first + vv.second));
|
return mmw / (0.5 * (lower + upper));
|
||||||
}
|
}
|
||||||
|
|
||||||
double PengRobinson::densSpinodalGas() const
|
double PengRobinson::densSpinodalGas() const
|
||||||
@ -615,11 +615,11 @@ double PengRobinson::densSpinodalGas() const
|
|||||||
};
|
};
|
||||||
|
|
||||||
boost::uintmax_t maxiter = 100;
|
boost::uintmax_t maxiter = 100;
|
||||||
std::pair<double, double> vv = bmt::toms748_solve(
|
auto [lower, upper] = bmt::toms748_solve(
|
||||||
resid, Vroot[1], Vroot[2], bmt::eps_tolerance<double>(48), maxiter);
|
resid, Vroot[1], Vroot[2], bmt::eps_tolerance<double>(48), maxiter);
|
||||||
|
|
||||||
double mmw = meanMolecularWeight();
|
double mmw = meanMolecularWeight();
|
||||||
return mmw / (0.5 * (vv.first + vv.second));
|
return mmw / (0.5 * (lower + upper));
|
||||||
}
|
}
|
||||||
|
|
||||||
double PengRobinson::dpdVCalc(double T, double molarVol, double& presCalc) const
|
double PengRobinson::dpdVCalc(double T, double molarVol, double& presCalc) const
|
||||||
|
@ -814,27 +814,27 @@ bool Phase::addSpecies(shared_ptr<Species> spec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
vector_fp comp(nElements());
|
vector_fp comp(nElements());
|
||||||
for (const auto& elem : spec->composition) {
|
for (const auto& [eName, stoich] : spec->composition) {
|
||||||
size_t m = elementIndex(elem.first);
|
size_t m = elementIndex(eName);
|
||||||
if (m == npos) { // Element doesn't exist in this phase
|
if (m == npos) { // Element doesn't exist in this phase
|
||||||
switch (m_undefinedElementBehavior) {
|
switch (m_undefinedElementBehavior) {
|
||||||
case UndefElement::ignore:
|
case UndefElement::ignore:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case UndefElement::add:
|
case UndefElement::add:
|
||||||
addElement(elem.first);
|
addElement(eName);
|
||||||
comp.resize(nElements());
|
comp.resize(nElements());
|
||||||
m = elementIndex(elem.first);
|
m = elementIndex(eName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UndefElement::error:
|
case UndefElement::error:
|
||||||
default:
|
default:
|
||||||
throw CanteraError("Phase::addSpecies",
|
throw CanteraError("Phase::addSpecies",
|
||||||
"Species '{}' contains an undefined element '{}'.",
|
"Species '{}' contains an undefined element '{}'.",
|
||||||
spec->name, elem.first);
|
spec->name, eName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
comp[m] = elem.second;
|
comp[m] = stoich;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ne = nElements();
|
size_t ne = nElements();
|
||||||
@ -947,9 +947,9 @@ vector<std::string> Phase::findIsomers(const compositionMap& compMap) const
|
|||||||
{
|
{
|
||||||
vector<std::string> isomerNames;
|
vector<std::string> isomerNames;
|
||||||
|
|
||||||
for (const auto& k : m_species) {
|
for (const auto& [name, species] : m_species) {
|
||||||
if (k.second->composition == compMap) {
|
if (species->composition == compMap) {
|
||||||
isomerNames.emplace_back(k.first);
|
isomerNames.emplace_back(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,13 +1017,13 @@ void Phase::compositionChanged() {
|
|||||||
vector_fp Phase::getCompositionFromMap(const compositionMap& comp) const
|
vector_fp Phase::getCompositionFromMap(const compositionMap& comp) const
|
||||||
{
|
{
|
||||||
vector_fp X(m_kk);
|
vector_fp X(m_kk);
|
||||||
for (const auto& sp : comp) {
|
for (const auto& [name, value] : comp) {
|
||||||
size_t loc = speciesIndex(sp.first);
|
size_t loc = speciesIndex(name);
|
||||||
if (loc == npos) {
|
if (loc == npos) {
|
||||||
throw CanteraError("Phase::getCompositionFromMap",
|
throw CanteraError("Phase::getCompositionFromMap",
|
||||||
"Unknown species '{}'", sp.first);
|
"Unknown species '{}'", name);
|
||||||
}
|
}
|
||||||
X[loc] = sp.second;
|
X[loc] = value;
|
||||||
}
|
}
|
||||||
return X;
|
return X;
|
||||||
}
|
}
|
||||||
|
@ -393,9 +393,9 @@ void RedlichKwongMFTP::initThermo()
|
|||||||
AnyMap critPropsDb;
|
AnyMap critPropsDb;
|
||||||
std::unordered_map<std::string, AnyMap*> dbSpecies;
|
std::unordered_map<std::string, AnyMap*> dbSpecies;
|
||||||
|
|
||||||
for (auto& item : m_species) {
|
for (auto& [name, species] : m_species) {
|
||||||
auto& data = item.second->input;
|
auto& data = species->input;
|
||||||
size_t k = speciesIndex(item.first);
|
size_t k = speciesIndex(name);
|
||||||
if (!isnan(a_coeff_vec(0, k + m_kk * k))) {
|
if (!isnan(a_coeff_vec(0, k + m_kk * k))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -420,23 +420,23 @@ void RedlichKwongMFTP::initThermo()
|
|||||||
}
|
}
|
||||||
double b = eos.convert("b", "m^3/kmol");
|
double b = eos.convert("b", "m^3/kmol");
|
||||||
foundCoeffs = true;
|
foundCoeffs = true;
|
||||||
setSpeciesCoeffs(item.first, a0, a1, b);
|
setSpeciesCoeffs(name, a0, a1, b);
|
||||||
m_coeffSource[k] = CoeffSource::EoS;
|
m_coeffSource[k] = CoeffSource::EoS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eos.hasKey("binary-a")) {
|
if (eos.hasKey("binary-a")) {
|
||||||
AnyMap& binary_a = eos["binary-a"].as<AnyMap>();
|
AnyMap& binary_a = eos["binary-a"].as<AnyMap>();
|
||||||
const UnitSystem& units = binary_a.units();
|
const UnitSystem& units = binary_a.units();
|
||||||
for (auto& item2 : binary_a) {
|
for (auto& [name2, coeff] : binary_a) {
|
||||||
double a0 = 0, a1 = 0;
|
double a0 = 0, a1 = 0;
|
||||||
if (item2.second.isScalar()) {
|
if (coeff.isScalar()) {
|
||||||
a0 = units.convert(item2.second, "Pa*m^6/kmol^2*K^0.5");
|
a0 = units.convert(coeff, "Pa*m^6/kmol^2*K^0.5");
|
||||||
} else {
|
} else {
|
||||||
auto avec = item2.second.asVector<AnyValue>(2);
|
auto avec = coeff.asVector<AnyValue>(2);
|
||||||
a0 = units.convert(avec[0], "Pa*m^6/kmol^2*K^0.5");
|
a0 = units.convert(avec[0], "Pa*m^6/kmol^2*K^0.5");
|
||||||
a1 = units.convert(avec[1], "Pa*m^6/kmol^2/K^0.5");
|
a1 = units.convert(avec[1], "Pa*m^6/kmol^2/K^0.5");
|
||||||
}
|
}
|
||||||
setBinaryCoeffs(item.first, item2.first, a0, a1);
|
setBinaryCoeffs(name, name2, a0, a1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,7 +462,7 @@ void RedlichKwongMFTP::initThermo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// All names in critical-properties.yaml are upper case
|
// All names in critical-properties.yaml are upper case
|
||||||
auto ucName = boost::algorithm::to_upper_copy(item.first);
|
auto ucName = boost::algorithm::to_upper_copy(name);
|
||||||
if (dbSpecies.count(ucName)) {
|
if (dbSpecies.count(ucName)) {
|
||||||
auto& spec = *dbSpecies.at(ucName);
|
auto& spec = *dbSpecies.at(ucName);
|
||||||
auto& critProps = spec["critical-parameters"].as<AnyMap>();
|
auto& critProps = spec["critical-parameters"].as<AnyMap>();
|
||||||
@ -477,11 +477,11 @@ void RedlichKwongMFTP::initThermo()
|
|||||||
// Assuming no temperature dependence (that is, a1 = 0)
|
// Assuming no temperature dependence (that is, a1 = 0)
|
||||||
double a = omega_a * pow(GasConstant, 2) * pow(Tc, 2.5) / Pc;
|
double a = omega_a * pow(GasConstant, 2) * pow(Tc, 2.5) / Pc;
|
||||||
double b = omega_b * GasConstant * Tc / Pc;
|
double b = omega_b * GasConstant * Tc / Pc;
|
||||||
setSpeciesCoeffs(item.first, a, 0.0, b);
|
setSpeciesCoeffs(name, a, 0.0, b);
|
||||||
} else {
|
} else {
|
||||||
throw InputFileError("RedlichKwongMFTP::initThermo", data,
|
throw InputFileError("RedlichKwongMFTP::initThermo", data,
|
||||||
"No critical property or Redlich-Kwong parameters found "
|
"No critical property or Redlich-Kwong parameters found "
|
||||||
"for species {}.", item.first);
|
"for species {}.", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -521,14 +521,14 @@ void RedlichKwongMFTP::getSpeciesParameters(const std::string& name,
|
|||||||
auto& eosNode = speciesNode["equation-of-state"].getMapWhere(
|
auto& eosNode = speciesNode["equation-of-state"].getMapWhere(
|
||||||
"model", "Redlich-Kwong", true);
|
"model", "Redlich-Kwong", true);
|
||||||
AnyMap bin_a;
|
AnyMap bin_a;
|
||||||
for (const auto& item : m_binaryParameters.at(name)) {
|
for (const auto& [name2, coeffs] : m_binaryParameters.at(name)) {
|
||||||
if (item.second.second == 0) {
|
if (coeffs.second == 0) {
|
||||||
bin_a[item.first].setQuantity(item.second.first, "Pa*m^6/kmol^2*K^0.5");
|
bin_a[name2].setQuantity(coeffs.first, "Pa*m^6/kmol^2*K^0.5");
|
||||||
} else {
|
} else {
|
||||||
vector<AnyValue> coeffs(2);
|
vector<AnyValue> C(2);
|
||||||
coeffs[0].setQuantity(item.second.first, "Pa*m^6/kmol^2*K^0.5");
|
C[0].setQuantity(coeffs.first, "Pa*m^6/kmol^2*K^0.5");
|
||||||
coeffs[1].setQuantity(item.second.second, "Pa*m^6/kmol^2/K^0.5");
|
C[1].setQuantity(coeffs.second, "Pa*m^6/kmol^2/K^0.5");
|
||||||
bin_a[item.first] = std::move(coeffs);
|
bin_a[name2] = std::move(C);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eosNode["binary-a"] = std::move(bin_a);
|
eosNode["binary-a"] = std::move(bin_a);
|
||||||
@ -667,11 +667,11 @@ doublereal RedlichKwongMFTP::densSpinodalLiquid() const
|
|||||||
};
|
};
|
||||||
|
|
||||||
boost::uintmax_t maxiter = 100;
|
boost::uintmax_t maxiter = 100;
|
||||||
std::pair<double, double> vv = bmt::toms748_solve(
|
auto [lower, upper] = bmt::toms748_solve(
|
||||||
resid, Vroot[0], Vroot[1], bmt::eps_tolerance<double>(48), maxiter);
|
resid, Vroot[0], Vroot[1], bmt::eps_tolerance<double>(48), maxiter);
|
||||||
|
|
||||||
doublereal mmw = meanMolecularWeight();
|
doublereal mmw = meanMolecularWeight();
|
||||||
return mmw / (0.5 * (vv.first + vv.second));
|
return mmw / (0.5 * (lower + upper));
|
||||||
}
|
}
|
||||||
|
|
||||||
doublereal RedlichKwongMFTP::densSpinodalGas() const
|
doublereal RedlichKwongMFTP::densSpinodalGas() const
|
||||||
@ -689,11 +689,11 @@ doublereal RedlichKwongMFTP::densSpinodalGas() const
|
|||||||
};
|
};
|
||||||
|
|
||||||
boost::uintmax_t maxiter = 100;
|
boost::uintmax_t maxiter = 100;
|
||||||
std::pair<double, double> vv = bmt::toms748_solve(
|
auto [lower, upper] = bmt::toms748_solve(
|
||||||
resid, Vroot[1], Vroot[2], bmt::eps_tolerance<double>(48), maxiter);
|
resid, Vroot[1], Vroot[2], bmt::eps_tolerance<double>(48), maxiter);
|
||||||
|
|
||||||
doublereal mmw = meanMolecularWeight();
|
doublereal mmw = meanMolecularWeight();
|
||||||
return mmw / (0.5 * (vv.first + vv.second));
|
return mmw / (0.5 * (lower + upper));
|
||||||
}
|
}
|
||||||
|
|
||||||
doublereal RedlichKwongMFTP::dpdVCalc(doublereal TKelvin, doublereal molarVol, doublereal& presCalc) const
|
doublereal RedlichKwongMFTP::dpdVCalc(doublereal TKelvin, doublereal molarVol, doublereal& presCalc) const
|
||||||
|
@ -41,14 +41,14 @@ double Species::molecularWeight() {
|
|||||||
if (m_molecularWeight == Undef) {
|
if (m_molecularWeight == Undef) {
|
||||||
double weight = 0.0;
|
double weight = 0.0;
|
||||||
const auto& elements = elementWeights();
|
const auto& elements = elementWeights();
|
||||||
for (const auto& comp : composition) {
|
for (const auto& [eName, stoich] : composition) {
|
||||||
auto search = elements.find(comp.first);
|
auto search = elements.find(eName);
|
||||||
if (search != elements.end()) {
|
if (search != elements.end()) {
|
||||||
if (search->second < 0) {
|
if (search->second < 0) {
|
||||||
throw CanteraError("setMolecularWeight",
|
throw CanteraError("setMolecularWeight",
|
||||||
"element '{}' has no stable isotopes", comp.first);
|
"element '{}' has no stable isotopes", eName);
|
||||||
}
|
}
|
||||||
weight += search->second * comp.second;
|
weight += search->second * stoich;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setMolecularWeight(weight);
|
setMolecularWeight(weight);
|
||||||
@ -140,9 +140,9 @@ unique_ptr<Species> newSpecies(const AnyMap& node)
|
|||||||
"thermo", "transport"
|
"thermo", "transport"
|
||||||
};
|
};
|
||||||
s->input.setUnits(node.units());
|
s->input.setUnits(node.units());
|
||||||
for (const auto& item : node) {
|
for (const auto& [key, child] : node) {
|
||||||
if (known_keys.count(item.first) == 0) {
|
if (known_keys.count(key) == 0) {
|
||||||
s->input[item.first] = item.second;
|
s->input[key] = child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s->input.applyUnits();
|
s->input.applyUnits();
|
||||||
|
@ -174,12 +174,12 @@ void setupMu0(Mu0Poly& thermo, const AnyMap& node)
|
|||||||
bool dimensionless = node.getBool("dimensionless", false);
|
bool dimensionless = node.getBool("dimensionless", false);
|
||||||
double h0 = node.convert("h0", "J/kmol", 0.0);
|
double h0 = node.convert("h0", "J/kmol", 0.0);
|
||||||
map<double, double> T_mu;
|
map<double, double> T_mu;
|
||||||
for (const auto& item : node["data"]) {
|
for (const auto& [T_str, mu] : node["data"]) {
|
||||||
double T = node.units().convertTo(fpValueCheck(item.first), "K");
|
double T = node.units().convertTo(fpValueCheck(T_str), "K");
|
||||||
if (dimensionless) {
|
if (dimensionless) {
|
||||||
T_mu[T] = item.second.asDouble() * GasConstant * T;
|
T_mu[T] = mu.asDouble() * GasConstant * T;
|
||||||
} else {
|
} else {
|
||||||
T_mu[T] = node.units().convert(item.second, "J/kmol");
|
T_mu[T] = node.units().convert(mu, "J/kmol");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
thermo.setParameters(h0, T_mu);
|
thermo.setParameters(h0, T_mu);
|
||||||
|
@ -76,9 +76,9 @@ void GasTransportData::setCustomaryUnits(
|
|||||||
void GasTransportData::validate(const Species& sp)
|
void GasTransportData::validate(const Species& sp)
|
||||||
{
|
{
|
||||||
double nAtoms = 0;
|
double nAtoms = 0;
|
||||||
for (const auto& elem : sp.composition) {
|
for (const auto& [eName, stoich] : sp.composition) {
|
||||||
if (!caseInsensitiveEquals(elem.first, "E")) {
|
if (!caseInsensitiveEquals(eName, "E")) {
|
||||||
nAtoms += elem.second;
|
nAtoms += stoich;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,15 +291,15 @@ TEST(AnyMap, iterators)
|
|||||||
AnyMap m = AnyMap::fromYamlString(
|
AnyMap m = AnyMap::fromYamlString(
|
||||||
"{a: 1, b: two, c: 3.01, d: {foo: 1, bar: 2}}");
|
"{a: 1, b: two, c: 3.01, d: {foo: 1, bar: 2}}");
|
||||||
std::vector<std::string> keys;
|
std::vector<std::string> keys;
|
||||||
for (const auto& item : m) {
|
for (const auto& [key, value] : m) {
|
||||||
keys.push_back(item.first);
|
keys.push_back(key);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(keys.size(), (size_t) 4);
|
EXPECT_EQ(keys.size(), (size_t) 4);
|
||||||
EXPECT_TRUE(std::find(keys.begin(), keys.end(), "c") != keys.end());
|
EXPECT_TRUE(std::find(keys.begin(), keys.end(), "c") != keys.end());
|
||||||
keys.clear();
|
keys.clear();
|
||||||
|
|
||||||
for (const auto& item : m.at("d")) {
|
for (const auto& [key, value] : m.at("d")) {
|
||||||
keys.push_back(item.first);
|
keys.push_back(key);
|
||||||
}
|
}
|
||||||
EXPECT_EQ(keys.size(), (size_t) 2);
|
EXPECT_EQ(keys.size(), (size_t) 2);
|
||||||
EXPECT_TRUE(std::find(keys.begin(), keys.end(), "bar") != keys.end());
|
EXPECT_TRUE(std::find(keys.begin(), keys.end(), "bar") != keys.end());
|
||||||
@ -378,8 +378,8 @@ TEST(AnyMap, dumpYamlString)
|
|||||||
AnyMap original = AnyMap::fromYamlFile("h2o2.yaml");
|
AnyMap original = AnyMap::fromYamlFile("h2o2.yaml");
|
||||||
std::string serialized = original.toYamlString();
|
std::string serialized = original.toYamlString();
|
||||||
AnyMap generated = AnyMap::fromYamlString(serialized);
|
AnyMap generated = AnyMap::fromYamlString(serialized);
|
||||||
for (const auto& item : original) {
|
for (const auto& [key, value] : original) {
|
||||||
EXPECT_TRUE(generated.hasKey(item.first));
|
EXPECT_TRUE(generated.hasKey(key));
|
||||||
}
|
}
|
||||||
EXPECT_EQ(original["species"].getMapWhere("name", "OH")["thermo"]["data"].asVector<vector_fp>(),
|
EXPECT_EQ(original["species"].getMapWhere("name", "OH")["thermo"]["data"].asVector<vector_fp>(),
|
||||||
generated["species"].getMapWhere("name", "OH")["thermo"]["data"].asVector<vector_fp>());
|
generated["species"].getMapWhere("name", "OH")["thermo"]["data"].asVector<vector_fp>());
|
||||||
@ -396,8 +396,8 @@ TEST(AnyMap, YamlFlowStyle)
|
|||||||
// The serialized version should contain two lines, and end with a newline.
|
// The serialized version should contain two lines, and end with a newline.
|
||||||
EXPECT_EQ(std::count(serialized.begin(), serialized.end(), '\n'), 2);
|
EXPECT_EQ(std::count(serialized.begin(), serialized.end(), '\n'), 2);
|
||||||
AnyMap generated = AnyMap::fromYamlString(serialized);
|
AnyMap generated = AnyMap::fromYamlString(serialized);
|
||||||
for (const auto& item : original) {
|
for (const auto& [key, value] : original) {
|
||||||
EXPECT_TRUE(generated.hasKey(item.first));
|
EXPECT_TRUE(generated.hasKey(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,8 +445,8 @@ TEST(AnyMap, definedKeyOrdering)
|
|||||||
|
|
||||||
std::string result = m.toYamlString();
|
std::string result = m.toYamlString();
|
||||||
std::unordered_map<std::string, size_t> loc;
|
std::unordered_map<std::string, size_t> loc;
|
||||||
for (auto& item : m) {
|
for (auto& [key, value] : m) {
|
||||||
loc[item.first] = result.find(item.first);
|
loc[key] = result.find(key);
|
||||||
}
|
}
|
||||||
EXPECT_LT(loc["three"], loc["one"]);
|
EXPECT_LT(loc["three"], loc["one"]);
|
||||||
EXPECT_LT(loc["three"], loc["half"]);
|
EXPECT_LT(loc["three"], loc["half"]);
|
||||||
|
@ -94,10 +94,10 @@ public:
|
|||||||
void SetUp() {
|
void SetUp() {
|
||||||
// See if we should skip this test specific test case
|
// See if we should skip this test specific test case
|
||||||
if (setup.hasKey("known-failures")) {
|
if (setup.hasKey("known-failures")) {
|
||||||
auto name = testing::UnitTest::GetInstance()->current_test_info()->name();
|
auto current = testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||||
for (auto& item : setup["known-failures"].asMap<string>()) {
|
for (auto& [pattern, reason] : setup["known-failures"].asMap<string>()) {
|
||||||
if (regex_search(name, regex(item.first))) {
|
if (regex_search(current, regex(pattern))) {
|
||||||
GTEST_SKIP() << item.second;
|
GTEST_SKIP() << reason;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user