https://mooseframework.inl.gov
RedistributeProperties.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "RedistributeProperties.h"
11 
12 #include "MaterialProperty.h"
14 
15 #include <timpi/parallel_sync.h>
16 
18 
21 {
23  return params;
24 }
25 
27  : RelationshipManager(parameters)
28 {
29 }
30 
31 void
32 RedistributeProperties::operator()(const MeshBase::const_element_iterator &,
33  const MeshBase::const_element_iterator &,
35  map_type &)
36 {
37 }
38 
39 std::unique_ptr<libMesh::GhostingFunctor>
41 {
42  return _app.getFactory().copyConstruct(*this);
43 }
44 
45 std::string
47 {
48  return "RedistributeProperties";
49 }
50 
51 // the LHS ("this" object) in MooseApp::addRelationshipManager is the existing RelationshipManager
52 // object to which we are comparing the rhs to determine whether it should get added
53 bool
55 {
56  const auto * rm = dynamic_cast<const RedistributeProperties *>(&rhs);
57 
58  // All RedistributeProperties objects are effectively equivalent
59  return rm;
60 }
61 
62 void
64 {
65  _materials.emplace_back(&mat_props);
66 }
67 
68 void
70 {
71  const MeshBase & mesh = _moose_mesh->getMesh();
72  const processor_id_type pid = mesh.processor_id();
73 
74  for (auto & mat_prop_store : _materials)
75  {
76  // Once we've redistributed data elsewhere we'll delete it here.
77  //
78  // We don't need stored properties on non-local elements, and so
79  // we don't compute them and we don't *bother deleting them when
80  // non-local elements are coarsened away*, so this may be our last
81  // chance to avoid dangling pointers in future redistribute()
82  // calls.
83  std::set<const Elem *> elems_being_migrated;
84 
85  if (mat_prop_store->hasStatefulProperties())
86  {
87  mooseAssert(
88  !Threads::in_threads,
89  "This routine has not been implemented for threads. Please query this routine before "
90  "a threaded region or contact a MOOSE developer to discuss.");
91 
92  for (const auto state : mat_prop_store->stateIndexRange())
93  {
94  MaterialPropertyStorage::PropsType & props_map = mat_prop_store->setProps(state);
95  typedef std::unordered_map<unsigned int, std::string> stored_props_type;
96  typedef std::tuple<stored_props_type, dof_id_type, int> stored_elem_type;
97  std::map<processor_id_type, std::vector<stored_elem_type>> props_to_push;
98 
99  // Take non-const references here for compatibility with dataStore(T&)
100  for (auto & [elem, elem_props_map] : props_map)
101  {
102  // There better be an element here
103  mooseAssert(elem, "Null element found in material property map?");
104 
105  // It had better be a *real* element here, not a dangling
106  // pointer
107  mooseAssert(elem->id() < mesh.max_elem_id(),
108  "Invalid (dangling? corrupted?) element in material property map?");
109  mooseAssert(elem->processor_id() < mesh.n_processors(),
110  "Invalid (corrupted?) element in material property map?");
111 
112  // If it's not in the particular mesh we're responsible for,
113  // we can skip it. MOOSE mixes non-displaced with displaced
114  // mesh properties in their storages.
115  if (elem != mesh.query_elem_ptr(elem->id()))
116  continue;
117 
118  std::set<processor_id_type> target_pids;
119 
120  if (elem->active())
121  target_pids.insert(elem->processor_id());
122  else if (elem->subactive())
123  {
124  mooseAssert(elem->parent(),
125  "Invalid (corrupted?) subactive element in material property map");
126  mooseAssert(elem->parent()->refinement_flag() == Elem::JUST_COARSENED,
127  "Invalid (subactive child of not-just-coarsened) element in material "
128  "property map");
129  target_pids.insert(elem->parent()->processor_id());
130  }
131  else
132  {
133  mooseAssert(elem->ancestor(),
134  "Unexpected relationship for element in material property map?");
135  mooseAssert(elem->has_children(),
136  "Ancestor element with no children in material property map?");
137  for (const Elem & child : elem->child_ref_range())
138  target_pids.insert(child.processor_id());
139  }
140 
141  // If we're being migrated elsewhere and we're not needed
142  // for AMR/C locally then we should erase the local entry
143  bool remote_pid = false, local_pid = false;
144  for (processor_id_type target_pid : target_pids)
145  if (target_pid == pid)
146  local_pid = true;
147  else
148  {
149  remote_pid = true;
150 
151  stored_props_type stored_props;
152  unsigned int n_q_points = 0;
153  for (auto & [prop_id, prop_vals] : elem_props_map)
154  {
155  mooseAssert(!prop_vals.empty(),
156  "Empty MaterialProperties in stateful properties map?");
157 
158  for (const auto & prop : prop_vals)
159  n_q_points = std::max(n_q_points, prop.size());
160 
161  std::ostringstream oss;
162  dataStore(oss, prop_vals, nullptr);
163  stored_props[prop_id] = oss.str();
164  }
165 
166  // Get the stored data ready to push to the element's new
167  // processor
168  props_to_push[target_pid].emplace_back(
169  std::move(stored_props), elem->id(), n_q_points);
170  }
171 
172  if (remote_pid && !local_pid)
173  elems_being_migrated.insert(elem);
174  }
175 
176  auto recv_functor = [&, mat_prop_store_ptr = mat_prop_store](
177  processor_id_type, const std::vector<stored_elem_type> & data)
178  {
179  for (const auto & [elem_hash, elem_id, n_q_points] : data)
180  {
181  const Elem * elem = mesh.elem_ptr(elem_id);
182  auto & elem_props = props_map[elem];
183 
184  for (const auto & [prop_id, prop_str] : elem_hash)
185  {
186  // This should be called "initPropsIfNecessary"... which
187  // is confusing but convenient.
188  //
189  // We need to *only* initProps for the map we're working
190  // on, otherwise we might see an
191  // initialized-but-not-filled entry in the next map and
192  // foolishly try to send it places.
193  mat_prop_store_ptr->initProps(0, state, elem, prop_id, n_q_points);
194 
195  mooseAssert(elem_props.contains(prop_id),
196  "Trying to load into a nonexistant property id?");
197  MaterialProperties & mat_props = elem_props[prop_id];
198  std::istringstream iss(prop_str);
199  dataLoad(iss, mat_props, nullptr);
200  }
201  }
202  };
203 
204  Parallel::push_parallel_vector_data(mesh.comm(), props_to_push, recv_functor);
205  }
206  }
207 
208  for (const Elem * elem : elems_being_migrated)
209  mat_prop_store->eraseProperty(elem);
210  }
211 }
HashMap is an abstraction for dictionary data type, we make it thread-safe by locking inserts...
Definition: HashMap.h:18
Stores the stateful material properties computed by materials.
MeshBase & mesh
MooseMesh * _moose_mesh
Pointer to the MooseMesh object.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
virtual std::string getInfo() const override
Method for returning relationship manager information (suitable for console output).
void dataLoad(std::istream &stream, PenetrationInfo *&pinfo, void *context)
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
std::unique_ptr< T > copyConstruct(const T &object)
Copy constructs the object object.
Definition: Factory.h:310
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition: MooseApp.h:424
auto max(const L &left, const R &right)
RedistributeProperties(const InputParameters &parameters)
uint8_t processor_id_type
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:3443
std::vector< MaterialPropertyStorage * > _materials
virtual void operator()(const MeshBase::const_element_iterator &range_begin, const MeshBase::const_element_iterator &range_end, processor_id_type p, map_type &coupled_elements) override
This function doesn&#39;t actually add anything to coupled_elements - we solely use the redistribute() ov...
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
registerMooseObject("MooseApp", RedistributeProperties)
virtual void redistribute() override
RelationshipManagers are used for describing what kinds of non-local resources are needed for an obje...
static InputParameters validParams()
void addMaterialPropertyStorage(MaterialPropertyStorage &mat_props)
Pushes the given pair ( mat_data , mat_props ) onto our list of _materials data to redistribute each ...
virtual bool operator>=(const RelationshipManager &rhs) const override
Whether this relationship manager provides more or the same amount and type of ghosting as the rhs...
void dataStore(std::ostream &stream, PenetrationInfo *&pinfo, void *context)
virtual std::unique_ptr< GhostingFunctor > clone() const override
Abstract GhostingFunctor code relies on clone(), which for us is just a copy construction into a new ...
static InputParameters validParams()
RedistributeProperties is used for its redistribute() callback, which ensures that any stateful prope...