libMesh
Public Types | Public Member Functions | Public Attributes | Protected Attributes | List of all members
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy Struct Reference

#include <generic_projector.h>

Inheritance diagram for libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy:
[legend]

Public Types

typedef std::unordered_multimap< const Node *, std::tuple< const Elem *, unsigned short, var_set > > ves_multimap
 

Public Member Functions

 SortAndCopy (GenericProjector &p)
 
 SortAndCopy (SortAndCopy &other, Threads::split)
 
void operator() (const ConstElemRange &range)
 
void join (const SortAndCopy &other)
 
void insert_ids (const std::vector< dof_id_type > &ids, const std::vector< FValue > &vals, processor_id_type pid)
 
void find_dofs_to_send (const Node &node, const Elem &elem, unsigned short node_num, const var_set &vars)
 
void insert_id (dof_id_type id, const FValue &val, processor_id_type pid)
 
void insert_ids (const std::vector< dof_id_type > &ids, const std::vector< FValue > &vals, processor_id_type pid)
 
void join (const SubFunctor &other)
 

Public Attributes

ves_multimap vertices
 
ves_multimap edges
 
ves_multimap sides
 
std::vector< const Elem * > interiors
 
ProjectionAction action
 
FFunctor f
 
const Systemsystem
 
FEMContext context
 
GenericProjectorprojector
 
std::unordered_map< dof_id_type, std::pair< FValue, processor_id_type > > new_ids_to_push
 
std::unordered_map< dof_id_type, FValue > new_ids_to_save
 

Protected Attributes

std::vector< FEContinuityconts
 

Detailed Description

template<typename FFunctor, typename GFunctor, typename FValue, typename ProjectionAction>
struct libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy

Definition at line 240 of file generic_projector.h.

Member Typedef Documentation

◆ ves_multimap

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
typedef std::unordered_multimap<const Node *, std::tuple<const Elem *, unsigned short, var_set> > libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::ves_multimap

Definition at line 260 of file generic_projector.h.

Constructor & Destructor Documentation

◆ SortAndCopy() [1/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::SortAndCopy ( GenericProjector p)
inline

Definition at line 241 of file generic_projector.h.

241 : SubFunctor(p) {}

◆ SortAndCopy() [2/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::SortAndCopy ( SortAndCopy other,
Threads::split   
)
inline

Definition at line 243 of file generic_projector.h.

243 : SubFunctor(other.projector) {}

Member Function Documentation

◆ find_dofs_to_send()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::find_dofs_to_send ( const Node node,
const Elem elem,
unsigned short  node_num,
const var_set vars 
)
inherited

Definition at line 2345 of file generic_projector.h.

2346 {
2347  libmesh_assert (&node == elem.node_ptr(node_num));
2348 
2349  // Any ghosted node in our range might have an owner who needs our
2350  // data
2351  const processor_id_type owner = node.processor_id();
2352  if (owner != system.processor_id())
2353  {
2354  const MeshBase & mesh = system.get_mesh();
2355  const DofMap & dof_map = system.get_dof_map();
2356 
2357  // But let's check and see if we can be certain the owner can
2358  // compute any or all of its own dof coefficients on that node.
2359  std::vector<dof_id_type> node_dof_ids, patch_dof_ids;
2360  for (const auto & var : vars)
2361  {
2362  const Variable & variable = system.variable(var);
2363 
2364  if (!variable.active_on_subdomain(elem.subdomain_id()))
2365  continue;
2366 
2367  dof_map.dof_indices(elem, node_num, node_dof_ids, var);
2368  }
2369  libmesh_assert(std::is_sorted(node_dof_ids.begin(),
2370  node_dof_ids.end()));
2371  const std::vector<dof_id_type> & patch =
2372  (*this->projector.nodes_to_elem)[node.id()];
2373  for (const auto & elem_id : patch)
2374  {
2375  const Elem & patch_elem = mesh.elem_ref(elem_id);
2376  if (!patch_elem.active() || owner != patch_elem.processor_id())
2377  continue;
2378  dof_map.dof_indices(&patch_elem, patch_dof_ids);
2379  std::sort(patch_dof_ids.begin(), patch_dof_ids.end());
2380 
2381  // Remove any node_dof_ids that we see can be calculated on
2382  // this element
2383  std::vector<dof_id_type> diff_ids(node_dof_ids.size());
2384  auto it = std::set_difference(node_dof_ids.begin(), node_dof_ids.end(),
2385  patch_dof_ids.begin(), patch_dof_ids.end(), diff_ids.begin());
2386  diff_ids.resize(it-diff_ids.begin());
2387  node_dof_ids.swap(diff_ids);
2388  if (node_dof_ids.empty())
2389  break;
2390  }
2391 
2392  // Give ids_to_push default invalid pid: not yet computed
2393  for (auto id : node_dof_ids)
2395  }
2396 }

References libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), libMesh::DofMap::dof_indices(), libMesh::MeshBase::elem_ref(), libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::Parallel::Utils::is_sorted(), libMesh::libmesh_assert(), mesh, libMesh::Elem::node_ptr(), libMesh::DofObject::processor_id(), and libMesh::Elem::subdomain_id().

◆ insert_id()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_id ( dof_id_type  id,
const FValue &  val,
processor_id_type  pid 
)
inherited

Definition at line 1117 of file generic_projector.h.

1118 {
1119  auto iter = new_ids_to_push.find(id);
1120  if (iter == new_ids_to_push.end())
1121  action.insert(id, val);
1122  else
1123  {
1125  iter->second = std::make_pair(val, pid);
1126  }
1127  if (!this->projector.done_saving_ids)
1128  {
1129  libmesh_assert(!new_ids_to_save.count(id));
1130  new_ids_to_save[id] = val;
1131  }
1132 }

References libMesh::DofObject::invalid_processor_id, and libMesh::libmesh_assert().

◆ insert_ids() [1/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_ids ( const std::vector< dof_id_type > &  ids,
const std::vector< FValue > &  vals,
processor_id_type  pid 
)
inherited

Definition at line 1138 of file generic_projector.h.

1139 {
1140  libmesh_assert_equal_to(ids.size(), vals.size());
1141  for (auto i : index_range(ids))
1142  {
1143  const dof_id_type id = ids[i];
1144  const FValue & val = vals[i];
1145 
1146  auto iter = new_ids_to_push.find(id);
1147  if (iter == new_ids_to_push.end())
1148  action.insert(id, val);
1149  else
1150  {
1152  iter->second = std::make_pair(val, pid);
1153  }
1154  if (!this->projector.done_saving_ids)
1155  {
1156  libmesh_assert(!new_ids_to_save.count(id));
1157  new_ids_to_save[id] = val;
1158  }
1159  }
1160 }

References libMesh::index_range(), libMesh::DofObject::invalid_processor_id, and libMesh::libmesh_assert().

◆ insert_ids() [2/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_ids

Definition at line 1138 of file generic_projector.h.

1139 {
1140  libmesh_assert_equal_to(ids.size(), vals.size());
1141  for (auto i : index_range(ids))
1142  {
1143  const dof_id_type id = ids[i];
1144  const FValue & val = vals[i];
1145 
1146  auto iter = new_ids_to_push.find(id);
1147  if (iter == new_ids_to_push.end())
1148  action.insert(id, val);
1149  else
1150  {
1152  iter->second = std::make_pair(val, pid);
1153  }
1154  if (!this->projector.done_saving_ids)
1155  {
1156  libmesh_assert(!new_ids_to_save.count(id));
1157  new_ids_to_save[id] = val;
1158  }
1159  }
1160 }

◆ join() [1/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::join ( const SortAndCopy other)

Definition at line 1612 of file generic_projector.h.

1613 {
1614  auto merge_multimaps = [](ves_multimap & self, const ves_multimap & other_mm)
1615  {
1616  for (const auto & pair : other_mm)
1617  {
1618  const Node * node = pair.first;
1619  auto remaining_vars = std::get<2>(pair.second);
1620 
1621  auto my_range = self.equal_range(node);
1622  for (const auto & v_ent : as_range(my_range))
1623  for (const unsigned int var_covered :
1624  std::get<2>(v_ent.second))
1625  remaining_vars.erase(var_covered);
1626 
1627  if (!remaining_vars.empty())
1628  self.emplace
1629  (node, std::make_tuple(std::get<0>(pair.second),
1630  std::get<1>(pair.second),
1631  std::move(remaining_vars)));
1632  }
1633  };
1634 
1635  merge_multimaps(vertices, other.vertices);
1636  merge_multimaps(edges, other.edges);
1637  merge_multimaps(sides, other.sides);
1638 
1639  std::sort(interiors.begin(), interiors.end());
1640  std::vector<const Elem *> other_interiors = other.interiors;
1641  std::sort(other_interiors.begin(), other_interiors.end());
1642  std::vector<const Elem *> merged_interiors;
1643  std::set_union(interiors.begin(), interiors.end(),
1644  other_interiors.begin(), other_interiors.end(),
1645  std::back_inserter(merged_interiors));
1646  interiors.swap(merged_interiors);
1647 
1648  SubFunctor::join(other);
1649 }

References libMesh::as_range(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::edges, libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::interiors, libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::sides, and libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::vertices.

◆ join() [2/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::join ( const SubFunctor other)
inherited

Definition at line 1166 of file generic_projector.h.

1167 {
1168  new_ids_to_push.insert(other.new_ids_to_push.begin(), other.new_ids_to_push.end());
1169  new_ids_to_save.insert(other.new_ids_to_save.begin(), other.new_ids_to_save.end());
1170 }

References libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_push, and libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_save.

◆ operator()()

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::operator() ( const ConstElemRange range)

Definition at line 1176 of file generic_projector.h.

1177 {
1178  // Look at all the elements in the range. Directly copy values from
1179  // unchanged elements. For other elements, determine sets of
1180  // vertices, edge nodes, and side nodes to project.
1181  //
1182  // As per our other weird nomenclature, "sides" means faces in 3D
1183  // and edges in 2D, and "edges" gets skipped in 2D
1184  //
1185  // This gets tricky in the case of subdomain-restricted
1186  // variables, for which we might need to do the same projection
1187  // from different elements when evaluating different variables.
1188  // We'll keep track of which variables can be projected from which
1189  // elements.
1190 
1191  // If we copy DoFs on a node, keep track of it so we don't bother
1192  // with any redundant interpolations or projections later.
1193  //
1194  // We still need to keep track of *which* variables get copied,
1195  // since we may be able to copy elements which lack some
1196  // subdomain-restricted variables.
1197  //
1198  // For extra_hanging_dofs FE types, we'll keep track of which
1199  // variables were copied from vertices, and which from edges/sides,
1200  // because those types need copies made from *both* on hanging
1201  // nodes.
1202  std::unordered_map<const Node *, std::pair<var_set, var_set>> copied_nodes;
1203 
1204  const unsigned int sys_num = system.number();
1205 
1206  // At hanging nodes for variables with extra hanging dofs we'll need
1207  // to do projections *separately* from vertex elements and side/edge
1208  // elements.
1209  std::vector<unsigned short> extra_hanging_dofs;
1210  bool all_extra_hanging_dofs = true;
1211  for (auto v_num : this->projector.variables)
1212  {
1213  if (extra_hanging_dofs.size() <= v_num)
1214  extra_hanging_dofs.resize(v_num+1, false);
1215  extra_hanging_dofs[v_num] =
1217 
1218  if (!extra_hanging_dofs[v_num])
1219  all_extra_hanging_dofs = false;
1220  }
1221 
1222  for (const auto & elem : range)
1223  {
1224  // If we're doing AMR, we might be able to copy more DoFs than
1225  // we interpolate or project.
1226  bool copy_this_elem = false;
1227 
1228 #ifdef LIBMESH_ENABLE_AMR
1229  // If we're projecting from an old grid
1230  if (f.is_grid_projection())
1231  {
1232  // If this element doesn't have an old_dof_object, but it
1233  // wasn't just refined or just coarsened into activity, then
1234  // it must be newly added, so the user is responsible for
1235  // setting the new dofs on it during a grid projection.
1236  if (!elem->old_dof_object &&
1237  elem->refinement_flag() != Elem::JUST_REFINED &&
1238  elem->refinement_flag() != Elem::JUST_COARSENED)
1239  continue;
1240 
1241  // If this is an unchanged element, just copy everything
1242  if ((elem->refinement_flag() != Elem::JUST_REFINED &&
1243  elem->refinement_flag() != Elem::JUST_COARSENED &&
1244  elem->p_refinement_flag() != Elem::JUST_REFINED &&
1245  elem->p_refinement_flag() != Elem::JUST_COARSENED))
1246  copy_this_elem = true;
1247  else
1248  {
1249  bool reinitted = false;
1250 
1251  // If this element has a low order monomial which has
1252  // merely been h refined, copy it.
1253  for (auto v_num : this->projector.variables)
1254  {
1255  const Variable & var = system.variable(v_num);
1256  if (!var.active_on_subdomain(elem->subdomain_id()))
1257  continue;
1258  FEType fe_type = var.type();
1259 
1260  if (fe_type.family == MONOMIAL &&
1261  fe_type.order == CONSTANT &&
1262  elem->p_level() == 0 &&
1263  elem->refinement_flag() != Elem::JUST_COARSENED &&
1264  elem->p_refinement_flag() != Elem::JUST_COARSENED)
1265  {
1266  if (!reinitted)
1267  {
1268  reinitted = true;
1269  context.pre_fe_reinit(system, elem);
1270  }
1271 
1272  std::vector<FValue> Ue(1);
1273  std::vector<dof_id_type> elem_dof_ids(1);
1274 
1275  f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1276  elem_dof_ids, Ue);
1277 
1278  action.insert(elem_dof_ids[0], Ue[0]);
1279  }
1280  }
1281  }
1282  }
1283 #endif // LIBMESH_ENABLE_AMR
1284 
1285  const int dim = elem->dim();
1286 
1287  const unsigned int n_vertices = elem->n_vertices();
1288  const unsigned int n_edges = elem->n_edges();
1289  const unsigned int n_nodes = elem->n_nodes();
1290 
1291  // In 1-D we already handle our sides as vertices
1292  const unsigned int n_sides = (dim > 1) * elem->n_sides();
1293 
1294  // What variables are supported on each kind of node on this elem?
1295  var_set vertex_vars, edge_vars, side_vars;
1296 
1297  // If we have non-vertex nodes, the first is an edge node, but
1298  // if we're in 2D we'll call that a side node
1299  const bool has_edge_nodes = (n_nodes > n_vertices && dim > 2);
1300 
1301  // If we have even more nodes, the next is a side node.
1302  const bool has_side_nodes =
1303  (n_nodes > n_vertices + ((dim > 2) * n_edges));
1304 
1305  // We may be out of nodes at this point or we have interior
1306  // nodes which may have DoFs to project too
1307  const bool has_interior_nodes =
1308  (n_nodes > n_vertices + ((dim > 2) * n_edges) + n_sides);
1309 
1310  for (auto v_num : this->projector.variables)
1311  {
1312  const Variable & var = this->projector.system.variable(v_num);
1313  if (!var.active_on_subdomain(elem->subdomain_id()))
1314  continue;
1315  FEType fe_type = var.type();
1316  fe_type.order =
1317  libMesh::Order (fe_type.order + elem->p_level());
1318  const ElemType elem_type = elem->type();
1319 
1320  if (FEInterface::n_dofs_at_node(dim, fe_type, elem_type, 0))
1321  vertex_vars.insert(vertex_vars.end(), v_num);
1322 
1323  // The first non-vertex node is always an edge node if those
1324  // exist. All edge nodes have the same number of DoFs
1325  if (has_edge_nodes)
1326  if (FEInterface::n_dofs_at_node(dim, fe_type, elem_type, n_vertices))
1327  edge_vars.insert(edge_vars.end(), v_num);
1328 
1329  if (has_side_nodes)
1330  {
1331  if (dim != 3)
1332  {
1333  if (FEInterface::n_dofs_at_node(dim, fe_type, elem_type, n_vertices))
1334  side_vars.insert(side_vars.end(), v_num);
1335  }
1336  else
1337  // In 3D, not all face nodes always have the same number of
1338  // DoFs! We'll loop over all sides to be safe.
1339  for (unsigned int n = 0; n != n_nodes; ++n)
1340  if (elem->is_face(n))
1341  if (FEInterface::n_dofs_at_node(dim, fe_type,
1342  elem_type, n))
1343  {
1344  side_vars.insert(side_vars.end(), v_num);
1345  break;
1346  }
1347  }
1348 
1349  if (FEInterface::n_dofs_per_elem(dim, fe_type, elem_type) ||
1350  (has_interior_nodes &&
1351  FEInterface::n_dofs_at_node(dim, fe_type, elem_type, n_nodes-1)))
1352  {
1353 #ifdef LIBMESH_ENABLE_AMR
1354  // We may have already just copied constant monomials,
1355  // or we may be about to copy the whole element
1356  if ((f.is_grid_projection() &&
1357  fe_type.family == MONOMIAL &&
1358  fe_type.order == CONSTANT &&
1359  elem->p_level() == 0 &&
1360  elem->refinement_flag() != Elem::JUST_COARSENED &&
1361  elem->p_refinement_flag() != Elem::JUST_COARSENED)
1362  || copy_this_elem
1363  )
1364  continue;
1365 #endif // LIBMESH_ENABLE_AMR
1366 
1367  // We need to project any other variables
1368  if (interiors.empty() || interiors.back() != elem)
1369  interiors.push_back(elem);
1370  }
1371  }
1372 
1373  // We'll use a greedy algorithm in most cases: if another
1374  // element has already claimed some of our DoFs, we'll let it do
1375  // the work.
1376  auto erase_covered_vars = []
1377  (const Node * node, var_set & remaining, const ves_multimap & covered)
1378  {
1379  auto covered_range = covered.equal_range(node);
1380  for (const auto & v_ent : as_range(covered_range))
1381  for (const unsigned int var_covered :
1382  std::get<2>(v_ent.second))
1383  remaining.erase(var_covered);
1384  };
1385 
1386  auto erase_nonhanging_vars = [&extra_hanging_dofs]
1387  (const Node * node, var_set & remaining, const ves_multimap & covered)
1388  {
1389  auto covered_range = covered.equal_range(node);
1390  for (const auto & v_ent : as_range(covered_range))
1391  for (const unsigned int var_covered :
1392  std::get<2>(v_ent.second))
1393  if (!extra_hanging_dofs[var_covered])
1394  remaining.erase(var_covered);
1395  };
1396 
1397  auto erase_copied_vars = [&copied_nodes, &extra_hanging_dofs]
1398  (const Node * node, bool is_vertex, var_set & remaining)
1399  {
1400  auto copying_range = copied_nodes.equal_range(node);
1401  for (const auto & v_ent : as_range(copying_range))
1402  {
1403  for (const unsigned int var_covered :
1404  v_ent.second.first)
1405  if (is_vertex || !extra_hanging_dofs[var_covered])
1406  remaining.erase(var_covered);
1407 
1408  for (const unsigned int var_covered :
1409  v_ent.second.second)
1410  if (!is_vertex || !extra_hanging_dofs[var_covered])
1411  remaining.erase(var_covered);
1412  }
1413  };
1414 
1415  for (unsigned int v=0; v != n_vertices; ++v)
1416  {
1417  const Node * node = elem->node_ptr(v);
1418 
1419  auto remaining_vars = vertex_vars;
1420 
1421  erase_covered_vars(node, remaining_vars, vertices);
1422 
1423  if (remaining_vars.empty())
1424  continue;
1425 
1426  if (!all_extra_hanging_dofs)
1427  {
1428  erase_nonhanging_vars(node, remaining_vars, edges);
1429  if (remaining_vars.empty())
1430  continue;
1431 
1432  erase_nonhanging_vars(node, remaining_vars, sides);
1433  if (remaining_vars.empty())
1434  continue;
1435  }
1436 
1437  erase_copied_vars(node, true, remaining_vars);
1438  if (remaining_vars.empty())
1439  continue;
1440 
1441  if (copy_this_elem)
1442  {
1443  for (auto var : remaining_vars)
1444  {
1445  std::vector<dof_id_type> node_dof_ids;
1446  std::vector<FValue> values;
1447 
1448  f.eval_old_dofs(*elem, v, var, node_dof_ids, values);
1449 
1450  insert_ids(node_dof_ids, values, node->processor_id());
1451  }
1452  copied_nodes[node].first.insert(remaining_vars.begin(),
1453  remaining_vars.end());
1454  this->find_dofs_to_send(*node, *elem, v, remaining_vars);
1455  }
1456  else
1457  vertices.emplace
1458  (node, std::make_tuple(elem, v, std::move(remaining_vars)));
1459  }
1460 
1461  if (has_edge_nodes)
1462  {
1463  for (unsigned int e=0; e != n_edges; ++e)
1464  {
1465  const Node * node = elem->node_ptr(n_vertices+e);
1466 
1467  auto remaining_vars = edge_vars;
1468 
1469  erase_covered_vars(node, remaining_vars, edges);
1470  if (remaining_vars.empty())
1471  continue;
1472 
1473  erase_covered_vars(node, remaining_vars, sides);
1474  if (remaining_vars.empty())
1475  continue;
1476 
1477  if (!all_extra_hanging_dofs)
1478  {
1479  erase_nonhanging_vars(node, remaining_vars, vertices);
1480  if (remaining_vars.empty())
1481  continue;
1482  }
1483 
1484  erase_copied_vars(node, false, remaining_vars);
1485  if (remaining_vars.empty())
1486  continue;
1487 
1488  if (copy_this_elem)
1489  {
1490  for (auto var : remaining_vars)
1491  {
1492  std::vector<dof_id_type> edge_dof_ids;
1493  std::vector<FValue> values;
1494 
1495  f.eval_old_dofs(*elem, n_vertices+e, var, edge_dof_ids, values);
1496 
1497  insert_ids(edge_dof_ids, values, node->processor_id());
1498  }
1499  copied_nodes[node].second.insert(remaining_vars.begin(),
1500  remaining_vars.end());
1501  this->find_dofs_to_send(*node, *elem, n_vertices+e, remaining_vars);
1502  }
1503  else
1504  edges.emplace
1505  (node, std::make_tuple(elem, e, std::move(remaining_vars)));
1506  }
1507  }
1508 
1509  if (has_side_nodes)
1510  {
1511  for (unsigned int side=0; side != n_sides; ++side)
1512  {
1513  const Node * node = nullptr;
1514  unsigned short node_num = n_vertices+(dim>2)*n_edges+side;
1515  if (dim != 3)
1516  node = elem->node_ptr(node_num);
1517  else
1518  {
1519  // In 3D only some sides may have nodes
1520  for (unsigned int n = 0; n != n_nodes; ++n)
1521  {
1522  if (!elem->is_face(n))
1523  continue;
1524 
1525  if (elem->is_node_on_side(n, side))
1526  {
1527  node_num = n;
1528  node = elem->node_ptr(node_num);
1529  break;
1530  }
1531  }
1532  }
1533 
1534  if (!node)
1535  continue;
1536 
1537  auto remaining_vars = side_vars;
1538 
1539  erase_covered_vars(node, remaining_vars, edges);
1540  if (remaining_vars.empty())
1541  continue;
1542 
1543  erase_covered_vars(node, remaining_vars, sides);
1544  if (remaining_vars.empty())
1545  continue;
1546 
1547  if (!all_extra_hanging_dofs)
1548  {
1549  erase_nonhanging_vars(node, remaining_vars, vertices);
1550  if (remaining_vars.empty())
1551  continue;
1552  }
1553 
1554  erase_copied_vars(node, false, remaining_vars);
1555  if (remaining_vars.empty())
1556  continue;
1557 
1558  if (copy_this_elem)
1559  {
1560  for (auto var : remaining_vars)
1561  {
1562  std::vector<dof_id_type> side_dof_ids;
1563  std::vector<FValue> values;
1564 
1565  f.eval_old_dofs(*elem, node_num, var, side_dof_ids, values);
1566 
1567  insert_ids(side_dof_ids, values, node->processor_id());
1568  }
1569  copied_nodes[node].second.insert(remaining_vars.begin(),
1570  remaining_vars.end());
1571  this->find_dofs_to_send(*node, *elem, node_num, remaining_vars);
1572  }
1573  else
1574  sides.emplace
1575  (node, std::make_tuple(elem, side, std::move(remaining_vars)));
1576  }
1577  }
1578 
1579  // Elements with elemental dofs might need those copied too.
1580  if (copy_this_elem)
1581  {
1582  for (auto v_num : this->projector.variables)
1583  {
1584  const Variable & var = system.variable(v_num);
1585  if (!var.active_on_subdomain(elem->subdomain_id()))
1586  continue;
1587  FEType fe_type = var.type();
1588 
1589  std::vector<FValue> Ue;
1590  std::vector<dof_id_type> elem_dof_ids;
1591  f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1592  elem_dof_ids, Ue);
1593  action.insert(elem_dof_ids, Ue);
1594 
1595  if (has_interior_nodes)
1596  {
1597  std::vector<FValue> Un;
1598  std::vector<dof_id_type> node_dof_ids;
1599 
1600  f.eval_old_dofs(*elem, n_nodes-1, v_num, node_dof_ids, Un);
1601  action.insert(node_dof_ids, Un);
1602  }
1603  }
1604  }
1605  }
1606 }

References libMesh::Variable::active_on_subdomain(), libMesh::as_range(), libMesh::CONSTANT, dim, libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::Elem::JUST_COARSENED, libMesh::Elem::JUST_REFINED, libMesh::MONOMIAL, libMesh::FEInterface::n_dofs_at_node(), libMesh::FEInterface::n_dofs_per_elem(), n_nodes, libMesh::FEType::order, libMesh::DofObject::processor_id(), libMesh::Variable::system(), libMesh::Variable::type(), and libMesh::System::variable().

Member Data Documentation

◆ action

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
ProjectionAction libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::action

Definition at line 193 of file generic_projector.h.

◆ context

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
FEMContext libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::context

Definition at line 198 of file generic_projector.h.

◆ conts

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::vector<FEContinuity> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::conts
protectedinherited

Definition at line 201 of file generic_projector.h.

◆ edges

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
ves_multimap libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::edges

◆ f

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
FFunctor libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::f

Definition at line 194 of file generic_projector.h.

◆ interiors

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::vector<const Elem *> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::interiors

◆ new_ids_to_push

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::unordered_map<dof_id_type, std::pair<FValue, processor_id_type> > libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_push
inherited

◆ new_ids_to_save

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
std::unordered_map<dof_id_type, FValue> libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::new_ids_to_save
inherited

◆ projector

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
GenericProjector& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::projector
inherited

Definition at line 154 of file generic_projector.h.

◆ sides

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
ves_multimap libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::sides

◆ system

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
const System& libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::system

Definition at line 203 of file generic_projector.h.

◆ vertices

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
ves_multimap libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::vertices

The documentation for this struct was generated from the following file:
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::GenericProjector::SubFunctor::new_ids_to_save
std::unordered_map< dof_id_type, FValue > new_ids_to_save
Definition: generic_projector.h:169
libMesh::FEInterface::extra_hanging_dofs
static bool extra_hanging_dofs(const FEType &fe_t)
Definition: fe_interface.C:1656
libMesh::GenericProjector::SortAndCopy::sides
ves_multimap sides
Definition: generic_projector.h:262
libMesh::Elem::JUST_REFINED
Definition: elem.h:1172
libMesh::GenericProjector::var_set
std::set< unsigned int > var_set
Definition: generic_projector.h:149
libMesh::GenericProjector::SortAndCopy::vertices
ves_multimap vertices
Definition: generic_projector.h:262
libMesh::GenericProjector::SubFunctor::SubFunctor
SubFunctor(GenericProjector &p)
Definition: generic_projector.h:1031
libMesh::FEInterface::n_dofs_at_node
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
Definition: fe_interface.C:503
libMesh::GenericProjector::SortAndCopy::ves_multimap
std::unordered_multimap< const Node *, std::tuple< const Elem *, unsigned short, var_set > > ves_multimap
Definition: generic_projector.h:260
libMesh::index_range
IntRange< std::size_t > index_range(const std::vector< T > &vec)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:106
libMesh::FEMContext::pre_fe_reinit
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
Definition: fem_context.C:1642
libMesh::Order
Order
Definition: enum_order.h:40
libMesh::System::number
unsigned int number() const
Definition: system.h:2075
libMesh::Variable::type
const FEType & type() const
Definition: variable.h:119
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::GenericProjector::SubFunctor::new_ids_to_push
std::unordered_map< dof_id_type, std::pair< FValue, processor_id_type > > new_ids_to_push
Definition: generic_projector.h:165
libMesh::System::variable
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
Definition: system.h:2183
libMesh::Parallel::Utils::is_sorted
bool is_sorted(const std::vector< KeyType > &v)
Definition: parallel_conversion_utils.h:52
dim
unsigned int dim
Definition: adaptivity_ex3.C:113
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::GenericProjector::SubFunctor::insert_ids
void insert_ids(const std::vector< dof_id_type > &ids, const std::vector< FValue > &vals, processor_id_type pid)
Definition: generic_projector.h:1138
libMesh::GenericProjector::SubFunctor::find_dofs_to_send
void find_dofs_to_send(const Node &node, const Elem &elem, unsigned short node_num, const var_set &vars)
Definition: generic_projector.h:2345
libMesh::GenericProjector::done_saving_ids
bool done_saving_ids
Definition: generic_projector.h:93
libMesh::FEInterface::n_dofs_per_elem
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
Definition: fe_interface.C:534
libMesh::GenericProjector::SubFunctor::context
FEMContext context
Definition: generic_projector.h:198
libMesh::GenericProjector::SortAndCopy::edges
ves_multimap edges
Definition: generic_projector.h:262
libMesh::System::get_mesh
const MeshBase & get_mesh() const
Definition: system.h:2083
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::CONSTANT
Definition: enum_order.h:41
libMesh::as_range
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libMesh::GenericProjector::nodes_to_elem
std::unordered_map< dof_id_type, std::vector< dof_id_type > > * nodes_to_elem
Definition: generic_projector.h:92
n_nodes
const dof_id_type n_nodes
Definition: tecplot_io.C:68
libMesh::Elem::JUST_COARSENED
Definition: elem.h:1173
libMesh::GenericProjector::SubFunctor::join
void join(const SubFunctor &other)
Definition: generic_projector.h:1166
libMesh::MONOMIAL
Definition: enum_fe_family.h:39
libMesh::GenericProjector::SortAndCopy::interiors
std::vector< const Elem * > interiors
Definition: generic_projector.h:263
libMesh::FEType::order
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:197
libMesh::DofObject::invalid_processor_id
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:432
libMesh::GenericProjector::SubFunctor::action
ProjectionAction action
Definition: generic_projector.h:193
libMesh::GenericProjector::SubFunctor::projector
GenericProjector & projector
Definition: generic_projector.h:154
libMesh::GenericProjector::system
const System & system
Definition: generic_projector.h:83
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::GenericProjector::SubFunctor::f
FFunctor f
Definition: generic_projector.h:194
libMesh::GenericProjector::SubFunctor::system
const System & system
Definition: generic_projector.h:203
libMesh::GenericProjector::variables
const std::vector< unsigned int > & variables
Definition: generic_projector.h:91
libMesh::ElemType
ElemType
Defines an enum for geometric element types.
Definition: enum_elem_type.h:33