17 #include "libmesh/dof_object.h" 19 #include "metaphysicl/parallel_dualnumber.h" 20 #include "metaphysicl/parallel_semidynamicsparsenumberarray.h" 24 #include "libmesh/data_type.h" 25 #include "libmesh/parallel_algebra.h" 30 #include <unordered_map> 42 LIBMESH_DIM * LIBMESH_DIM)
73 const Parallel::Communicator & communicator,
74 const bool send_data_back)
80 using Datum = std::pair<dof_id_type, T>;
81 std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
83 for (
auto & pr : dof_map)
85 const auto *
const dof_object = pr.first;
86 const auto proc_id = dof_object->processor_id();
87 if (proc_id == our_proc_id)
90 push_data[proc_id].push_back(std::make_pair(dof_object->id(), std::move(pr.second)));
93 const auto & lm_mesh =
mesh.getMesh();
94 std::unordered_map<processor_id_type, std::vector<const DofObject *>>
95 pid_to_dof_object_for_sending_back;
98 [nodal, our_proc_id, &lm_mesh, &dof_map, &pid_to_dof_object_for_sending_back, send_data_back](
101 mooseAssert(pid != our_proc_id,
"We do not send messages to ourself here");
104 for (
auto & pr : sent_data)
106 const auto dof_id = pr.first;
107 const auto *
const dof_object =
108 nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
109 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
110 mooseAssert(dof_object,
"This should be non-null");
113 pid_to_dof_object_for_sending_back[pid].push_back(dof_object);
115 dof_map[dof_object][0] += pr.second[0];
116 dof_map[dof_object][1] += pr.second[1];
126 std::unordered_map<processor_id_type, std::vector<Datum>> push_back_data;
128 for (
const auto & [pid, dof_objects] : pid_to_dof_object_for_sending_back)
130 auto & pid_send_data = push_back_data[pid];
131 pid_send_data.reserve(dof_objects.size());
132 for (
const DofObject *
const dof_object : dof_objects)
134 const auto & [tangent_one, tangent_two] = libmesh_map_find(dof_map, dof_object);
135 pid_send_data.push_back({dof_object->id(), {tangent_one, tangent_two}});
139 auto sent_back_action_functor =
140 [nodal, our_proc_id, &lm_mesh, &dof_map](
const processor_id_type libmesh_dbg_var(pid),
141 const std::vector<Datum> & sent_data)
143 mooseAssert(pid != our_proc_id,
"We do not send messages to ourself here");
146 for (
auto & [dof_id, tangents] : sent_data)
148 const auto *
const dof_object =
149 nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
150 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
151 mooseAssert(dof_object,
"This should be non-null");
152 auto & [our_tangent_one, our_tangent_two] = dof_map[dof_object];
153 our_tangent_one = tangents[0];
154 our_tangent_two = tangents[1];
170 communicateR2T(std::unordered_map<const DofObject *, ADRankTwoTensor> & dof_map_adr2t,
173 const Parallel::Communicator & communicator,
174 const bool send_data_back)
180 using Datum = std::pair<dof_id_type, ADRankTwoTensor>;
181 std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
183 for (
auto & pr : dof_map_adr2t)
185 const auto *
const dof_object = pr.first;
186 const auto proc_id = dof_object->processor_id();
187 if (proc_id == our_proc_id)
190 push_data[proc_id].push_back(std::make_pair(dof_object->id(), std::move(pr.second)));
193 const auto & lm_mesh =
mesh.getMesh();
194 std::unordered_map<processor_id_type, std::vector<const DofObject *>>
195 pid_to_dof_object_for_sending_back;
197 auto action_functor =
202 &pid_to_dof_object_for_sending_back,
203 send_data_back](
const processor_id_type pid,
const std::vector<Datum> & sent_data)
205 mooseAssert(pid != our_proc_id,
"We do not send messages to ourself here");
208 for (
auto & pr : sent_data)
210 const auto dof_id = pr.first;
211 const auto *
const dof_object =
212 nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
213 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
214 mooseAssert(dof_object,
"This should be non-null");
217 pid_to_dof_object_for_sending_back[pid].push_back(dof_object);
221 dof_map_adr2t[dof_object](i,
j) += pr.second(i,
j);
231 std::unordered_map<processor_id_type, std::vector<Datum>> push_back_data;
233 for (
const auto & [pid, dof_objects] : pid_to_dof_object_for_sending_back)
235 auto & pid_send_data = push_back_data[pid];
236 pid_send_data.reserve(dof_objects.size());
237 for (
const DofObject *
const dof_object : dof_objects)
239 const auto & r2t = libmesh_map_find(dof_map_adr2t, dof_object);
240 pid_send_data.push_back({dof_object->id(), r2t});
244 auto sent_back_action_functor =
245 [nodal, our_proc_id, &lm_mesh, &dof_map_adr2t](
const processor_id_type libmesh_dbg_var(pid),
246 const std::vector<Datum> & sent_data)
248 mooseAssert(pid != our_proc_id,
"We do not send messages to ourself here");
251 for (
auto & [dof_id, r2t_sent] : sent_data)
253 const auto *
const dof_object =
254 nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
255 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
256 mooseAssert(dof_object,
"This should be non-null");
257 auto & r2t = dof_map_adr2t[dof_object];
265 template <
typename T>
270 const Parallel::Communicator & communicator,
271 const bool send_data_back)
277 using Datum = std::tuple<dof_id_type, T>;
278 std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
280 for (
auto & pr : dof_to_adreal)
282 const auto *
const dof_object = pr.first;
283 const auto proc_id = dof_object->processor_id();
284 if (proc_id == our_proc_id)
287 push_data[proc_id].push_back(std::make_tuple(dof_object->id(), std::move(pr.second)));
290 const auto & lm_mesh =
mesh.getMesh();
291 std::unordered_map<processor_id_type, std::vector<const DofObject *>>
292 pid_to_dof_object_for_sending_back;
294 auto action_functor =
299 &pid_to_dof_object_for_sending_back,
300 send_data_back](
const processor_id_type pid,
const std::vector<Datum> & sent_data)
302 mooseAssert(pid != our_proc_id,
"We do not send messages to ourself here");
305 for (
auto & [dof_id, weighted_gap] : sent_data)
307 const auto *
const dof_object =
308 nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
309 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
310 mooseAssert(dof_object,
"This should be non-null");
312 pid_to_dof_object_for_sending_back[pid].push_back(dof_object);
313 auto & our_adreal = dof_to_adreal[dof_object];
314 our_adreal += weighted_gap;
324 std::unordered_map<processor_id_type, std::vector<Datum>> push_back_data;
326 for (
const auto & [pid, dof_objects] : pid_to_dof_object_for_sending_back)
328 auto & pid_send_data = push_back_data[pid];
329 pid_send_data.reserve(dof_objects.size());
330 for (
const DofObject *
const dof_object : dof_objects)
332 const auto & our_adreal = libmesh_map_find(dof_to_adreal, dof_object);
333 pid_send_data.push_back(std::make_tuple(dof_object->id(), our_adreal));
337 auto sent_back_action_functor =
338 [nodal, our_proc_id, &lm_mesh, &dof_to_adreal](
const processor_id_type libmesh_dbg_var(pid),
339 const std::vector<Datum> & sent_data)
341 mooseAssert(pid != our_proc_id,
"We do not send messages to ourself here");
344 for (
auto & [dof_id, adreal] : sent_data)
346 const auto *
const dof_object =
347 nodal ?
static_cast<const DofObject *
>(lm_mesh.node_ptr(dof_id))
348 : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
349 mooseAssert(dof_object,
"This should be non-null");
350 auto & our_adreal = dof_to_adreal[dof_object];
369 std::unordered_map<
const DofObject *, std::pair<ADReal, Real>> & dof_to_weighted_gap,
373 const Parallel::Communicator & communicator,
374 bool send_data_back);
StandardType(const ADRankTwoTensor *example=nullptr)
DualNumber< Real, DNDerivativeType, true > ADReal
void push_parallel_vector_data(const Communicator &comm, MapToVectors &&data, const ActionFunctor &act_on_data)
uint8_t processor_id_type
void libmesh_ignore(const Args &...)
static const bool is_fixed_type
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator
IntRange< T > make_range(T beg, T end)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")