635 std::vector<std::string> from_prop_ids_to_names;
636 dataLoad(stream, from_prop_ids_to_names,
nullptr);
639 dataLoad(stream, from_stateful_prop_id_to_prop_id,
nullptr);
641 decltype(storage._prop_records) from_prop_records;
642 dataLoad(stream, from_prop_records,
nullptr);
644 decltype(storage.numStates()) num_states;
645 dataLoad(stream, num_states,
nullptr);
649 const auto build_maps = [](
const auto & prop_records,
const auto & ids_to_names)
651 std::map<std::string, std::set<std::string>> object_to_props, prop_to_objects;
653 if (prop_records[i] && prop_records[i]->stateful())
655 const auto & prop = ids_to_names[i];
656 for (
const auto & declarer : (*prop_records[i]).declarers)
658 object_to_props[declarer].insert(prop);
659 prop_to_objects[prop].insert(declarer);
663 return std::make_pair(std::move(object_to_props), std::move(prop_to_objects));
666 const std::vector<std::string> prop_ids_to_names(registry.idsToNamesBegin(),
667 registry.idsToNamesEnd());
668 const auto [object_to_props, prop_to_objects] =
671 const auto [from_object_to_props, from_prop_to_objects] =
672 build_maps(from_prop_records, from_prop_ids_to_names);
675 for (
const auto & [
object, props] : object_to_props)
677 const auto find_from_object = from_object_to_props.find(
object);
683 if (find_from_object != from_object_to_props.end())
685 const auto & from_props = find_from_object->second;
686 if (props != from_props)
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";
707 " was stored in restart but no longer exists. This is not supported when " 708 "recovering stateful material properties.");
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))
723 "The stateful material property '",
725 "' was declared in ",
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.");
732 std::vector<std::optional<unsigned int>> to_stateful_ids(from_stateful_prop_id_to_prop_id.size());
737 for (
auto & record_ptr : to_prop_records)
739 record_ptr->restored =
false;
742 for (
const auto from_stateful_id :
index_range(from_stateful_prop_id_to_prop_id))
744 const auto from_prop_id = from_stateful_prop_id_to_prop_id[from_stateful_id];
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");
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];
754 if (
const auto query_to_prop_id = registry.queryID(name))
756 const auto to_prop_id = *query_to_prop_id;
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];
762 if (to_record.stateful())
764 if (from_record.type != to_record.type)
766 "The type for the restarted stateful material property '", name,
"' does not match");
771 if (from_record.state != to_record.state)
772 mooseError(
"The number of states for the restarted stateful material property '",
774 "' do not match.\n\n",
775 "Checkpointed states: ",
777 "\nCurrent states: ",
781 mooseAssert(to_stateful_id != invalid_uint,
"Not stateful");
783 to_stateful_ids[from_stateful_id] = to_stateful_id;
786 to_record.restored =
true;
790 mooseAssert(from_stateful_id == to_stateful_id,
"Does not have direct mapping");
796 for (
const auto state :
make_range(num_states))
798 std::size_t num_elems;
799 dataLoad(stream, num_elems,
nullptr);
801 for (std::size_t i_elem = 0; i_elem < num_elems; ++i_elem)
805 mooseAssert(elem,
"Null element");
807 std::size_t num_sides;
808 dataLoad(stream, num_sides,
nullptr);
810 for (std::size_t i_side = 0; i_side < num_sides; ++i_side)
815 std::size_t num_props;
816 dataLoad(stream, num_props,
nullptr);
817 mooseAssert(num_props <= to_stateful_ids.size(),
"Missized map");
819 std::size_t num_q_points;
820 dataLoad(stream, num_q_points,
nullptr);
823 MaterialPropertyStorage::RestartableMapType::mapped_type * restart_entry =
nullptr;
827 for (
const auto from_stateful_id :
make_range(num_props))
831 std::stringstream data;
833 data.seekg(0, std::ios::beg);
836 if (
const auto to_stateful_id_ptr = to_stateful_ids[from_stateful_id])
838 const auto to_stateful_id = *to_stateful_id_ptr;
844 in_place_entry = &storage.
setProps(elem, side, state);
846 dataLoad(data, (*in_place_entry)[to_stateful_id],
nullptr);
855 auto & mat_entry = (*restart_entry)[to_stateful_id];
856 if (state >= mat_entry.size())
857 mat_entry.resize(state + 1);
859 mat_entry[state] = std::move(data);
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...
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'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)
void dataLoad(std::istream &stream, MaterialPropertyStorage &storage, void *context)
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.