https://mooseframework.inl.gov
MortarContactUtils.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 "MortarContactUtils.h"
11 
12 #include <tuple>
13 
14 namespace Moose
15 {
16 namespace Mortar
17 {
18 namespace Contact
19 {
20 void
22  std::unordered_map<const DofObject *, std::pair<ADReal, Real>> & dof_to_weighted_gap,
23  const MooseMesh & mesh,
24  const bool nodal,
25  const bool normalize_c,
26  const Parallel::Communicator & communicator,
27  const bool send_data_back)
28 {
29  libmesh_parallel_only(communicator);
30  const auto our_proc_id = communicator.rank();
31 
32  // We may have weighted gap information that should go to other processes that own the dofs
33  using Datum = std::tuple<dof_id_type, ADReal, Real>;
34  std::unordered_map<processor_id_type, std::vector<Datum>> push_data;
35 
36  for (auto & pr : dof_to_weighted_gap)
37  {
38  const auto * const dof_object = pr.first;
39  const auto proc_id = dof_object->processor_id();
40  if (proc_id == our_proc_id)
41  continue;
42 
43  push_data[proc_id].push_back(
44  std::make_tuple(dof_object->id(), std::move(pr.second.first), pr.second.second));
45  }
46 
47  const auto & lm_mesh = mesh.getMesh();
48  std::unordered_map<processor_id_type, std::vector<const DofObject *>>
49  pid_to_dof_object_for_sending_back;
50 
51  auto action_functor =
52  [nodal,
53  our_proc_id,
54  &lm_mesh,
55  &dof_to_weighted_gap,
56  &normalize_c,
57  &pid_to_dof_object_for_sending_back,
58  send_data_back](const processor_id_type pid, const std::vector<Datum> & sent_data)
59  {
60  mooseAssert(pid != our_proc_id, "We do not send messages to ourself here");
61  libmesh_ignore(our_proc_id);
62 
63  for (auto & [dof_id, weighted_gap, normalization] : sent_data)
64  {
65  const auto * const dof_object =
66  nodal ? static_cast<const DofObject *>(lm_mesh.node_ptr(dof_id))
67  : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
68  mooseAssert(dof_object, "This should be non-null");
69  if (send_data_back)
70  pid_to_dof_object_for_sending_back[pid].push_back(dof_object);
71  auto & [our_weighted_gap, our_normalization] = dof_to_weighted_gap[dof_object];
72  our_weighted_gap += weighted_gap;
73  if (normalize_c)
74  our_normalization += normalization;
75  }
76  };
77 
78  TIMPI::push_parallel_vector_data(communicator, push_data, action_functor);
79 
80  // Now send data back if requested
81  if (!send_data_back)
82  return;
83 
84  std::unordered_map<processor_id_type, std::vector<Datum>> push_back_data;
85 
86  for (const auto & [pid, dof_objects] : pid_to_dof_object_for_sending_back)
87  {
88  auto & pid_send_data = push_back_data[pid];
89  pid_send_data.reserve(dof_objects.size());
90  for (const DofObject * const dof_object : dof_objects)
91  {
92  const auto & [our_weighted_gap, our_normalization] =
93  libmesh_map_find(dof_to_weighted_gap, dof_object);
94  pid_send_data.push_back(
95  std::make_tuple(dof_object->id(), our_weighted_gap, our_normalization));
96  }
97  }
98 
99  auto sent_back_action_functor =
100  [nodal, our_proc_id, &lm_mesh, &dof_to_weighted_gap, &normalize_c](
101  const processor_id_type libmesh_dbg_var(pid), const std::vector<Datum> & sent_data)
102  {
103  mooseAssert(pid != our_proc_id, "We do not send messages to ourself here");
104  libmesh_ignore(our_proc_id);
105 
106  for (auto & [dof_id, weighted_gap, normalization] : sent_data)
107  {
108  const auto * const dof_object =
109  nodal ? static_cast<const DofObject *>(lm_mesh.node_ptr(dof_id))
110  : static_cast<const DofObject *>(lm_mesh.elem_ptr(dof_id));
111  mooseAssert(dof_object, "This should be non-null");
112  auto & [our_weighted_gap, our_normalization] = dof_to_weighted_gap[dof_object];
113  our_weighted_gap = weighted_gap;
114  if (normalize_c)
115  our_normalization = normalization;
116  }
117  };
118  TIMPI::push_parallel_vector_data(communicator, push_back_data, sent_back_action_functor);
119 }
120 }
121 }
122 }
MeshBase & mesh
void communicateGaps(std::unordered_map< const DofObject *, std::pair< ADReal, Real >> &dof_to_weighted_gap, const MooseMesh &mesh, bool nodal, bool normalize_c, const Parallel::Communicator &communicator, bool send_data_back)
This function is used to communicate gaps across processes.
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 &...)
DIE A HORRIBLE DEATH HERE typedef MPI_Comm communicator