https://mooseframework.inl.gov
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>

Inheritance diagram for MaterialPropertyStorage:
[legend]

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, FEProblemBase &problem)
 
void prolongStatefulProps (processor_id_type pid, const std::vector< std::vector< QpMap >> &refinement_map, const libMesh::QBase &qrule, const libMesh::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 libMesh::QBase &qrule, const libMesh::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 libMesh::QBase &qrule, const libMesh::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
 
libMesh::IntRange< unsigned intstateIndexRange () const
 
libMesh::IntRange< unsigned intstatefulIndexRange () const
 
const MaterialDatagetMaterialData (const THREAD_ID tid) const
 
MaterialDatagetMaterialData (const THREAD_ID tid)
 
const std::set< const MooseObject * > & getConsumers (Moose::MaterialDataType type) const
 
void addConsumer (Moose::MaterialDataType type, const MooseObject *object)
 Add object as the consumer of storage of type type. More...
 
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

FEProblemBase_problem
 Reference to the problem. More...
 
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...
 
std::map< Moose::MaterialDataType, std::set< const MooseObject * > > _consumers
 The consumers of this storage. 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 43 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 255 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 452 of file MaterialPropertyStorage.h.

Constructor & Destructor Documentation

◆ MaterialPropertyStorage()

MaterialPropertyStorage::MaterialPropertyStorage ( MaterialPropertyRegistry registry,
FEProblemBase problem 
)

Definition at line 23 of file MaterialPropertyStorage.C.

25  : _problem(problem),
26  _max_state(0),
29  _restart_in_place(false),
30  _recovering(false)
31 {
33  for (const auto tid : make_range(libMesh::n_threads()))
34  _material_data.emplace_back(*this, tid);
35 }
unsigned int n_threads()
std::vector< MaterialData > _material_data
The threaded material data.
static Moose::ParameterRegistry & registry
libMesh::Threads::spin_mutex & _spin_mtx
FEProblemBase & _problem
Reference to the problem.
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

◆ addConsumer()

void MaterialPropertyStorage::addConsumer ( Moose::MaterialDataType  type,
const MooseObject object 
)
inline

Add object as the consumer of storage of type type.

Definition at line 342 of file MaterialPropertyStorage.h.

Referenced by FEProblemBase::getMaterialData().

343  {
344  _consumers[type].insert(object);
345  }
std::map< Moose::MaterialDataType, std::set< const MooseObject * > > _consumers
The consumers of this storage.

◆ 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 493 of file MaterialPropertyStorage.C.

Referenced by MaterialData::addPropertyHelper().

497 {
498  if (state > MaterialData::max_state)
499  mooseError("Material property state of ",
500  state,
501  " is not supported. Max state supported: ",
503 
504  // Increment state as needed
505  if (maxState() < state)
506  _max_state = state;
507 
508  // Register the property
509  const auto prop_id = _registry.addOrGetID(prop_name, {});
510 
511  // Instantiate the record if needed
512  if (_prop_records.size() < _registry.size())
513  _prop_records.resize(_registry.size());
514  if (!_prop_records[prop_id])
515  _prop_records[prop_id] = PropRecord();
516 
517  // Fill the record
518  auto & record = *_prop_records[prop_id];
519  record.type = type.name();
520  if (declarer)
521  record.declarers.emplace(declarer->typeAndName());
522  record.state = std::max(state, record.state);
523 
524  // Keep track of stateful props by quick access
525  if (state > 0 && std::find(_stateful_prop_id_to_prop_id.begin(),
527  prop_id) == _stateful_prop_id_to_prop_id.end())
528  {
529  _stateful_prop_id_to_prop_id.push_back(prop_id);
530  record.stateful_id = _stateful_prop_id_to_prop_id.size() - 1;
531  }
532 
533  return prop_id;
534 }
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
Definition: KokkosUtils.h:30
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
Definition: MooseError.h:323
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:57
static constexpr unsigned int max_state
The max time state supported (2 = older)
Definition: MaterialData.h:43
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 436 of file MaterialPropertyStorage.C.

Referenced by MaterialData::copy().

441 {
442  copy(tid, &elem_to, &elem_from, side, n_qpoints);
443 }
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 446 of file MaterialPropertyStorage.C.

451 {
452  auto to_props = initProps(tid, elem_to, side, n_qpoints);
453 
454  for (const auto state : stateIndexRange())
455  {
456  const auto & from_props = props(elem_from, side, state);
457  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
458  for (const auto qp : make_range(n_qpoints))
459  (*to_props[state])[i].qpCopy(qp, from_props[i], qp);
460  }
461 }
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) ...
libMesh::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 76 of file MaterialPropertyStorage.C.

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

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

◆ getConsumers()

const std::set< const MooseObject * > & MaterialPropertyStorage::getConsumers ( Moose::MaterialDataType  type) const
Returns
The consumers of storage of type type

Definition at line 108 of file MaterialPropertyStorage.C.

Referenced by FEProblemBase::getMaterialPropertyStorageConsumers().

109 {
110  static const std::set<const MooseObject *> empty;
111 
112  const auto it = _consumers.find(type);
113 
114  if (it != _consumers.end())
115  return it->second;
116 
117  return empty;
118 }
std::map< Moose::MaterialDataType, std::set< const MooseObject * > > _consumers
The consumers of this storage.

◆ getMaterialData() [1/2]

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

◆ getMaterialData() [2/2]

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

Definition at line 332 of file MaterialPropertyStorage.h.

332 { return _material_data[tid]; }
std::vector< MaterialData > _material_data
The threaded material data.

◆ getMaterialPropertyRegistry()

const MaterialPropertyRegistry& MaterialPropertyStorage::getMaterialPropertyRegistry ( ) const
inline

Definition at line 285 of file MaterialPropertyStorage.h.

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

285 { 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 90 of file MaterialPropertyStorage.C.

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

91 {
92  mooseAssert(_prop_records.size() > id, "Invalid ID");
93  auto & prop_record_ptr = _prop_records[id];
94  mooseAssert(prop_record_ptr, "Not initialized");
95  return *prop_record_ptr;
96 }
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 246 of file MaterialPropertyStorage.h.

246 { return maxState() > 1; }

◆ hasProperty()

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

Definition at line 267 of file MaterialPropertyStorage.h.

Referenced by MaterialData::hasProperty().

267 { 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 497 of file MaterialPropertyStorage.h.

Referenced by initProps(), and swap().

500 {
501  return setProps(state)[elem][side];
502 }
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 537 of file MaterialPropertyStorage.C.

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

541 {
542  std::vector<MaterialProperties *> props(numStates());
543  for (const auto state : stateIndexRange())
544  props[state] = &this->initProps(tid, state, elem, side, n_qpoints);
545  return props;
546 }
libMesh::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 549 of file MaterialPropertyStorage.C.

554 {
555  auto & material_data = _material_data[tid];
556  material_data.resize(n_qpoints);
557 
558  auto & mat_props = initAndSetProps(elem, side, state);
559 
560  // In some special cases, material_data might be larger than n_qpoints
561  if (material_data.isOnlyResizeIfSmaller())
562  n_qpoints = material_data.nQPoints();
563 
564  const auto n_props = _stateful_prop_id_to_prop_id.size();
565  if (mat_props.size() < n_props)
566  mat_props.resize(n_props, {});
567 
568  // init properties (allocate memory. etc)
569  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
570  if (!mat_props.hasValue(i))
571  {
572  const auto prop_id = _stateful_prop_id_to_prop_id[i];
573  mat_props.setPointer(i, material_data.props(0)[prop_id].clone(n_qpoints), {});
574  mooseAssert(mat_props[i].id() == prop_id, "Inconsistent id");
575  }
576 
577  return mat_props;
578 }
std::vector< MaterialData > _material_data
The threaded material data.
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) ...
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 285 of file MaterialPropertyStorage.C.

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

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

◆ isRestoredProperty()

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

Definition at line 99 of file MaterialPropertyStorage.C.

Referenced by dataLoad().

100 {
101  const auto & record = getPropRecord(_registry.getID(name));
102  if (!record.stateful())
103  mooseAssert(!record.restored, "Stateful properties should not be restored");
104  return record.restored;
105 }
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 302 of file MaterialPropertyStorage.h.

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

303  {
304  mooseAssert(_max_state < _storage.size(), "Too big");
305  return _max_state;
306  }
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 310 of file MaterialPropertyStorage.h.

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

310 { return maxState() + 1; }

◆ prolongStatefulProps()

void MaterialPropertyStorage::prolongStatefulProps ( processor_id_type  pid,
const std::vector< std::vector< QpMap >> &  refinement_map,
const libMesh::QBase qrule,
const libMesh::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 166 of file MaterialPropertyStorage.C.

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

177 {
178  mooseAssert(input_child != -1 || input_parent_side == input_child_side, "Invalid inputs!");
179 
180  unsigned int n_qpoints = 0;
181 
182  // If we passed in -1 for these then we really need to store properties at 0
183  unsigned int parent_side = input_parent_side == -1 ? 0 : input_parent_side;
184  unsigned int child_side = input_child_side == -1 ? 0 : input_child_side;
185 
186  if (input_child_side == -1) // Not doing side projection (ie, doing volume projection)
187  n_qpoints = qrule.n_points();
188  else
189  n_qpoints = qrule_face.n_points();
190 
191  _material_data[tid].resize(n_qpoints);
192 
193  unsigned int n_children = elem.n_children();
194 
195  std::vector<unsigned int> children;
196 
197  if (input_child != -1) // Passed in a child explicitly
198  children.push_back(input_child);
199  else
200  {
201  children.resize(n_children);
202  for (unsigned int child = 0; child < n_children; child++)
203  children[child] = child;
204  }
205 
206  for (const auto & child : children)
207  {
208  // If we're not projecting an internal child side, but we are projecting sides, see if this
209  // child is on that side
210  if (input_child == -1 && input_child_side != -1 && !elem.is_child_on_side(child, parent_side))
211  continue;
212 
213  const Elem * child_elem = elem.child_ptr(child);
214 
215  // If it's not a local child then it'll be prolonged where it is
216  // local
217  if (child_elem->processor_id() != pid)
218  continue;
219 
220  mooseAssert(child < refinement_map.size(), "Refinement_map vector not initialized");
221  const std::vector<QpMap> & child_map = refinement_map[child];
222 
223  auto child_props = initProps(tid, child_elem, child_side, n_qpoints);
224 
225  for (const auto state : stateIndexRange())
226  {
227  const auto & parent_props = parent_material_props.props(&elem, parent_side, state);
228  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
229  for (const auto qp : index_range(refinement_map[child]))
230  (*child_props[state])[i].qpCopy(qp, parent_props[i], child_map[qp]._to);
231  }
232  }
233 }
std::vector< MaterialData > _material_data
The threaded material data.
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) ...
libMesh::IntRange< unsigned int > stateIndexRange() const
unsigned int n_points() 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.
auto index_range(const T &sizable)

◆ 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 474 of file MaterialPropertyStorage.h.

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

475 {
476  mooseAssert(state < _storage.size(), "Invalid material property state " + std::to_string(state));
477  return _storage[state];
478 }
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 481 of file MaterialPropertyStorage.h.

482 {
483  const auto find_elem = props(state).find(elem);
484  mooseAssert(find_elem != props(state).end(), "Material property does not have elem entry");
485  const auto find_side = find_elem->second.find(side);
486  mooseAssert(find_side != find_elem->second.end(), "Material property does not have side entry");
487  return find_side->second;
488 }
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 68 of file MaterialPropertyStorage.C.

69 {
70  if (_prop_records.size() > id && _prop_records[id] && _prop_records[id]->stateful())
71  return _registry.getName(id);
72  return {};
73 }
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 libMesh::QBase qrule,
const libMesh::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 236 of file MaterialPropertyStorage.C.

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

244 {
245  unsigned int side;
246 
247  bool doing_a_side = input_side != -1;
248 
249  unsigned int n_qpoints = 0;
250 
251  if (!doing_a_side)
252  {
253  side = 0; // Use 0 for the elem
254  n_qpoints = qrule.n_points();
255  }
256  else
257  {
258  side = input_side;
259  n_qpoints = qrule_face.n_points();
260  }
261 
262  auto parent_props = initProps(tid, &elem, side, n_qpoints);
263 
264  // Copy from the child stateful properties
265  for (const auto qp : index_range(coarsening_map))
266  {
267  const std::pair<unsigned int, QpMap> & qp_pair = coarsening_map[qp];
268  unsigned int child = qp_pair.first;
269 
270  mooseAssert(child < coarsened_element_children.size(),
271  "Coarsened element children vector not initialized");
272  const Elem * child_elem = coarsened_element_children[child];
273  const QpMap & qp_map = qp_pair.second;
274 
275  for (const auto state : stateIndexRange())
276  {
277  const auto & child_props = props(child_elem, side, state);
278  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
279  (*parent_props[state])[i].qpCopy(qp, child_props[i], qp_map._to);
280  }
281  }
282 }
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:73
unsigned int _to
The qp to map to.
Definition: MooseMesh.h:82
libMesh::IntRange< unsigned int > stateIndexRange() const
unsigned int n_points() 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.
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 491 of file MaterialPropertyStorage.h.

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

492 {
493  return const_cast<MaterialProperties &>(std::as_const(*this).props(elem, side, state));
494 }

◆ 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 505 of file MaterialPropertyStorage.h.

506 {
507  return const_cast<MaterialPropertyStorage::PropsType &>(std::as_const(*this).props(state));
508 }
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 353 of file MaterialPropertyStorage.h.

353 { _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 83 of file MaterialPropertyStorage.C.

84 {
85  _restart_in_place = true;
86  _restartable_map.clear();
87 }
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 38 of file MaterialPropertyStorage.C.

Referenced by swap().

41 {
42  for (const auto i : make_range(std::min(stateful_prop_ids.size(), data_from.size())))
43  if (stateful_prop_ids[i] < data.size() && data.hasValue(stateful_prop_ids[i]) &&
44  data_from.hasValue(i))
45  {
46  auto & prop = data[stateful_prop_ids[i]];
47  auto & prop_from = data_from[i];
48  prop.swap(prop_from);
49  }
50 }
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 53 of file MaterialPropertyStorage.C.

Referenced by swapBack().

56 {
57  for (const auto i : make_range(std::min(stateful_prop_ids.size(), data.size())))
58  if (stateful_prop_ids[i] < data_from.size() && data.hasValue(i) &&
59  data_from.hasValue(stateful_prop_ids[i]))
60  {
61  auto & prop = data[i];
62  auto & prop_from = data_from[stateful_prop_ids[i]];
63  prop.swap(prop_from);
64  }
65 }
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 421 of file MaterialPropertyStorage.C.

Referenced by FEProblemBase::advanceState().

422 {
423  mooseAssert(hasStatefulProperties(), "Doesn't have stateful props");
424 
431  for (unsigned int state = maxState(); state != 0; state--)
432  std::swap(setProps(state), setProps(state - 1));
433 }
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()

libMesh::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 323 of file MaterialPropertyStorage.h.

Referenced by initStatefulProps().

324  {
326  }
unsigned int numStates() const

◆ statefulProps()

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

Definition at line 283 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()

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

Definition at line 314 of file MaterialPropertyStorage.h.

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

315  {
317  }
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 464 of file MaterialPropertyStorage.C.

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

465 {
466  Threads::spin_mutex::scoped_lock lock(this->_spin_mtx);
467 
468  for (const auto state : stateIndexRange())
470  _material_data[tid].props(state),
471  // Would be nice to make this setProps()
472  initAndSetProps(&elem, side, state));
473 }
std::vector< MaterialData > _material_data
The threaded material data.
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) ...
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.
libMesh::IntRange< unsigned int > stateIndexRange() const
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.
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 476 of file MaterialPropertyStorage.C.

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

477 {
478  Threads::spin_mutex::scoped_lock lock(this->_spin_mtx);
479 
480  for (const auto state : stateIndexRange())
482  setProps(&elem, side, state),
483  _material_data[tid].props(state));
484 
485  // Workaround for MOOSE difficulties in keeping materialless
486  // elements (e.g. Lower D elements in Mortar code) materials
487  for (const auto state : stateIndexRange())
488  if (props(&elem, side, state).empty())
489  setProps(state)[&elem].erase(side);
490 }
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)
std::vector< MaterialData > _material_data
The threaded material data.
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) ...
libMesh::Threads::spin_mutex & _spin_mtx
static void shallowSwapDataBack(const std::vector< unsigned int > &stateful_prop_ids, MaterialProperties &data, MaterialProperties &data_from)
libMesh::IntRange< unsigned int > stateIndexRange() const
const PropsType & props(const unsigned int state=0) const
Access methods to the stored material property data with the given state state.

◆ updateStatefulPropsForPRefinement()

void MaterialPropertyStorage::updateStatefulPropsForPRefinement ( const processor_id_type  pid,
const std::vector< QpMap > &  p_refinement_map,
const libMesh::QBase qrule,
const libMesh::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 121 of file MaterialPropertyStorage.C.

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

129 {
130  unsigned int n_qpoints = 0;
131 
132  // If we passed in -1 for these then we really need to store properties at 0
133  unsigned int side = input_side == -1 ? 0 : input_side;
134 
135  if (input_side == -1) // Not doing side projection (ie, doing volume projection)
136  n_qpoints = qrule.n_points();
137  else
138  n_qpoints = qrule_face.n_points();
139 
140  _material_data[tid].resize(n_qpoints);
141 
142  mooseAssert(elem.active(), "We should be doing p-refinement on active elements only");
143  mooseAssert(elem.processor_id() == pid, "Prolongation should be occurring locally");
144  mooseAssert(p_refinement_map.size() == n_qpoints, "Refinement map not proper size");
145 
146  auto current_p_level_props = initProps(tid, &elem, side, n_qpoints);
147 
148  for (const auto state : stateIndexRange())
149  for (const auto i : index_range(_stateful_prop_id_to_prop_id))
150  {
151  auto & current_p_level_prop = (*current_p_level_props[state])[i];
152  // We need to clone this property in order to not overwrite the values we're going to be
153  // reading from
154  auto previous_p_level_prop = current_p_level_prop.clone(current_p_level_prop.size());
155  // Cloning, despite its name, does not copy the data. Luckily since we are about to overwrite
156  // all of the current_p_level_prop data, we can just swap its data over to our
157  // previous_p_level_prop
158  previous_p_level_prop->swap(current_p_level_prop);
159  current_p_level_prop.resize(n_qpoints);
160  for (const auto qp : index_range(p_refinement_map))
161  current_p_level_prop.qpCopy(qp, *previous_p_level_prop, p_refinement_map[qp]._to);
162  }
163 }
std::vector< MaterialData > _material_data
The threaded material data.
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) ...
libMesh::IntRange< unsigned int > stateIndexRange() const
unsigned int n_points() 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...
auto index_range(const T &sizable)

Friends And Related Function Documentation

◆ dataLoad

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

Definition at line 644 of file MaterialPropertyStorage.C.

Referenced by initStatefulProps().

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

582 {
583  // Store the material property ID -> name map for mapping back
584  const auto & registry = storage.getMaterialPropertyRegistry();
585  std::vector<std::string> ids_to_names(registry.idsToNamesBegin(), registry.idsToNamesEnd());
586  dataStore(stream, ids_to_names, nullptr);
587 
588  // Store the stateful ID -> property ID map for mapping back
589  dataStore(stream, storage._stateful_prop_id_to_prop_id, nullptr);
590 
591  // Store the prop -> record map
592  dataStore(stream, storage._prop_records, nullptr);
593 
594  // Store the number of states
595  auto num_states = storage.numStates();
596  dataStore(stream, num_states, nullptr);
597 
598  // Store every property
599  for (const auto state : storage.stateIndexRange())
600  {
601  std::size_t num_elems = storage.setProps(state).size();
602  dataStore(stream, num_elems, nullptr);
603 
604  for (auto & elem_side_map_pair : storage.setProps(state))
605  {
606  const Elem * elem = elem_side_map_pair.first;
607  mooseAssert(elem, "Null element");
608  dataStore(stream, elem, context);
609 
610  auto & side_map = elem_side_map_pair.second;
611  std::size_t num_sides = side_map.size();
612  dataStore(stream, num_sides, nullptr);
613 
614  for (auto & [side, props] : side_map)
615  {
616  dataStore(stream, side, nullptr);
617 
618  std::size_t num_props = props.size();
619  dataStore(stream, num_props, nullptr);
620  mooseAssert(num_props > 0, "No properties");
621 
622  std::size_t n_q_points = 0;
623  for (const auto & entry : props)
624  if (entry.size() > n_q_points)
625  n_q_points = entry.size();
626  dataStore(stream, n_q_points, nullptr);
627 
628  // Here we actually store a stringstream of the data instead of the data directly, because
629  // upon load we don't know if we can load it immediately into place or if we need to cache
630  // it to load later. We also store it as skippable so that we can support not loading a
631  // property if it no longer exists in restart
632  for (auto & entry : props)
633  {
634  std::stringstream out;
635  dataStore(out, entry, nullptr);
636  dataStore(stream, out, nullptr);
637  }
638  }
639  }
640  }
641 }
MaterialProperties & setProps(const Elem *elem, unsigned int side, const unsigned int state=0)
friend void dataStore(std::ostream &, MaterialPropertyStorage &, void *)
static Moose::ParameterRegistry & registry
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)
std::size_t size() const
libMesh::IntRange< unsigned int > stateIndexRange() 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 463 of file MaterialPropertyStorage.h.

◆ RedistributeProperties

friend class RedistributeProperties
friend

Definition at line 466 of file MaterialPropertyStorage.h.

Member Data Documentation

◆ _consumers

std::map<Moose::MaterialDataType, std::set<const MooseObject *> > MaterialPropertyStorage::_consumers
protected

The consumers of this storage.

Definition at line 391 of file MaterialPropertyStorage.h.

Referenced by addConsumer(), and getConsumers().

◆ _material_data

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

◆ _max_state

unsigned int MaterialPropertyStorage::_max_state
private

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

Definition at line 437 of file MaterialPropertyStorage.h.

Referenced by addProperty(), and maxState().

◆ _problem

FEProblemBase& MaterialPropertyStorage::_problem
protected

Reference to the problem.

Definition at line 379 of file MaterialPropertyStorage.h.

◆ _prop_records

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

Property records indexed by property id (may be null)

Definition at line 385 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 460 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 445 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 458 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 455 of file MaterialPropertyStorage.h.

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

◆ _spin_mtx

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

Definition at line 442 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 388 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 382 of file MaterialPropertyStorage.h.

Referenced by maxState(), and props().


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