96 if (action.size() == 1)
97 pars.applyParameters(action[0]->parameters());
102 "The temperature unit must be specified for Thermochimica objects to be constructed");
106 "The pressure unit must be specified for Thermochimica objects to be constructed");
110 "The mass unit must be specified for Thermochimica objects to be constructed");
114 "Temperature variable must be specified for this object to be constructed");
119 "output_species_unit",
120 "Output mass unit must be specified for Thermochimica user object to be constructed");
124 #ifdef THERMOCHIMICA_ENABLED 128 const auto thermo_file = getParam<FileName>(
"thermofile");
130 if (thermo_file.length() > 1024)
132 "Path exceeds Thermochimica's maximal permissible length of 1024 with ",
133 thermo_file.length(),
137 Thermochimica::setThermoFilename(thermo_file);
140 Thermochimica::parseThermoFile();
142 const auto idbg = Thermochimica::checkInfoThermo();
144 paramError(
"thermofile",
"Thermochimica data file cannot be parsed. ", idbg);
149 Thermochimica::checkTemperature(tunit);
150 Thermochimica::setUnitTemperature(tunit);
151 int idbg = Thermochimica::checkInfoThermo();
153 paramError(
"tunit",
"Cannot set temperature unit in Thermochimica", idbg);
156 Thermochimica::checkPressure(punit);
157 Thermochimica::setUnitPressure(punit);
158 idbg = Thermochimica::checkInfoThermo();
160 paramError(
"punit",
"Cannot set pressure unit in Thermochimica", idbg);
163 std::replace(munit.begin(), munit.end(),
'_',
' ');
164 Thermochimica::checkMass(munit);
165 Thermochimica::setUnitMass(munit);
166 idbg = Thermochimica::checkInfoThermo();
168 paramError(
"munit",
"Cannot set mass unit in Thermochimica", idbg);
170 _elements = getParam<std::vector<std::string>>(
"elements");
173 _elements.resize(Thermochimica::getNumberElementsDatabase());
174 _elements = Thermochimica::getElementsDatabase();
175 mooseInfo(
"Thermochimica elements: 'ALL' specified in input file. Using: ",
180 std::vector<std::string> db_elements(Thermochimica::getNumberElementsDatabase());
181 db_elements = Thermochimica::getElementsDatabase();
183 if (std::find(db_elements.begin(), db_elements.end(),
_elements[i]) == db_elements.end())
194 Thermochimica::setTemperaturePressure(1000.0, 1.0);
195 Thermochimica::setElementMass(0, 0.0);
198 Thermochimica::setElementMass(Thermochimica::atomicNumber(
_elements[i]), 1.0);
200 Thermochimica::setup();
204 _phases = getParam<std::vector<std::string>>(
"output_phases");
207 auto [soln_phases, stoich_phases] = Thermochimica::getNumberPhasesSystem();
208 _phases.resize(soln_phases + stoich_phases);
209 _phases = Thermochimica::getPhaseNamesSystem();
210 mooseInfo(
"ChemicalCompositionAction phases: 'ALL' specified in input file. Using: ",
215 auto db_phases = Thermochimica::getPhaseNamesSystem();
217 if (std::find(db_phases.begin(), db_phases.end(),
_phases[i]) == db_phases.end())
218 paramError(
"output_phases",
"Phase '",
_phases[i],
"' was not found in the simulation.");
224 auto species = getParam<std::vector<std::string>>(
"output_species");
225 auto db_phases = Thermochimica::getPhaseNamesSystem();
226 auto n_db_species = Thermochimica::getNumberSpeciesSystem();
227 auto db_species = Thermochimica::getSpeciesSystem();
229 if (Thermochimica::isPhaseMQM(i))
231 auto [pairs, quads, idbg] =
232 Thermochimica::getMqmqaNumberPairsQuads(Thermochimica::getPhaseNamesSystem()[i]);
233 n_db_species[i] = pairs;
236 if (species.size() == 1 && species[0] ==
"ALL")
238 if (!n_db_species.empty())
239 species.resize(n_db_species.back());
241 mooseInfo(
"ChemicalCompositionAction species: 'ALL' specified in input file. Thermochimica " 242 "returned no possible species.");
246 for (
const auto i :
make_range(db_species.size()))
249 species.push_back(db_phases[i] +
":" + db_species[i][
j]);
252 mooseInfo(
"ChemicalCompositionAction species: 'ALL' specified in input file. Using: ",
259 std::vector<std::string> tokens;
261 if (tokens.size() == 1)
262 paramError(
"output_species",
"No ':' separator found in variable '", species[i],
"'");
264 auto phase_index = std::find(db_phases.begin(), db_phases.end(), tokens[0]);
265 if (phase_index == db_phases.end())
269 "' of output species '",
271 "' not found in the simulation.");
272 auto sp = db_species[std::distance(db_phases.begin(), phase_index)];
273 if (std::find(sp.begin(), sp.end(), tokens[1]) == sp.end())
275 "output_species",
"Species '", tokens[1],
"' was not found in the simulation.");
282 auto element_potentials = getParam<std::vector<std::string>>(
"output_element_potentials");
283 if (element_potentials.size() == 1 && element_potentials[0] ==
"ALL")
287 element_potentials.resize(
_elements.size());
289 element_potentials[i] =
"mu:" +
_elements[i];
291 "ChemicalCompositionAction element potentials: 'ALL' specified in input file. Using: ",
297 for (
const auto i :
index_range(element_potentials))
299 std::vector<std::string> tokens;
301 if (tokens.size() == 1)
303 "No ':' separator found in variable '",
304 element_potentials[i],
310 "' was not found in the simulation.");
318 auto vapor_pressures = getParam<std::vector<std::string>>(
"output_vapor_pressures");
319 if (!Thermochimica::isPhaseGas(0))
321 "No gas phase found in the simulation. Cannot output vapor pressures.");
322 if (vapor_pressures.size() == 1 && vapor_pressures[0] ==
"ALL")
324 vapor_pressures.resize(Thermochimica::getNumberSpeciesSystem()[0]);
326 auto db_gas_species = Thermochimica::getSpeciesInPhase(0);
327 auto gas_name = Thermochimica::getPhaseNamesSystem()[0];
330 vapor_pressures[i] =
"vp:" + gas_name +
':' + db_gas_species[i];
333 mooseInfo(
"ChemicalCompositionAction vapor pressures: 'ALL' specified in input file. Using: ",
338 auto db_gas_species = Thermochimica::getSpeciesInPhase(0);
342 std::vector<std::string> tokens;
344 if (tokens.size() == 1)
346 "No ':' separator found in variable '",
349 if (tokens[1] != Thermochimica::getPhaseNamesSystem()[0])
353 "' of vapor species '",
355 "' is not a gas phase. Cannot calculate vapor pressure.");
356 if (std::find(db_gas_species.begin(), db_gas_species.end(), tokens[2]) ==
357 db_gas_species.end())
361 "' was not found in the gas phase of simulation.");
369 auto element_phases = getParam<std::vector<std::string>>(
"output_element_phases");
370 auto db_phases = Thermochimica::getPhaseNamesSystem();
371 if (element_phases.size() == 1 && element_phases[0] ==
"ALL")
373 element_phases.resize(
_elements.size() * db_phases.size());
383 "ChemicalCompositionAction elements in phase: 'ALL' specified in input file. Using: ",
391 std::vector<std::string> tokens;
393 if (tokens.size() == 1)
395 "No ':' separator found in variable '",
398 if (std::find(db_phases.begin(), db_phases.end(), tokens[1]) == db_phases.end())
404 "' not found in the simulation.");
409 "' was not found in the simulation.");
415 Thermochimica::resetThermoAll();
Store common ChemicalComposition action parameters.
std::vector< std::pair< std::string, std::string > > _tokenized_phase_elements
void tokenize(const std::string &str, std::vector< T > &elements, unsigned int min_len=1, const std::string &delims="/")
std::vector< std::string > _elements
Element names.
InputParameterWarehouse & getInputParameterWarehouse()
void mooseInfo(Args &&... args) const
Action(const InputParameters ¶meters)
std::vector< std::pair< std::string, std::string > > _tokenized_species
Tokenized versions of the output variables to avoid redoing tokenization.
MooseObjectName uniqueActionName() const
bool isParamValid(const std::string &name) const
std::vector< std::string > _phases
List of phases tracked by Thermochimica.
void paramError(const std::string ¶m, Args... args) const
std::string stringify(const T &t)
void checkLibraryAvailability(MooseObject &self)
Check if thermochimica is available and throw an error if it is not.
std::vector< unsigned int > _element_ids
Atomic numbers of the selected elements.
std::vector< std::pair< std::string, std::string > > _tokenized_vapor_species
IntRange< T > make_range(T beg, T end)
const InputParameters & parameters() const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::vector< std::string > _tokenized_element_potentials
std::vector< const T *> getActions()
auto index_range(const T &sizable)