libMesh
Loading...
Searching...
No Matches
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)
 
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_ids (const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
 
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_ids (const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
 
void find_dofs_to_send (const Node &node, const Elem &elem, unsigned short node_num, const var_set &vars)
 
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_id (dof_id_type id, const InsertInput &val, processor_id_type pid)
 
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void insert_id (dof_id_type id, const InsertInput &val, 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< typename FFunctor::ValuePushType, processor_id_type > > new_ids_to_push
 
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > new_ids_to_save
 

Protected Attributes

std::vector< FEContinuityconts
 
std::vector< FEFieldTypefield_types
 

Detailed Description

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

Definition at line 280 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 300 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 281 of file generic_projector.h.

281: 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 283 of file generic_projector.h.

283: 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 2844 of file generic_projector.h.

2846{
2847 libmesh_assert (&node == elem.node_ptr(node_num));
2848
2849 // Any ghosted node in our range might have an owner who needs our
2850 // data
2851 const processor_id_type owner = node.processor_id();
2852 if (owner != system.processor_id())
2853 {
2854 const MeshBase & mesh = system.get_mesh();
2855 const DofMap & dof_map = system.get_dof_map();
2856
2857 // But let's check and see if we can be certain the owner can
2858 // compute any or all of its own dof coefficients on that node.
2859 std::vector<dof_id_type> node_dof_ids, patch_dof_ids;
2860 for (const auto & var : vars)
2861 {
2862 const Variable & variable = system.variable(var);
2863
2864 if (!variable.active_on_subdomain(elem.subdomain_id()))
2865 continue;
2866
2867 dof_map.dof_indices(elem, node_num, node_dof_ids, var);
2868 }
2869 libmesh_assert(std::is_sorted(node_dof_ids.begin(),
2870 node_dof_ids.end()));
2871 const std::vector<dof_id_type> & patch =
2872 (*this->projector.nodes_to_elem)[node.id()];
2873 for (const auto & elem_id : patch)
2874 {
2875 const Elem & patch_elem = mesh.elem_ref(elem_id);
2876 if (!patch_elem.active() || owner != patch_elem.processor_id())
2877 continue;
2878 dof_map.dof_indices(&patch_elem, patch_dof_ids);
2879 std::sort(patch_dof_ids.begin(), patch_dof_ids.end());
2880
2881 // Remove any node_dof_ids that we see can be calculated on
2882 // this element
2883 std::vector<dof_id_type> diff_ids(node_dof_ids.size());
2884 auto it = std::set_difference(node_dof_ids.begin(), node_dof_ids.end(),
2885 patch_dof_ids.begin(), patch_dof_ids.end(), diff_ids.begin());
2886 diff_ids.resize(it-diff_ids.begin());
2887 node_dof_ids.swap(diff_ids);
2888 if (node_dof_ids.empty())
2889 break;
2890 }
2891
2892 // Give ids_to_push default invalid pid: not yet computed
2893 for (auto id : node_dof_ids)
2894 new_ids_to_push[id].second = DofObject::invalid_processor_id;
2895 }
2896}
processor_id_type processor_id() const
const Variable & variable(unsigned int var) const
Return a constant reference to Variable var.
Definition system.C:2704
const DofMap & get_dof_map() const
Definition system.h:2417
const MeshBase & get_mesh() const
Definition system.h:2401
MeshBase & mesh
libmesh_assert(ctx)
uint8_t processor_id_type
Definition id_types.h:104
std::unordered_map< dof_id_type, std::pair< typename FFunctor::ValuePushType, processor_id_type > > new_ids_to_push

References libMesh::Elem::active(), libMesh::Variable::active_on_subdomain(), libMesh::DofMap::dof_indices(), libMesh::System::get_dof_map(), libMesh::System::get_mesh(), libMesh::DofObject::id(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), mesh, libMesh::Elem::node_ptr(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::Elem::subdomain_id(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system, and libMesh::System::variable().

◆ insert_id() [1/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type >
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_id ( dof_id_type  id,
const InsertInput &  val,
processor_id_type  pid 
)
inherited

Definition at line 1378 of file generic_projector.h.

1380{
1381 libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1382 "expected by the ProjectionAction");
1383}

◆ insert_id() [2/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_id ( dof_id_type  id,
const InsertInput &  val,
processor_id_type  pid 
)
inherited

◆ insert_ids() [1/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_ids ( const std::vector< dof_id_type > &  ids,
const std::vector< InsertInput > &  vals,
processor_id_type  pid 
)

Definition at line 213 of file generic_projector.h.

1424{
1425 libmesh_error_msg("ID insertion should only occur when the provided input matches that "
1426 "expected by the ProjectionAction");
1427}

◆ insert_ids() [2/2]

template<typename FFunctor , typename GFunctor , typename FValue , typename ProjectionAction >
template<typename InsertInput , typename std::enable_if< !std::is_same< typename ProjectionAction::InsertInput, InsertInput >::value, int >::type = 0>
void libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SubFunctor::insert_ids ( const std::vector< dof_id_type > &  ids,
const std::vector< InsertInput > &  vals,
processor_id_type  pid 
)

◆ 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 1941 of file generic_projector.h.

1943{
1944 auto merge_multimaps = [](ves_multimap & self, const ves_multimap & other_mm)
1945 {
1946 for (const auto & pair : other_mm)
1947 {
1948 const Node * node = pair.first;
1949 auto remaining_vars = std::get<2>(pair.second);
1950
1951 auto my_range = self.equal_range(node);
1952 for (const auto & v_ent : as_range(my_range))
1953 for (const unsigned int var_covered :
1954 std::get<2>(v_ent.second))
1955 remaining_vars.erase(var_covered);
1956
1957 if (!remaining_vars.empty())
1958 self.emplace
1959 (node, std::make_tuple(std::get<0>(pair.second),
1960 std::get<1>(pair.second),
1961 std::move(remaining_vars)));
1962 }
1963 };
1964
1965 merge_multimaps(vertices, other.vertices);
1966 merge_multimaps(edges, other.edges);
1967 merge_multimaps(sides, other.sides);
1968
1969 std::sort(interiors.begin(), interiors.end());
1970 std::vector<const Elem *> other_interiors = other.interiors;
1971 std::sort(other_interiors.begin(), other_interiors.end());
1972 std::vector<const Elem *> merged_interiors;
1973 std::set_union(interiors.begin(), interiors.end(),
1974 other_interiors.begin(), other_interiors.end(),
1975 std::back_inserter(merged_interiors));
1976 interiors.swap(merged_interiors);
1977
1978 SubFunctor::join(other);
1979}
void ErrorVector unsigned int
const Elem & get(const ElemType type_in)
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
std::unordered_multimap< const Node *, std::tuple< const Elem *, unsigned short, var_set > > ves_multimap
std::vector< const Elem * > interiors
void join(const SubFunctor &other)

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 >::SubFunctor::join(), 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 1470 of file generic_projector.h.

1472{
1473 new_ids_to_push.insert(other.new_ids_to_push.begin(), other.new_ids_to_push.end());
1474 new_ids_to_save.insert(other.new_ids_to_save.begin(), other.new_ids_to_save.end());
1475}
std::unordered_map< dof_id_type, typename FFunctor::ValuePushType > new_ids_to_save

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

Referenced by libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::SortAndCopy::join().

◆ 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 1480 of file generic_projector.h.

1482{
1483 LOG_SCOPE ("SortAndCopy::operator()","GenericProjector");
1484
1485 // Look at all the elements in the range. Directly copy values from
1486 // unchanged elements. For other elements, determine sets of
1487 // vertices, edge nodes, and side nodes to project.
1488 //
1489 // As per our other weird nomenclature, "sides" means faces in 3D
1490 // and edges in 2D, and "edges" gets skipped in 2D
1491 //
1492 // This gets tricky in the case of subdomain-restricted
1493 // variables, for which we might need to do the same projection
1494 // from different elements when evaluating different variables.
1495 // We'll keep track of which variables can be projected from which
1496 // elements.
1497
1498 // If we copy DoFs on a node, keep track of it so we don't bother
1499 // with any redundant interpolations or projections later.
1500 //
1501 // We still need to keep track of *which* variables get copied,
1502 // since we may be able to copy elements which lack some
1503 // subdomain-restricted variables.
1504 //
1505 // For extra_hanging_dofs FE types, we'll keep track of which
1506 // variables were copied from vertices, and which from edges/sides,
1507 // because those types need copies made from *both* on hanging
1508 // nodes.
1509 std::unordered_map<const Node *, std::pair<var_set, var_set>> copied_nodes;
1510
1511 const unsigned int sys_num = system.number();
1512
1513 // At hanging nodes for variables with extra hanging dofs we'll need
1514 // to do projections *separately* from vertex elements and side/edge
1515 // elements.
1516 std::vector<unsigned short> extra_hanging_dofs;
1517 bool all_extra_hanging_dofs = true;
1518 for (auto v_num : this->projector.variables)
1519 {
1520 if (extra_hanging_dofs.size() <= v_num)
1521 extra_hanging_dofs.resize(v_num+1, false);
1522 extra_hanging_dofs[v_num] =
1524
1525 if (!extra_hanging_dofs[v_num])
1526 all_extra_hanging_dofs = false;
1527 }
1528
1529 for (const auto & elem : range)
1530 {
1531 // If we're doing AMR, we might be able to copy more DoFs than
1532 // we interpolate or project.
1533 bool copy_this_elem = false;
1534
1535#ifdef LIBMESH_ENABLE_AMR
1536 // If we're projecting from an old grid
1537 if (f.is_grid_projection())
1538 {
1539 // If this element doesn't have an old_dof_object, but it
1540 // wasn't just refined or just coarsened into activity, then
1541 // it must be newly added, so the user is responsible for
1542 // setting the new dofs on it during a grid projection.
1543 const DofObject * old_dof_object = elem->get_old_dof_object();
1544 const Elem::RefinementState h_flag = elem->refinement_flag();
1545 const Elem::RefinementState p_flag = elem->p_refinement_flag();
1546 if (!old_dof_object &&
1547 h_flag != Elem::JUST_REFINED &&
1548 h_flag != Elem::JUST_COARSENED)
1549 continue;
1550
1551 // If this is an unchanged element, just copy everything
1552 if (h_flag != Elem::JUST_REFINED &&
1553 h_flag != Elem::JUST_COARSENED &&
1554 p_flag != Elem::JUST_REFINED &&
1555 p_flag != Elem::JUST_COARSENED)
1556 copy_this_elem = true;
1557 else
1558 {
1559 bool reinitted = false;
1560
1561 const unsigned int p_level = elem->p_level();
1562
1563 // If this element has a low order monomial which has
1564 // merely been h refined, copy it.
1565 const bool copy_possible =
1566 p_level == 0 &&
1567 h_flag != Elem::JUST_COARSENED &&
1568 p_flag != Elem::JUST_COARSENED;
1569
1570 std::vector<typename FFunctor::ValuePushType> Ue(1);
1571 std::vector<dof_id_type> elem_dof_ids(1);
1572
1573 for (auto v_num : this->projector.variables)
1574 {
1575 const Variable & var = system.variable(v_num);
1576 if (!var.active_on_subdomain(elem->subdomain_id()))
1577 continue;
1578 const FEType fe_type = var.type();
1579
1580 if (fe_type.family == MONOMIAL &&
1581 fe_type.order == CONSTANT &&
1582 copy_possible)
1583 {
1584 if (!reinitted)
1585 {
1586 reinitted = true;
1588 }
1589
1590 f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1591 elem_dof_ids, Ue);
1592
1593 action.insert(elem_dof_ids[0], Ue[0]);
1594 }
1595 }
1596 }
1597 }
1598#endif // LIBMESH_ENABLE_AMR
1599
1600 const int dim = elem->dim();
1601
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();
1605
1606 // In 1-D we already handle our sides as vertices
1607 const unsigned int n_sides = (dim > 1) * elem->n_sides();
1608
1609 // What variables are supported on each kind of node on this elem?
1610 var_set vertex_vars, edge_vars, side_vars;
1611
1612 // If we have non-vertex nodes, the first is an edge node, but
1613 // if we're in 2D we'll call that a side node
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);
1616
1617 // If we have even more nodes, the next is a side node.
1618 const bool has_side_nodes =
1619 (n_nodes > n_vertices + ((dim > 2) * n_edges));
1620
1621 // We may be out of nodes at this point or we have interior
1622 // nodes which may have DoFs to project too
1623 const bool has_interior_nodes =
1624 (n_nodes > n_vertices + ((dim > 2) * n_edges) + n_sides);
1625
1626 for (auto v_num : this->projector.variables)
1627 {
1628 const Variable & var = this->projector.system.variable(v_num);
1629 if (!var.active_on_subdomain(elem->subdomain_id()))
1630 continue;
1631 const FEType fe_type = var.type();
1632 const bool add_p_level = fe_type.p_refinement;
1633
1634 // If we're trying to do projections on an isogeometric
1635 // analysis mesh, only the finite element nodes constrained
1636 // by those spline nodes truly have delta function degrees
1637 // of freedom. We'll have to back out the spline degrees of
1638 // freedom indirectly later.
1639 if (fe_type.family == RATIONAL_BERNSTEIN &&
1640 elem->type() == NODEELEM)
1641 continue;
1642
1643 if (FEInterface::n_dofs_at_node(fe_type, elem, 0, add_p_level))
1644 vertex_vars.insert(vertex_vars.end(), v_num);
1645
1646 // The first non-vertex node is always an edge node if those
1647 // exist. All edge nodes have the same number of DoFs
1648 if (has_edge_nodes)
1649 if (FEInterface::n_dofs_at_node(fe_type, elem, n_vertices, add_p_level))
1650 edge_vars.insert(edge_vars.end(), v_num);
1651
1652 if (has_side_nodes)
1653 {
1654 if (dim != 3)
1655 {
1656 if (FEInterface::n_dofs_at_node(fe_type, elem, n_vertices, add_p_level))
1657 side_vars.insert(side_vars.end(), v_num);
1658 }
1659 else
1660 // In 3D, not all face nodes always have the same number of
1661 // DoFs! We'll loop over all sides to be safe.
1662 for (unsigned int n = 0; n != n_nodes; ++n)
1663 if (elem->is_face(n))
1664 if (FEInterface::n_dofs_at_node(fe_type, elem, n, add_p_level))
1665 {
1666 side_vars.insert(side_vars.end(), v_num);
1667 break;
1668 }
1669 }
1670
1671 if (FEInterface::n_dofs_per_elem(fe_type, elem, add_p_level) ||
1672 (has_interior_nodes &&
1673 FEInterface::n_dofs_at_node(fe_type, elem, n_nodes-1, add_p_level)))
1674 {
1675#ifdef LIBMESH_ENABLE_AMR
1676 // We may have already just copied constant monomials,
1677 // or we may be about to copy the whole element
1678 if ((f.is_grid_projection() &&
1679 fe_type.family == MONOMIAL &&
1680 fe_type.order == CONSTANT &&
1681 elem->p_level() == 0 &&
1682 elem->refinement_flag() != Elem::JUST_COARSENED &&
1683 elem->p_refinement_flag() != Elem::JUST_COARSENED)
1684 || copy_this_elem
1685 )
1686 continue;
1687#endif // LIBMESH_ENABLE_AMR
1688
1689 // We need to project any other variables
1690 if (interiors.empty() || interiors.back() != elem)
1691 interiors.push_back(elem);
1692 }
1693 }
1694
1695 // We'll use a greedy algorithm in most cases: if another
1696 // element has already claimed some of our DoFs, we'll let it do
1697 // the work.
1698 auto erase_covered_vars = []
1699 (const Node * node, var_set & remaining, const ves_multimap & covered)
1700 {
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);
1706 };
1707
1708 auto erase_nonhanging_vars = [&extra_hanging_dofs]
1709 (const Node * node, var_set & remaining, const ves_multimap & covered)
1710 {
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);
1717 };
1718
1719 auto erase_copied_vars = [&copied_nodes, &extra_hanging_dofs]
1720 (const Node * node, bool is_vertex, var_set & remaining)
1721 {
1722 auto copying_range = copied_nodes.equal_range(node);
1723 for (const auto & v_ent : as_range(copying_range))
1724 {
1725 for (const unsigned int var_covered :
1726 v_ent.second.first)
1727 if (is_vertex || !extra_hanging_dofs[var_covered])
1728 remaining.erase(var_covered);
1729
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);
1734 }
1735 };
1736
1737 // Treat polyhedron midnode as a vertex
1738 // NOTE: if we start having edge or side nodes on polyhedra, we need to use that +1 offset
1739 // in the edge and side nodes code as well!
1740#ifndef NDEBUG
1741 for (auto v_num : this->projector.variables)
1742 {
1743 const auto & family = this->projector.system.variable(v_num).type().family;
1744 // Add to the list once known to be correctly functioning with the midnode
1745 libmesh_assert(!has_poly_midnode || (family == LAGRANGE || family == MONOMIAL || family == XYZ));
1746 }
1747#endif
1748 for (const auto v : make_range(n_vertices + has_poly_midnode))
1749 {
1750 const Node * node = elem->node_ptr(v);
1751
1752 auto remaining_vars = vertex_vars;
1753
1754 erase_covered_vars(node, remaining_vars, vertices);
1755
1756 if (remaining_vars.empty())
1757 continue;
1758
1759 if (!all_extra_hanging_dofs)
1760 {
1761 erase_nonhanging_vars(node, remaining_vars, edges);
1762 if (remaining_vars.empty())
1763 continue;
1764
1765 erase_nonhanging_vars(node, remaining_vars, sides);
1766 if (remaining_vars.empty())
1767 continue;
1768 }
1769
1770 erase_copied_vars(node, true, remaining_vars);
1771 if (remaining_vars.empty())
1772 continue;
1773
1774 if (copy_this_elem)
1775 {
1776 std::vector<dof_id_type> node_dof_ids;
1777 std::vector<typename FFunctor::ValuePushType> values;
1778
1779 for (auto var : remaining_vars)
1780 {
1781 f.eval_old_dofs(*elem, v, var, node_dof_ids, values);
1782 insert_ids(node_dof_ids, values, node->processor_id());
1783 }
1784 copied_nodes[node].first.insert(remaining_vars.begin(),
1785 remaining_vars.end());
1786 this->find_dofs_to_send(*node, *elem, v, remaining_vars);
1787 }
1788 else
1789 vertices.emplace
1790 (node, std::make_tuple(elem, v, std::move(remaining_vars)));
1791 }
1792
1793 if (has_edge_nodes)
1794 {
1795 for (unsigned int e=0; e != n_edges; ++e)
1796 {
1797 const Node * node = elem->node_ptr(n_vertices+e);
1798
1799 auto remaining_vars = edge_vars;
1800
1801 erase_covered_vars(node, remaining_vars, edges);
1802 if (remaining_vars.empty())
1803 continue;
1804
1805 erase_covered_vars(node, remaining_vars, sides);
1806 if (remaining_vars.empty())
1807 continue;
1808
1809 if (!all_extra_hanging_dofs)
1810 {
1811 erase_nonhanging_vars(node, remaining_vars, vertices);
1812 if (remaining_vars.empty())
1813 continue;
1814 }
1815
1816 erase_copied_vars(node, false, remaining_vars);
1817 if (remaining_vars.empty())
1818 continue;
1819
1820 if (copy_this_elem)
1821 {
1822 std::vector<dof_id_type> edge_dof_ids;
1823 std::vector<typename FFunctor::ValuePushType> values;
1824
1825 for (auto var : remaining_vars)
1826 {
1827 f.eval_old_dofs(*elem, n_vertices+e, var, edge_dof_ids, values);
1828 insert_ids(edge_dof_ids, values, node->processor_id());
1829 }
1830
1831 copied_nodes[node].second.insert(remaining_vars.begin(),
1832 remaining_vars.end());
1833 this->find_dofs_to_send(*node, *elem, n_vertices+e, remaining_vars);
1834 }
1835 else
1836 edges.emplace
1837 (node, std::make_tuple(elem, e, std::move(remaining_vars)));
1838 }
1839 }
1840
1841 if (has_side_nodes)
1842 {
1843 for (unsigned int side=0; side != n_sides; ++side)
1844 {
1845 const Node * node = nullptr;
1846 unsigned short node_num = n_vertices+(dim>2)*n_edges+side;
1847 if (dim != 3)
1848 node = elem->node_ptr(node_num);
1849 else
1850 {
1851 // In 3D only some sides may have nodes
1852 for (unsigned int n = 0; n != n_nodes; ++n)
1853 {
1854 if (!elem->is_face(n))
1855 continue;
1856
1857 if (elem->is_node_on_side(n, side))
1858 {
1859 node_num = n;
1860 node = elem->node_ptr(node_num);
1861 break;
1862 }
1863 }
1864 }
1865
1866 if (!node)
1867 continue;
1868
1869 auto remaining_vars = side_vars;
1870
1871 erase_covered_vars(node, remaining_vars, edges);
1872 if (remaining_vars.empty())
1873 continue;
1874
1875 erase_covered_vars(node, remaining_vars, sides);
1876 if (remaining_vars.empty())
1877 continue;
1878
1879 if (!all_extra_hanging_dofs)
1880 {
1881 erase_nonhanging_vars(node, remaining_vars, vertices);
1882 if (remaining_vars.empty())
1883 continue;
1884 }
1885
1886 erase_copied_vars(node, false, remaining_vars);
1887 if (remaining_vars.empty())
1888 continue;
1889
1890 if (copy_this_elem)
1891 {
1892 std::vector<dof_id_type> side_dof_ids;
1893 std::vector<typename FFunctor::ValuePushType> values;
1894
1895 for (auto var : remaining_vars)
1896 {
1897 f.eval_old_dofs(*elem, node_num, var, side_dof_ids, values);
1898 insert_ids(side_dof_ids, values, node->processor_id());
1899 }
1900
1901 copied_nodes[node].second.insert(remaining_vars.begin(),
1902 remaining_vars.end());
1903 this->find_dofs_to_send(*node, *elem, node_num, remaining_vars);
1904 }
1905 else
1906 sides.emplace
1907 (node, std::make_tuple(elem, side, std::move(remaining_vars)));
1908 }
1909 }
1910
1911 // Elements with elemental dofs might need those copied too.
1912 if (copy_this_elem)
1913 {
1914 std::vector<typename FFunctor::ValuePushType> U;
1915 std::vector<dof_id_type> dof_ids;
1916
1917 for (auto v_num : this->projector.variables)
1918 {
1919 const Variable & var = system.variable(v_num);
1920 if (!var.active_on_subdomain(elem->subdomain_id()))
1921 continue;
1922 FEType fe_type = var.type();
1923
1924 f.eval_old_dofs(*elem, fe_type, sys_num, v_num,
1925 dof_ids, U);
1926 action.insert(dof_ids, U);
1927
1928 if (has_interior_nodes)
1929 {
1930 f.eval_old_dofs(*elem, n_nodes-1, v_num, dof_ids, U);
1931 action.insert(dof_ids, U);
1932 }
1933 }
1934 }
1935 }
1936}
unsigned int dim
RefinementState
Enumeration of possible element refinement states.
Definition elem.h:1446
@ JUST_COARSENED
Definition elem.h:1450
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
static unsigned int n_dofs_per_elem(const unsigned int dim, const FEType &fe_t, const ElemType t)
static bool extra_hanging_dofs(const FEType &fe_t)
virtual void pre_fe_reinit(const System &, const Elem *e)
Reinitializes local data vectors/matrices on the current geometric element.
bool p_refinement
Whether or not the finite elements for this type increase their p refinement level on geometric eleme...
Definition fe_type.h:292
FEFamily family
The type of finite element.
Definition fe_type.h:228
const std::vector< unsigned int > & variables
std::set< unsigned int > var_set
unsigned int number() const
Definition system.h:2393
const FEType & type() const
Definition variable.h:144
@ RATIONAL_BERNSTEIN
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...
Definition int_range.h:176
void insert_ids(const std::vector< dof_id_type > &ids, const std::vector< InsertInput > &vals, processor_id_type pid)
void find_dofs_to_send(const Node &node, const Elem &elem, unsigned short node_num, const var_set &vars)
const dof_id_type n_nodes
Definition tecplot_io.C:67

References libMesh::Variable::active_on_subdomain(), libMesh::as_range(), libMesh::C0POLYHEDRON, libMesh::CONSTANT, dim, libMesh::FEInterface::extra_hanging_dofs(), libMesh::FEType::family, libMesh::DofObject::get_old_dof_object(), libMesh::Elem::JUST_COARSENED, libMesh::Elem::JUST_REFINED, libMesh::LAGRANGE, libMesh::libmesh_assert(), libMesh::make_range(), libMesh::MONOMIAL, libMesh::FEInterface::n_dofs_at_node(), libMesh::FEInterface::n_dofs_per_elem(), n_nodes, libMesh::NODEELEM, libMesh::System::number(), libMesh::FEType::order, libMesh::FEType::p_refinement, libMesh::DofObject::processor_id(), libMesh::RATIONAL_BERNSTEIN, libMesh::Variable::system(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::system, libMesh::Variable::type(), libMesh::System::variable(), and libMesh::XYZ.

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 231 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 236 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

◆ 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 232 of file generic_projector.h.

◆ field_types

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

◆ 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<typename FFunctor::ValuePushType, 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, typename FFunctor::ValuePushType> 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

◆ 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 242 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: