www.mooseframework.org
Classes | Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | Friends | List of all members
MaterialPropertyStorage Class Reference

Stores the stateful material properties computed by materials. More...

#include <MaterialPropertyStorage.h>

Classes

struct  PropRecord
 Basic structure for storing information about a property. More...
 

Public Types

typedef HashMap< const Elem *, HashMap< unsigned int, MaterialProperties > > PropsType
 Accessible type of the stored material property data. More...
 

Public Member Functions

 MaterialPropertyStorage (MaterialPropertyRegistry &registry)
 
void prolongStatefulProps (processor_id_type pid, const std::vector< std::vector< QpMap >> &refinement_map, const QBase &qrule, const QBase &qrule_face, MaterialPropertyStorage &parent_material_props, const THREAD_ID tid, const Elem &elem, const int input_parent_side, const int input_child, const int input_child_side)
 Creates storage for newly created elements from mesh Adaptivity. More...
 
void updateStatefulPropsForPRefinement (const processor_id_type pid, const std::vector< QpMap > &p_refinement_map, const QBase &qrule, const QBase &qrule_face, const THREAD_ID tid, const Elem &elem, const int input_side)
 Based on the p-refinement flag of elem, either prolong (for refinement) or restrict (for coarsening) the stateful material property data. More...
 
void restrictStatefulProps (const std::vector< std::pair< unsigned int, QpMap >> &coarsening_map, const std::vector< const Elem *> &coarsened_element_children, const QBase &qrule, const QBase &qrule_face, const THREAD_ID tid, const Elem &elem, int input_side=-1)
 Creates storage for newly created elements from mesh Adaptivity. More...
 
void initStatefulProps (const THREAD_ID tid, const std::vector< std::shared_ptr< MaterialBase >> &mats, const unsigned int n_qpoints, const Elem &elem, const unsigned int side=0)
 Initialize stateful material properties. More...
 
void shift ()
 Shift the material properties in time. More...
 
void copy (const THREAD_ID tid, const Elem &elem_to, const Elem &elem_from, unsigned int side, unsigned int n_qpoints)
 Copy material properties from elem_from to elem_to. More...
 
void copy (const THREAD_ID tid, const Elem *elem_to, const Elem *elem_from, unsigned int side, unsigned int n_qpoints)
 Copy material properties from elem_from to elem_to. More...
 
void swap (const THREAD_ID tid, const Elem &elem, unsigned int side)
 Swap (shallow copy) material properties in MaterialData and MaterialPropertyStorage Thread safe. More...
 
void swapBack (const THREAD_ID tid, const Elem &elem, unsigned int side)
 Swap (shallow copy) material properties in MaterialPropertyStorage and MaterialDat Thread safe. More...
 
bool hasStatefulProperties () const
 
bool hasOlderProperties () const
 
bool hasProperty (const std::string &prop_name) const
 
unsigned int addProperty (const std::string &prop_name, const std::type_info &type, const unsigned int state, const MaterialBase *const declarer)
 Adds a property with the name prop_name, type type, and state state (0 = current, 1 = old, etc) More...
 
const std::vector< unsigned int > & statefulProps () const
 
const MaterialPropertyRegistrygetMaterialPropertyRegistry () const
 
std::optional< std::string > queryStatefulPropName (const unsigned int id) const
 
void eraseProperty (const Elem *elem)
 Remove the property storage and element pointer from internal data structures Use this when elements are deleted so we don't end up with invalid elem pointers (for e.g. More...
 
unsigned int maxState () const
 
unsigned int numStates () const
 
IntRange< unsigned intstateIndexRange () const
 
IntRange< unsigned intstatefulIndexRange () const
 
MaterialDatagetMaterialData (const THREAD_ID tid)
 
void setRecovering ()
 Sets the loading of stateful material properties to recover. More...
 
void setRestartInPlace ()
 Sets the loading of stateful material properties in place. More...
 
const PropRecordgetPropRecord (const unsigned int id) const
 Get the property record associated with the material with id id. More...
 
bool isRestoredProperty (const std::string &name) const
 
const PropsTypeprops (const unsigned int state=0) const
 Access methods to the stored material property data with the given state state. More...
 
const MaterialPropertiesprops (const Elem *elem, unsigned int side, const unsigned int state=0) const
 
MaterialPropertiessetProps (const Elem *elem, unsigned int side, const unsigned int state=0)
 

Protected Member Functions

void sizeProps (MaterialProperties &mp, unsigned int size)
 

Protected Attributes

std::array< PropsType, MaterialData::max_state+1 > _storage
 The actual storage. More...
 
std::vector< std::optional< PropRecord > > _prop_records
 Property records indexed by property id (may be null) More...
 
std::vector< unsigned int_stateful_prop_id_to_prop_id
 the vector of stateful property ids (the vector index is the map to stateful prop_id) More...
 

Private Types

typedef std::unordered_map< std::pair< const Elem *, unsigned int >, std::map< unsigned int, std::vector< std::stringstream > > > RestartableMapType
 

Private Member Functions

std::vector< MaterialProperties * > initProps (const THREAD_ID tid, const Elem *elem, unsigned int side, unsigned int n_qpoints)
 Initializes hashmap entries for element and side to proper qpoint and property count sizes. More...
 
MaterialPropertiesinitProps (const THREAD_ID tid, const unsigned int state, const Elem *elem, unsigned int side, unsigned int n_qpoints)
 Initializes just one hashmap's entries. More...
 
PropsTypesetProps (const unsigned int state)
 
MaterialPropertiesinitAndSetProps (const Elem *elem, const unsigned int side, const unsigned int state)
 

Static Private Member Functions

static void shallowSwapData (const std::vector< unsigned int > &stateful_prop_ids, MaterialProperties &data, MaterialProperties &data_from)
 Shallow copies of material properties. More...
 
static void shallowSwapDataBack (const std::vector< unsigned int > &stateful_prop_ids, MaterialProperties &data, MaterialProperties &data_from)
 

Private Attributes

unsigned int _max_state
 The maximum state (0 = current, 1 = old, 2 = older) More...
 
libMesh::Threads::spin_mutex_spin_mtx
 
MaterialPropertyRegistry_registry
 Shared registry (across storage objects) for property names and IDs. More...
 
std::vector< MaterialData_material_data
 The threaded material data. More...
 
RestartableMapType _restartable_map
 The restartable data to be loaded in initStatefulProps() later. More...
 
bool _restart_in_place
 Whether or not we want to restart stateful properties in place. More...
 
bool _recovering
 Whether or not we're recovering; enforces a one-to-one mapping of stateful properties. More...
 

Friends

class ProjectMaterialProperties
 
class RedistributeProperties
 
void dataLoad (std::istream &, MaterialPropertyStorage &, void *)
 
void dataStore (std::ostream &, MaterialPropertyStorage &, void *)
 

Detailed Description

Stores the stateful material properties computed by materials.

Thread-safe

Definition at line 42 of file MaterialPropertyStorage.h.

Member Typedef Documentation

◆ PropsType

Accessible type of the stored material property data.

This probably should have been returned as a proxy class; only access it via foo[elem][side] and maybe we'll be able to refactor it in the future without breaking your code.

Definition at line 254 of file MaterialPropertyStorage.h.

◆ RestartableMapType

typedef std::unordered_map<std::pair<const Elem *, unsigned int>, std::map<unsigned int, std::vector<std::stringstream> > > MaterialPropertyStorage::RestartableMapType
private

Definition at line 428 of file MaterialPropertyStorage.h.

Constructor & Destructor Documentation

◆ MaterialPropertyStorage()

MaterialPropertyStorage::MaterialPropertyStorage ( MaterialPropertyRegistry registry)

Definition at line 23 of file MaterialPropertyStorage.C.

24  : _max_state(0),
26  _registry(registry),
27  _restart_in_place(false),
28  _recovering(false)
29 {
31  for (const auto tid : make_range(libMesh::n_threads()))
32  _material_data.emplace_back(*this, tid);
33 }
unsigned int n_threads()
std::vector< MaterialData > _material_data
The threaded material data.
libMesh::Threads::spin_mutex & _spin_mtx
bool _recovering
Whether or not we&#39;re recovering; enforces a one-to-one mapping of stateful properties.
IntRange< T > make_range(T beg, T end)
MaterialPropertyRegistry & _registry
Shared registry (across storage objects) for property names and IDs.
bool _restart_in_place
Whether or not we want to restart stateful properties in place.
unsigned int _max_state
The maximum state (0 = current, 1 = old, 2 = older)
spin_mutex spin_mtx

Member Function Documentation

◆ addProperty()

unsigned int MaterialPropertyStorage::addProperty ( const std::string &  prop_name,
const std::type_info &  type,
const unsigned int  state,
const MaterialBase *const  declarer 
)

Adds a property with the name prop_name, type type, and state state (0 = current, 1 = old, etc)

This is idempotent - calling multiple times with the same name will provide the same id and works fine.

declarer should be specified by the object declaring the property if it is being declared.

Definition at line 478 of file MaterialPropertyStorage.C.

Referenced by MaterialData::addPropertyHelper().

482 {
483  if (state > MaterialData::max_state)
484  mooseError("Material property state of ",
485  state,
486  " is not supported. Max state supported: ",
488 
489  // Increment state as needed
490  if (maxState() < state)
491  _max_state = state;
492 
493  // Register the property
494  const auto prop_id = _registry.addOrGetID(prop_name, {});
495 
496  // Instantiate the record if needed
497  if (_prop_records.size() < _registry.size())
498  _prop_records.resize(_registry.size());
499  if (!_prop_records[prop_id])
500  _prop_records[prop_id] = PropRecord();
501 
502  // Fill the record
503  auto & record = *_prop_records[prop_id];
504  record.type = type.name();
505  if (declarer)
506  record.declarers.emplace(declarer->typeAndName());
507  record.state = std::max(state, record.state);
508 
509  // Keep track of stateful props by quick access
510  if (state > 0 && std::find(_stateful_prop_id_to_prop_id.begin(),
512  prop_id) == _stateful_prop_id_to_prop_id.end())
513  {
514  _stateful_prop_id_to_prop_id.push_back(prop_id);
515  record.stateful_id = _stateful_prop_id_to_prop_id.size() - 1;
516  }
517 
518  return prop_id;
519 }
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
std::vector< std::optional< PropRecord > > _prop_records
Property records indexed by property id (may be null)
auto max(const L &left, const R &right)
unsigned int addOrGetID(const std::string &name, const WriteKey)
std::string typeAndName() const
Get the class&#39;s combined type and name; useful in error handling.
Definition: MooseBase.C:27
static constexpr unsigned int max_state
The max time state supported (2 = older)
Definition: MaterialData.h:39
MaterialPropertyRegistry & _registry
Shared registry (across storage objects) for property names and IDs.
unsigned int _max_state
The maximum state (0 = current, 1 = old, 2 = older)

◆ copy() [1/2]

void MaterialPropertyStorage::copy ( const THREAD_ID  tid,
const Elem &  elem_to,
const Elem &  elem_from,
unsigned int  side,
unsigned int  n_qpoints 
)

Copy material properties from elem_from to elem_to.

Thread safe.

WARNING: This is not capable of copying material data to/from elements on other processors. It only works if both elem_to and elem_from are both on the local processor. We can't currently check to ensure that they're on processor here because this isn't a ParallelObject.

Parameters
tidThe thread ID
elem_toElement to copy data to
elem_fromElement to copy data from
sideSide number (elemental material properties have this equal to zero)
n_qpointsnumber of quadrature points to work with

Definition at line 421 of file MaterialPropertyStorage.C.

Referenced by MaterialData::copy().

426 {
427  copy(tid, &elem_to, &elem_from, side, n_qpoints);
428 }
void copy(const THREAD_ID tid, const Elem &elem_to, const Elem &elem_from, unsigned int side, unsigned int n_qpoints)
Copy material properties from elem_from to elem_to.

◆ copy() [2/2]

void MaterialPropertyStorage::copy ( const THREAD_ID  tid,
const Elem *  elem_to,
const Elem *  elem_from,
unsigned int  side,
unsigned int  n_qpoints 
)

Copy material properties from elem_from to elem_to.

Similar to the other method but using pointers to elements instead of references.

Parameters
tidThe thread ID
elem_toPointer to the element to copy data to
elem_fromPointer to the element to copy data from
sideSide number (elemental material properties have this equal to zero)
n_qpointsnumber of quadrature points to work with

Definition at line 431 of file MaterialPropertyStorage.C.

436 {
437  auto to_props = initProps(tid, elem_to, side, n_qpoints);
438 
439  for (const auto state : stateIndexRange())
440  {
441  const auto & from_props = props(elem_from, side, state);
442  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
443  for (const auto qp : make_range(n_qpoints))
444  (*to_props[state])[i].qpCopy(qp, from_props[i], qp);
445  }
446 }
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
IntRange< unsigned int > stateIndexRange() const
std::vector< MaterialProperties * > initProps(const THREAD_ID tid, const Elem *elem, unsigned int side, unsigned int n_qpoints)
Initializes hashmap entries for element and side to proper qpoint and property count sizes...
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
IntRange< T > make_range(T beg, T end)
auto index_range(const T &sizable)

◆ eraseProperty()

void MaterialPropertyStorage::eraseProperty ( const Elem *  elem)

Remove the property storage and element pointer from internal data structures Use this when elements are deleted so we don't end up with invalid elem pointers (for e.g.

stateful properties) hanging around in our data structures

Definition at line 74 of file MaterialPropertyStorage.C.

Referenced by MaterialData::eraseProperty(), and FEProblemBase::meshChangedHelper().

75 {
76  for (const auto state : stateIndexRange())
77  setProps(state).erase(elem);
78 }
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)
IntRange< unsigned int > stateIndexRange() const

◆ getMaterialData()

MaterialData& MaterialPropertyStorage::getMaterialData ( const THREAD_ID  tid)
inline

◆ getMaterialPropertyRegistry()

const MaterialPropertyRegistry& MaterialPropertyStorage::getMaterialPropertyRegistry ( ) const
inline

Definition at line 284 of file MaterialPropertyStorage.h.

Referenced by dataLoad(), dataStore(), and MaterialData::getPropertyId().

284 { return _registry; }
MaterialPropertyRegistry & _registry
Shared registry (across storage objects) for property names and IDs.

◆ getPropRecord()

const MaterialPropertyStorage::PropRecord & MaterialPropertyStorage::getPropRecord ( const unsigned int  id) const

Get the property record associated with the material with id id.

Definition at line 88 of file MaterialPropertyStorage.C.

Referenced by dataLoad(), MaterialData::getMaxStateRequested(), initStatefulProps(), and isRestoredProperty().

89 {
90  mooseAssert(_prop_records.size() > id, "Invalid ID");
91  auto & prop_record_ptr = _prop_records[id];
92  mooseAssert(prop_record_ptr, "Not initialized");
93  return *prop_record_ptr;
94 }
std::vector< std::optional< PropRecord > > _prop_records
Property records indexed by property id (may be null)

◆ hasOlderProperties()

bool MaterialPropertyStorage::hasOlderProperties ( ) const
inline
Returns
a Boolean indicating whether or not this material has older properties declared

Definition at line 245 of file MaterialPropertyStorage.h.

245 { return maxState() > 1; }

◆ hasProperty()

bool MaterialPropertyStorage::hasProperty ( const std::string &  prop_name) const
inline

Definition at line 266 of file MaterialPropertyStorage.h.

Referenced by MaterialData::hasProperty().

266 { return _registry.hasProperty(prop_name); }
bool hasProperty(const std::string &name) const
MaterialPropertyRegistry & _registry
Shared registry (across storage objects) for property names and IDs.

◆ hasStatefulProperties()

bool MaterialPropertyStorage::hasStatefulProperties ( ) const
inline

◆ initAndSetProps()

MaterialProperties & MaterialPropertyStorage::initAndSetProps ( const Elem *  elem,
const unsigned int  side,
const unsigned int  state 
)
inlineprivate
Returns
A writeable reference to the properties for elem elem, side side, and state state.

Similar to setProps, but will initialize (default construct) the entry if it does not exist.

Definition at line 473 of file MaterialPropertyStorage.h.

Referenced by initProps(), and swap().

476 {
477  return setProps(state)[elem][side];
478 }
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)

◆ initProps() [1/2]

std::vector< MaterialProperties * > MaterialPropertyStorage::initProps ( const THREAD_ID  tid,
const Elem *  elem,
unsigned int  side,
unsigned int  n_qpoints 
)
private

Initializes hashmap entries for element and side to proper qpoint and property count sizes.

Definition at line 522 of file MaterialPropertyStorage.C.

Referenced by copy(), initStatefulProps(), prolongStatefulProps(), restrictStatefulProps(), and updateStatefulPropsForPRefinement().

526 {
527  std::vector<MaterialProperties *> props(numStates());
528  for (const auto state : stateIndexRange())
529  props[state] = &this->initProps(tid, state, elem, side, n_qpoints);
530  return props;
531 }
IntRange< unsigned int > stateIndexRange() const
unsigned int numStates() const
std::vector< MaterialProperties * > initProps(const THREAD_ID tid, const Elem *elem, unsigned int side, unsigned int n_qpoints)
Initializes hashmap entries for element and side to proper qpoint and property count sizes...
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.

◆ initProps() [2/2]

MaterialProperties & MaterialPropertyStorage::initProps ( const THREAD_ID  tid,
const unsigned int  state,
const Elem *  elem,
unsigned int  side,
unsigned int  n_qpoints 
)
private

Initializes just one hashmap's entries.

Definition at line 534 of file MaterialPropertyStorage.C.

539 {
540  auto & material_data = getMaterialData(tid);
541  material_data.resize(n_qpoints);
542 
543  auto & mat_props = initAndSetProps(elem, side, state);
544 
545  // In some special cases, material_data might be larger than n_qpoints
546  if (material_data.isOnlyResizeIfSmaller())
547  n_qpoints = material_data.nQPoints();
548 
549  const auto n_props = _stateful_prop_id_to_prop_id.size();
550  if (mat_props.size() < n_props)
551  mat_props.resize(n_props, {});
552 
553  // init properties (allocate memory. etc)
554  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
555  if (!mat_props.hasValue(i))
556  {
557  const auto prop_id = _stateful_prop_id_to_prop_id[i];
558  mat_props.setPointer(i, material_data.props(0)[prop_id].clone(n_qpoints), {});
559  mooseAssert(mat_props[i].id() == prop_id, "Inconsistent id");
560  }
561 
562  return mat_props;
563 }
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
MaterialData & getMaterialData(const THREAD_ID tid)
auto index_range(const T &sizable)
MaterialProperties & initAndSetProps(const Elem *elem, const unsigned int side, const unsigned int state)

◆ initStatefulProps()

void MaterialPropertyStorage::initStatefulProps ( const THREAD_ID  tid,
const std::vector< std::shared_ptr< MaterialBase >> &  mats,
const unsigned int  n_qpoints,
const Elem &  elem,
const unsigned int  side = 0 
)

Initialize stateful material properties.

Parameters
tidThe thread ID
matsMaterials that will compute the initial values
n_qpointsNumber of quadrature points
elemElement we are on
sideSide of the element 'elem' (0 for volumetric material properties)

If restartable stateful information is available, this will load from restart instead of calling initStatefulProperties()

Definition at line 270 of file MaterialPropertyStorage.C.

Referenced by ComputeMaterialsObjectThread::onBoundary(), ComputeMaterialsObjectThread::onElement(), ComputeMaterialsObjectThread::onInterface(), and ComputeMaterialsObjectThread::onInternalSide().

275 {
276  // Material -> stateful properties that need to be restarted for said material
277  // We need this because we need to initialize everything in dependency the dependency ordering
278  // as given in mats, which means that we can't just do these all up front
279  std::unordered_map<const MaterialBase *,
280  std::vector<std::pair<unsigned int, std::vector<std::stringstream> *>>>
281  materials_to_restart;
282  // Find the entry in the restartable data (binary data waiting to be restarted)
283  // for this [elem, side], if any
284  RestartableMapType::mapped_type * restartable_entry = nullptr;
285  if (_restartable_map.size())
286  if (auto it = _restartable_map.find(std::make_pair(&elem, side)); it != _restartable_map.end())
287  restartable_entry = &it->second;
288 
289  // The stateful objects that we're going to initialize. This is needed for materials that are
290  // passed in as mat that are not stateful, who we don't want to call initStatefulProperties() on.
291  // We unfortunately can only determine this here due to block/boundary restriction, which is
292  // not known without mapping property -> material
293  std::vector<MaterialBase *> stateful_mats;
294  // The stateful IDs that we need to copy back
295  std::vector<unsigned int> stateful_ids_to_copy;
296 
297 #ifndef NDEBUG
298  // All of the stateful IDs; used to make sure that we're not supplying one property
299  // across multiple materials
300  std::set<unsigned int> stateful_ids;
301 #endif
302 
303  // Work through all of the materials that we were passed to figure out which ones are stateful
304  // that we need to initialize, and also to figure out which ones we need to restart
305  for (const auto & mat : mats)
306  {
307  // For keeping track of this material in stateful_mats
308  bool stateful = false;
309 
310  // Check each material that was declared
311  for (const auto id : mat->getSuppliedPropIDs())
312  {
313  const auto & record = getPropRecord(id);
314  if (record.stateful())
315  {
316  const auto stateful_id = record.stateful_id;
317  stateful = true;
318 
319 #ifndef NDEBUG
320  const auto it_inserted_pair = stateful_ids.insert(stateful_id);
321  mooseAssert(it_inserted_pair.second,
322  "Material property '" + _registry.getName(id) +
323  "' supplied by multiple materials at the same point");
324 #endif
325 
326  bool restarting = false;
327  // We have restartable data for this [elem, side]; see if we have it for this prop
328  if (restartable_entry)
329  {
330  if (auto id_datum_pair_it = restartable_entry->find(stateful_id);
331  id_datum_pair_it != restartable_entry->end())
332  {
333  restarting = true;
334  materials_to_restart[mat.get()].emplace_back(stateful_id, &id_datum_pair_it->second);
335  }
336  }
337 
338  if (!restarting)
339  stateful_ids_to_copy.push_back(record.stateful_id);
340  }
341  }
342 
343  if (stateful || mat->forceStatefulInit())
344  stateful_mats.push_back(mat.get());
345  }
346 
347  // This currently initializes all of the stateful properties for this [elem, side],
348  // even though we didn't necessarily need to init all of them. Future work?
349  auto props = initProps(tid, &elem, side, n_qpoints);
350 
351  // Whether or not we have swapped material data from _storage to _material_data
352  // When we're initializing from initStatefulProperties, the MaterialBase objects
353  // need to be able to access the data in _material_data. When we're initalizing
354  // from restart, we need to be able to access from _storage.
355  bool swapped = false;
356 
357  // Initialize properties
358  for (auto mat : stateful_mats)
359  {
360  const auto materials_to_restart_find = materials_to_restart.find(mat);
361  const bool restart = materials_to_restart_find != materials_to_restart.end();
362 
363  if (!restart || mat->forceStatefulInit())
364  {
365  // Need stateful _material_data in the material to store
366  if (!swapped)
367  {
368  swap(tid, elem, side);
369  swapped = true;
370  }
371 
372  mat->initStatefulProperties(n_qpoints);
373  }
374 
375  if (restart)
376  {
377  // Need data in _storage
378  if (swapped)
379  {
380  swapBack(tid, elem, side);
381  swapped = false;
382  }
383 
384  // Load from the cached binary backup into place
385  for (auto & [stateful_id, datum_ptr] : materials_to_restart_find->second)
386  for (const auto state : index_range(*datum_ptr))
387  {
388  (*datum_ptr)[state].seekg(0, std::ios::beg);
389  dataLoad((*datum_ptr)[state], (*props[state])[stateful_id], nullptr);
390  }
391  }
392  }
393 
394  // Done with accessing from _material_data
395  if (swapped)
396  swapBack(tid, elem, side);
397 
398  // Copy to older states as needed, only for non-restarted data
399  for (const auto stateful_id : stateful_ids_to_copy)
400  for (const auto state : statefulIndexRange())
401  for (const auto qp : make_range(n_qpoints))
402  (*props[state])[stateful_id].qpCopy(qp, (*props[0])[stateful_id], qp);
403 }
IntRange< unsigned int > statefulIndexRange() const
void swapBack(const THREAD_ID tid, const Elem &elem, unsigned int side)
Swap (shallow copy) material properties in MaterialPropertyStorage and MaterialDat Thread safe...
std::vector< MaterialProperties * > initProps(const THREAD_ID tid, const Elem *elem, unsigned int side, unsigned int n_qpoints)
Initializes hashmap entries for element and side to proper qpoint and property count sizes...
RestartableMapType _restartable_map
The restartable data to be loaded in initStatefulProps() later.
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
const std::string & getName(const unsigned int id) const
IntRange< T > make_range(T beg, T end)
MaterialPropertyRegistry & _registry
Shared registry (across storage objects) for property names and IDs.
friend void dataLoad(std::istream &, MaterialPropertyStorage &, void *)
void swap(const THREAD_ID tid, const Elem &elem, unsigned int side)
Swap (shallow copy) material properties in MaterialData and MaterialPropertyStorage Thread safe...
const PropRecord & getPropRecord(const unsigned int id) const
Get the property record associated with the material with id id.
MaterialBases compute MaterialProperties.
Definition: MaterialBase.h:60
auto index_range(const T &sizable)

◆ isRestoredProperty()

bool MaterialPropertyStorage::isRestoredProperty ( const std::string &  name) const
Returns
Whether or not the material property with name name was restored

Definition at line 97 of file MaterialPropertyStorage.C.

Referenced by dataLoad().

98 {
99  const auto & record = getPropRecord(_registry.getID(name));
100  if (!record.stateful())
101  mooseAssert(!record.restored, "Stateful properties should not be restored");
102  return record.restored;
103 }
bool restored
Whether or not this property was restored (stateful only)
unsigned int getID(const std::string &name) const
MaterialPropertyRegistry & _registry
Shared registry (across storage objects) for property names and IDs.
const PropRecord & getPropRecord(const unsigned int id) const
Get the property record associated with the material with id id.

◆ maxState()

unsigned int MaterialPropertyStorage::maxState ( ) const
inline
Returns
The current maximum stored state (0 = none, 1 = old, 2 = older)

Definition at line 301 of file MaterialPropertyStorage.h.

Referenced by addProperty(), hasOlderProperties(), hasStatefulProperties(), numStates(), and shift().

302  {
303  mooseAssert(_max_state < _storage.size(), "Too big");
304  return _max_state;
305  }
std::array< PropsType, MaterialData::max_state+1 > _storage
The actual storage.
unsigned int _max_state
The maximum state (0 = current, 1 = old, 2 = older)

◆ numStates()

unsigned int MaterialPropertyStorage::numStates ( ) const
inline
Returns
The number of stored states (2 = up to old, 3 = up to older)

Definition at line 309 of file MaterialPropertyStorage.h.

Referenced by dataLoad(), dataStore(), initProps(), statefulIndexRange(), and stateIndexRange().

309 { return maxState() + 1; }

◆ prolongStatefulProps()

void MaterialPropertyStorage::prolongStatefulProps ( processor_id_type  pid,
const std::vector< std::vector< QpMap >> &  refinement_map,
const QBase &  qrule,
const QBase &  qrule_face,
MaterialPropertyStorage parent_material_props,
const THREAD_ID  tid,
const Elem &  elem,
const int  input_parent_side,
const int  input_child,
const int  input_child_side 
)

Creates storage for newly created elements from mesh Adaptivity.

Also, copies values from the parent qps to the new children.

Note - call this on the MaterialPropertyStorage object for the children that you want to project to. ie, if you are trying to project to the sides of the children, then call this on the boundary MaterialPropertyStorage. Pass in the parent MaterialPropertyStorage you are projecting from. ie the volume one if you are projecting to "internal" child element faces.

There are 3 cases here:

  1. Volume to volume (parent_side = -1, child = -1, child_side = -1) Call on volume MaterialPropertyStorage and pass volume MaterialPropertyStorage for parent_material_props
  2. Parent side to child side (parent_side = 0+, child = -1, child_side = 0+) where parent_side == child_side Call on boundary MaterialPropertyStorage and pass boundary MaterialPropertyStorage for parent_material_props
  3. Child side to parent volume (parent_side = -1, child = 0+, child_side = 0+) Call on boundary MaterialPropertyStorage and pass volume MaterialPropertyStorage for parent_material_props
Parameters
pid- processor id of children to prolong to
refinement_map- 2D array of QpMap objects
qruleThe current quadrature rule
qrule_faceThe current face qrule
parent_material_propsThe place to pull parent material property values from
tidThe thread ID
elemThe parent element that was just refined
input_parent_side- the side of the parent for which material properties are prolonged
input_child- the number of the child
input_child_side- the side on the child where material properties will be prolonged

Definition at line 151 of file MaterialPropertyStorage.C.

Referenced by ProjectMaterialProperties::onBoundary(), ProjectMaterialProperties::onElement(), and ProjectMaterialProperties::onInternalSide().

162 {
163  mooseAssert(input_child != -1 || input_parent_side == input_child_side, "Invalid inputs!");
164 
165  unsigned int n_qpoints = 0;
166 
167  // If we passed in -1 for these then we really need to store properties at 0
168  unsigned int parent_side = input_parent_side == -1 ? 0 : input_parent_side;
169  unsigned int child_side = input_child_side == -1 ? 0 : input_child_side;
170 
171  if (input_child_side == -1) // Not doing side projection (ie, doing volume projection)
172  n_qpoints = qrule.n_points();
173  else
174  n_qpoints = qrule_face.n_points();
175 
176  getMaterialData(tid).resize(n_qpoints);
177 
178  unsigned int n_children = elem.n_children();
179 
180  std::vector<unsigned int> children;
181 
182  if (input_child != -1) // Passed in a child explicitly
183  children.push_back(input_child);
184  else
185  {
186  children.resize(n_children);
187  for (unsigned int child = 0; child < n_children; child++)
188  children[child] = child;
189  }
190 
191  for (const auto & child : children)
192  {
193  // If we're not projecting an internal child side, but we are projecting sides, see if this
194  // child is on that side
195  if (input_child == -1 && input_child_side != -1 && !elem.is_child_on_side(child, parent_side))
196  continue;
197 
198  const Elem * child_elem = elem.child_ptr(child);
199 
200  // If it's not a local child then it'll be prolonged where it is
201  // local
202  if (child_elem->processor_id() != pid)
203  continue;
204 
205  mooseAssert(child < refinement_map.size(), "Refinement_map vector not initialized");
206  const std::vector<QpMap> & child_map = refinement_map[child];
207 
208  auto child_props = initProps(tid, child_elem, child_side, n_qpoints);
209 
210  for (const auto state : stateIndexRange())
211  {
212  const auto & parent_props = parent_material_props.props(&elem, parent_side, state);
213  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
214  for (const auto qp : index_range(refinement_map[child]))
215  (*child_props[state])[i].qpCopy(qp, parent_props[i], child_map[qp]._to);
216  }
217  }
218 }
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
IntRange< unsigned int > stateIndexRange() const
std::vector< MaterialProperties * > initProps(const THREAD_ID tid, const Elem *elem, unsigned int side, unsigned int n_qpoints)
Initializes hashmap entries for element and side to proper qpoint and property count sizes...
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
MaterialData & getMaterialData(const THREAD_ID tid)
auto index_range(const T &sizable)
void resize(unsigned int n_qpoints)
Resize the data to hold properties for n_qpoints quadrature points.
Definition: MaterialData.C:21

◆ props() [1/2]

const MaterialPropertyStorage::PropsType & MaterialPropertyStorage::props ( const unsigned int  state = 0) const
inline

Access methods to the stored material property data with the given state state.

Definition at line 450 of file MaterialPropertyStorage.h.

Referenced by copy(), initProps(), initStatefulProps(), prolongStatefulProps(), props(), restrictStatefulProps(), swap(), and swapBack().

451 {
452  mooseAssert(state < _storage.size(), "Invalid material property state " + std::to_string(state));
453  return _storage[state];
454 }
std::array< PropsType, MaterialData::max_state+1 > _storage
The actual storage.

◆ props() [2/2]

const MaterialProperties & MaterialPropertyStorage::props ( const Elem *  elem,
unsigned int  side,
const unsigned int  state = 0 
) const
inline

Definition at line 457 of file MaterialPropertyStorage.h.

458 {
459  const auto find_elem = props(state).find(elem);
460  mooseAssert(find_elem != props(state).end(), "Material property does not have elem entry");
461  const auto find_side = find_elem->second.find(side);
462  mooseAssert(find_side != find_elem->second.end(), "Material property does not have side entry");
463  return find_side->second;
464 }
iterator find(const Key &k)
Definition: HashMap.h:36
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.

◆ queryStatefulPropName()

std::optional< std::string > MaterialPropertyStorage::queryStatefulPropName ( const unsigned int  id) const
Returns
The name of the stateful property with id id, if any.

Definition at line 66 of file MaterialPropertyStorage.C.

Referenced by FEProblemBase::checkDependMaterialsHelper().

67 {
68  if (_prop_records.size() > id && _prop_records[id] && _prop_records[id]->stateful())
69  return _registry.getName(id);
70  return {};
71 }
std::vector< std::optional< PropRecord > > _prop_records
Property records indexed by property id (may be null)
const std::string & getName(const unsigned int id) const
MaterialPropertyRegistry & _registry
Shared registry (across storage objects) for property names and IDs.

◆ restrictStatefulProps()

void MaterialPropertyStorage::restrictStatefulProps ( const std::vector< std::pair< unsigned int, QpMap >> &  coarsening_map,
const std::vector< const Elem *> &  coarsened_element_children,
const QBase &  qrule,
const QBase &  qrule_face,
const THREAD_ID  tid,
const Elem &  elem,
int  input_side = -1 
)

Creates storage for newly created elements from mesh Adaptivity.

Also, copies values from the children to the parent.

Parameters
coarsening_map- map from unsigned ints to QpMap's
coarsened_element_children- a pointer to a vector of coarsened element children
qruleThe current quadrature rule
qrule_faceThe current face qrule
tidThe thread ID
elemThe parent element that was just refined
input_sideSide of the element 'elem' (0 for volumetric material properties)

Definition at line 221 of file MaterialPropertyStorage.C.

Referenced by ProjectMaterialProperties::onBoundary(), and ProjectMaterialProperties::onElement().

229 {
230  unsigned int side;
231 
232  bool doing_a_side = input_side != -1;
233 
234  unsigned int n_qpoints = 0;
235 
236  if (!doing_a_side)
237  {
238  side = 0; // Use 0 for the elem
239  n_qpoints = qrule.n_points();
240  }
241  else
242  {
243  side = input_side;
244  n_qpoints = qrule_face.n_points();
245  }
246 
247  auto parent_props = initProps(tid, &elem, side, n_qpoints);
248 
249  // Copy from the child stateful properties
250  for (const auto qp : index_range(coarsening_map))
251  {
252  const std::pair<unsigned int, QpMap> & qp_pair = coarsening_map[qp];
253  unsigned int child = qp_pair.first;
254 
255  mooseAssert(child < coarsened_element_children.size(),
256  "Coarsened element children vector not initialized");
257  const Elem * child_elem = coarsened_element_children[child];
258  const QpMap & qp_map = qp_pair.second;
259 
260  for (const auto state : stateIndexRange())
261  {
262  const auto & child_props = props(child_elem, side, state);
263  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
264  (*parent_props[state])[i].qpCopy(qp, child_props[i], qp_map._to);
265  }
266  }
267 }
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
Helper object for holding qp mapping info.
Definition: MooseMesh.h:69
IntRange< unsigned int > stateIndexRange() const
unsigned int _to
The qp to map to.
Definition: MooseMesh.h:78
std::vector< MaterialProperties * > initProps(const THREAD_ID tid, const Elem *elem, unsigned int side, unsigned int n_qpoints)
Initializes hashmap entries for element and side to proper qpoint and property count sizes...
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
auto index_range(const T &sizable)

◆ setProps() [1/2]

MaterialProperties & MaterialPropertyStorage::setProps ( const Elem *  elem,
unsigned int  side,
const unsigned int  state = 0 
)
inline

Definition at line 467 of file MaterialPropertyStorage.h.

Referenced by dataLoad(), dataStore(), eraseProperty(), initAndSetProps(), shift(), and swapBack().

468 {
469  return const_cast<MaterialProperties &>(std::as_const(*this).props(elem, side, state));
470 }

◆ setProps() [2/2]

MaterialPropertyStorage::PropsType & MaterialPropertyStorage::setProps ( const unsigned int  state)
inlineprivate
Returns
A writeable reference to the properties at state state.

Definition at line 481 of file MaterialPropertyStorage.h.

482 {
483  return const_cast<MaterialPropertyStorage::PropsType &>(std::as_const(*this).props(state));
484 }
HashMap is an abstraction for dictionary data type, we make it thread-safe by locking inserts...
Definition: HashMap.h:18

◆ setRecovering()

void MaterialPropertyStorage::setRecovering ( )
inline

Sets the loading of stateful material properties to recover.

This enforces the requirement of one-to-one stateful material properties, disabling advanced restart of stateful properties

Definition at line 335 of file MaterialPropertyStorage.h.

335 { _recovering = true; }
bool _recovering
Whether or not we&#39;re recovering; enforces a one-to-one mapping of stateful properties.

◆ setRestartInPlace()

void MaterialPropertyStorage::setRestartInPlace ( )

Sets the loading of stateful material properties in place.

On init, this cannot be set because we must first call initProps() to properly initialize the dynamic types within _storage. After the first sweep through with initProps(), we can then load the stateful props directly in place into _storage

Also clears _restartable_map, as it should no longer be needed

Definition at line 81 of file MaterialPropertyStorage.C.

82 {
83  _restart_in_place = true;
84  _restartable_map.clear();
85 }
RestartableMapType _restartable_map
The restartable data to be loaded in initStatefulProps() later.
bool _restart_in_place
Whether or not we want to restart stateful properties in place.

◆ shallowSwapData()

void MaterialPropertyStorage::shallowSwapData ( const std::vector< unsigned int > &  stateful_prop_ids,
MaterialProperties data,
MaterialProperties data_from 
)
staticprivate

Shallow copies of material properties.

Definition at line 36 of file MaterialPropertyStorage.C.

Referenced by swap().

39 {
40  for (const auto i : make_range(std::min(stateful_prop_ids.size(), data_from.size())))
41  if (stateful_prop_ids[i] < data.size() && data.hasValue(stateful_prop_ids[i]) &&
42  data_from.hasValue(i))
43  {
44  auto & prop = data[stateful_prop_ids[i]];
45  auto & prop_from = data_from[i];
46  prop.swap(prop_from);
47  }
48 }
std::size_t size() const
IntRange< T > make_range(T beg, T end)
auto min(const L &left, const R &right)
bool hasValue(const std::size_t i) const

◆ shallowSwapDataBack()

void MaterialPropertyStorage::shallowSwapDataBack ( const std::vector< unsigned int > &  stateful_prop_ids,
MaterialProperties data,
MaterialProperties data_from 
)
staticprivate

Definition at line 51 of file MaterialPropertyStorage.C.

Referenced by swapBack().

54 {
55  for (const auto i : make_range(std::min(stateful_prop_ids.size(), data.size())))
56  if (stateful_prop_ids[i] < data_from.size() && data.hasValue(i) &&
57  data_from.hasValue(stateful_prop_ids[i]))
58  {
59  auto & prop = data[i];
60  auto & prop_from = data_from[stateful_prop_ids[i]];
61  prop.swap(prop_from);
62  }
63 }
std::size_t size() const
IntRange< T > make_range(T beg, T end)
auto min(const L &left, const R &right)
bool hasValue(const std::size_t i) const

◆ shift()

void MaterialPropertyStorage::shift ( )

Shift the material properties in time.

Old material properties become older, current material properties become old. Older material properties are reused for computing current properties. This is called when solve succeeded.

Shift properties back in time and reuse older data for current (save reallocations etc.) With current, old, and older this can be accomplished by two swaps: older <-> old old <-> current

Definition at line 406 of file MaterialPropertyStorage.C.

Referenced by FEProblemBase::advanceState().

407 {
408  mooseAssert(hasStatefulProperties(), "Doesn't have stateful props");
409 
416  for (unsigned int state = maxState(); state != 0; state--)
417  std::swap(setProps(state), setProps(state - 1));
418 }
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)
void swap(std::vector< T > &data, const std::size_t idx0, const std::size_t idx1, const libMesh::Parallel::Communicator &comm)
Swap function for serial or distributed vector of data.
Definition: Shuffle.h:494

◆ sizeProps()

void MaterialPropertyStorage::sizeProps ( MaterialProperties mp,
unsigned int  size 
)
protected

◆ statefulIndexRange()

IntRange<unsigned int> MaterialPropertyStorage::statefulIndexRange ( ) const
inline
Returns
A range over stateful states to be used in range-based for loops

Will be an empty range if there are no stateful states

Definition at line 319 of file MaterialPropertyStorage.h.

Referenced by initStatefulProps().

320  {
321  return IntRange<unsigned int>(1, numStates());
322  }
unsigned int numStates() const

◆ statefulProps()

const std::vector<unsigned int>& MaterialPropertyStorage::statefulProps ( ) const
inline

Definition at line 282 of file MaterialPropertyStorage.h.

std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...

◆ stateIndexRange()

IntRange<unsigned int> MaterialPropertyStorage::stateIndexRange ( ) const
inline
Returns
A range over states to be used in range-based for loops

Definition at line 313 of file MaterialPropertyStorage.h.

Referenced by copy(), dataStore(), eraseProperty(), initProps(), prolongStatefulProps(), MaterialData::resize(), restrictStatefulProps(), swap(), swapBack(), and updateStatefulPropsForPRefinement().

313 { return IntRange<unsigned int>(0, numStates()); }
unsigned int numStates() const

◆ swap()

void MaterialPropertyStorage::swap ( const THREAD_ID  tid,
const Elem &  elem,
unsigned int  side 
)

Swap (shallow copy) material properties in MaterialData and MaterialPropertyStorage Thread safe.

Parameters
tidThe thread id
elemElement id
sideSide number (elemental material properties have this equal to zero)

Definition at line 449 of file MaterialPropertyStorage.C.

Referenced by initStatefulProps(), and MaterialData::swap().

450 {
451  Threads::spin_mutex::scoped_lock lock(this->_spin_mtx);
452 
453  for (const auto state : stateIndexRange())
455  getMaterialData(tid).props(state),
456  // Would be nice to make this setProps()
457  initAndSetProps(&elem, side, state));
458 }
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
IntRange< unsigned int > stateIndexRange() const
libMesh::Threads::spin_mutex & _spin_mtx
static void shallowSwapData(const std::vector< unsigned int > &stateful_prop_ids, MaterialProperties &data, MaterialProperties &data_from)
Shallow copies of material properties.
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
MaterialData & getMaterialData(const THREAD_ID tid)
MaterialProperties & initAndSetProps(const Elem *elem, const unsigned int side, const unsigned int state)

◆ swapBack()

void MaterialPropertyStorage::swapBack ( const THREAD_ID  tid,
const Elem &  elem,
unsigned int  side 
)

Swap (shallow copy) material properties in MaterialPropertyStorage and MaterialDat Thread safe.

Parameters
tidThe thread id
elemElement id
sideSide number (elemental material properties have this equal to zero)

Definition at line 461 of file MaterialPropertyStorage.C.

Referenced by initStatefulProps(), and MaterialData::swapBack().

462 {
463  Threads::spin_mutex::scoped_lock lock(this->_spin_mtx);
464 
465  for (const auto state : stateIndexRange())
467  setProps(&elem, side, state),
468  getMaterialData(tid).props(state));
469 
470  // Workaround for MOOSE difficulties in keeping materialless
471  // elements (e.g. Lower D elements in Mortar code) materials
472  for (const auto state : stateIndexRange())
473  if (props(&elem, side, state).empty())
474  setProps(state)[&elem].erase(side);
475 }
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
IntRange< unsigned int > stateIndexRange() const
libMesh::Threads::spin_mutex & _spin_mtx
static void shallowSwapDataBack(const std::vector< unsigned int > &stateful_prop_ids, MaterialProperties &data, MaterialProperties &data_from)
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
MaterialData & getMaterialData(const THREAD_ID tid)

◆ updateStatefulPropsForPRefinement()

void MaterialPropertyStorage::updateStatefulPropsForPRefinement ( const processor_id_type  pid,
const std::vector< QpMap > &  p_refinement_map,
const QBase &  qrule,
const QBase &  qrule_face,
const THREAD_ID  tid,
const Elem &  elem,
const int  input_side 
)

Based on the p-refinement flag of elem, either prolong (for refinement) or restrict (for coarsening) the stateful material property data.

Parameters
pidThe rank returned by the mesh. This is used to assert that we are only prolonging/restricting for elements that our process owns
p_refinement_mapA map that describes, for each quadrature point on the current level which quadrature point on the previous level it is closest to
qruleThe volumetric quadrature rule
qrule_faceThe face quadrature rule
tidThe thread ID
elemThe element that was just p-refined or coarsened that we are performing material property prolongation/restriction for
input_sideWhich element side we are performing material property prolongation/restriction for. Pass in -1 for doing volumetric prolongation/restriction

Definition at line 106 of file MaterialPropertyStorage.C.

Referenced by ProjectMaterialProperties::onBoundary(), and ProjectMaterialProperties::onElement().

114 {
115  unsigned int n_qpoints = 0;
116 
117  // If we passed in -1 for these then we really need to store properties at 0
118  unsigned int side = input_side == -1 ? 0 : input_side;
119 
120  if (input_side == -1) // Not doing side projection (ie, doing volume projection)
121  n_qpoints = qrule.n_points();
122  else
123  n_qpoints = qrule_face.n_points();
124 
125  getMaterialData(tid).resize(n_qpoints);
126 
127  mooseAssert(elem.active(), "We should be doing p-refinement on active elements only");
128  mooseAssert(elem.processor_id() == pid, "Prolongation should be occurring locally");
129  mooseAssert(p_refinement_map.size() == n_qpoints, "Refinement map not proper size");
130 
131  auto current_p_level_props = initProps(tid, &elem, side, n_qpoints);
132 
133  for (const auto state : stateIndexRange())
134  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
135  {
136  auto & current_p_level_prop = (*current_p_level_props[state])[i];
137  // We need to clone this property in order to not overwrite the values we're going to be
138  // reading from
139  auto previous_p_level_prop = current_p_level_prop.clone(current_p_level_prop.size());
140  // Cloning, despite its name, does not copy the data. Luckily since we are about to overwrite
141  // all of the current_p_level_prop data, we can just swap its data over to our
142  // previous_p_level_prop
143  previous_p_level_prop->swap(current_p_level_prop);
144  current_p_level_prop.resize(n_qpoints);
145  for (const auto qp : index_range(p_refinement_map))
146  current_p_level_prop.qpCopy(qp, *previous_p_level_prop, p_refinement_map[qp]._to);
147  }
148 }
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
IntRange< unsigned int > stateIndexRange() const
std::vector< MaterialProperties * > initProps(const THREAD_ID tid, const Elem *elem, unsigned int side, unsigned int n_qpoints)
Initializes hashmap entries for element and side to proper qpoint and property count sizes...
MaterialData & getMaterialData(const THREAD_ID tid)
auto index_range(const T &sizable)
void resize(unsigned int n_qpoints)
Resize the data to hold properties for n_qpoints quadrature points.
Definition: MaterialData.C:21

Friends And Related Function Documentation

◆ dataLoad

void dataLoad ( std::istream &  stream,
MaterialPropertyStorage storage,
void context 
)
friend

Definition at line 629 of file MaterialPropertyStorage.C.

Referenced by initStatefulProps().

630 {
631  storage._restartable_map.clear();
632 
633  const auto & registry = storage.getMaterialPropertyRegistry();
634 
635  std::vector<std::string> from_prop_ids_to_names;
636  dataLoad(stream, from_prop_ids_to_names, nullptr);
637 
638  decltype(storage._stateful_prop_id_to_prop_id) from_stateful_prop_id_to_prop_id;
639  dataLoad(stream, from_stateful_prop_id_to_prop_id, nullptr);
640 
641  decltype(storage._prop_records) from_prop_records;
642  dataLoad(stream, from_prop_records, nullptr);
643 
644  decltype(storage.numStates()) num_states;
645  dataLoad(stream, num_states, nullptr);
646 
647  {
648  // Build maps of material object -> properties and property -> material objects
649  const auto build_maps = [](const auto & prop_records, const auto & ids_to_names)
650  {
651  std::map<std::string, std::set<std::string>> object_to_props, prop_to_objects;
652  for (const auto i : index_range(prop_records))
653  if (prop_records[i] && prop_records[i]->stateful())
654  {
655  const auto & prop = ids_to_names[i];
656  for (const auto & declarer : (*prop_records[i]).declarers)
657  {
658  object_to_props[declarer].insert(prop);
659  prop_to_objects[prop].insert(declarer);
660  }
661  }
662 
663  return std::make_pair(std::move(object_to_props), std::move(prop_to_objects));
664  };
665  // Maps for the current stateful properties
666  const std::vector<std::string> prop_ids_to_names(registry.idsToNamesBegin(),
667  registry.idsToNamesEnd());
668  const auto [object_to_props, prop_to_objects] =
669  build_maps(storage._prop_records, prop_ids_to_names);
670  // Maps for the stored stateful properties
671  const auto [from_object_to_props, from_prop_to_objects] =
672  build_maps(from_prop_records, from_prop_ids_to_names);
673 
674  // Enforce our stateful requirements
675  for (const auto & [object, props] : object_to_props)
676  {
677  const auto find_from_object = from_object_to_props.find(object);
678 
679  // We have a material object that was stored with the same name that
680  // had stateful material properties. Here, we enforce that the stateful
681  // properties stored match exactly the ones that we have declared in
682  // the new run
683  if (find_from_object != from_object_to_props.end())
684  {
685  const auto & from_props = find_from_object->second;
686  if (props != from_props)
687  {
688  std::stringstream error;
689  error << "The stateful material properties in " << object
690  << " that are being restarted do not match the stored properties in the same "
691  "material object from the checkpoint.\n\n";
692  error << "Checkpointed stateful properties:\n";
693  for (const auto & prop : from_props)
694  error << " - " << prop << "\n";
695  error << "\nCurrent stateful properties:\n";
696  for (const auto & prop : props)
697  error << " - " << prop << "\n";
698  mooseError(error.str());
699  }
700  }
701  // We're recovering and we haven't found a stateful material object. We require a
702  // one-to-one stateful mapping when recovering
703  else if (storage._recovering)
704  {
705  mooseError("The ",
706  object,
707  " was stored in restart but no longer exists. This is not supported when "
708  "recovering stateful material properties.");
709  }
710  }
711 
712  // We can easily support this, but have chosen not to due to ambiguity and we
713  // don't yet know how to express this ambiguity. Just removing this error
714  // _should_ make it work without issue because to_stateful_ids below for this
715  // property will be an empty optional, which means simply don't load it. Or,
716  // we could load it into the new property.
717  for (const auto & [from_prop, from_objects] : from_prop_to_objects)
718  if (const auto find_objects = prop_to_objects.find(from_prop);
719  find_objects != prop_to_objects.end())
720  for (const auto & object : find_objects->second)
721  if (!from_objects.count(object))
722  mooseError(
723  "The stateful material property '",
724  from_prop,
725  "' was declared in ",
726  object,
727  " but was not declared in that object on checkpoint.\n\nThis is not currently "
728  "supported due to ambiguity.\n\nPlease contact the development team on "
729  "GitHub if you desire this capability.");
730  }
731 
732  std::vector<std::optional<unsigned int>> to_stateful_ids(from_stateful_prop_id_to_prop_id.size());
733 
734  auto & to_prop_records = storage._prop_records;
735 
736  // Mark everything as not restored in the event that we call this again
737  for (auto & record_ptr : to_prop_records)
738  if (record_ptr)
739  record_ptr->restored = false;
740 
741  // Fill the mapping from previous ID to current stateful ID
742  for (const auto from_stateful_id : index_range(from_stateful_prop_id_to_prop_id))
743  {
744  const auto from_prop_id = from_stateful_prop_id_to_prop_id[from_stateful_id];
745 
746  mooseAssert(from_prop_id < from_prop_records.size(), "Invalid record map");
747  mooseAssert(from_prop_records[from_prop_id], "Not set");
748  const auto & from_record = *from_prop_records[from_prop_id];
749  mooseAssert(from_record.stateful(), "Not stateful");
750 
751  mooseAssert(from_prop_id < from_prop_ids_to_names.size(), "Invalid ID map");
752  const auto & name = from_prop_ids_to_names[from_prop_id];
753 
754  if (const auto query_to_prop_id = registry.queryID(name))
755  {
756  const auto to_prop_id = *query_to_prop_id;
757 
758  mooseAssert(to_prop_id < to_prop_records.size(), "Invalid record map");
759  mooseAssert(to_prop_records[to_prop_id], "Not set");
760  auto & to_record = *to_prop_records[to_prop_id];
761 
762  if (to_record.stateful())
763  {
764  if (from_record.type != to_record.type)
765  mooseError(
766  "The type for the restarted stateful material property '", name, "' does not match");
767 
768  // I'm not sure if we need to enforce this one, but I don't want to think
769  // about it deeply so we'll just make it an error until someone complains
770  // we have time to think
771  if (from_record.state != to_record.state)
772  mooseError("The number of states for the restarted stateful material property '",
773  name,
774  "' do not match.\n\n",
775  "Checkpointed states: ",
776  from_record.state,
777  "\nCurrent states: ",
778  to_record.state);
779 
780  const auto to_stateful_id = storage.getPropRecord(to_prop_id).stateful_id;
781  mooseAssert(to_stateful_id != invalid_uint, "Not stateful");
782 
783  to_stateful_ids[from_stateful_id] = to_stateful_id;
784 
785  // Mark that we're going to restore this property
786  to_record.restored = true;
787  mooseAssert(storage.isRestoredProperty(name), "Restored mismatch");
788 
789  if (storage._recovering)
790  mooseAssert(from_stateful_id == to_stateful_id, "Does not have direct mapping");
791  }
792  }
793  }
794 
795  // Load the properties
796  for (const auto state : make_range(num_states))
797  {
798  std::size_t num_elems;
799  dataLoad(stream, num_elems, nullptr);
800 
801  for (std::size_t i_elem = 0; i_elem < num_elems; ++i_elem)
802  {
803  const Elem * elem;
804  dataLoad(stream, elem, context);
805  mooseAssert(elem, "Null element");
806 
807  std::size_t num_sides;
808  dataLoad(stream, num_sides, nullptr);
809 
810  for (std::size_t i_side = 0; i_side < num_sides; ++i_side)
811  {
812  unsigned int side;
813  dataLoad(stream, side, nullptr);
814 
815  std::size_t num_props;
816  dataLoad(stream, num_props, nullptr);
817  mooseAssert(num_props <= to_stateful_ids.size(), "Missized map");
818 
819  std::size_t num_q_points;
820  dataLoad(stream, num_q_points, nullptr);
821 
822  // Avoid multiple map lookups for entries pertaining to [elem, side]
823  MaterialPropertyStorage::RestartableMapType::mapped_type * restart_entry = nullptr;
824  MaterialProperties * in_place_entry = nullptr;
825 
826  // Load each stateful property
827  for (const auto from_stateful_id : make_range(num_props))
828  {
829  // Load the binary data, which lets us choose in a moment whether
830  // or not to load it in place or to cache it to load later
831  std::stringstream data;
832  dataLoad(stream, data, nullptr);
833  data.seekg(0, std::ios::beg);
834 
835  // We have a property to load into
836  if (const auto to_stateful_id_ptr = to_stateful_ids[from_stateful_id])
837  {
838  const auto to_stateful_id = *to_stateful_id_ptr;
839 
840  // Load the data directly into _storage
841  if (storage._restart_in_place)
842  {
843  if (!in_place_entry)
844  in_place_entry = &storage.setProps(elem, side, state);
845 
846  dataLoad(data, (*in_place_entry)[to_stateful_id], nullptr);
847  }
848  // Properties aren't initialized, so load the data into
849  // _restartable_map to be loaded later in initStatefulProps()
850  else
851  {
852  if (!restart_entry)
853  restart_entry = &storage._restartable_map[std::make_pair(elem, side)];
854 
855  auto & mat_entry = (*restart_entry)[to_stateful_id];
856  if (state >= mat_entry.size())
857  mat_entry.resize(state + 1);
858 
859  mat_entry[state] = std::move(data);
860  }
861  }
862  }
863  }
864  }
865  }
866 }
std::string name(const ElemQuality q)
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:299
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
const MaterialPropertyRegistry & getMaterialPropertyRegistry() const
std::vector< std::optional< PropRecord > > _prop_records
Property records indexed by property id (may be null)
bool isRestoredProperty(const std::string &name) const
bool _recovering
Whether or not we&#39;re recovering; enforces a one-to-one mapping of stateful properties.
unsigned int numStates() const
RestartableMapType _restartable_map
The restartable data to be loaded in initStatefulProps() later.
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
IntRange< T > make_range(T beg, T end)
friend void dataLoad(std::istream &, MaterialPropertyStorage &, void *)
bool _restart_in_place
Whether or not we want to restart stateful properties in place.
const PropRecord & getPropRecord(const unsigned int id) const
Get the property record associated with the material with id id.
auto index_range(const T &sizable)
unsigned int stateful_id
The stateful id in _storage used for this property, if any.

◆ dataStore

void dataStore ( std::ostream &  stream,
MaterialPropertyStorage storage,
void context 
)
friend

Definition at line 566 of file MaterialPropertyStorage.C.

567 {
568  // Store the material property ID -> name map for mapping back
569  const auto & registry = storage.getMaterialPropertyRegistry();
570  std::vector<std::string> ids_to_names(registry.idsToNamesBegin(), registry.idsToNamesEnd());
571  dataStore(stream, ids_to_names, nullptr);
572 
573  // Store the stateful ID -> property ID map for mapping back
574  dataStore(stream, storage._stateful_prop_id_to_prop_id, nullptr);
575 
576  // Store the prop -> record map
577  dataStore(stream, storage._prop_records, nullptr);
578 
579  // Store the number of states
580  auto num_states = storage.numStates();
581  dataStore(stream, num_states, nullptr);
582 
583  // Store every property
584  for (const auto state : storage.stateIndexRange())
585  {
586  std::size_t num_elems = storage.setProps(state).size();
587  dataStore(stream, num_elems, nullptr);
588 
589  for (auto & elem_side_map_pair : storage.setProps(state))
590  {
591  const Elem * elem = elem_side_map_pair.first;
592  mooseAssert(elem, "Null element");
593  dataStore(stream, elem, context);
594 
595  auto & side_map = elem_side_map_pair.second;
596  std::size_t num_sides = side_map.size();
597  dataStore(stream, num_sides, nullptr);
598 
599  for (auto & [side, props] : side_map)
600  {
601  dataStore(stream, side, nullptr);
602 
603  std::size_t num_props = props.size();
604  dataStore(stream, num_props, nullptr);
605  mooseAssert(num_props > 0, "No properties");
606 
607  std::size_t n_q_points = 0;
608  for (const auto & entry : props)
609  if (entry.size() > n_q_points)
610  n_q_points = entry.size();
611  dataStore(stream, n_q_points, nullptr);
612 
613  // Here we actually store a stringstream of the data instead of the data directly, because
614  // upon load we don't know if we can load it immediately into place or if we need to cache
615  // it to load later. We also store it as skippable so that we can support not loading a
616  // property if it no longer exists in restart
617  for (auto & entry : props)
618  {
619  std::stringstream out;
620  dataStore(out, entry, nullptr);
621  dataStore(stream, out, nullptr);
622  }
623  }
624  }
625  }
626 }
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)
friend void dataStore(std::ostream &, MaterialPropertyStorage &, void *)
std::vector< unsigned int > _stateful_prop_id_to_prop_id
the vector of stateful property ids (the vector index is the map to stateful prop_id) ...
const MaterialPropertyRegistry & getMaterialPropertyRegistry() const
IntRange< unsigned int > stateIndexRange() const
std::vector< std::optional< PropRecord > > _prop_records
Property records indexed by property id (may be null)
std::size_t size() const
unsigned int numStates() const
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
OStreamProxy out

◆ ProjectMaterialProperties

friend class ProjectMaterialProperties
friend

Definition at line 439 of file MaterialPropertyStorage.h.

◆ RedistributeProperties

friend class RedistributeProperties
friend

Definition at line 442 of file MaterialPropertyStorage.h.

Member Data Documentation

◆ _material_data

std::vector<MaterialData> MaterialPropertyStorage::_material_data
private

The threaded material data.

Definition at line 424 of file MaterialPropertyStorage.h.

Referenced by getMaterialData(), and MaterialPropertyStorage().

◆ _max_state

unsigned int MaterialPropertyStorage::_max_state
private

The maximum state (0 = current, 1 = old, 2 = older)

Definition at line 413 of file MaterialPropertyStorage.h.

Referenced by addProperty(), and maxState().

◆ _prop_records

std::vector<std::optional<PropRecord> > MaterialPropertyStorage::_prop_records
protected

Property records indexed by property id (may be null)

Definition at line 364 of file MaterialPropertyStorage.h.

Referenced by addProperty(), dataLoad(), dataStore(), getPropRecord(), and queryStatefulPropName().

◆ _recovering

bool MaterialPropertyStorage::_recovering
private

Whether or not we're recovering; enforces a one-to-one mapping of stateful properties.

Definition at line 436 of file MaterialPropertyStorage.h.

Referenced by dataLoad(), and setRecovering().

◆ _registry

MaterialPropertyRegistry& MaterialPropertyStorage::_registry
private

Shared registry (across storage objects) for property names and IDs.

Definition at line 421 of file MaterialPropertyStorage.h.

Referenced by addProperty(), getMaterialPropertyRegistry(), hasProperty(), initStatefulProps(), isRestoredProperty(), and queryStatefulPropName().

◆ _restart_in_place

bool MaterialPropertyStorage::_restart_in_place
private

Whether or not we want to restart stateful properties in place.

Definition at line 434 of file MaterialPropertyStorage.h.

Referenced by dataLoad(), and setRestartInPlace().

◆ _restartable_map

RestartableMapType MaterialPropertyStorage::_restartable_map
private

The restartable data to be loaded in initStatefulProps() later.

Definition at line 431 of file MaterialPropertyStorage.h.

Referenced by dataLoad(), initStatefulProps(), and setRestartInPlace().

◆ _spin_mtx

libMesh::Threads::spin_mutex& MaterialPropertyStorage::_spin_mtx
private

Definition at line 418 of file MaterialPropertyStorage.h.

Referenced by swap(), and swapBack().

◆ _stateful_prop_id_to_prop_id

std::vector<unsigned int> MaterialPropertyStorage::_stateful_prop_id_to_prop_id
protected

the vector of stateful property ids (the vector index is the map to stateful prop_id)

Definition at line 367 of file MaterialPropertyStorage.h.

Referenced by addProperty(), copy(), dataLoad(), dataStore(), initProps(), prolongStatefulProps(), restrictStatefulProps(), statefulProps(), swap(), swapBack(), and updateStatefulPropsForPRefinement().

◆ _storage

std::array<PropsType, MaterialData::max_state + 1> MaterialPropertyStorage::_storage
protected

The actual storage.

Definition at line 361 of file MaterialPropertyStorage.h.

Referenced by maxState(), and props().


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