[Input] Search current directory for referenced YAML input files
This commit is contained in:
parent
2c58dd78c6
commit
fdfbc58a1e
8 changed files with 43 additions and 15 deletions
|
|
@ -78,6 +78,7 @@ if 'clean' in COMMAND_LINE_TARGETS:
|
|||
for name in os.listdir('interfaces/cython/cantera/data/'):
|
||||
if name != '__init__.py':
|
||||
removeFile('interfaces/cython/cantera/data/' + name)
|
||||
removeDirectory('interfaces/cython/cantera/test/data/test_subdir')
|
||||
for name in os.listdir('interfaces/cython/cantera/test/data/'):
|
||||
if name != '__init__.py':
|
||||
removeFile('interfaces/cython/cantera/test/data/' + name)
|
||||
|
|
|
|||
|
|
@ -228,9 +228,12 @@ public:
|
|||
|
||||
//! Create an AnyMap from a YAML file.
|
||||
/*!
|
||||
* Searches the Cantera include path for the file.
|
||||
* Searches the directory containing the optionally-specified parent file
|
||||
* first, followed by the current working directory and the Cantera include
|
||||
* path.
|
||||
*/
|
||||
static AnyMap fromYamlFile(const std::string& name);
|
||||
static AnyMap fromYamlFile(const std::string& name,
|
||||
const std::string& parent_name="");
|
||||
|
||||
//! Create an AnyMap from a string containing a YAML document
|
||||
static AnyMap fromYamlString(const std::string& yaml);
|
||||
|
|
|
|||
1
interfaces/cython/.gitignore
vendored
1
interfaces/cython/.gitignore
vendored
|
|
@ -9,6 +9,7 @@ cantera/test/data/*.dat
|
|||
cantera/test/data/*.csv
|
||||
cantera/test/data/*.yaml
|
||||
cantera/test/data/*.yml
|
||||
cantera/test/data/test_subdir
|
||||
setup.py
|
||||
scripts/ctml_writer.py
|
||||
scripts/ctml_writer
|
||||
|
|
|
|||
|
|
@ -749,18 +749,37 @@ AnyMap AnyMap::fromYamlString(const std::string& yaml) {
|
|||
return amap;
|
||||
}
|
||||
|
||||
AnyMap AnyMap::fromYamlFile(const std::string& name) {
|
||||
std::string fullName = findInputFile(name);
|
||||
int mtime = get_modified_time(fullName);
|
||||
AnyMap AnyMap::fromYamlFile(const std::string& name,
|
||||
const std::string& parent_name)
|
||||
{
|
||||
std::string fullName;
|
||||
// See if a file with this name exists in a path relative to the parent file
|
||||
size_t islash = parent_name.find_last_of("/\\");
|
||||
if (islash != npos) {
|
||||
std::string parent_path = parent_name.substr(0, islash);
|
||||
if (std::ifstream(parent_path + "/" + name).good()) {
|
||||
fullName = parent_path + "/" + name;
|
||||
}
|
||||
}
|
||||
// Otherwise, search the Cantera include path for the file
|
||||
if (fullName.empty()) {
|
||||
fullName = findInputFile(name);
|
||||
}
|
||||
|
||||
// Check for an already-parsed YAML file with the same last-modified time,
|
||||
// and return that if possible
|
||||
int mtime = get_modified_time(fullName);
|
||||
std::unique_lock<std::mutex> lock(yaml_cache_mutex);
|
||||
auto iter = s_cache.find(fullName);
|
||||
if (iter != s_cache.end() && iter->second.second == mtime) {
|
||||
return iter->second.first;
|
||||
}
|
||||
|
||||
if (!std::ifstream(fullName).good()) {
|
||||
throw CanteraError("AnyMap::fromYamlFile", "Input file '{}' not found "
|
||||
"on the Cantera search path.", name);
|
||||
}
|
||||
|
||||
// Generate an AnyMap from the YAML file and store it in the cache
|
||||
auto& cache_item = s_cache[fullName];
|
||||
cache_item.second = mtime;
|
||||
|
|
@ -777,6 +796,7 @@ AnyMap AnyMap::fromYamlFile(const std::string& name) {
|
|||
s_cache.erase(fullName);
|
||||
throw;
|
||||
}
|
||||
cache_item.first["__file__"] = fullName;
|
||||
|
||||
// Return a copy of the AnyMap
|
||||
return cache_item.first;
|
||||
|
|
|
|||
|
|
@ -111,12 +111,13 @@ void addReactions(Kinetics& kin, const AnyMap& phaseNode, const AnyMap& rootNode
|
|||
throw CanteraError("setupKinetics", "Unknown rule '{}' for adding "
|
||||
"species from the '{}' section.", rules[i], sections[i]);
|
||||
}
|
||||
const auto& slash = boost::ifind_first(sections[i], "/");
|
||||
const auto& slash = boost::ifind_last(sections[i], "/");
|
||||
if (slash) {
|
||||
// specified section is in a different file
|
||||
string fileName (sections[i].begin(), slash.begin());
|
||||
string node(slash.end(), sections[i].end());
|
||||
AnyMap reactions = AnyMap::fromYamlFile(fileName);
|
||||
AnyMap reactions = AnyMap::fromYamlFile(fileName,
|
||||
rootNode.getString("__file__", ""));
|
||||
for (const auto& R : reactions[node].asVector<AnyMap>()) {
|
||||
kin.addReaction(newReaction(R, kin));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -431,11 +431,12 @@ void setupPhase(ThermoPhase& thermo, const AnyMap& phaseNode,
|
|||
for (const auto& elemNode : phaseNode["elements"].asVector<AnyMap>()) {
|
||||
const string& source = elemNode.begin()->first;
|
||||
const auto& names = elemNode.begin()->second.asVector<string>();
|
||||
const auto& slash = boost::ifind_first(source, "/");
|
||||
const auto& slash = boost::ifind_last(source, "/");
|
||||
if (slash) {
|
||||
std::string fileName(source.begin(), slash.begin());
|
||||
std::string node(slash.end(), source.end());
|
||||
const AnyMap elements = AnyMap::fromYamlFile(fileName);
|
||||
const AnyMap elements = AnyMap::fromYamlFile(fileName,
|
||||
rootNode.getString("__file__", ""));
|
||||
addElements(thermo, names,
|
||||
elements[node].asMap("symbol"), false);
|
||||
} else if (rootNode.hasKey(source)) {
|
||||
|
|
@ -476,12 +477,13 @@ void setupPhase(ThermoPhase& thermo, const AnyMap& phaseNode,
|
|||
for (const auto& speciesNode : phaseNode["species"].asVector<AnyMap>()) {
|
||||
const string& source = speciesNode.begin()->first;
|
||||
const auto& names = speciesNode.begin()->second;
|
||||
const auto& slash = boost::ifind_first(source, "/");
|
||||
const auto& slash = boost::ifind_last(source, "/");
|
||||
if (slash) {
|
||||
// source is a different input file
|
||||
std::string fileName(source.begin(), slash.begin());
|
||||
std::string node(slash.end(), source.end());
|
||||
AnyMap species = AnyMap::fromYamlFile(fileName);
|
||||
AnyMap species = AnyMap::fromYamlFile(fileName,
|
||||
rootNode.getString("__file__", ""));
|
||||
addSpecies(thermo, names, species[node]);
|
||||
} else if (rootNode.hasKey(source)) {
|
||||
// source is in the current file
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ phases:
|
|||
thermo: ideal-gas
|
||||
elements:
|
||||
- default: [N, O]
|
||||
- species-elements.yaml/isotopes: [Ar]
|
||||
- test_subdir/species-elements.yaml/isotopes: [Ar]
|
||||
species: [O2, NO, N2, AR]
|
||||
note: replace Argon with custom element from a different file
|
||||
state: {T: 900.0, P: 5 atm, Y: {O2: 0.4, N2: 0.4, AR: 0.2}}
|
||||
|
|
@ -33,7 +33,7 @@ phases:
|
|||
thermo: ideal-gas
|
||||
species:
|
||||
- species: [O2, N2]
|
||||
- species-elements.yaml/species: [NO2, N2O]
|
||||
- ../../test/data/test_subdir/species-elements.yaml/species: [NO2, N2O]
|
||||
state: {T: 300.0, P: 1 atm, X: "N2O:0.3, O2:0.7"}
|
||||
|
||||
- name: species-all
|
||||
|
|
@ -50,8 +50,8 @@ phases:
|
|||
kinetics: gas
|
||||
species:
|
||||
- species: all
|
||||
- species-elements.yaml/species: all
|
||||
reactions: [reactions, species-elements.yaml/nox-reactions]
|
||||
- test_subdir/species-elements.yaml/species: all
|
||||
reactions: [reactions, test_subdir/species-elements.yaml/nox-reactions]
|
||||
state: {T: 300.0, P: 1 atm, X: {AR: 0.2, O2: 0.7, N2: 0.1}}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue