1202 std::unordered_map<const Node *, std::pair<var_set, var_set>> copied_nodes;
1209 std::vector<unsigned short> extra_hanging_dofs;
1210 bool all_extra_hanging_dofs =
true;
1213 if (extra_hanging_dofs.size() <= v_num)
1214 extra_hanging_dofs.resize(v_num+1,
false);
1215 extra_hanging_dofs[v_num] =
1218 if (!extra_hanging_dofs[v_num])
1219 all_extra_hanging_dofs =
false;
1222 for (
const auto & elem : range)
1226 bool copy_this_elem =
false;
1228 #ifdef LIBMESH_ENABLE_AMR
1230 if (
f.is_grid_projection())
1236 if (!elem->old_dof_object &&
1246 copy_this_elem =
true;
1249 bool reinitted =
false;
1256 if (!var.active_on_subdomain(elem->subdomain_id()))
1258 FEType fe_type = var.
type();
1262 elem->p_level() == 0 &&
1272 std::vector<FValue> Ue(1);
1273 std::vector<dof_id_type> elem_dof_ids(1);
1275 f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1278 action.insert(elem_dof_ids[0], Ue[0]);
1283 #endif // LIBMESH_ENABLE_AMR
1285 const int dim = elem->dim();
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();
1292 const unsigned int n_sides = (
dim > 1) * elem->n_sides();
1295 var_set vertex_vars, edge_vars, side_vars;
1299 const bool has_edge_nodes = (
n_nodes > n_vertices &&
dim > 2);
1302 const bool has_side_nodes =
1303 (
n_nodes > n_vertices + ((
dim > 2) * n_edges));
1307 const bool has_interior_nodes =
1308 (
n_nodes > n_vertices + ((
dim > 2) * n_edges) + n_sides);
1313 if (!var.active_on_subdomain(elem->subdomain_id()))
1315 FEType fe_type = var.
type();
1318 const ElemType elem_type = elem->type();
1321 vertex_vars.insert(vertex_vars.end(), v_num);
1327 edge_vars.insert(edge_vars.end(), v_num);
1334 side_vars.insert(side_vars.end(), v_num);
1339 for (
unsigned int n = 0; n !=
n_nodes; ++n)
1340 if (elem->is_face(n))
1344 side_vars.insert(side_vars.end(), v_num);
1350 (has_interior_nodes &&
1353 #ifdef LIBMESH_ENABLE_AMR
1356 if ((
f.is_grid_projection() &&
1359 elem->p_level() == 0 &&
1365 #endif // LIBMESH_ENABLE_AMR
1376 auto erase_covered_vars = []
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);
1386 auto erase_nonhanging_vars = [&extra_hanging_dofs]
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);
1397 auto erase_copied_vars = [&copied_nodes, &extra_hanging_dofs]
1398 (
const Node * node,
bool is_vertex,
var_set & remaining)
1400 auto copying_range = copied_nodes.equal_range(node);
1401 for (
const auto & v_ent :
as_range(copying_range))
1403 for (
const unsigned int var_covered :
1405 if (is_vertex || !extra_hanging_dofs[var_covered])
1406 remaining.erase(var_covered);
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);
1415 for (
unsigned int v=0; v != n_vertices; ++v)
1417 const Node * node = elem->node_ptr(v);
1419 auto remaining_vars = vertex_vars;
1421 erase_covered_vars(node, remaining_vars,
vertices);
1423 if (remaining_vars.empty())
1426 if (!all_extra_hanging_dofs)
1428 erase_nonhanging_vars(node, remaining_vars,
edges);
1429 if (remaining_vars.empty())
1432 erase_nonhanging_vars(node, remaining_vars,
sides);
1433 if (remaining_vars.empty())
1437 erase_copied_vars(node,
true, remaining_vars);
1438 if (remaining_vars.empty())
1443 for (
auto var : remaining_vars)
1445 std::vector<dof_id_type> node_dof_ids;
1446 std::vector<FValue> values;
1448 f.eval_old_dofs(*elem, v, var, node_dof_ids, values);
1450 insert_ids(node_dof_ids, values, node->processor_id());
1452 copied_nodes[node].first.insert(remaining_vars.begin(),
1453 remaining_vars.end());
1458 (node, std::make_tuple(elem, v, std::move(remaining_vars)));
1463 for (
unsigned int e=0; e != n_edges; ++e)
1465 const Node * node = elem->node_ptr(n_vertices+e);
1467 auto remaining_vars = edge_vars;
1469 erase_covered_vars(node, remaining_vars,
edges);
1470 if (remaining_vars.empty())
1473 erase_covered_vars(node, remaining_vars,
sides);
1474 if (remaining_vars.empty())
1477 if (!all_extra_hanging_dofs)
1479 erase_nonhanging_vars(node, remaining_vars,
vertices);
1480 if (remaining_vars.empty())
1484 erase_copied_vars(node,
false, remaining_vars);
1485 if (remaining_vars.empty())
1490 for (
auto var : remaining_vars)
1492 std::vector<dof_id_type> edge_dof_ids;
1493 std::vector<FValue> values;
1495 f.eval_old_dofs(*elem, n_vertices+e, var, edge_dof_ids, values);
1497 insert_ids(edge_dof_ids, values, node->processor_id());
1499 copied_nodes[node].second.insert(remaining_vars.begin(),
1500 remaining_vars.end());
1505 (node, std::make_tuple(elem, e, std::move(remaining_vars)));
1511 for (
unsigned int side=0; side != n_sides; ++side)
1513 const Node * node =
nullptr;
1514 unsigned short node_num = n_vertices+(
dim>2)*n_edges+side;
1516 node = elem->node_ptr(node_num);
1520 for (
unsigned int n = 0; n !=
n_nodes; ++n)
1522 if (!elem->is_face(n))
1525 if (elem->is_node_on_side(n, side))
1528 node = elem->node_ptr(node_num);
1537 auto remaining_vars = side_vars;
1539 erase_covered_vars(node, remaining_vars,
edges);
1540 if (remaining_vars.empty())
1543 erase_covered_vars(node, remaining_vars,
sides);
1544 if (remaining_vars.empty())
1547 if (!all_extra_hanging_dofs)
1549 erase_nonhanging_vars(node, remaining_vars,
vertices);
1550 if (remaining_vars.empty())
1554 erase_copied_vars(node,
false, remaining_vars);
1555 if (remaining_vars.empty())
1560 for (
auto var : remaining_vars)
1562 std::vector<dof_id_type> side_dof_ids;
1563 std::vector<FValue> values;
1565 f.eval_old_dofs(*elem, node_num, var, side_dof_ids, values);
1567 insert_ids(side_dof_ids, values, node->processor_id());
1569 copied_nodes[node].second.insert(remaining_vars.begin(),
1570 remaining_vars.end());
1575 (node, std::make_tuple(elem, side, std::move(remaining_vars)));
1585 if (!var.active_on_subdomain(elem->subdomain_id()))
1587 FEType fe_type = var.
type();
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,
1593 action.insert(elem_dof_ids, Ue);
1595 if (has_interior_nodes)
1597 std::vector<FValue> Un;
1598 std::vector<dof_id_type> node_dof_ids;
1600 f.eval_old_dofs(*elem,
n_nodes-1, v_num, node_dof_ids, Un);
1601 action.insert(node_dof_ids, Un);