Resolve discrepancies of nomenclature in C++/Python

Argument names of SolutionArray IO in C++ and Python were not
consistent, which is resolved in this commit.
This commit is contained in:
Ingmar Schoegl 2023-06-21 09:49:26 -06:00
parent 5a4e3f861a
commit 0d58bac3b5
5 changed files with 132 additions and 130 deletions

View File

@ -190,22 +190,22 @@ public:
* Write header data to a HDF container file. * Write header data to a HDF container file.
* *
* @param fname Name of HDF container file * @param fname Name of HDF container file
* @param id Identifier of group holding header information * @param name Identifier of group holding header information
* @param desc Custom comment describing dataset * @param desc Custom comment describing dataset
* @param overwrite Force overwrite if file/group exists; optional (default=false) * @param overwrite Force overwrite if file/group exists; optional (default=false)
*/ */
static void writeHeader(const string& fname, const string& id, const string& desc, static void writeHeader(const string& fname, const string& name, const string& desc,
bool overwrite=false); bool overwrite=false);
/*! /*!
* Write header data to AnyMap; used by YAML serialization. * Write header data to AnyMap; used by YAML serialization.
* *
* @param root Root node of AnyMap structure * @param root Root node of AnyMap structure
* @param id Identifier of node holding header information * @param name Identifier of node holding header information
* @param desc Custom comment describing dataset * @param desc Custom comment describing dataset
* @param overwrite Force overwrite if node exists; optional (default=false) * @param overwrite Force overwrite if node exists; optional (default=false)
*/ */
static void writeHeader(AnyMap& root, const string& id, const string& desc, static void writeHeader(AnyMap& root, const string& name, const string& desc,
bool overwrite=false); bool overwrite=false);
/*! /*!
@ -223,23 +223,23 @@ public:
* Write SolutionArray data to a HDF container file. * Write SolutionArray data to a HDF container file.
* *
* @param fname Name of HDF container file * @param fname Name of HDF container file
* @param id Identifier of group holding header information * @param name Identifier of group holding header information
* @param sub Name identifier of subgroup holding SolutionArray data * @param sub Name identifier of subgroup holding SolutionArray data
* @param overwrite Force overwrite if subgroup exists; optional (default=false) * @param overwrite Force overwrite if subgroup exists; optional (default=false)
* @param compression Compression level; optional (default=0; HDF only) * @param compression Compression level; optional (default=0; HDF only)
*/ */
void writeEntry(const string& fname, const string& id, const string& sub, void writeEntry(const string& fname, const string& name, const string& sub,
bool overwrite=false, int compression=0); bool overwrite=false, int compression=0);
/*! /*!
* Write SolutionArray data to AnyMap; used by YAML serialization. * Write SolutionArray data to AnyMap; used by YAML serialization.
* *
* @param root Root node of AnyMap structure * @param root Root node of AnyMap structure
* @param id Identifier of node holding header information and subgroup * @param name Identifier of node holding header information and subgroup
* @param sub Name identifier of subgroup holding SolutionArray data * @param sub Name identifier of subgroup holding SolutionArray data
* @param overwrite Force overwrite if subgroup exists; optional (default=false) * @param overwrite Force overwrite if subgroup exists; optional (default=false)
*/ */
void writeEntry(AnyMap& root, const string& id, const string& sub, void writeEntry(AnyMap& root, const string& name, const string& sub,
bool overwrite=false); bool overwrite=false);
/*! /*!
@ -262,7 +262,7 @@ public:
* objects generated by Sim1D hold simulation settings). * objects generated by Sim1D hold simulation settings).
* *
* @param fname Name of output file (CSV, YAML or HDF) * @param fname Name of output file (CSV, YAML or HDF)
* @param id Identifier of location within the container file; this node/group * @param name Identifier of location within the container file; this node/group
* contains header information and a subgroup holding actual SolutionArray data * contains header information and a subgroup holding actual SolutionArray data
* (YAML/HDF only) * (YAML/HDF only)
* @param sub Name identifier for the subgroup holding the SolutionArray data and * @param sub Name identifier for the subgroup holding the SolutionArray data and
@ -276,7 +276,7 @@ public:
* if not specified (default=""), the native basis of the underlying * if not specified (default=""), the native basis of the underlying
* ThermoPhase manager is used - @see nativeState (CSV only) * ThermoPhase manager is used - @see nativeState (CSV only)
*/ */
void save(const string& fname, const string& id="", const string& sub="", void save(const string& fname, const string& name="", const string& sub="",
const string& desc="", bool overwrite=false, int compression=0, const string& desc="", bool overwrite=false, int compression=0,
const string& basis=""); const string& basis="");
@ -284,35 +284,35 @@ public:
* Read header information from a HDF container file. * Read header information from a HDF container file.
* *
* @param fname Name of HDF container file * @param fname Name of HDF container file
* @param id Identifier of group holding header information * @param name Identifier of group holding header information
*/ */
static AnyMap readHeader(const string& fname, const string& id); static AnyMap readHeader(const string& fname, const string& name);
/*! /*!
* Read header information from AnyMap; used by YAML serialization. * Read header information from AnyMap; used by YAML serialization.
* *
* @param root Root node of AnyMap structure * @param root Root node of AnyMap structure
* @param id Identifier of node holding header information * @param name Identifier of node holding header information
*/ */
static AnyMap readHeader(const AnyMap& root, const string& id); static AnyMap readHeader(const AnyMap& root, const string& name);
/*! /*!
* Restore SolutionArray data from a HDF container file. * Restore SolutionArray data from a HDF container file.
* *
* @param fname Name of HDF container file * @param fname Name of HDF container file
* @param id Identifier of group holding header information * @param name Identifier of group holding header information
* @param sub Name identifier of subgroup holding SolutionArray data * @param sub Name identifier of subgroup holding SolutionArray data
*/ */
void readEntry(const string& fname, const string& id, const string& sub); void readEntry(const string& fname, const string& name, const string& sub);
/*! /*!
* Restore SolutionArray data from AnyMap; used by YAML serialization. * Restore SolutionArray data from AnyMap; used by YAML serialization.
* *
* @param root Root node of AnyMap structure * @param root Root node of AnyMap structure
* @param id Identifier of node holding header information * @param name Identifier of node holding header information
* @param sub Name identifier of subgroup holding SolutionArray data * @param sub Name identifier of subgroup holding SolutionArray data
*/ */
void readEntry(const AnyMap& root, const string& id, const string& sub); void readEntry(const AnyMap& root, const string& name, const string& sub);
/*! /*!
* Restore SolutionArray data and header information from a container file. * Restore SolutionArray data and header information from a container file.
@ -321,13 +321,13 @@ public:
* using the @see save method. * using the @see save method.
* *
* @param fname Name of container file (YAML or HDF) * @param fname Name of container file (YAML or HDF)
* @param id Identifier of location within the container file; this node/group * @param name Identifier of location within the container file; this node/group
* contains header information and a subgroup holding actual SolutionArray data * contains header information and a subgroup holding actual SolutionArray data
* @param sub Name identifier for the subgroup holding the SolutionArray data and * @param sub Name identifier for the subgroup holding the SolutionArray data and
* metadata objects. If omitted (""), the subgroup name defaults to "data" * metadata objects. If omitted (""), the subgroup name defaults to "data"
* @return AnyMap containing header information * @return AnyMap containing header information
*/ */
AnyMap restore(const string& fname, const string& id, const string& sub=""); AnyMap restore(const string& fname, const string& name, const string& sub="");
protected: protected:
//! Service function used to resize SolutionArray //! Service function used to resize SolutionArray

View File

@ -148,14 +148,14 @@ public:
* main 1D domain is saved. * main 1D domain is saved.
* *
* @param fname Name of output container file * @param fname Name of output container file
* @param id Identifier of solution within the container file * @param name Identifier of solution within the container file
* @param desc Description of the solution * @param desc Description of the solution
* @param overwrite Force overwrite if name exists; optional (default=false) * @param overwrite Force overwrite if name exists; optional (default=false)
* @param compression Compression level (optional; HDF only) * @param compression Compression level (optional; HDF only)
* @param basis Output mass ("Y"/"mass") or mole ("X"/"mole") fractions (CSV only); * @param basis Output mass ("Y"/"mass") or mole ("X"/"mole") fractions (CSV only);
* if omitted (default=""), the native storage mode is used * if omitted (default=""), the native storage mode is used
*/ */
void save(const std::string& fname, const std::string& id, void save(const std::string& fname, const std::string& name,
const std::string& desc, bool overwrite=false, int compression=0, const std::string& desc, bool overwrite=false, int compression=0,
const string& basis=""); const string& basis="");
@ -173,12 +173,12 @@ public:
/** /**
* Save the residual of the current solution to a container file. * Save the residual of the current solution to a container file.
* @param fname Name of output container file * @param fname Name of output container file
* @param id Identifier of solution within the container file * @param name Identifier of solution within the container file
* @param desc Description of the solution * @param desc Description of the solution
* @param overwrite Force overwrite if name exists; optional (default=false) * @param overwrite Force overwrite if name exists; optional (default=false)
* @param compression Compression level (optional; HDF only) * @param compression Compression level (optional; HDF only)
*/ */
void saveResidual(const std::string& fname, const std::string& id, void saveResidual(const std::string& fname, const std::string& name,
const std::string& desc, bool overwrite=false, int compression=0); const std::string& desc, bool overwrite=false, int compression=0);
/** /**
@ -194,10 +194,10 @@ public:
/** /**
* Initialize the solution with a previously-saved solution. * Initialize the solution with a previously-saved solution.
* @param fname Name of container file * @param fname Name of container file
* @param id Identifier of solution within the container file * @param name Identifier of solution within the container file
* @return AnyMap containing header information * @return AnyMap containing header information
*/ */
AnyMap restore(const std::string& fname, const std::string& id); AnyMap restore(const std::string& fname, const std::string& name);
//! @} //! @}

View File

@ -678,16 +678,16 @@ cdef class SolutionArrayBase:
cxx_state.push_back(item) cxx_state.push_back(item)
self.base.append(cxx_state, py_to_anymap(extra)) self.base.append(cxx_state, py_to_anymap(extra))
def _cxx_save(self, filename, name, key, description, def _cxx_save(self, filename, name, sub, description,
overwrite, compression, basis): overwrite, compression, basis):
""" Interface `SolutionArray.save` with C++ core """ """ Interface `SolutionArray.save` with C++ core """
self.base.save( self.base.save(
stringify(str(filename)), stringify(name), stringify(key), stringify(str(filename)), stringify(name), stringify(sub),
stringify(description), overwrite, compression, stringify(basis)) stringify(description), overwrite, compression, stringify(basis))
def _cxx_restore(self, filename, name, key): def _cxx_restore(self, filename, name, sub):
""" Interface `SolutionArray.restore` with C++ core """ """ Interface `SolutionArray.restore` with C++ core """
cdef CxxAnyMap header cdef CxxAnyMap header
header = self.base.restore( header = self.base.restore(
stringify(str(filename)), stringify(name), stringify(key)) stringify(str(filename)), stringify(name), stringify(sub))
return anymap_to_py(header) return anymap_to_py(header)

View File

@ -915,15 +915,15 @@ AnyMap preamble(const string& desc)
return data; return data;
} }
AnyMap& openField(AnyMap& root, const string& id) AnyMap& openField(AnyMap& root, const string& name)
{ {
if (!id.size()) { if (!name.size()) {
return root; return root;
} }
// locate field based on 'id' // locate field based on 'name'
vector<string> tokens; vector<string> tokens;
tokenizePath(id, tokens); tokenizePath(name, tokens);
AnyMap* ptr = &root; // use raw pointer to avoid copying AnyMap* ptr = &root; // use raw pointer to avoid copying
string path = ""; string path = "";
for (auto& field : tokens) { for (auto& field : tokens) {
@ -940,28 +940,28 @@ AnyMap& openField(AnyMap& root, const string& id)
return *ptr; return *ptr;
} }
void SolutionArray::writeHeader(const string& fname, const string& id, void SolutionArray::writeHeader(const string& fname, const string& name,
const string& desc, bool overwrite) const string& desc, bool overwrite)
{ {
Storage file(fname, true); Storage file(fname, true);
if (file.checkGroup(id, true)) { if (file.checkGroup(name, true)) {
if (!overwrite) { if (!overwrite) {
throw CanteraError("SolutionArray::writeHeader", throw CanteraError("SolutionArray::writeHeader",
"Group id '{}' exists; use 'overwrite' argument to overwrite.", id); "Group name '{}' exists; use 'overwrite' argument to overwrite.", name);
} }
file.deleteGroup(id); file.deleteGroup(name);
file.checkGroup(id, true); file.checkGroup(name, true);
} }
file.writeAttributes(id, preamble(desc)); file.writeAttributes(name, preamble(desc));
} }
void SolutionArray::writeHeader(AnyMap& root, const string& id, void SolutionArray::writeHeader(AnyMap& root, const string& name,
const string& desc, bool overwrite) const string& desc, bool overwrite)
{ {
AnyMap& data = openField(root, id); AnyMap& data = openField(root, name);
if (!data.empty() && !overwrite) { if (!data.empty() && !overwrite) {
throw CanteraError("SolutionArray::writeHeader", throw CanteraError("SolutionArray::writeHeader",
"Field id '{}' exists; use 'overwrite' argument to overwrite.", id); "Field name '{}' exists; use 'overwrite' argument to overwrite.", name);
} }
data.update(preamble(desc)); data.update(preamble(desc));
} }
@ -995,7 +995,7 @@ void SolutionArray::writeEntry(const string& fname, bool overwrite, const string
vector<bool> isSpecies; vector<bool> isSpecies;
std::stringstream header; std::stringstream header;
for (const auto& key : names) { for (const auto& key : names) {
string name = key; string label = key;
size_t col; size_t col;
if (speciesNames.find(key) == speciesNames.end()) { if (speciesNames.find(key) == speciesNames.end()) {
// Pre-read component vectors // Pre-read component vectors
@ -1016,20 +1016,20 @@ void SolutionArray::writeEntry(const string& fname, bool overwrite, const string
components.emplace_back(AnyValue()); components.emplace_back(AnyValue());
col = components.size() - 1; col = components.size() - 1;
if (mole) { if (mole) {
name = "X_" + name; label = "X_" + label;
} else { } else {
name = "Y_" + name; label = "Y_" + label;
} }
} }
if (name.find("\"") != string::npos || name.find("\n") != string::npos) { if (label.find("\"") != string::npos || label.find("\n") != string::npos) {
throw NotImplementedError("SolutionArray::writeEntry", throw NotImplementedError("SolutionArray::writeEntry",
"Detected column name containing double quotes or line feeds: '{}'.", "Detected column name containing double quotes or line feeds: '{}'.",
name); label);
} }
if (name.find(",") != string::npos) { if (label.find(",") != string::npos) {
header << "\"" << name << "\""; header << "\"" << label << "\"";
} else { } else {
header << name; header << label;
} }
if (col != last) { if (col != last) {
header << ","; header << ",";
@ -1093,12 +1093,12 @@ void SolutionArray::writeEntry(const string& fname, bool overwrite, const string
output << std::endl << std::setprecision(default_precision); output << std::endl << std::setprecision(default_precision);
} }
void SolutionArray::writeEntry(const string& fname, const string& id, const string& sub, void SolutionArray::writeEntry(const string& fname, const string& name,
bool overwrite, int compression) const string& sub, bool overwrite, int compression)
{ {
if (id == "") { if (name == "") {
throw CanteraError("SolutionArray::writeEntry", throw CanteraError("SolutionArray::writeEntry",
"Group id specifying root location must not be empty."); "Group name specifying root location must not be empty.");
} }
if (m_size < m_dataSize) { if (m_size < m_dataSize) {
throw NotImplementedError("SolutionArray::writeEntry", throw NotImplementedError("SolutionArray::writeEntry",
@ -1108,7 +1108,7 @@ void SolutionArray::writeEntry(const string& fname, const string& id, const stri
if (compression) { if (compression) {
file.setCompressionLevel(compression); file.setCompressionLevel(compression);
} }
string path = id; string path = name;
if (sub != "") { if (sub != "") {
path += "/" + sub; path += "/" + sub;
} else { } else {
@ -1117,7 +1117,7 @@ void SolutionArray::writeEntry(const string& fname, const string& id, const stri
if (file.checkGroup(path, true)) { if (file.checkGroup(path, true)) {
if (!overwrite) { if (!overwrite) {
throw CanteraError("SolutionArray::writeEntry", throw CanteraError("SolutionArray::writeEntry",
"Group id '{}' exists; use 'overwrite' argument to overwrite.", id); "Group name '{}' exists; use 'overwrite' argument to overwrite.", name);
} }
file.deleteGroup(path); file.deleteGroup(path);
file.checkGroup(path, true); file.checkGroup(path, true);
@ -1137,8 +1137,8 @@ void SolutionArray::writeEntry(const string& fname, const string& id, const stri
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& [name, offset] : nativeState) { for (auto& [key, offset] : nativeState) {
if (name == "X" || name == "Y") { if (key == "X" || key == "Y") {
vector<vector<double>> prop; vector<vector<double>> 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;
@ -1147,38 +1147,38 @@ void SolutionArray::writeEntry(const string& fname, const string& id, const stri
} }
AnyValue data; AnyValue data;
data = prop; data = prop;
file.writeData(path, name, data); file.writeData(path, key, data);
} else { } else {
auto data = getComponent(name); auto data = getComponent(key);
file.writeData(path, name, data); file.writeData(path, key, data);
} }
} }
for (const auto& [name, value] : *m_extra) { for (const auto& [key, value] : *m_extra) {
if (isSimpleVector(value)) { if (isSimpleVector(value)) {
file.writeData(path, name, value); file.writeData(path, key, value);
} else if (value.is<void>()) { } else if (value.is<void>()) {
// skip unintialized component // skip unintialized component
} else { } else {
throw NotImplementedError("SolutionArray::writeEntry", throw NotImplementedError("SolutionArray::writeEntry",
"Unable to save component '{}' with data type {}.", "Unable to save component '{}' with data type {}.",
name, value.type_str()); key, value.type_str());
} }
} }
} }
void SolutionArray::writeEntry(AnyMap& root, const string& id, const string& sub, void SolutionArray::writeEntry(AnyMap& root, const string& name, const string& sub,
bool overwrite) bool overwrite)
{ {
if (id == "") { if (name == "") {
throw CanteraError("SolutionArray::writeEntry", throw CanteraError("SolutionArray::writeEntry",
"Field id specifying root location must not be empty."); "Field name specifying root location must not be empty.");
} }
if (m_size < m_dataSize) { if (m_size < m_dataSize) {
throw NotImplementedError("SolutionArray::writeEntry", throw NotImplementedError("SolutionArray::writeEntry",
"Unable to save sliced data."); "Unable to save sliced data.");
} }
string path = id; string path = name;
if (sub != "") { if (sub != "") {
path += "/" + sub; path += "/" + sub;
} else { } else {
@ -1188,7 +1188,7 @@ void SolutionArray::writeEntry(AnyMap& root, const string& id, const string& sub
bool preexisting = !data.empty(); bool preexisting = !data.empty();
if (preexisting && !overwrite) { if (preexisting && !overwrite) {
throw CanteraError("SolutionArray::writeEntry", throw CanteraError("SolutionArray::writeEntry",
"Field id '{}' exists; use 'overwrite' argument to overwrite.", id); "Field name '{}' exists; use 'overwrite' argument to overwrite.", name);
} }
if (apiNdim() == 1) { if (apiNdim() == 1) {
data["size"] = int(m_dataSize); data["size"] = int(m_dataSize);
@ -1197,8 +1197,8 @@ void SolutionArray::writeEntry(AnyMap& root, const string& id, const string& sub
} }
data.update(m_meta); data.update(m_meta);
for (auto& [name, value] : *m_extra) { for (auto& [key, value] : *m_extra) {
data[name] = value; data[key] = value;
} }
auto phase = m_sol->thermo(); auto phase = m_sol->thermo();
@ -1227,14 +1227,14 @@ void SolutionArray::writeEntry(AnyMap& root, const string& id, const string& sub
} }
} else if (m_size > 1) { } else if (m_size > 1) {
const auto& nativeState = phase->nativeState(); const auto& nativeState = phase->nativeState();
for (auto& [name, offset] : nativeState) { for (auto& [key, offset] : nativeState) {
if (name == "X" || name == "Y") { if (key == "X" || key == "Y") {
for (auto& spc : phase->speciesNames()) { for (auto& spc : phase->speciesNames()) {
data[spc] = getComponent(spc); data[spc] = getComponent(spc);
} }
data["basis"] = name == "X" ? "mole" : "mass"; data["basis"] = key == "X" ? "mole" : "mass";
} else { } else {
data[name] = getComponent(name); data[key] = getComponent(key);
} }
} }
data["components"] = componentNames(); data["components"] = componentNames();
@ -1265,7 +1265,7 @@ void SolutionArray::append(const vector<double>& state, const AnyMap& extra)
} }
} }
void SolutionArray::save(const string& fname, const string& id, const string& sub, void SolutionArray::save(const string& fname, const string& name, const string& sub,
const string& desc, bool overwrite, int compression, const string& desc, bool overwrite, int compression,
const string& basis) const string& basis)
{ {
@ -1276,8 +1276,9 @@ void SolutionArray::save(const string& fname, const string& id, const string& su
size_t dot = fname.find_last_of("."); size_t dot = fname.find_last_of(".");
string extension = (dot != npos) ? toLowerCopy(fname.substr(dot + 1)) : ""; string extension = (dot != npos) ? toLowerCopy(fname.substr(dot + 1)) : "";
if (extension == "csv") { if (extension == "csv") {
if (id != "") { if (name != "") {
warn_user("SolutionArray::save", "Parameter 'id' not used for CSV output."); warn_user("SolutionArray::save",
"Parameter 'name' not used for CSV output.");
} }
writeEntry(fname, overwrite, basis); writeEntry(fname, overwrite, basis);
return; return;
@ -1287,8 +1288,8 @@ void SolutionArray::save(const string& fname, const string& id, const string& su
"Argument 'basis' is not used for HDF or YAML output.", basis); "Argument 'basis' is not used for HDF or YAML output.", basis);
} }
if (extension == "h5" || extension == "hdf" || extension == "hdf5") { if (extension == "h5" || extension == "hdf" || extension == "hdf5") {
writeHeader(fname, id, desc, overwrite); writeHeader(fname, name, desc, overwrite);
writeEntry(fname, id, sub, true, compression); writeEntry(fname, name, sub, true, compression);
return; return;
} }
if (extension == "yaml" || extension == "yml") { if (extension == "yaml" || extension == "yml") {
@ -1297,8 +1298,8 @@ void SolutionArray::save(const string& fname, const string& id, const string& su
if (std::ifstream(fname).good()) { if (std::ifstream(fname).good()) {
data = AnyMap::fromYamlFile(fname); data = AnyMap::fromYamlFile(fname);
} }
writeHeader(data, id, desc, overwrite); writeHeader(data, name, desc, overwrite);
writeEntry(data, id, sub, true); writeEntry(data, name, sub, true);
// Write the output file and remove the now-outdated cached file // Write the output file and remove the now-outdated cached file
std::ofstream out(fname); std::ofstream out(fname);
@ -1310,22 +1311,22 @@ void SolutionArray::save(const string& fname, const string& id, const string& su
"Unknown file extension '{}'.", extension); "Unknown file extension '{}'.", extension);
} }
AnyMap SolutionArray::readHeader(const string& fname, const string& id) AnyMap SolutionArray::readHeader(const string& fname, const string& name)
{ {
Storage file(fname, false); Storage file(fname, false);
file.checkGroup(id); file.checkGroup(name);
return file.readAttributes(id, false); return file.readAttributes(name, false);
} }
const AnyMap& locateField(const AnyMap& root, const string& id) const AnyMap& locateField(const AnyMap& root, const string& name)
{ {
if (!id.size()) { if (!name.size()) {
return root; return root;
} }
// locate field based on 'id' // locate field based on 'name'
vector<string> tokens; vector<string> tokens;
tokenizePath(id, tokens); tokenizePath(name, tokens);
const AnyMap* ptr = &root; // use raw pointer to avoid copying const AnyMap* ptr = &root; // use raw pointer to avoid copying
string path = ""; string path = "";
for (auto& field : tokens) { for (auto& field : tokens) {
@ -1333,27 +1334,27 @@ const AnyMap& locateField(const AnyMap& root, const string& id)
const AnyMap& sub = *ptr; const AnyMap& sub = *ptr;
if (!sub.hasKey(field) || !sub[field].is<AnyMap>()) { if (!sub.hasKey(field) || !sub[field].is<AnyMap>()) {
throw CanteraError("SolutionArray::locateField", throw CanteraError("SolutionArray::locateField",
"No field or solution with id '{}'.", path); "No field or solution with name '{}'.", path);
} }
ptr = &sub[field].as<AnyMap>(); ptr = &sub[field].as<AnyMap>();
} }
return *ptr; return *ptr;
} }
AnyMap SolutionArray::readHeader(const AnyMap& root, const string& id) AnyMap SolutionArray::readHeader(const AnyMap& root, const string& name)
{ {
auto sub = locateField(root, id); auto sub = locateField(root, name);
AnyMap header; AnyMap header;
for (const auto& [name, value] : sub) { for (const auto& [key, value] : sub) {
if (!sub[name].is<AnyMap>()) { if (!sub[key].is<AnyMap>()) {
header[name] = value; header[key] = value;
} }
} }
return header; return header;
} }
AnyMap SolutionArray::restore(const string& fname, AnyMap SolutionArray::restore(const string& fname,
const string& id, const string& sub) const string& name, const string& sub)
{ {
size_t dot = fname.find_last_of("."); size_t dot = fname.find_last_of(".");
string extension = (dot != npos) ? toLowerCopy(fname.substr(dot + 1)) : ""; string extension = (dot != npos) ? toLowerCopy(fname.substr(dot + 1)) : "";
@ -1364,12 +1365,12 @@ AnyMap SolutionArray::restore(const string& fname,
"'read_csv' instead."); "'read_csv' instead.");
} }
if (extension == "h5" || extension == "hdf" || extension == "hdf5") { if (extension == "h5" || extension == "hdf" || extension == "hdf5") {
readEntry(fname, id, sub); readEntry(fname, name, sub);
header = readHeader(fname, id); header = readHeader(fname, name);
} else if (extension == "yaml" || extension == "yml") { } else if (extension == "yaml" || extension == "yml") {
const AnyMap& root = AnyMap::fromYamlFile(fname); const AnyMap& root = AnyMap::fromYamlFile(fname);
readEntry(root, id, sub); readEntry(root, name, sub);
header = readHeader(root, id); header = readHeader(root, name);
} else { } else {
throw CanteraError("SolutionArray::restore", throw CanteraError("SolutionArray::restore",
"Unknown file extension '{}'; supported extensions include " "Unknown file extension '{}'; supported extensions include "
@ -1609,23 +1610,24 @@ string getName(const set<string>& names, const string& name)
return name; // let exception be thrown elsewhere return name; // let exception be thrown elsewhere
} }
void SolutionArray::readEntry(const string& fname, const string& id, const string& sub) void SolutionArray::readEntry(const string& fname, const string& name,
const string& sub)
{ {
Storage file(fname, false); Storage file(fname, false);
if (id == "") { if (name == "") {
throw CanteraError("SolutionArray::readEntry", throw CanteraError("SolutionArray::readEntry",
"Group id specifying root location must not be empty."); "Group name specifying root location must not be empty.");
} }
string path = id; string path = name;
if (sub != "" && file.checkGroup(id + "/" + sub, true)) { if (sub != "" && file.checkGroup(name + "/" + sub, true)) {
path += "/" + sub; path += "/" + sub;
} else if (sub == "" && file.checkGroup(id + "/data", true)) { } else if (sub == "" && file.checkGroup(name + "/data", true)) {
// default data location // default data location
path += "/data"; path += "/data";
} }
if (!file.checkGroup(path)) { if (!file.checkGroup(path)) {
throw CanteraError("SolutionArray::readEntry", throw CanteraError("SolutionArray::readEntry",
"Group id specifying data entry is empty."); "Group name specifying data entry is empty.");
} }
m_extra->clear(); m_extra->clear();
auto [size, names] = file.contents(path); auto [size, names] = file.contents(path);
@ -1735,8 +1737,8 @@ void SolutionArray::readEntry(const string& fname, const string& id, const strin
m_sol->thermo()->saveState(nState, m_data->data() + i * m_stride); m_sol->thermo()->saveState(nState, m_data->data() + i * m_stride);
} }
warn_user("SolutionArray::readEntry", warn_user("SolutionArray::readEntry",
"Detected legacy HDF format with incomplete state information\nfor id '{}' " "Detected legacy HDF format with incomplete state information\nfor name "
"(pressure missing).", path); "'{}' (pressure missing).", path);
} else if (mode == "") { } else if (mode == "") {
throw CanteraError("SolutionArray::readEntry", throw CanteraError("SolutionArray::readEntry",
"Data are not consistent with full state modes."); "Data are not consistent with full state modes.");
@ -1774,19 +1776,19 @@ void SolutionArray::readEntry(const string& fname, const string& id, const strin
} }
} }
void SolutionArray::readEntry(const AnyMap& root, const string& id, const string& sub) void SolutionArray::readEntry(const AnyMap& root, const string& name, const string& sub)
{ {
if (id == "") { if (name == "") {
throw CanteraError("SolutionArray::readEntry", throw CanteraError("SolutionArray::readEntry",
"Field id specifying root location must not be empty."); "Field name specifying root location must not be empty.");
} }
auto path = locateField(root, id); auto path = locateField(root, name);
if (path.hasKey("generator") && sub != "") { if (path.hasKey("generator") && sub != "") {
// read entry from subfolder (since Cantera 3.0) // read entry from subfolder (since Cantera 3.0)
path = locateField(root, id + "/" + sub); path = locateField(root, name + "/" + sub);
} else if (sub == "" && path.hasKey("data")) { } else if (sub == "" && path.hasKey("data")) {
// default data location // default data location
path = locateField(root, id + "/data"); path = locateField(root, name + "/data");
} }
// set size and initialize // set size and initialize
@ -1837,8 +1839,8 @@ void SolutionArray::readEntry(const AnyMap& root, const string& id, const string
auto Y = path["mass-fractions"].asMap<double>(); auto Y = path["mass-fractions"].asMap<double>();
m_sol->thermo()->setState_TPY(T, m_sol->thermo()->pressure(), Y); m_sol->thermo()->setState_TPY(T, m_sol->thermo()->pressure(), Y);
warn_user("SolutionArray::readEntry", warn_user("SolutionArray::readEntry",
"Detected legacy YAML format with incomplete state information\nfor id " "Detected legacy YAML format with incomplete state information\n"
"'{}' (pressure missing).", id + "/" + sub); "for name '{}' (pressure missing).", name + "/" + sub);
} else if (mode == "") { } else if (mode == "") {
throw CanteraError("SolutionArray::readEntry", throw CanteraError("SolutionArray::readEntry",
"Data are not consistent with full state modes."); "Data are not consistent with full state modes.");

View File

@ -125,7 +125,7 @@ void Sim1D::save(const std::string& fname, const std::string& id,
} }
} }
void Sim1D::save(const std::string& fname, const std::string& id, void Sim1D::save(const std::string& fname, const std::string& name,
const std::string& desc, bool overwrite, int compression, const std::string& desc, bool overwrite, int compression,
const string& basis) const string& basis)
{ {
@ -146,10 +146,10 @@ void Sim1D::save(const std::string& fname, const std::string& id,
"Species basis '{}' not implemented for HDF5 or YAML output.", basis); "Species basis '{}' not implemented for HDF5 or YAML output.", basis);
} }
if (extension == "h5" || extension == "hdf" || extension == "hdf5") { if (extension == "h5" || extension == "hdf" || extension == "hdf5") {
SolutionArray::writeHeader(fname, id, desc, overwrite); SolutionArray::writeHeader(fname, name, desc, overwrite);
for (auto dom : m_dom) { for (auto dom : m_dom) {
auto arr = dom->asArray(m_state->data() + dom->loc()); auto arr = dom->asArray(m_state->data() + dom->loc());
arr->writeEntry(fname, id, dom->id(), overwrite, compression); arr->writeEntry(fname, name, dom->id(), overwrite, compression);
} }
return; return;
} }
@ -159,11 +159,11 @@ void Sim1D::save(const std::string& fname, const std::string& id,
if (std::ifstream(fname).good()) { if (std::ifstream(fname).good()) {
data = AnyMap::fromYamlFile(fname); data = AnyMap::fromYamlFile(fname);
} }
SolutionArray::writeHeader(data, id, desc, overwrite); SolutionArray::writeHeader(data, name, desc, overwrite);
for (auto dom : m_dom) { for (auto dom : m_dom) {
auto arr = dom->asArray(m_state->data() + dom->loc()); auto arr = dom->asArray(m_state->data() + dom->loc());
arr->writeEntry(data, id, dom->id(), overwrite); arr->writeEntry(data, name, dom->id(), overwrite);
} }
// Write the output file and remove the now-outdated cached file // Write the output file and remove the now-outdated cached file
@ -186,7 +186,7 @@ void Sim1D::saveResidual(const std::string& fname, const std::string& id,
} }
} }
void Sim1D::saveResidual(const std::string& fname, const std::string& id, void Sim1D::saveResidual(const std::string& fname, const std::string& name,
const std::string& desc, bool overwrite, int compression) const std::string& desc, bool overwrite, int compression)
{ {
vector_fp res(m_state->size(), -999); vector_fp res(m_state->size(), -999);
@ -195,7 +195,7 @@ void Sim1D::saveResidual(const std::string& fname, const std::string& id,
// save() function reads. // save() function reads.
vector<double> backup(*m_state); vector<double> backup(*m_state);
*m_state = res; *m_state = res;
save(fname, id, desc, overwrite, compression); save(fname, name, desc, overwrite, compression);
*m_state = backup; *m_state = backup;
} }
@ -293,7 +293,7 @@ AnyMap Sim1D::restore(const std::string& fname, const std::string& id, int logle
return restore(fname, id); return restore(fname, id);
} }
AnyMap Sim1D::restore(const std::string& fname, const std::string& id) AnyMap Sim1D::restore(const std::string& fname, const std::string& name)
{ {
size_t dot = fname.find_last_of("."); size_t dot = fname.find_last_of(".");
string extension = (dot != npos) ? toLowerCopy(fname.substr(dot+1)) : ""; string extension = (dot != npos) ? toLowerCopy(fname.substr(dot+1)) : "";
@ -304,11 +304,11 @@ AnyMap Sim1D::restore(const std::string& fname, const std::string& id)
AnyMap header; AnyMap header;
if (extension == "h5" || extension == "hdf" || extension == "hdf5") { if (extension == "h5" || extension == "hdf" || extension == "hdf5") {
std::map<std::string, shared_ptr<SolutionArray>> arrs; std::map<std::string, shared_ptr<SolutionArray>> arrs;
header = SolutionArray::readHeader(fname, id); header = SolutionArray::readHeader(fname, name);
for (auto dom : m_dom) { for (auto dom : m_dom) {
auto arr = SolutionArray::create(dom->solution()); auto arr = SolutionArray::create(dom->solution());
arr->readEntry(fname, id, dom->id()); arr->readEntry(fname, name, dom->id());
dom->resize(dom->nComponents(), arr->size()); dom->resize(dom->nComponents(), arr->size());
if (!header.hasKey("generator")) { if (!header.hasKey("generator")) {
arr->meta() = legacyH5(arr, header); arr->meta() = legacyH5(arr, header);
@ -324,11 +324,11 @@ AnyMap Sim1D::restore(const std::string& fname, const std::string& id)
} else if (extension == "yaml" || extension == "yml") { } else if (extension == "yaml" || extension == "yml") {
AnyMap root = AnyMap::fromYamlFile(fname); AnyMap root = AnyMap::fromYamlFile(fname);
std::map<std::string, shared_ptr<SolutionArray>> arrs; std::map<std::string, shared_ptr<SolutionArray>> arrs;
header = SolutionArray::readHeader(root, id); header = SolutionArray::readHeader(root, name);
for (auto dom : m_dom) { for (auto dom : m_dom) {
auto arr = SolutionArray::create(dom->solution()); auto arr = SolutionArray::create(dom->solution());
arr->readEntry(root, id, dom->id()); arr->readEntry(root, name, dom->id());
dom->resize(dom->nComponents(), arr->size()); dom->resize(dom->nComponents(), arr->size());
arrs[dom->id()] = arr; arrs[dom->id()] = arr;
} }