https://mooseframework.inl.gov
Private Member Functions | Friends | List of all members
MaterialProperties::WriteKey Class Reference

#include <MaterialProperty.h>

Private Member Functions

 WriteKey ()
 
 WriteKey (const WriteKey &)
 

Friends

class MaterialData
 
class MaterialPropertyStorage
 
void dataLoad (std::istream &, MaterialPropertyStorage &, void *)
 

Detailed Description

Definition at line 395 of file MaterialProperty.h.

Constructor & Destructor Documentation

◆ WriteKey() [1/2]

MaterialProperties::WriteKey::WriteKey ( )
inlineprivate

Definition at line 401 of file MaterialProperty.h.

401 {}

◆ WriteKey() [2/2]

MaterialProperties::WriteKey::WriteKey ( const WriteKey )
inlineprivate

Definition at line 402 of file MaterialProperty.h.

402 {}

Friends And Related Function Documentation

◆ dataLoad

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

Definition at line 644 of file MaterialPropertyStorage.C.

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.
RestartableMapType _restartable_map
The restartable data to be loaded in initStatefulProps() later.
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.

◆ MaterialData

friend class MaterialData
friend

Definition at line 397 of file MaterialProperty.h.

◆ MaterialPropertyStorage

friend class MaterialPropertyStorage
friend

Definition at line 398 of file MaterialProperty.h.


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