https://mooseframework.inl.gov
Classes | Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | List of all members
ThermochimicaDataBase< is_nodal > Class Template Reference

User object that performs a Gibbs energy minimization at each node by calling the Thermochimica code. More...

#include <ThermochimicaData.h>

Inheritance diagram for ThermochimicaDataBase< is_nodal >:
[legend]

Classes

struct  Data
 

Public Member Functions

 ThermochimicaDataBase (const InputParameters &parameters)
 
 ~ThermochimicaDataBase ()
 
virtual void initialize () override
 
virtual void execute () override
 
virtual void finalize () override
 
virtual void threadJoin (const UserObject &) override
 
void reinitDataMooseFromTc ()
 Function to get re-initialization data from Thermochimica and save it in member variables of this UserObject. More...
 
void reinitDataMooseToTc ()
 Function to load re-initialization data saved in this UserObject back into Thermochimica. More...
 
const DatagetNodalData (dof_id_type id) const
 
const DatagetElementData (dof_id_type id) const
 
const DatagetData (dof_id_type id) const
 

Static Public Member Functions

static InputParameters validParams ()
 

Protected Types

enum  ReinitializationType { ReinitializationType::NONE, ReinitializationType::TIME, ReinitializationType::NODE }
 
enum  OutputMassUnit { OutputMassUnit::MOLES, OutputMassUnit::FRACTION }
 Mass unit for output species. More...
 

Protected Member Functions

void server ()
 
template<typename T >
void expect (T expect_msg)
 
template<typename T >
void notify (T send_msg)
 

Protected Attributes

const VariableValue_pressure
 
const VariableValue_temperature
 
const std::size_t _n_phases
 
const std::size_t _n_species
 
const std::size_t _n_elements
 
const std::size_t _n_vapor_species
 
const std::size_t _n_phase_elements
 
const std::size_t _n_potentials
 
std::vector< const VariableValue * > _el
 
const ChemicalCompositionAction_action
 
std::vector< unsigned int_el_ids
 
enum ThermochimicaDataBase::ReinitializationType _reinit
 
const std::vector< std::string > & _ph_names
 
const std::vector< std::string > & _element_potentials
 
const std::vector< std::pair< std::string, std::string > > & _species_phase_pairs
 
const std::vector< std::pair< std::string, std::string > > & _vapor_phase_pairs
 
const std::vector< std::pair< std::string, std::string > > & _phase_element_pairs
 
std::unordered_map< dof_id_type, Data_data
 Nodal data (Used only for reinitialization) More...
 
std::vector< MooseWritableVariable * > _ph
 Writable phase amount variables. More...
 
std::vector< MooseWritableVariable * > _sp
 Writable species amount variables. More...
 
std::vector< MooseWritableVariable * > _vp
 Writable vapour pressures for each element. More...
 
std::vector< MooseWritableVariable * > _el_pot
 Writable chemical potential variables for each element. More...
 
std::vector< MooseWritableVariable * > _el_ph
 Writable variable for molar amounts of each element in specified phase. More...
 
enum ThermochimicaDataBase::OutputMassUnit _output_mass_unit
 
int _socket
 communication socket More...
 
pid_t _pid
 child PID More...
 
dof_id_type_shared_dofid_mem
 shared memory pointer for dof_id_type values More...
 
Real_shared_real_mem
 shared memory pointer for Real values More...
 
dof_id_type _current_id
 
const bool _output_element_potentials
 Element chemical potential output. More...
 
const bool _output_vapor_pressures
 
const bool _output_element_phases
 

Detailed Description

template<bool is_nodal>
class ThermochimicaDataBase< is_nodal >

User object that performs a Gibbs energy minimization at each node by calling the Thermochimica code.

This object can only be added through the ChemicalCompositionAction which also sets up the variables for the calculation.

Definition at line 30 of file ThermochimicaData.h.

Member Enumeration Documentation

◆ OutputMassUnit

template<bool is_nodal>
enum ThermochimicaDataBase::OutputMassUnit
strongprotected

Mass unit for output species.

Enumerator
MOLES 
FRACTION 

Definition at line 134 of file ThermochimicaData.h.

134 { MOLES, FRACTION } _output_mass_unit;
enum ThermochimicaDataBase::OutputMassUnit _output_mass_unit

◆ ReinitializationType

template<bool is_nodal>
enum ThermochimicaDataBase::ReinitializationType
strongprotected
Enumerator
NONE 
TIME 
NODE 

Definition at line 101 of file ThermochimicaData.h.

101 { NONE, TIME, NODE } _reinit;
enum ThermochimicaDataBase::ReinitializationType _reinit
NONE

Constructor & Destructor Documentation

◆ ThermochimicaDataBase()

template<bool is_nodal>
ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase ( const InputParameters parameters)

Definition at line 77 of file ThermochimicaData.C.

79  _pressure(coupledValue("pressure")),
80  _temperature(coupledValue("temperature")),
81  _n_phases(coupledComponents("output_phases")),
82  _n_species(coupledComponents("output_species")),
83  _n_elements(coupledComponents("elements")),
84  _n_vapor_species(coupledComponents("output_vapor_pressures")),
85  _n_phase_elements(coupledComponents("output_element_phases")),
86  _n_potentials(coupledComponents("output_element_potentials")),
89  "_chemical_composition_action")),
91  _reinit(parameters.get<MooseEnum>("reinit_type").getEnum<ReinitializationType>()),
97  _output_element_potentials(isCoupled("output_element_potentials")),
98  _output_vapor_pressures(isCoupled("output_vapor_pressures")),
99  _output_element_phases(isCoupled("output_element_phases")),
100  _ph(_n_phases),
101  _sp(_n_species),
105  _output_mass_unit(parameters.get<MooseEnum>("output_species_unit").getEnum<OutputMassUnit>())
106 {
108 
109  if (_el_ids.size() != _n_elements)
110  mooseError("Element IDs size does not match number of elements.");
111  for (const auto i : make_range(_n_elements))
112  _el[i] = &coupledValue("elements", i);
113 
114  if (isParamValid("output_phases"))
115  {
116  if (_ph_names.size() != _n_phases)
117  mooseError("Phase names vector size does not match number of phases.");
118 
119  for (const auto i : make_range(_n_phases))
120  _ph[i] = &writableVariable("output_phases", i);
121  }
122 
123  if (isParamValid("output_species"))
124  {
125  if (_species_phase_pairs.size() != _n_species)
126  mooseError("Species name vector size does not match number of output species.");
127 
128  for (const auto i : make_range(_n_species))
129  _sp[i] = &writableVariable("output_species", i);
130  }
131 
132  if (isParamValid("output_vapor_pressures"))
133  {
134  if (_vapor_phase_pairs.size() != _n_vapor_species)
135  mooseError("Vapor species name vector size does not match number of output vapor species.");
136 
137  for (const auto i : make_range(_n_vapor_species))
138  _vp[i] = &writableVariable("output_vapor_pressures", i);
139  }
140 
141  if (isParamValid("output_element_phases"))
142  {
144  mooseError("Element phase vector size does not match number of output elements in phases");
145 
146  for (const auto i : make_range(_n_phase_elements))
147  _el_ph[i] = &writableVariable("output_element_phases", i);
148  }
149 
150  if (isParamValid("output_element_potentials"))
151  {
152  if (_element_potentials.size() != _n_potentials)
153  mooseError("Element potentials vector size does not match number of element potentials "
154  "specified for output.");
155 
156  for (const auto i : make_range(_n_potentials))
157  _el_pot[i] = &writableVariable("output_element_potentials", i);
158  }
159  // buffer size
160  const auto dofid_size = std::max(/* send */ 1, /* receive */ 0);
161  const auto real_size =
162  std::max(/* send */ 2 + _n_elements,
163  /* receive */ _n_phases + _n_species + _element_potentials.size() +
165 
166  // set up shared memory for communication with child process
167  auto shared_mem =
168  static_cast<std::byte *>(mmap(nullptr,
169  dofid_size * sizeof(dof_id_type) + real_size * sizeof(Real),
170  PROT_READ | PROT_WRITE,
171  MAP_ANONYMOUS | MAP_SHARED,
172  -1 /* fd */,
173  0 /* offset */));
174  if (shared_mem == MAP_FAILED)
175  mooseError("Failed to allocate shared memory for thermochimica IPC.");
176 
177  // set up buffer partitions
178  _shared_dofid_mem = reinterpret_cast<dof_id_type *>(shared_mem);
179  _shared_real_mem = reinterpret_cast<Real *>(shared_mem + dofid_size * sizeof(dof_id_type));
180 
181  // set up a bidirectional communication socket
182  int sockets[2];
183  if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0)
184  mooseError("Failed to create socketpair for thermochimica IPC.");
185 
186  // fork child process that will manage thermochimica calls
187  _pid = fork();
188  if (_pid < 0)
189  mooseError("Fork failed for thermochimica library.");
190  if (_pid == 0)
191  {
192  // here we are in the child process
193  _socket = sockets[0];
194  // clean exit upon SIGTERM (mainly for Civet code coverage)
195  signal(SIGTERM, ThermochimicaDataBase_handler);
196 
197 #ifdef THERMOCHIMICA_ENABLED
198  // Initialize database in Thermochimica
199  if (isParamValid("thermofile"))
200  {
201  const auto thermo_file = this->template getParam<FileName>("thermofile");
202 
203  if (thermo_file.length() > 1024)
204  this->paramError("thermofile",
205  "Path exceeds Thermochimica's maximal permissible length of 1024 with ",
206  thermo_file.length(),
207  " characters: ",
208  thermo_file);
209 
210  Thermochimica::setThermoFilename(thermo_file);
211 
212  // Read in thermodynamics model, only once
213  Thermochimica::parseThermoFile();
214 
215  const auto idbg = Thermochimica::checkInfoThermo();
216  if (idbg != 0)
217  this->paramError("thermofile", "Thermochimica data file cannot be parsed. ", idbg);
218  }
219 #endif
220 
221  while (true)
222  server();
223  }
224 
225  // parent process continues here
226  _socket = sockets[1];
227 }
OutputMassUnit
Mass unit for output species.
const std::vector< std::pair< std::string, std::string > > & _species_phase_pairs
const std::size_t _n_elements
enum ThermochimicaDataBase::ReinitializationType _reinit
void mooseError(Args &&... args)
typename std::conditional< is_nodal, NodalUserObject, ElementUserObject >::type ThermochimicaDataBaseParent
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
const std::vector< unsigned int > & elementIDs() const
const bool _output_vapor_pressures
T getCheckedPointerParam(const std::string &name, const std::string &error_string="") const
std::vector< MooseWritableVariable * > _el_pot
Writable chemical potential variables for each element.
const std::vector< std::string > & elementPotentials() const
T getEnum() const
const std::vector< std::string > & phases() const
enum ThermochimicaDataBase::OutputMassUnit _output_mass_unit
int _socket
communication socket
const std::vector< std::string > & _ph_names
std::vector< unsigned int > _el_ids
std::vector< MooseWritableVariable * > _vp
Writable vapour pressures for each element.
const std::vector< std::pair< std::string, std::string > > & _phase_element_pairs
const std::vector< std::string > & _element_potentials
const std::vector< std::pair< std::string, std::string > > & speciesPhasePairs() const
const bool _output_element_potentials
Element chemical potential output.
const std::size_t _n_phases
const std::size_t _n_vapor_species
std::vector< const VariableValue * > _el
void ThermochimicaDataBase_handler(int)
const std::size_t _n_potentials
const std::size_t _n_species
void checkLibraryAvailability(MooseObject &self)
Check if thermochimica is available and throw an error if it is not.
const ChemicalCompositionAction & _action
dof_id_type * _shared_dofid_mem
shared memory pointer for dof_id_type values
const std::vector< std::pair< std::string, std::string > > & vaporPhasePairs() const
Real * _shared_real_mem
shared memory pointer for Real values
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< MooseWritableVariable * > _sp
Writable species amount variables.
const VariableValue & _temperature
const VariableValue & _pressure
const std::size_t _n_phase_elements
IntRange< T > make_range(T beg, T end)
std::vector< MooseWritableVariable * > _el_ph
Writable variable for molar amounts of each element in specified phase.
The ChemicalCompositionAction sets up user objects, aux kernels, and aux variables for a thermochemis...
const std::vector< std::pair< std::string, std::string > > & phaseElementPairs() const
const std::vector< std::pair< std::string, std::string > > & _vapor_phase_pairs
std::vector< MooseWritableVariable * > _ph
Writable phase amount variables.
uint8_t dof_id_type

◆ ~ThermochimicaDataBase()

template<bool is_nodal>
ThermochimicaDataBase< is_nodal >::~ThermochimicaDataBase ( )

Definition at line 230 of file ThermochimicaData.C.

231 {
232  if (_pid)
233  kill(_pid, SIGTERM);
234 }

Member Function Documentation

◆ execute()

template<bool is_nodal>
void ThermochimicaDataBase< is_nodal >::execute ( )
overridevirtual

Definition at line 269 of file ThermochimicaData.C.

270 {
271  // either one DOF at a node or (currently) one DOF for constant monomial FV!
272  // This is enforced automatically by the ChemicalComposition action, which creates the correct
273  // variables.
274  const unsigned int qp = 0;
275 
276  // store current dofID
277  if constexpr (is_nodal)
278  _shared_dofid_mem[0] = this->_current_node->id();
279  else
280  _shared_dofid_mem[0] = this->_current_elem->id();
281 
282  // store all required data in shared memory
284  _shared_real_mem[1] = _pressure[qp];
285  for (const auto i : make_range(_n_elements))
286  _shared_real_mem[2 + i] = (*_el[i])[qp];
287 
288  // message child process to trigger calculation
289  notify('A');
290 
291  // and wait for the child process to signal end of calculation
292  expect('B');
293 
294  // unpack data from shared memory
295  std::size_t idx = 0;
296 
297  for (const auto i : make_range(_n_phases))
298  _ph[i]->setDofValue(_shared_real_mem[idx++], qp);
299 
300  for (const auto i : make_range(_n_species))
301  _sp[i]->setDofValue(_shared_real_mem[idx++], qp);
302 
304  for (const auto i : index_range(_element_potentials))
305  _el_pot[i]->setDofValue(_shared_real_mem[idx++], qp);
306 
308  for (const auto i : make_range(_n_vapor_species))
309  _vp[i]->setDofValue(_shared_real_mem[idx++], qp);
310 
312  for (const auto i : make_range(_n_phase_elements))
313  _el_ph[i]->setDofValue(_shared_real_mem[idx++], qp);
314 }
const std::size_t _n_elements
const bool _output_vapor_pressures
std::vector< MooseWritableVariable * > _el_pot
Writable chemical potential variables for each element.
std::vector< MooseWritableVariable * > _vp
Writable vapour pressures for each element.
const std::vector< std::string > & _element_potentials
const bool _output_element_potentials
Element chemical potential output.
const std::size_t _n_phases
const std::size_t _n_vapor_species
std::vector< const VariableValue * > _el
const std::size_t _n_species
dof_id_type * _shared_dofid_mem
shared memory pointer for dof_id_type values
void notify(T send_msg)
Real * _shared_real_mem
shared memory pointer for Real values
std::vector< MooseWritableVariable * > _sp
Writable species amount variables.
const VariableValue & _temperature
const VariableValue & _pressure
const std::size_t _n_phase_elements
IntRange< T > make_range(T beg, T end)
std::vector< MooseWritableVariable * > _el_ph
Writable variable for molar amounts of each element in specified phase.
void expect(T expect_msg)
auto index_range(const T &sizable)
std::vector< MooseWritableVariable * > _ph
Writable phase amount variables.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)

◆ expect()

template<bool is_nodal>
template<typename T >
void ThermochimicaDataBase< is_nodal >::expect ( expect_msg)
protected

Definition at line 245 of file ThermochimicaData.C.

246 {
247  T msg;
248  while (read(_socket, &msg, sizeof(T)) == 0)
249  {
250  if (errno == EAGAIN)
251  continue;
252  mooseError("Read error waiting for '", expect_msg, "' ", errno, ' ', strerror(errno));
253  }
254  if (msg != expect_msg)
255  mooseError("Expected '", expect_msg, "' but received '", msg, "'");
256 }
void mooseError(Args &&... args)
int _socket
communication socket

◆ finalize()

template<bool is_nodal>
virtual void ThermochimicaDataBase< is_nodal >::finalize ( )
inlineoverridevirtual

Definition at line 39 of file ThermochimicaData.h.

39 {}

◆ getData()

template<bool is_nodal>
const ThermochimicaDataBase< is_nodal >::Data & ThermochimicaDataBase< is_nodal >::getData ( dof_id_type  id) const

Definition at line 607 of file ThermochimicaData.C.

608 {
609  const auto it = _data.find(id);
610  if (it == _data.end())
611  {
612  if constexpr (is_nodal)
613  mooseError("Unable to look up data for node ", id);
614  else
615  mooseError("Unable to look up data for element ", id);
616  }
617  return it->second;
618 }
void mooseError(Args &&... args)
std::unordered_map< dof_id_type, Data > _data
Nodal data (Used only for reinitialization)

◆ getElementData()

template<bool is_nodal>
const ThermochimicaDataBase< is_nodal >::Data & ThermochimicaDataBase< is_nodal >::getElementData ( dof_id_type  id) const

Definition at line 598 of file ThermochimicaData.C.

599 {
600  if constexpr (is_nodal)
601  mooseError("Requesting per element data from a nodal object.");
602  return this->getData(element_id);
603 }
void mooseError(Args &&... args)
const Data & getData(dof_id_type id) const

◆ getNodalData()

template<bool is_nodal>
const ThermochimicaDataBase< is_nodal >::Data & ThermochimicaDataBase< is_nodal >::getNodalData ( dof_id_type  id) const

Definition at line 589 of file ThermochimicaData.C.

590 {
591  if constexpr (!is_nodal)
592  mooseError("Requesting nodal data from an element object.");
593  return this->getData(node_id);
594 }
void mooseError(Args &&... args)
const Data & getData(dof_id_type id) const

◆ initialize()

template<bool is_nodal>
void ThermochimicaDataBase< is_nodal >::initialize ( )
overridevirtual

Definition at line 238 of file ThermochimicaData.C.

239 {
240 }

◆ notify()

template<bool is_nodal>
template<typename T >
void ThermochimicaDataBase< is_nodal >::notify ( send_msg)
protected

Definition at line 261 of file ThermochimicaData.C.

262 {
263  if (write(_socket, &send_msg, sizeof(T)) != sizeof(T))
264  mooseError("Failed to notify thermochimica library child process.");
265 }
void mooseError(Args &&... args)
int _socket
communication socket

◆ reinitDataMooseFromTc()

template<bool is_nodal>
void ThermochimicaDataBase< is_nodal >::reinitDataMooseFromTc ( )

Function to get re-initialization data from Thermochimica and save it in member variables of this UserObject.

Definition at line 525 of file ThermochimicaData.C.

526 {
527 #ifdef THERMOCHIMICA_ENABLED
528  auto & d = _data[_current_id];
529 
531  {
532  Thermochimica::saveReinitData();
533  auto data = Thermochimica::getReinitData();
534 
536  {
537  d._assemblage = std::move(data.assemblage);
538  d._moles_phase = std::move(data.molesPhase);
539  d._element_potential = std::move(data.elementPotential);
540  d._chemical_potential = std::move(data.chemicalPotential);
541  d._mol_fraction = std::move(data.moleFraction);
542  d._elements_used = std::move(data.elementsUsed);
543  d._reinit_available = data.reinitAvailable;
544  }
545  }
546 #endif
547 }
enum ThermochimicaDataBase::ReinitializationType _reinit
std::unordered_map< dof_id_type, Data > _data
Nodal data (Used only for reinitialization)

◆ reinitDataMooseToTc()

template<bool is_nodal>
void ThermochimicaDataBase< is_nodal >::reinitDataMooseToTc ( )

Function to load re-initialization data saved in this UserObject back into Thermochimica.

Definition at line 551 of file ThermochimicaData.C.

552 {
553 #ifdef THERMOCHIMICA_ENABLED
554  // Tell Thermochimica whether a re-initialization is requested for this calculation
555  switch (_reinit)
556  {
558  Thermochimica::setReinitRequested(false);
559  break;
560  default:
561  Thermochimica::setReinitRequested(true);
562  }
563  // If we have re-initialization data and want a re-initialization, then
564  // load data into Thermochimica
565  auto it = _data.find(_current_id);
566 
567  if (it != _data.end() &&
568  _reinit == ReinitializationType::TIME) // If doing previous timestep reinit
569  {
570  auto & d = it->second;
571  if (d._reinit_available)
572  {
573  Thermochimica::resetReinit();
574  Thermochimica::ReinitializationData data;
575  data.assemblage = d._assemblage;
576  data.molesPhase = d._moles_phase;
577  data.elementPotential = d._element_potential;
578  data.chemicalPotential = d._chemical_potential;
579  data.moleFraction = d._mol_fraction;
580  data.elementsUsed = d._elements_used;
581  Thermochimica::setReinitData(data);
582  }
583  }
584 #endif
585 }
enum ThermochimicaDataBase::ReinitializationType _reinit
std::unordered_map< dof_id_type, Data > _data
Nodal data (Used only for reinitialization)

◆ server()

template<bool is_nodal>
void ThermochimicaDataBase< is_nodal >::server ( )
protected

Definition at line 318 of file ThermochimicaData.C.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

319 {
320  // wait for message from parent process
321  expect('A');
322 
323 #ifdef THERMOCHIMICA_ENABLED
324  // fetch data from shared memory
326 
327  auto temperature = _shared_real_mem[0];
328  auto pressure = _shared_real_mem[1];
329 
330  // Set temperature and pressure for thermochemistry solver
331  Thermochimica::setTemperaturePressure(temperature, pressure);
332 
333  // Reset all element masses to 0
334  Thermochimica::setElementMass(0, 0.0);
335 
336  // Set element masses
337  for (const auto i : make_range(_n_elements))
338  Thermochimica::setElementMass(_el_ids[i], _shared_real_mem[2 + i]);
339 
340  // Optionally ask for a re-initialization (if reinit_requested == true)
342 
343  // Calculate thermochemical equilibrium
344  Thermochimica::thermochimica();
345 
346  // Check for error status
347  auto idbg = Thermochimica::checkInfoThermo();
348  if (idbg != 0)
349  // error out for now, but we should send a code to the parent process
350  mooseError("Thermochimica error ", idbg);
351 
352  // Save data for future reinits
354 
355  // Get requested phase indices if phase concentration output was requested
356  // i.e. if output_phases is coupled
357  auto moles_phase = Thermochimica::getMolesPhase();
358 
359  std::size_t idx = 0;
360 
361  for (const auto i : make_range(_n_phases))
362  {
363  // Is this maybe constant? No it isn't for now
364  auto [index, idbg] = Thermochimica::getPhaseIndex(_ph_names[i]);
365  if (idbg != 0)
366  mooseError("Failed to get index of phase '", _ph_names[i], "'");
367  // Convert from 1-based (fortran) to 0-based (c++) indexing
368  if (index - 1 < 0)
369  _shared_real_mem[idx] = 0.0;
370  else
371  _shared_real_mem[idx] = moles_phase[index - 1];
372  idx++;
373  }
374 
375  auto db_phases = Thermochimica::getPhaseNamesSystem();
376  auto getSpeciesMoles =
377  [this, moles_phase, db_phases](const std::string phase,
378  const std::string species) -> std::pair<double, int>
379  {
380  Real value = 0.0;
381  int code = 0;
382 
383  auto [index, idbg] = Thermochimica::getPhaseIndex(phase);
384 
385  if (Thermochimica::isPhaseMQM(
386  std::distance(db_phases.begin(), std::find(db_phases.begin(), db_phases.end(), phase))))
387  {
388  auto [fraction, idbg] = Thermochimica::getMqmqaPairMolFraction(phase, species);
389 
390  switch (_output_mass_unit)
391  {
393  {
394  value = fraction;
395  code = idbg;
396  break;
397  }
399  {
400  auto [molesPair, idbgPair] = Thermochimica::getMqmqaMolesPairs(phase);
401  value = molesPair * fraction;
402  code = idbg + idbgPair;
403  break;
404  }
405  default:
406  break;
407  }
408  }
409  else
410  {
411  auto [fraction, idbg] = Thermochimica::getOutputMolSpeciesPhase(phase, species);
412  switch (_output_mass_unit)
413  {
415  {
416  value = fraction;
417  code = idbg;
418  break;
419  }
421  {
422  value = index >= 1 ? moles_phase[index - 1] * fraction : 0.0;
423  code = idbg;
424  break;
425  }
426  default:
427  break;
428  }
429  }
430  return {value, code};
431  };
432 
433  for (const auto i : make_range(_n_species))
434  {
435  auto [fraction, idbg] = getSpeciesMoles(
436  _species_phase_pairs[i].first,
437  _species_phase_pairs[i].second); // can we somehow use IDs instead of strings here?
438 
439  if (idbg == 0)
440  _shared_real_mem[idx] = fraction;
441  else if (idbg == 1)
442  _shared_real_mem[idx] = 0.0;
443 #ifndef NDEBUG
444  else
445  mooseError("Failed to get phase speciation for phase '",
446  _species_phase_pairs[i].first,
447  "' and species '",
448  _species_phase_pairs[i].second,
449  "'. Thermochimica returned ",
450  idbg);
451 #endif
452  idx++;
453  }
454 
456  for (const auto i : index_range(_element_potentials))
457  {
458  auto [potential, idbg] = Thermochimica::getOutputChemPot(_element_potentials[i]);
459  if (idbg == 0)
460  _shared_real_mem[idx] = potential;
461  else if (idbg == 1)
462  // element not present, just leave this at 0 for now
463  _shared_real_mem[idx] = 0.0;
464 #ifndef NDEBUG
465  else if (idbg == -1)
466  mooseError("Failed to get element potential for element '",
468  "'. Thermochimica returned ",
469  idbg);
470 #endif
471  idx++;
472  }
473 
475  for (const auto i : make_range(_n_vapor_species))
476  {
477  auto [fraction, moles, idbg] =
478  Thermochimica::getOutputMolSpecies(_vapor_phase_pairs[i].second);
479  libmesh_ignore(moles);
480 
481  if (idbg == 0)
482  _shared_real_mem[idx] = fraction * pressure;
483  else if (idbg == 1)
484  _shared_real_mem[idx] = 0.0;
485 #ifndef NDEBUG
486  else
487  mooseError("Failed to get vapor pressure for phase '",
488  _vapor_phase_pairs[i].first,
489  "' and species '",
490  _vapor_phase_pairs[i].second,
491  "'. Thermochimica returned ",
492  idbg);
493 #endif
494  idx++;
495  }
496 
498  for (const auto i : make_range(_n_phase_elements))
499  {
500  auto [moles, idbg] = Thermochimica::getElementMolesInPhase(_phase_element_pairs[i].second,
501  _phase_element_pairs[i].first);
502 
503  if (idbg == 0)
504  _shared_real_mem[idx] = moles;
505  else if (idbg == 1)
506  _shared_real_mem[idx] = 0.0;
507 #ifndef NDEBUG
508  else
509  mooseError("Failed to get moles of element '",
510  _phase_element_pairs[i].second,
511  "' in phase '",
512  _phase_element_pairs[i].first,
513  "'. Thermochimica returned ",
514  idbg);
515 #endif
516  idx++;
517  }
518 #endif
519  // Send message back to parent process
520  notify('B');
521 }
const std::vector< std::pair< std::string, std::string > > & _species_phase_pairs
const std::size_t _n_elements
void mooseError(Args &&... args)
void reinitDataMooseFromTc()
Function to get re-initialization data from Thermochimica and save it in member variables of this Use...
const bool _output_vapor_pressures
void reinitDataMooseToTc()
Function to load re-initialization data saved in this UserObject back into Thermochimica.
static const std::string temperature
Definition: NS.h:59
enum ThermochimicaDataBase::OutputMassUnit _output_mass_unit
const std::vector< std::string > & _ph_names
std::vector< unsigned int > _el_ids
const std::vector< std::pair< std::string, std::string > > & _phase_element_pairs
const std::vector< std::string > & _element_potentials
void libmesh_ignore(const Args &...)
const bool _output_element_potentials
Element chemical potential output.
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
const std::size_t _n_phases
const std::size_t _n_vapor_species
const std::size_t _n_species
dof_id_type * _shared_dofid_mem
shared memory pointer for dof_id_type values
void notify(T send_msg)
Real * _shared_real_mem
shared memory pointer for Real values
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::size_t _n_phase_elements
static const std::string pressure
Definition: NS.h:56
IntRange< T > make_range(T beg, T end)
void expect(T expect_msg)
const std::vector< std::pair< std::string, std::string > > & _vapor_phase_pairs
auto index_range(const T &sizable)
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)

◆ threadJoin()

template<bool is_nodal>
virtual void ThermochimicaDataBase< is_nodal >::threadJoin ( const UserObject )
inlineoverridevirtual

Definition at line 40 of file ThermochimicaData.h.

40 {}

◆ validParams()

template<bool is_nodal>
InputParameters ThermochimicaDataBase< is_nodal >::validParams ( )
static

Definition at line 31 of file ThermochimicaData.C.

32 {
34 
35  if constexpr (is_nodal)
37  params, "Provides access to Thermochimica-calculated data at nodes.");
38  else
40  params, "Provides access to Thermochimica-calculated data at elements.");
41 
42  params.addRequiredCoupledVar("elements", "Amounts of elements");
43  params.addRequiredCoupledVar("temperature", "Coupled temperature");
44  params.addCoupledVar("pressure", 1.0, "Pressure");
45 
46  MooseEnum reinit_type("none time nodal", "nodal");
47  params.addParam<MooseEnum>(
48  "reinit_type", reinit_type, "Reinitialization scheme to use with Thermochimica");
49 
50  params.addCoupledVar("output_element_potentials", "Chemical potentials of elements");
51  params.addCoupledVar("output_phases", "Amounts of phases to be output");
52  params.addCoupledVar("output_species", "Amounts of species to be output");
53  params.addCoupledVar("output_vapor_pressures", "Vapour pressures of species to be output");
54  params.addCoupledVar("output_element_phases",
55  "Elements whose molar amounts in specific phases are requested");
56 
57  MooseEnum mUnit_op("mole_fraction moles", "moles");
58  params.addParam<MooseEnum>(
59  "output_species_unit", mUnit_op, "Mass unit for output species: mole_fractions or moles");
60 
61  if constexpr (is_nodal)
62  params.set<bool>("unique_node_execute") = true;
63 
64  params.addPrivateParam<ChemicalCompositionAction *>("_chemical_composition_action");
65  params.addParam<FileName>("thermofile",
66  "Thermodynamic file to be used for Thermochimica calculations");
67  return params;
68 }
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addPrivateParam(const std::string &name, const T &value)
T & set(const std::string &name, bool quiet_mode=false)
InputParameters validParams()
void addCoupledVar(const std::string &name, const std::string &doc_string)
void addRequiredCoupledVar(const std::string &name, const std::string &doc_string)
The ChemicalCompositionAction sets up user objects, aux kernels, and aux variables for a thermochemis...
void addClassDescription(InputParameters &params, const std::string &desc)
Add the supplied class description if thermochimica is available, otherwise add a warning message...

Member Data Documentation

◆ _action

template<bool is_nodal>
const ChemicalCompositionAction& ThermochimicaDataBase< is_nodal >::_action
protected

Definition at line 97 of file ThermochimicaData.h.

◆ _current_id

template<bool is_nodal>
dof_id_type ThermochimicaDataBase< is_nodal >::_current_id
protected

Definition at line 149 of file ThermochimicaData.h.

◆ _data

template<bool is_nodal>
std::unordered_map<dof_id_type, Data> ThermochimicaDataBase< is_nodal >::_data
protected

Nodal data (Used only for reinitialization)

Definition at line 110 of file ThermochimicaData.h.

◆ _el

template<bool is_nodal>
std::vector<const VariableValue *> ThermochimicaDataBase< is_nodal >::_el
protected

◆ _el_ids

template<bool is_nodal>
std::vector<unsigned int> ThermochimicaDataBase< is_nodal >::_el_ids
protected

◆ _el_ph

template<bool is_nodal>
std::vector<MooseWritableVariable *> ThermochimicaDataBase< is_nodal >::_el_ph
protected

Writable variable for molar amounts of each element in specified phase.

Definition at line 131 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _el_pot

template<bool is_nodal>
std::vector<MooseWritableVariable *> ThermochimicaDataBase< is_nodal >::_el_pot
protected

Writable chemical potential variables for each element.

Definition at line 128 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _element_potentials

template<bool is_nodal>
const std::vector<std::string>& ThermochimicaDataBase< is_nodal >::_element_potentials
protected

◆ _n_elements

template<bool is_nodal>
const std::size_t ThermochimicaDataBase< is_nodal >::_n_elements
protected

◆ _n_phase_elements

template<bool is_nodal>
const std::size_t ThermochimicaDataBase< is_nodal >::_n_phase_elements
protected

◆ _n_phases

template<bool is_nodal>
const std::size_t ThermochimicaDataBase< is_nodal >::_n_phases
protected

◆ _n_potentials

template<bool is_nodal>
const std::size_t ThermochimicaDataBase< is_nodal >::_n_potentials
protected

◆ _n_species

template<bool is_nodal>
const std::size_t ThermochimicaDataBase< is_nodal >::_n_species
protected

◆ _n_vapor_species

template<bool is_nodal>
const std::size_t ThermochimicaDataBase< is_nodal >::_n_vapor_species
protected

◆ _output_element_phases

template<bool is_nodal>
const bool ThermochimicaDataBase< is_nodal >::_output_element_phases
protected

Definition at line 115 of file ThermochimicaData.h.

◆ _output_element_potentials

template<bool is_nodal>
const bool ThermochimicaDataBase< is_nodal >::_output_element_potentials
protected

Element chemical potential output.

Definition at line 113 of file ThermochimicaData.h.

◆ _output_mass_unit

template<bool is_nodal>
enum ThermochimicaDataBase::OutputMassUnit ThermochimicaDataBase< is_nodal >::_output_mass_unit
protected

◆ _output_vapor_pressures

template<bool is_nodal>
const bool ThermochimicaDataBase< is_nodal >::_output_vapor_pressures
protected

Definition at line 114 of file ThermochimicaData.h.

◆ _ph

template<bool is_nodal>
std::vector<MooseWritableVariable *> ThermochimicaDataBase< is_nodal >::_ph
protected

Writable phase amount variables.

Definition at line 119 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _ph_names

template<bool is_nodal>
const std::vector<std::string>& ThermochimicaDataBase< is_nodal >::_ph_names
protected

◆ _phase_element_pairs

template<bool is_nodal>
const std::vector<std::pair<std::string, std::string> >& ThermochimicaDataBase< is_nodal >::_phase_element_pairs
protected

◆ _pid

template<bool is_nodal>
pid_t ThermochimicaDataBase< is_nodal >::_pid
protected

child PID

Definition at line 140 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _pressure

template<bool is_nodal>
const VariableValue& ThermochimicaDataBase< is_nodal >::_pressure
protected

Definition at line 85 of file ThermochimicaData.h.

◆ _reinit

template<bool is_nodal>
enum ThermochimicaDataBase::ReinitializationType ThermochimicaDataBase< is_nodal >::_reinit
protected

◆ _shared_dofid_mem

template<bool is_nodal>
dof_id_type* ThermochimicaDataBase< is_nodal >::_shared_dofid_mem
protected

shared memory pointer for dof_id_type values

Definition at line 143 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _shared_real_mem

template<bool is_nodal>
Real* ThermochimicaDataBase< is_nodal >::_shared_real_mem
protected

shared memory pointer for Real values

Definition at line 146 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _socket

template<bool is_nodal>
int ThermochimicaDataBase< is_nodal >::_socket
protected

communication socket

Definition at line 137 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _sp

template<bool is_nodal>
std::vector<MooseWritableVariable *> ThermochimicaDataBase< is_nodal >::_sp
protected

Writable species amount variables.

Definition at line 122 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().

◆ _species_phase_pairs

template<bool is_nodal>
const std::vector<std::pair<std::string, std::string> >& ThermochimicaDataBase< is_nodal >::_species_phase_pairs
protected

◆ _temperature

template<bool is_nodal>
const VariableValue& ThermochimicaDataBase< is_nodal >::_temperature
protected

Definition at line 86 of file ThermochimicaData.h.

◆ _vapor_phase_pairs

template<bool is_nodal>
const std::vector<std::pair<std::string, std::string> >& ThermochimicaDataBase< is_nodal >::_vapor_phase_pairs
protected

◆ _vp

template<bool is_nodal>
std::vector<MooseWritableVariable *> ThermochimicaDataBase< is_nodal >::_vp
protected

Writable vapour pressures for each element.

Definition at line 125 of file ThermochimicaData.h.

Referenced by ThermochimicaDataBase< is_nodal >::ThermochimicaDataBase().


The documentation for this class was generated from the following files: