1483 LOG_SCOPE (
"SortAndCopy::operator()",
"GenericProjector");
1509 std::unordered_map<const Node *, std::pair<var_set, var_set>> copied_nodes;
1516 std::vector<unsigned short> extra_hanging_dofs;
1517 bool all_extra_hanging_dofs =
true;
1520 if (extra_hanging_dofs.size() <= v_num)
1521 extra_hanging_dofs.resize(v_num+1,
false);
1522 extra_hanging_dofs[v_num] =
1525 if (!extra_hanging_dofs[v_num])
1526 all_extra_hanging_dofs =
false;
1529 for (
const auto & elem : range)
1533 bool copy_this_elem =
false;
1535 #ifdef LIBMESH_ENABLE_AMR 1537 if (
f.is_grid_projection())
1543 const DofObject * old_dof_object = elem->get_old_dof_object();
1546 if (!old_dof_object &&
1556 copy_this_elem =
true;
1559 bool reinitted =
false;
1561 const unsigned int p_level = elem->p_level();
1565 const bool copy_possible =
1570 std::vector<typename FFunctor::ValuePushType> Ue(1);
1571 std::vector<dof_id_type> elem_dof_ids(1);
1576 if (!var.active_on_subdomain(elem->subdomain_id()))
1578 const FEType fe_type = var.
type();
1590 f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1593 action.insert(elem_dof_ids[0], Ue[0]);
1598 #endif // LIBMESH_ENABLE_AMR 1600 const int dim = elem->dim();
1602 const unsigned int n_vertices = elem->n_vertices();
1603 const unsigned int n_edges = elem->n_edges();
1604 const unsigned int n_nodes = elem->n_nodes();
1607 const unsigned int n_sides = (
dim > 1) * elem->n_sides();
1610 var_set vertex_vars, edge_vars, side_vars;
1614 const bool has_poly_midnode = (elem->type() ==
C0POLYHEDRON) && (
n_nodes == n_vertices + 1);
1615 const bool has_edge_nodes = (
n_nodes > n_vertices + has_poly_midnode &&
dim > 2);
1618 const bool has_side_nodes =
1619 (
n_nodes > n_vertices + ((
dim > 2) * n_edges));
1623 const bool has_interior_nodes =
1624 (
n_nodes > n_vertices + ((
dim > 2) * n_edges) + n_sides);
1629 if (!var.active_on_subdomain(elem->subdomain_id()))
1631 const FEType fe_type = var.
type();
1644 vertex_vars.insert(vertex_vars.end(), v_num);
1650 edge_vars.insert(edge_vars.end(), v_num);
1657 side_vars.insert(side_vars.end(), v_num);
1662 for (
unsigned int n = 0; n !=
n_nodes; ++n)
1663 if (elem->is_face(n))
1666 side_vars.insert(side_vars.end(), v_num);
1672 (has_interior_nodes &&
1675 #ifdef LIBMESH_ENABLE_AMR 1678 if ((
f.is_grid_projection() &&
1681 elem->p_level() == 0 &&
1687 #endif // LIBMESH_ENABLE_AMR 1698 auto erase_covered_vars = []
1701 auto covered_range = covered.equal_range(node);
1702 for (
const auto & v_ent :
as_range(covered_range))
1703 for (
const unsigned int var_covered :
1704 std::get<2>(v_ent.second))
1705 remaining.erase(var_covered);
1708 auto erase_nonhanging_vars = [&extra_hanging_dofs]
1711 auto covered_range = covered.equal_range(node);
1712 for (
const auto & v_ent :
as_range(covered_range))
1713 for (
const unsigned int var_covered :
1714 std::get<2>(v_ent.second))
1715 if (!extra_hanging_dofs[var_covered])
1716 remaining.erase(var_covered);
1719 auto erase_copied_vars = [&copied_nodes, &extra_hanging_dofs]
1720 (
const Node * node,
bool is_vertex,
var_set & remaining)
1722 auto copying_range = copied_nodes.equal_range(node);
1723 for (
const auto & v_ent :
as_range(copying_range))
1725 for (
const unsigned int var_covered :
1727 if (is_vertex || !extra_hanging_dofs[var_covered])
1728 remaining.erase(var_covered);
1730 for (
const unsigned int var_covered :
1731 v_ent.second.second)
1732 if (!is_vertex || !extra_hanging_dofs[var_covered])
1733 remaining.erase(var_covered);
1748 for (
const auto v :
make_range(n_vertices + has_poly_midnode))
1750 const Node * node = elem->node_ptr(v);
1752 auto remaining_vars = vertex_vars;
1754 erase_covered_vars(node, remaining_vars,
vertices);
1756 if (remaining_vars.empty())
1759 if (!all_extra_hanging_dofs)
1761 erase_nonhanging_vars(node, remaining_vars,
edges);
1762 if (remaining_vars.empty())
1765 erase_nonhanging_vars(node, remaining_vars,
sides);
1766 if (remaining_vars.empty())
1770 erase_copied_vars(node,
true, remaining_vars);
1771 if (remaining_vars.empty())
1776 std::vector<dof_id_type> node_dof_ids;
1777 std::vector<typename FFunctor::ValuePushType> values;
1779 for (
auto var : remaining_vars)
1781 f.eval_old_dofs(*elem, v, var, node_dof_ids, values);
1782 insert_ids(node_dof_ids, values, node->processor_id());
1784 copied_nodes[node].first.insert(remaining_vars.begin(),
1785 remaining_vars.end());
1790 (node, std::make_tuple(elem, v, std::move(remaining_vars)));
1795 for (
unsigned int e=0; e != n_edges; ++e)
1797 const Node * node = elem->node_ptr(n_vertices+e);
1799 auto remaining_vars = edge_vars;
1801 erase_covered_vars(node, remaining_vars,
edges);
1802 if (remaining_vars.empty())
1805 erase_covered_vars(node, remaining_vars,
sides);
1806 if (remaining_vars.empty())
1809 if (!all_extra_hanging_dofs)
1811 erase_nonhanging_vars(node, remaining_vars,
vertices);
1812 if (remaining_vars.empty())
1816 erase_copied_vars(node,
false, remaining_vars);
1817 if (remaining_vars.empty())
1822 std::vector<dof_id_type> edge_dof_ids;
1823 std::vector<typename FFunctor::ValuePushType> values;
1825 for (
auto var : remaining_vars)
1827 f.eval_old_dofs(*elem, n_vertices+e, var, edge_dof_ids, values);
1828 insert_ids(edge_dof_ids, values, node->processor_id());
1831 copied_nodes[node].second.insert(remaining_vars.begin(),
1832 remaining_vars.end());
1837 (node, std::make_tuple(elem, e, std::move(remaining_vars)));
1843 for (
unsigned int side=0; side != n_sides; ++side)
1845 const Node * node =
nullptr;
1846 unsigned short node_num = n_vertices+(
dim>2)*n_edges+side;
1848 node = elem->node_ptr(node_num);
1852 for (
unsigned int n = 0; n !=
n_nodes; ++n)
1854 if (!elem->is_face(n))
1857 if (elem->is_node_on_side(n, side))
1860 node = elem->node_ptr(node_num);
1869 auto remaining_vars = side_vars;
1871 erase_covered_vars(node, remaining_vars,
edges);
1872 if (remaining_vars.empty())
1875 erase_covered_vars(node, remaining_vars,
sides);
1876 if (remaining_vars.empty())
1879 if (!all_extra_hanging_dofs)
1881 erase_nonhanging_vars(node, remaining_vars,
vertices);
1882 if (remaining_vars.empty())
1886 erase_copied_vars(node,
false, remaining_vars);
1887 if (remaining_vars.empty())
1892 std::vector<dof_id_type> side_dof_ids;
1893 std::vector<typename FFunctor::ValuePushType> values;
1895 for (
auto var : remaining_vars)
1897 f.eval_old_dofs(*elem, node_num, var, side_dof_ids, values);
1898 insert_ids(side_dof_ids, values, node->processor_id());
1901 copied_nodes[node].second.insert(remaining_vars.begin(),
1902 remaining_vars.end());
1907 (node, std::make_tuple(elem, side, std::move(remaining_vars)));
1914 std::vector<typename FFunctor::ValuePushType> U;
1915 std::vector<dof_id_type> dof_ids;
1920 if (!var.active_on_subdomain(elem->subdomain_id()))
1922 FEType fe_type = var.
type();
1924 f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1926 action.insert(dof_ids, U);
1928 if (has_interior_nodes)
1930 f.eval_old_dofs(*elem,
n_nodes-1, v_num, dof_ids, U);
1931 action.insert(dof_ids, U);
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
FEFamily family
The type of finite element.
bool p_refinement
Whether or not the finite elements for this type increase their p refinement level on geometric eleme...
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
std::unordered_multimap< const Node *, std::tuple< const Elem *, unsigned short, var_set > > ves_multimap
RefinementState
Enumeration of possible element refinement states.
std::vector< const Elem * > interiors
const dof_id_type n_nodes
unsigned int number() const
static bool extra_hanging_dofs(const FEType &fe_t)
void insert_ids(const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
const std::vector< unsigned int > & variables
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
void find_dofs_to_send(const Node &node, const Elem &elem, unsigned short node_num, const var_set &vars)
GenericProjector & projector
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
std::set< unsigned int > var_set
const FEType & type() const