diff --git a/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaElementData.md b/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaElementData.md index 850e76801b2a..89e6f8078378 100644 --- a/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaElementData.md +++ b/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaElementData.md @@ -10,7 +10,7 @@ This UserObject is designed for use with thermochemistry library Thermochimica. [`ThermochimicaElementData`](ThermochimicaElementData.md) performs Thermochimica calculations on elements. !alert note -This object can only be set up using teh [ChemicalComposition](ChemicalCompositionAction.md) action +This object can only be set up using the [ChemicalComposition](ChemicalCompositionAction.md) action Thermochimica is called by this object at every execute (please see the Thermochimica user manual for more details), and the data required to re-initialize Thermochimica calculations is diff --git a/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaNodalData.md b/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaNodalData.md index 3ce707355b58..2d6b6eed1288 100644 --- a/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaNodalData.md +++ b/modules/chemical_reactions/doc/content/source/userobjects/ThermochimicaNodalData.md @@ -8,28 +8,14 @@ This UserObject is designed for use with thermochemistry library Thermochimica. ## Description [`ThermochimicaNodalData`](ThermochimicaNodalData.md) performs Thermochimica calculations at nodes. -In this UserObject, the masses of elements included in the vector variable [!param](/UserObjects/ThermochimicaNodalData/elements) are input -to the Fortan 90 module Thermochimica, along with the temperature and pressure. Optionally, the -user may disable Thermochimica calculation re-initialization by setting [!param](/UserObjects/ThermochimicaNodalData/reinit_type) to `none`. -This may reduce memory use in the calculation, but will likely greatly increase the length of each -call to Thermochimica. !alert note -Currently this object is designed to only work with constant monomial type variables (one DOF per element)! +This object can only be set up using the [ChemicalComposition](ChemicalCompositionAction.md) action Thermochimica is called by this object at every execute (please see the Thermochimica user manual for more details), and the data required to re-initialize Thermochimica calculations is saved/loaded if re-initialization is enabled. -If the optional variable [!param](/UserObjects/ThermochimicaNodalData/output_phases) is set to a non-empty list of phase names, then concentration -data corresponding to these phases will be output. These phase names must exactly match those specified -in the datafile used for Thermochimica calculations. Similarly, if [!param](/UserObjects/ThermochimicaNodalData/output_species) is a non-empty list -of `phase:species` pairs, these will be parsed and the specified species in the specified phases will be -located in Thermochimica output and stored for later output via an AuxKernel. - -If [!param](/UserObjects/ThermochimicaNodalData/output_element_potentials) is a non-empty list formatted as `any_string:element_name`, then the chemical -potentials of the elements in the list are output to the variables specified in the list. - ## Example Input Syntax !syntax parameters /UserObjects/ThermochimicaNodalData diff --git a/modules/chemical_reactions/include/userobjects/ThermochimicaData.h b/modules/chemical_reactions/include/userobjects/ThermochimicaData.h index 25e19bc979b8..0fde85f7681e 100644 --- a/modules/chemical_reactions/include/userobjects/ThermochimicaData.h +++ b/modules/chemical_reactions/include/userobjects/ThermochimicaData.h @@ -32,6 +32,7 @@ class ThermochimicaDataBase : public ThermochimicaDataBaseParent public: static InputParameters validParams(); ThermochimicaDataBase(const InputParameters & parameters); + ~ThermochimicaDataBase(); virtual void initialize() override; virtual void execute() override; @@ -70,8 +71,16 @@ class ThermochimicaDataBase : public ThermochimicaDataBaseParent const Data & getData(dof_id_type id) const; protected: - // get current node or element ID - auto currentID(); + // child process routine to dispatch thermochimica calculations + void server(); + + // helper to wait on a socket read + template + void expect(T expect_msg); + + // send message to socket + template + void notify(T send_msg); const VariableValue & _pressure; const VariableValue & _temperature; @@ -124,6 +133,21 @@ class ThermochimicaDataBase : public ThermochimicaDataBaseParent /// Mass unit for output species const enum class OutputMassUnit { MOLES, FRACTION } _output_mass_unit; + /// communication socket + int _socket; + + /// child PID + pid_t _pid; + + /// shared memory pointer for dof_id_type values + dof_id_type * _shared_dofid_mem; + + /// shared memory pointer for Real values + Real * _shared_real_mem; + + // current node or element ID + dof_id_type _current_id; + using ThermochimicaDataBaseParent::isCoupled; using ThermochimicaDataBaseParent::isParamValid; using ThermochimicaDataBaseParent::coupledValue; diff --git a/modules/chemical_reactions/src/userobjects/ThermochimicaData.C b/modules/chemical_reactions/src/userobjects/ThermochimicaData.C index c07e4ffdb108..ac21cd7795dc 100644 --- a/modules/chemical_reactions/src/userobjects/ThermochimicaData.C +++ b/modules/chemical_reactions/src/userobjects/ThermochimicaData.C @@ -13,6 +13,11 @@ #include "ActionWarehouse.h" #include "libmesh/int_range.h" +#include // for mmap +#include // for fork +#include // for socketpair +#include // for kill + #ifdef THERMOCHIMICA_ENABLED #include "Thermochimica-cxx.h" #include "checkUnits.h" @@ -60,6 +65,12 @@ ThermochimicaDataBase::validParams() return params; } +void +ThermochimicaDataBase_handler(int /*signum*/) +{ + exit(0); +} + template ThermochimicaDataBase::ThermochimicaDataBase(const InputParameters & parameters) : ThermochimicaDataBaseParent(parameters), @@ -93,9 +104,6 @@ ThermochimicaDataBase::ThermochimicaDataBase(const InputParameters & p { ThermochimicaUtils::checkLibraryAvailability(*this); - if (n_threads() > 1) - mooseError("Thermochimica does not support multi-threaded runs."); - if (_el_ids.size() != _n_elements) mooseError("Element IDs size does not match number of elements."); for (const auto i : make_range(_n_elements)) @@ -146,6 +154,56 @@ ThermochimicaDataBase::ThermochimicaDataBase(const InputParameters & p for (const auto i : make_range(_n_potentials)) _el_pot[i] = &writableVariable("output_element_potentials", i); } + // buffer size + const auto dofid_size = std::max(/* send */ 1, /* receive */ 0); + const auto real_size = + std::max(/* send */ 2 + _n_elements, + /* receive */ _n_phases + _n_species + _element_potentials.size() + + _n_vapor_species + _n_phase_elements); + + // set up shared memory for communication with child process + auto shared_mem = + static_cast(mmap(nullptr, + dofid_size * sizeof(dof_id_type) + real_size * sizeof(Real), + PROT_READ | PROT_WRITE, + MAP_ANONYMOUS | MAP_SHARED, + -1 /* fd */, + 0 /* offset */)); + if (shared_mem == MAP_FAILED) + mooseError("Failed to allocate shared memory for thermochimica IPC."); + + // set up buffer partitions + _shared_dofid_mem = reinterpret_cast(shared_mem); + _shared_real_mem = reinterpret_cast(shared_mem + dofid_size * sizeof(dof_id_type)); + + // set up a bidirectional communication socket + int sockets[2]; + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) + mooseError("Failed to create socketpair for thermochimica IPC."); + + // fork child process that will manage thermochimica calls + _pid = fork(); + if (_pid < 0) + mooseError("Fork failed for thermochimica library."); + if (_pid == 0) + { + // here we are in the child process + _socket = sockets[0]; + // clean exit upon SIGTERM (mainly for Civet code coverage) + signal(SIGTERM, ThermochimicaDataBase_handler); + while (true) + server(); + } + + // parent process continues here + _socket = sockets[1]; +} + +template +ThermochimicaDataBase::~ThermochimicaDataBase() +{ + if (_pid) + kill(_pid, SIGTERM); } template @@ -154,18 +212,92 @@ ThermochimicaDataBase::initialize() { } +template +template +void +ThermochimicaDataBase::expect(T expect_msg) +{ + T msg; + while (read(_socket, &msg, sizeof(T)) == 0) + { + if (errno == EAGAIN) + continue; + mooseError("Read error waiting for '", expect_msg, "' ", errno, ' ', strerror(errno)); + } + if (msg != expect_msg) + mooseError("Expected '", expect_msg, "' but received '", msg, "'"); +} + +template +template +void +ThermochimicaDataBase::notify(T send_msg) +{ + write(_socket, &send_msg, sizeof(T)); +} + template void ThermochimicaDataBase::execute() { -#ifdef THERMOCHIMICA_ENABLED // either one DOF at a node or (currently) one DOF for constant monomial FV! // This is enforced automatically by the ChemicalComposition action, which creates the correct // variables. const unsigned int qp = 0; - auto temperature = _temperature[qp]; - auto pressure = _pressure[qp]; + // store current dofID + if constexpr (is_nodal) + _shared_dofid_mem[0] = this->_current_node->id(); + else + _shared_dofid_mem[0] = this->_current_elem->id(); + + // store all required data in shared memory + _shared_real_mem[0] = _temperature[qp]; + _shared_real_mem[1] = _pressure[qp]; + for (const auto i : make_range(_n_elements)) + _shared_real_mem[2 + i] = (*_el[i])[qp]; + + // message child process to trigger calculation + notify('A'); + + // and wait for the child process to signal end of calculation + expect('B'); + + // unpack data from shared memory + std::size_t idx = 0; + + for (const auto i : make_range(_n_phases)) + _ph[i]->setDofValue(_shared_real_mem[idx++], qp); + + for (const auto i : make_range(_n_species)) + _sp[i]->setDofValue(_shared_real_mem[idx++], qp); + + if (_output_element_potentials) + for (const auto i : index_range(_element_potentials)) + _el_pot[i]->setDofValue(_shared_real_mem[idx++], qp); + + if (_output_vapor_pressures) + for (const auto i : make_range(_n_vapor_species)) + _vp[i]->setDofValue(_shared_real_mem[idx++], qp); + + if (_output_element_phases) + for (const auto i : make_range(_n_phase_elements)) + _el_ph[i]->setDofValue(_shared_real_mem[idx++], qp); +} + +template +void +ThermochimicaDataBase::server() +{ + // wait for message from parent process + expect('A'); + +#ifdef THERMOCHIMICA_ENABLED + // fetch data from shared memory + _current_id = _shared_dofid_mem[0]; + + auto temperature = _shared_real_mem[0]; + auto pressure = _shared_real_mem[1]; // Set temperature and pressure for thermochemistry solver Thermochimica::setTemperaturePressure(temperature, pressure); @@ -175,7 +307,7 @@ ThermochimicaDataBase::execute() // Set element masses for (const auto i : make_range(_n_elements)) - Thermochimica::setElementMass(_el_ids[i], (*_el[i])[qp]); + Thermochimica::setElementMass(_el_ids[i], _shared_real_mem[2 + i]); // Optionally ask for a re-initialization (if reinit_requested == true) reinitDataMooseToTc(); @@ -186,176 +318,170 @@ ThermochimicaDataBase::execute() // Check for error status auto idbg = Thermochimica::checkInfoThermo(); if (idbg != 0) + // error out for now, but we should send a code to the parent process mooseError("Thermochimica error ", idbg); - else + + // Save data for future reinits + reinitDataMooseFromTc(); + + // Get requested phase indices if phase concentration output was requested + // i.e. if output_phases is coupled + auto moles_phase = Thermochimica::getMolesPhase(); + + std::size_t idx = 0; + + for (const auto i : make_range(_n_phases)) { - // Save data for future reinits - reinitDataMooseFromTc(); + // Is this maybe constant? No it isn't for now + auto [index, idbg] = Thermochimica::getPhaseIndex(_ph_names[i]); + if (idbg != 0) + mooseError("Failed to get index of phase '", _ph_names[i], "'"); + // Convert from 1-based (fortran) to 0-based (c++) indexing + if (index - 1 < 0) + _shared_real_mem[idx++] = 0.0; + else + _shared_real_mem[idx++] = moles_phase[index - 1]; + } - // Get requested phase indices if phase concentration output was requested - // i.e. if output_phases is coupled - auto moles_phase = Thermochimica::getMolesPhase(); + auto db_phases = Thermochimica::getPhaseNamesSystem(); + auto getSpeciesMoles = + [this, moles_phase, db_phases](const std::string phase, + const std::string species) -> std::pair + { + Real value = 0.0; + int code = 0; - for (const auto i : make_range(_n_phases)) - { - // Is this maybe constant? No it isn't for now - auto [index, idbg] = Thermochimica::getPhaseIndex(_ph_names[i]); - if (idbg != 0) - mooseError("Failed to get index of phase '", _ph_names[i], "'"); - // Convert from 1-based (fortran) to 0-based (c++) indexing - if (index - 1 < 0) - _ph[i]->setDofValue(0.0, qp); - else - _ph[i]->setDofValue(moles_phase[index - 1], qp); - } + auto [index, idbg] = Thermochimica::getPhaseIndex(phase); - auto db_phases = Thermochimica::getPhaseNamesSystem(); - auto getSpeciesMoles = - [this, moles_phase, db_phases](const std::string phase, - const std::string species) -> std::pair + if (Thermochimica::isPhaseMQM( + std::distance(db_phases.begin(), std::find(db_phases.begin(), db_phases.end(), phase)))) { - Real value = 0.0; - int code = 0; - - auto [index, idbg] = Thermochimica::getPhaseIndex(phase); + auto [fraction, idbg] = Thermochimica::getMqmqaPairMolFraction(phase, species); - if (Thermochimica::isPhaseMQM(std::distance( - db_phases.begin(), std::find(db_phases.begin(), db_phases.end(), phase)))) + switch (_output_mass_unit) { - auto [fraction, idbg] = Thermochimica::getMqmqaPairMolFraction(phase, species); - - switch (_output_mass_unit) + case OutputMassUnit::FRACTION: { - case OutputMassUnit::FRACTION: - { - value = fraction; - code = idbg; - break; - } - case OutputMassUnit::MOLES: - { - auto [molesPair, idbgPair] = Thermochimica::getMqmqaMolesPairs(phase); - value = molesPair * fraction; - code = idbg + idbgPair; - break; - } - default: - break; + value = fraction; + code = idbg; + break; } + case OutputMassUnit::MOLES: + { + auto [molesPair, idbgPair] = Thermochimica::getMqmqaMolesPairs(phase); + value = molesPair * fraction; + code = idbg + idbgPair; + break; + } + default: + break; } - else + } + else + { + auto [fraction, idbg] = Thermochimica::getOutputMolSpeciesPhase(phase, species); + switch (_output_mass_unit) { - auto [fraction, idbg] = Thermochimica::getOutputMolSpeciesPhase(phase, species); - switch (_output_mass_unit) + case OutputMassUnit::FRACTION: + { + value = fraction; + code = idbg; + break; + } + case OutputMassUnit::MOLES: { - case OutputMassUnit::FRACTION: - { - value = fraction; - code = idbg; - break; - } - case OutputMassUnit::MOLES: - { - value = index >= 1 ? moles_phase[index - 1] * fraction : 0.0; - code = idbg; - break; - } - default: - break; + value = index >= 1 ? moles_phase[index - 1] * fraction : 0.0; + code = idbg; + break; } + default: + break; } - return {value, code}; - }; + } + return {value, code}; + }; - for (const auto i : make_range(_n_species)) + for (const auto i : make_range(_n_species)) + { + auto [fraction, idbg] = getSpeciesMoles( + _species_phase_pairs[i].first, + _species_phase_pairs[i].second); // can we somehow use IDs instead of strings here? + + if (idbg == 0) + _shared_real_mem[idx++] = fraction; + else if (idbg == 1) + _shared_real_mem[idx++] = 0.0; +#ifndef NDEBUG + else + mooseError("Failed to get phase speciation for phase '", + _species_phase_pairs[i].first, + "' and species '", + _species_phase_pairs[i].second, + "'. Thermochimica returned ", + idbg); +#endif + } + + if (_output_element_potentials) + for (const auto i : index_range(_element_potentials)) { - auto [fraction, idbg] = getSpeciesMoles( - _species_phase_pairs[i].first, - _species_phase_pairs[i].second); // can we somehow use IDs instead of strings here? + auto [potential, idbg] = Thermochimica::getOutputChemPot(_element_potentials[i]); if (idbg == 0) - _sp[i]->setDofValue(fraction, qp); + _shared_real_mem[idx++] = potential; else if (idbg == 1) - _sp[i]->setDofValue(0.0, qp); + // element not present, just leave this at 0 for now + _shared_real_mem[idx++] = 0.0; + else if (idbg == -1) + Moose::out << "getoutputchempot " << idbg << "\n"; + } + + if (_output_vapor_pressures) + for (const auto i : make_range(_n_vapor_species)) + { + auto [fraction, moles, idbg] = + Thermochimica::getOutputMolSpecies(_vapor_phase_pairs[i].second); + libmesh_ignore(moles); + + if (idbg == 0) + _shared_real_mem[idx++] = fraction * pressure; + else if (idbg == 1) + _shared_real_mem[idx++] = 0.0; #ifndef NDEBUG else - mooseError("Failed to get phase speciation for phase '", - _species_phase_pairs[i].first, + mooseError("Failed to get vapor pressure for phase '", + _vapor_phase_pairs[i].first, "' and species '", - _species_phase_pairs[i].second, + _vapor_phase_pairs[i].second, "'. Thermochimica returned ", idbg); #endif } - if (_output_element_potentials) - for (const auto i : index_range(_element_potentials)) - { - auto [potential, idbg] = Thermochimica::getOutputChemPot(_element_potentials[i]); - - if (idbg == 0) - _el_pot[i]->setDofValue(potential, qp); - else if (idbg == 1) - // element not present, just leave this at 0 for now - _el_pot[i]->setDofValue(0.0, qp); - else if (idbg == -1) - Moose::out << "getoutputchempot " << idbg << "\n"; - } - - if (_output_vapor_pressures) - for (const auto i : make_range(_n_vapor_species)) - { - auto [fraction, moles, idbg] = - Thermochimica::getOutputMolSpecies(_vapor_phase_pairs[i].second); - libmesh_ignore(moles); - - if (idbg == 0) - _vp[i]->setDofValue(fraction * pressure, qp); - else if (idbg == 1) - _vp[i]->setDofValue(0.0, qp); -#ifndef NDEBUG - else - mooseError("Failed to get vapor pressure for phase '", - _vapor_phase_pairs[i].first, - "' and species '", - _vapor_phase_pairs[i].second, - "'. Thermochimica returned ", - idbg); -#endif - } - - if (_output_element_phases) - for (const auto i : make_range(_n_phase_elements)) - { - auto [moles, idbg] = Thermochimica::getElementMolesInPhase(_phase_element_pairs[i].second, - _phase_element_pairs[i].first); + if (_output_element_phases) + for (const auto i : make_range(_n_phase_elements)) + { + auto [moles, idbg] = Thermochimica::getElementMolesInPhase(_phase_element_pairs[i].second, + _phase_element_pairs[i].first); - if (idbg == 0) - _el_ph[i]->setDofValue(moles, qp); - else if (idbg == 1) - _el_ph[i]->setDofValue(0.0, qp); + if (idbg == 0) + _shared_real_mem[idx++] = moles; + else if (idbg == 1) + _shared_real_mem[idx++] = 0.0; #ifndef NDEBUG - else - mooseError("Failed to get moles of element '", - _phase_element_pairs[i].second, - "' in phase '", - _phase_element_pairs[i].first, - "'. Thermochimica returned ", - idbg); + else + mooseError("Failed to get moles of element '", + _phase_element_pairs[i].second, + "' in phase '", + _phase_element_pairs[i].first, + "'. Thermochimica returned ", + idbg); #endif - } - } + } #endif -} -template -auto -ThermochimicaDataBase::currentID() -{ - if constexpr (is_nodal) - return this->_current_node->id(); - else - return this->_current_elem->id(); + // Send message back to parent process + notify('B'); } template @@ -363,7 +489,7 @@ void ThermochimicaDataBase::reinitDataMooseFromTc() { #ifdef THERMOCHIMICA_ENABLED - auto & d = _data[currentID()]; + auto & d = _data[_current_id]; if (_reinit != ReinitializationType::NONE) { @@ -400,7 +526,8 @@ ThermochimicaDataBase::reinitDataMooseToTc() } // If we have re-initialization data and want a re-initialization, then // load data into Thermochimica - auto it = _data.find(currentID()); + auto it = _data.find(_current_id); + if (it != _data.end() && _reinit == ReinitializationType::TIME) // If doing previous timestep reinit { diff --git a/modules/chemical_reactions/test/tests/thermochimica/tests b/modules/chemical_reactions/test/tests/thermochimica/tests index 3ebc45c3011b..13cf8c88af9e 100644 --- a/modules/chemical_reactions/test/tests/thermochimica/tests +++ b/modules/chemical_reactions/test/tests/thermochimica/tests @@ -7,7 +7,6 @@ issues = '#22711' requirement = 'The system shall be able to set up a nodal thermochemistry solve using an action' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -20,7 +19,6 @@ issues = '#22711' requirement = 'The system shall be able to use reinitialization to speed up a nodal thermochimica solve' cli_args = 'ChemicalComposition/reinitialization_type=time' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -33,7 +31,6 @@ issues = '#25877' requirement = 'The system shall be able to set up an elemental thermochemistry solve using an action' cli_args = 'ChemicalComposition/is_fv=true Outputs/file_base=MoRu_FV_out' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -46,7 +43,6 @@ issues = '#25877' requirement = 'The system shall be able to use reinitialization to speed up an elemental thermochimica solve' cli_args = 'ChemicalComposition/reinitialization_type=time ChemicalComposition/is_fv=true Outputs/file_base=MoRu_FV_out' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -58,7 +54,6 @@ design = 'ThermochimicaNodalData.md' issues = '#25661' requirement = 'The system shall be able to use graciously handle a missing element in Thermochimica' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -71,7 +66,6 @@ issues = '#22711' requirement = 'The system shall be able to set up constant initial conditions from a CSV file' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -85,7 +79,6 @@ requirement = 'The system shall be able to use pairs as MQMQA phase species' cli_args = 'ChemicalComposition/output_species_unit=moles Outputs/exodus=true' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -100,7 +93,6 @@ requirement = 'The system shall be able to output moles of pairs for MQMQA phase species' cli_args = 'ChemicalComposition/output_species_unit=moles Outputs/csv=true' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -114,7 +106,6 @@ requirement = 'The system shall throw an error if an invalid output species format is detected' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] [separator_error2] @@ -126,7 +117,6 @@ requirement = 'The system shall throw an error if an invalid element potential format is detected' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -139,7 +129,6 @@ requirement = 'The system shall throw an error if an invalid element is specified' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -152,7 +141,6 @@ requirement = 'The system shall throw an error if a species absent from the database is specified for species output' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] [wrong_species2] @@ -164,11 +152,9 @@ requirement = 'The system shall throw an error if a wrong phase name of a species is specified for species output' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] - [wrong_element1] type = RunException input = MoRu.i @@ -178,7 +164,6 @@ requirement = 'The system shall throw an error if an element absent from the simulation is specified for chemical potential output' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -186,12 +171,12 @@ type = RunException input = MoRu.i expect_err = "Phase 'RandomPhase' was not found in the simulation." - cli_args = "GlobalParams/output_phases='BCCN HCPN RandomPhase' UserObjects/data/output_phases='BCCN HCPN RandomPhase'" + cli_args = "GlobalParams/output_phases='BCCN HCPN RandomPhase' " + "UserObjects/data/output_phases='BCCN HCPN RandomPhase'" issues = '#24269' requirement = 'The system shall throw an error if a phase absent from the simulation is specified for phase output' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -204,20 +189,19 @@ requirement = 'The system shall throw an error if a gas phase species name is not in correct format' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] [wrong_vapor_pressure2] type = RunException input = MoRu.i - expect_err = "Phase 'HCPN' of vapor species 'vp:HCPN:Mo' is not a gas phase. Cannot calculate vapor pressure." + expect_err = "Phase 'HCPN' of vapor species 'vp:HCPN:Mo' is not a gas phase. Cannot calculate " + "vapor pressure." cli_args = "GlobalParams/output_vapor_pressures='vp:HCPN:Mo'" issues = '#24269' requirement = 'The system shall throw an error if a species in a phase other than the gas phase is specified for vapor pressure output' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -230,7 +214,6 @@ requirement = 'The system shall throw an error if a species not present in gas phase is specified for vapor pressure output' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -243,7 +226,6 @@ requirement = 'The system shall throw an error if the wrong datafile is specified' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -255,7 +237,6 @@ issues = '#24552' requirement = 'The system shall be able to handle ALL option for elements by using all database elements' - max_threads = 1 rel_err = 1e-3 # this is the same error thermochimica uses for its internal tests required_submodule = 'contrib/thermochimica' [] @@ -269,7 +250,6 @@ requirement = 'The system shall throw an error if a wrong phase name is specified' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -282,7 +262,6 @@ requirement = 'The system shall throw an error if a wrong element name is specified' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] @@ -295,8 +274,6 @@ requirement = 'The system shall throw an error if the output elements in phase do not have enough tokens' design = ChemicalCompositionAction.md - max_threads = 1 required_submodule = 'contrib/thermochimica' [] - []