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_edge_nodes = (
n_nodes > n_vertices &&
dim > 2);
1617 const bool has_side_nodes =
1618 (
n_nodes > n_vertices + ((
dim > 2) * n_edges));
1622 const bool has_interior_nodes =
1623 (
n_nodes > n_vertices + ((
dim > 2) * n_edges) + n_sides);
1628 if (!var.active_on_subdomain(elem->subdomain_id()))
1630 const FEType fe_type = var.
type();
1633 const bool add_p_level = dof_map.should_p_refine(vg);
1645 vertex_vars.insert(vertex_vars.end(), v_num);
1651 edge_vars.insert(edge_vars.end(), v_num);
1658 side_vars.insert(side_vars.end(), v_num);
1663 for (
unsigned int n = 0; n !=
n_nodes; ++n)
1664 if (elem->is_face(n))
1667 side_vars.insert(side_vars.end(), v_num);
1673 (has_interior_nodes &&
1676 #ifdef LIBMESH_ENABLE_AMR 1679 if ((
f.is_grid_projection() &&
1682 elem->p_level() == 0 &&
1688 #endif // LIBMESH_ENABLE_AMR 1699 auto erase_covered_vars = []
1702 auto covered_range = covered.equal_range(node);
1703 for (
const auto & v_ent :
as_range(covered_range))
1704 for (
const unsigned int var_covered :
1705 std::get<2>(v_ent.second))
1706 remaining.erase(var_covered);
1709 auto erase_nonhanging_vars = [&extra_hanging_dofs]
1712 auto covered_range = covered.equal_range(node);
1713 for (
const auto & v_ent :
as_range(covered_range))
1714 for (
const unsigned int var_covered :
1715 std::get<2>(v_ent.second))
1716 if (!extra_hanging_dofs[var_covered])
1717 remaining.erase(var_covered);
1720 auto erase_copied_vars = [&copied_nodes, &extra_hanging_dofs]
1721 (
const Node * node,
bool is_vertex,
var_set & remaining)
1723 auto copying_range = copied_nodes.equal_range(node);
1724 for (
const auto & v_ent :
as_range(copying_range))
1726 for (
const unsigned int var_covered :
1728 if (is_vertex || !extra_hanging_dofs[var_covered])
1729 remaining.erase(var_covered);
1731 for (
const unsigned int var_covered :
1732 v_ent.second.second)
1733 if (!is_vertex || !extra_hanging_dofs[var_covered])
1734 remaining.erase(var_covered);
1738 for (
unsigned int v=0; v != n_vertices; ++v)
1740 const Node * node = elem->node_ptr(v);
1742 auto remaining_vars = vertex_vars;
1744 erase_covered_vars(node, remaining_vars,
vertices);
1746 if (remaining_vars.empty())
1749 if (!all_extra_hanging_dofs)
1751 erase_nonhanging_vars(node, remaining_vars,
edges);
1752 if (remaining_vars.empty())
1755 erase_nonhanging_vars(node, remaining_vars,
sides);
1756 if (remaining_vars.empty())
1760 erase_copied_vars(node,
true, remaining_vars);
1761 if (remaining_vars.empty())
1766 std::vector<dof_id_type> node_dof_ids;
1767 std::vector<typename FFunctor::ValuePushType> values;
1769 for (
auto var : remaining_vars)
1771 f.eval_old_dofs(*elem, v, var, node_dof_ids, values);
1772 insert_ids(node_dof_ids, values, node->processor_id());
1774 copied_nodes[node].first.insert(remaining_vars.begin(),
1775 remaining_vars.end());
1780 (node, std::make_tuple(elem, v, std::move(remaining_vars)));
1785 for (
unsigned int e=0; e != n_edges; ++e)
1787 const Node * node = elem->node_ptr(n_vertices+e);
1789 auto remaining_vars = edge_vars;
1791 erase_covered_vars(node, remaining_vars,
edges);
1792 if (remaining_vars.empty())
1795 erase_covered_vars(node, remaining_vars,
sides);
1796 if (remaining_vars.empty())
1799 if (!all_extra_hanging_dofs)
1801 erase_nonhanging_vars(node, remaining_vars,
vertices);
1802 if (remaining_vars.empty())
1806 erase_copied_vars(node,
false, remaining_vars);
1807 if (remaining_vars.empty())
1812 std::vector<dof_id_type> edge_dof_ids;
1813 std::vector<typename FFunctor::ValuePushType> values;
1815 for (
auto var : remaining_vars)
1817 f.eval_old_dofs(*elem, n_vertices+e, var, edge_dof_ids, values);
1818 insert_ids(edge_dof_ids, values, node->processor_id());
1821 copied_nodes[node].second.insert(remaining_vars.begin(),
1822 remaining_vars.end());
1827 (node, std::make_tuple(elem, e, std::move(remaining_vars)));
1833 for (
unsigned int side=0; side != n_sides; ++side)
1835 const Node * node =
nullptr;
1836 unsigned short node_num = n_vertices+(
dim>2)*n_edges+side;
1838 node = elem->node_ptr(node_num);
1842 for (
unsigned int n = 0; n !=
n_nodes; ++n)
1844 if (!elem->is_face(n))
1847 if (elem->is_node_on_side(n, side))
1850 node = elem->node_ptr(node_num);
1859 auto remaining_vars = side_vars;
1861 erase_covered_vars(node, remaining_vars,
edges);
1862 if (remaining_vars.empty())
1865 erase_covered_vars(node, remaining_vars,
sides);
1866 if (remaining_vars.empty())
1869 if (!all_extra_hanging_dofs)
1871 erase_nonhanging_vars(node, remaining_vars,
vertices);
1872 if (remaining_vars.empty())
1876 erase_copied_vars(node,
false, remaining_vars);
1877 if (remaining_vars.empty())
1882 std::vector<dof_id_type> side_dof_ids;
1883 std::vector<typename FFunctor::ValuePushType> values;
1885 for (
auto var : remaining_vars)
1887 f.eval_old_dofs(*elem, node_num, var, side_dof_ids, values);
1888 insert_ids(side_dof_ids, values, node->processor_id());
1891 copied_nodes[node].second.insert(remaining_vars.begin(),
1892 remaining_vars.end());
1897 (node, std::make_tuple(elem, side, std::move(remaining_vars)));
1904 std::vector<typename FFunctor::ValuePushType> U;
1905 std::vector<dof_id_type> dof_ids;
1910 if (!var.active_on_subdomain(elem->subdomain_id()))
1912 FEType fe_type = var.
type();
1914 f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1916 action.insert(dof_ids, U);
1918 if (has_interior_nodes)
1920 f.eval_old_dofs(*elem,
n_nodes-1, v_num, dof_ids, U);
1921 action.insert(dof_ids, U);
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
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.
unsigned int var_group_from_var_number(unsigned int var_num) const
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
std::set< unsigned int > var_set
const DofMap & get_dof_map() const
const FEType & type() const