https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
11
12#include "MaterialProperty.h"
14
15#include <timpi/parallel_sync.h>
16
18
25
30
31void
32RedistributeProperties::operator()(const MeshBase::const_element_iterator &,
33 const MeshBase::const_element_iterator &,
34 processor_id_type,
35 map_type &)
36{
37}
38
39std::unique_ptr<libMesh::GhostingFunctor>
41{
42 return _app.getFactory().copyConstruct(*this);
43}
44
45std::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
53bool
55{
56 const auto * rm = dynamic_cast<const RedistributeProperties *>(&rhs);
57
58 // All RedistributeProperties objects are effectively equivalent
59 return rm;
60}
61
62void
67
68void
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(
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}
void dataLoad(std::istream &stream, LineSegment &l, void *context)
void dataStore(std::ostream &stream, LineSegment &l, void *context)
registerMooseObject("MooseApp", RedistributeProperties)
std::unique_ptr< T > copyConstruct(const T &object)
Copy constructs the object object.
Definition Factory.h:358
HashMap is an abstraction for dictionary data type, we make it thread-safe by locking inserts.
Definition HashMap.h:19
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
Stores the stateful material properties computed by materials.
Factory & getFactory()
Retrieve a writable reference to the Factory associated with this App.
Definition MooseApp.h:407
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition MooseMesh.C:3549
MooseApp & _app
The MOOSE application this is associated with.
Definition MooseBase.h:375
RedistributeProperties is used for its redistribute() callback, which ensures that any stateful prope...
std::vector< MaterialPropertyStorage * > _materials
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()
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't actually add anything to coupled_elements - we solely use the redistribute() ov...
void addMaterialPropertyStorage(MaterialPropertyStorage &mat_props)
Pushes the given pair ( mat_data , mat_props ) onto our list of _materials data to redistribute each ...
virtual void redistribute() override
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.
virtual std::string getInfo() const override
Method for returning relationship manager information (suitable for console output).
RedistributeProperties(const InputParameters &parameters)
RelationshipManagers are used for describing what kinds of non-local resources are needed for an obje...
static InputParameters validParams()
MooseMesh * _moose_mesh
Pointer to the MooseMesh object.
std::map< const Elem *, const CouplingMatrix *, CompareDofObjectsByPIDAndThenID > map_type
MeshBase & mesh