58 bool hasDescription =
m_header.hasKey(
"description");
60 output[
"description"] =
m_header[
"description"];
62 output[
"generator"] =
"YamlWriter";
63 output[
"cantera-version"] = CANTERA_VERSION;
65 time_t now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
66 output[
"date"] =
trimCopy(std::ctime(&now));
68 output[
"description"].
setLoc(-6, 0);
70 output[
"generator"].
setLoc(-5, 0);
71 output[
"cantera-version"].
setLoc(-4, 0);
72 output[
"git-commit"].
setLoc(-3, 0);
73 output[
"date"].
setLoc(-2, 0);
76 set<string> exclude = {
77 "description",
"generator",
"cantera-version",
"git-commit",
"date"};
78 for (
const auto& [key, value] :
m_header) {
79 if (!exclude.count(key)) {
85 vector<AnyMap> phaseDefs(m_phases.size());
86 size_t nspecies_total = 0;
87 for (
size_t i = 0; i < m_phases.size(); i++) {
89 if (m_phases[i]->nAdjacent()) {
90 vector<string> adj_names;
91 for (
size_t j = 0; j < m_phases[i]->nAdjacent(); j++) {
92 adj_names.push_back(m_phases[i]->adjacent(j)->name());
94 phaseDefs[i][
"adjacent-phases"] = adj_names;
96 nspecies_total += m_phases[i]->thermo()->nSpecies();
98 output[
"phases"] = phaseDefs;
101 vector<AnyMap> elementDefs;
102 std::unordered_map<string, size_t> elementDefIndex;
103 for (
const auto& phase : m_phases) {
104 for (
auto& elementDef : phase->thermo()->elementDefinitions()) {
105 const string& symbol = elementDef[
"symbol"].asString();
106 if (elementDefIndex.count(symbol) == 0) {
107 elementDefs.emplace_back(std::move(elementDef));
108 elementDefIndex[symbol] = elementDefs.size() - 1;
109 }
else if (elementDefs[elementDefIndex[symbol]] != elementDef) {
111 "Multiple elements with different definitions are not "
112 "supported:\n>>>>>>\n{}\n======\n{}\n<<<<<<\n",
113 elementDef.toYamlString(),
114 elementDefs[elementDefIndex[symbol]].toYamlString());
118 if (!elementDefs.empty()) {
119 output[
"elements"] = std::move(elementDefs);
123 vector<AnyMap> speciesDefs;
124 speciesDefs.reserve(nspecies_total);
125 std::unordered_map<string, size_t> speciesDefIndex;
126 for (
const auto& phase : m_phases) {
127 const auto thermo = phase->thermo();
128 for (
const auto& name : thermo->speciesNames()) {
129 const auto& species = thermo->species(name);
132 if (speciesDefIndex.count(name) == 0) {
133 speciesDefs.emplace_back(speciesDef);
134 speciesDefIndex[name] = speciesDefs.size() - 1;
135 }
else if (speciesDefs[speciesDefIndex[name]] != speciesDef) {
137 "Multiple species with different definitions are not "
138 "supported:\n>>>>>>\n{}\n======\n{}\n<<<<<<\n",
139 speciesDef.toYamlString(),
140 speciesDefs[speciesDefIndex[name]].toYamlString());
144 output[
"species"] = speciesDefs;
147 map<string, vector<AnyMap>> allReactions;
148 for (
const auto& phase : m_phases) {
149 const auto kin = phase->kinetics();
150 if (!kin || !kin->nReactions()) {
154 kin->checkDuplicates(
false,
true);
155 vector<AnyMap> reactions;
156 for (
size_t i = 0; i < kin->nReactions(); i++) {
159 allReactions[phase->name()] = std::move(reactions);
167 map<string, vector<string>> phaseGroups;
169 for (
const auto& phase : m_phases) {
170 const auto kin = phase->kinetics();
171 string name = phase->name();
172 if (!kin || !kin->nReactions()) {
176 for (
auto& [canonicalPhase, dependentPhases] : phaseGroups) {
177 if (allReactions[canonicalPhase] == allReactions[name]) {
178 dependentPhases.push_back(name);
179 allReactions.erase(name);
185 phaseGroups[name].push_back(name);
190 if (phaseGroups.size() == 1) {
191 output[
"reactions"] = std::move(allReactions[phaseGroups.begin()->first]);
193 for (
const auto& [canonicalPhase, dependentPhases] : phaseGroups) {
195 for (
auto& name : dependentPhases) {
196 groupName += name +
"-";
198 groupName +=
"reactions";
199 output[groupName] = std::move(allReactions[canonicalPhase]);
201 for (
auto& name : dependentPhases) {
202 AnyMap& phaseDef = output[
"phases"].getMapWhere(
"name", name);
203 phaseDef[
"reactions"] = vector<string>{groupName};
210 return output.toYamlString();