21 #include "libmesh/dof_map.h" 
   22 #include "libmesh/fe.h" 
   23 #include "libmesh/fe_interface.h" 
   24 #include "libmesh/elem.h" 
   25 #include "libmesh/remote_elem.h" 
   26 #include "libmesh/threads.h" 
   27 #include "libmesh/enum_to_string.h" 
   34 void lagrange_nodal_soln(
const Elem * elem,
 
   36                          const std::vector<Number> & elem_soln,
 
   37                          std::vector<Number> &       nodal_soln)
 
   39   const unsigned int n_nodes = elem->n_nodes();
 
   42   const Order totalorder = static_cast<Order>(order+elem->p_level());
 
   57               libmesh_assert_equal_to (elem_soln.size(), 2);
 
   58               libmesh_assert_equal_to (nodal_soln.size(), 3);
 
   60               nodal_soln[0] = elem_soln[0];
 
   61               nodal_soln[1] = elem_soln[1];
 
   62               nodal_soln[2] = .5*(elem_soln[0] + elem_soln[1]);
 
   69               libmesh_assert_equal_to (elem_soln.size(), 2);
 
   70               libmesh_assert_equal_to (nodal_soln.size(), 4);
 
   72               nodal_soln[0] = elem_soln[0];
 
   73               nodal_soln[1] = elem_soln[1];
 
   74               nodal_soln[2] = (2.*elem_soln[0] + elem_soln[1])/3.;
 
   75               nodal_soln[3] = (elem_soln[0] + 2.*elem_soln[1])/3.;
 
   83               libmesh_assert_equal_to (elem_soln.size(), 3);
 
   84               libmesh_assert_equal_to (nodal_soln.size(), 6);
 
   86               nodal_soln[0] = elem_soln[0];
 
   87               nodal_soln[1] = elem_soln[1];
 
   88               nodal_soln[2] = elem_soln[2];
 
   89               nodal_soln[3] = .5*(elem_soln[0] + elem_soln[1]);
 
   90               nodal_soln[4] = .5*(elem_soln[1] + elem_soln[2]);
 
   91               nodal_soln[5] = .5*(elem_soln[2] + elem_soln[0]);
 
  100               libmesh_assert_equal_to (elem_soln.size(), 4);
 
  103                 libmesh_assert_equal_to (nodal_soln.size(), 8);
 
  105                 libmesh_assert_equal_to (nodal_soln.size(), 9);
 
  108               nodal_soln[0] = elem_soln[0];
 
  109               nodal_soln[1] = elem_soln[1];
 
  110               nodal_soln[2] = elem_soln[2];
 
  111               nodal_soln[3] = elem_soln[3];
 
  112               nodal_soln[4] = .5*(elem_soln[0] + elem_soln[1]);
 
  113               nodal_soln[5] = .5*(elem_soln[1] + elem_soln[2]);
 
  114               nodal_soln[6] = .5*(elem_soln[2] + elem_soln[3]);
 
  115               nodal_soln[7] = .5*(elem_soln[3] + elem_soln[0]);
 
  118                 nodal_soln[8] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
 
  126               libmesh_assert_equal_to (elem_soln.size(), 4);
 
  127               libmesh_assert_equal_to (nodal_soln.size(), 10);
 
  129               nodal_soln[0] = elem_soln[0];
 
  130               nodal_soln[1] = elem_soln[1];
 
  131               nodal_soln[2] = elem_soln[2];
 
  132               nodal_soln[3] = elem_soln[3];
 
  133               nodal_soln[4] = .5*(elem_soln[0] + elem_soln[1]);
 
  134               nodal_soln[5] = .5*(elem_soln[1] + elem_soln[2]);
 
  135               nodal_soln[6] = .5*(elem_soln[2] + elem_soln[0]);
 
  136               nodal_soln[7] = .5*(elem_soln[3] + elem_soln[0]);
 
  137               nodal_soln[8] = .5*(elem_soln[3] + elem_soln[1]);
 
  138               nodal_soln[9] = .5*(elem_soln[3] + elem_soln[2]);
 
  147               libmesh_assert_equal_to (elem_soln.size(), 8);
 
  150                 libmesh_assert_equal_to (nodal_soln.size(), 20);
 
  152                 libmesh_assert_equal_to (nodal_soln.size(), 27);
 
  154               nodal_soln[0]  = elem_soln[0];
 
  155               nodal_soln[1]  = elem_soln[1];
 
  156               nodal_soln[2]  = elem_soln[2];
 
  157               nodal_soln[3]  = elem_soln[3];
 
  158               nodal_soln[4]  = elem_soln[4];
 
  159               nodal_soln[5]  = elem_soln[5];
 
  160               nodal_soln[6]  = elem_soln[6];
 
  161               nodal_soln[7]  = elem_soln[7];
 
  162               nodal_soln[8]  = .5*(elem_soln[0] + elem_soln[1]);
 
  163               nodal_soln[9]  = .5*(elem_soln[1] + elem_soln[2]);
 
  164               nodal_soln[10] = .5*(elem_soln[2] + elem_soln[3]);
 
  165               nodal_soln[11] = .5*(elem_soln[3] + elem_soln[0]);
 
  166               nodal_soln[12] = .5*(elem_soln[0] + elem_soln[4]);
 
  167               nodal_soln[13] = .5*(elem_soln[1] + elem_soln[5]);
 
  168               nodal_soln[14] = .5*(elem_soln[2] + elem_soln[6]);
 
  169               nodal_soln[15] = .5*(elem_soln[3] + elem_soln[7]);
 
  170               nodal_soln[16] = .5*(elem_soln[4] + elem_soln[5]);
 
  171               nodal_soln[17] = .5*(elem_soln[5] + elem_soln[6]);
 
  172               nodal_soln[18] = .5*(elem_soln[6] + elem_soln[7]);
 
  173               nodal_soln[19] = .5*(elem_soln[4] + elem_soln[7]);
 
  177                   nodal_soln[20] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
 
  178                   nodal_soln[21] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[4] + elem_soln[5]);
 
  179                   nodal_soln[22] = .25*(elem_soln[1] + elem_soln[2] + elem_soln[5] + elem_soln[6]);
 
  180                   nodal_soln[23] = .25*(elem_soln[2] + elem_soln[3] + elem_soln[6] + elem_soln[7]);
 
  181                   nodal_soln[24] = .25*(elem_soln[3] + elem_soln[0] + elem_soln[7] + elem_soln[4]);
 
  182                   nodal_soln[25] = .25*(elem_soln[4] + elem_soln[5] + elem_soln[6] + elem_soln[7]);
 
  184                   nodal_soln[26] = .125*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3] +
 
  185                                          elem_soln[4] + elem_soln[5] + elem_soln[6] + elem_soln[7]);
 
  195               libmesh_assert_equal_to (elem_soln.size(), 6);
 
  198                 libmesh_assert_equal_to (nodal_soln.size(), 15);
 
  200                 libmesh_assert_equal_to (nodal_soln.size(), 18);
 
  202               nodal_soln[0]  = elem_soln[0];
 
  203               nodal_soln[1]  = elem_soln[1];
 
  204               nodal_soln[2]  = elem_soln[2];
 
  205               nodal_soln[3]  = elem_soln[3];
 
  206               nodal_soln[4]  = elem_soln[4];
 
  207               nodal_soln[5]  = elem_soln[5];
 
  208               nodal_soln[6]  = .5*(elem_soln[0] + elem_soln[1]);
 
  209               nodal_soln[7]  = .5*(elem_soln[1] + elem_soln[2]);
 
  210               nodal_soln[8]  = .5*(elem_soln[0] + elem_soln[2]);
 
  211               nodal_soln[9]  = .5*(elem_soln[0] + elem_soln[3]);
 
  212               nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
 
  213               nodal_soln[11] = .5*(elem_soln[2] + elem_soln[5]);
 
  214               nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
 
  215               nodal_soln[13] = .5*(elem_soln[4] + elem_soln[5]);
 
  216               nodal_soln[14] = .5*(elem_soln[3] + elem_soln[5]);
 
  220                   nodal_soln[15] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[4] + elem_soln[3]);
 
  221                   nodal_soln[16] = .25*(elem_soln[1] + elem_soln[2] + elem_soln[5] + elem_soln[4]);
 
  222                   nodal_soln[17] = .25*(elem_soln[2] + elem_soln[0] + elem_soln[3] + elem_soln[5]);
 
  230               libmesh_assert_equal_to (elem_soln.size(), 5);
 
  231               libmesh_assert_equal_to (nodal_soln.size(), 13);
 
  233               nodal_soln[0]  = elem_soln[0];
 
  234               nodal_soln[1]  = elem_soln[1];
 
  235               nodal_soln[2]  = elem_soln[2];
 
  236               nodal_soln[3]  = elem_soln[3];
 
  237               nodal_soln[4]  = elem_soln[4];
 
  238               nodal_soln[5]  = .5*(elem_soln[0] + elem_soln[1]);
 
  239               nodal_soln[6]  = .5*(elem_soln[1] + elem_soln[2]);
 
  240               nodal_soln[7]  = .5*(elem_soln[2] + elem_soln[3]);
 
  241               nodal_soln[8]  = .5*(elem_soln[3] + elem_soln[0]);
 
  242               nodal_soln[9]  = .5*(elem_soln[0] + elem_soln[4]);
 
  243               nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
 
  244               nodal_soln[11] = .5*(elem_soln[2] + elem_soln[4]);
 
  245               nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
 
  252               libmesh_assert_equal_to (elem_soln.size(), 5);
 
  253               libmesh_assert_equal_to (nodal_soln.size(), 14);
 
  255               nodal_soln[0]  = elem_soln[0];
 
  256               nodal_soln[1]  = elem_soln[1];
 
  257               nodal_soln[2]  = elem_soln[2];
 
  258               nodal_soln[3]  = elem_soln[3];
 
  259               nodal_soln[4]  = elem_soln[4];
 
  260               nodal_soln[5]  = .5*(elem_soln[0] + elem_soln[1]);
 
  261               nodal_soln[6]  = .5*(elem_soln[1] + elem_soln[2]);
 
  262               nodal_soln[7]  = .5*(elem_soln[2] + elem_soln[3]);
 
  263               nodal_soln[8]  = .5*(elem_soln[3] + elem_soln[0]);
 
  264               nodal_soln[9]  = .5*(elem_soln[0] + elem_soln[4]);
 
  265               nodal_soln[10] = .5*(elem_soln[1] + elem_soln[4]);
 
  266               nodal_soln[11] = .5*(elem_soln[2] + elem_soln[4]);
 
  267               nodal_soln[12] = .5*(elem_soln[3] + elem_soln[4]);
 
  268               nodal_soln[13] = .25*(elem_soln[0] + elem_soln[1] + elem_soln[2] + elem_soln[3]);
 
  277               nodal_soln = elem_soln;
 
  290               libmesh_assert_equal_to (elem_soln.size(), 3);
 
  291               libmesh_assert_equal_to (nodal_soln.size(), 4);
 
  294               nodal_soln[0] = elem_soln[0];
 
  295               nodal_soln[1] = elem_soln[1];
 
  296               nodal_soln[2] = (2.*elem_soln[0] - elem_soln[1] +
 
  298               nodal_soln[3] = (-elem_soln[0] + 2.*elem_soln[1] +
 
  307               nodal_soln = elem_soln;
 
  321         nodal_soln = elem_soln;
 
  330 unsigned int lagrange_n_dofs(
const ElemType t, 
const Order o)
 
  458       libmesh_error_msg(
"ERROR: Invalid Order " << 
Utility::enum_to_string(o) << 
" selected for LAGRANGE FE family!");
 
  465 unsigned int lagrange_n_dofs_at_node(
const ElemType t,
 
  467                                      const unsigned int n)
 
  660       libmesh_error_msg(
"Unsupported order: " << o );
 
  666 #ifdef LIBMESH_ENABLE_AMR 
  667 void lagrange_compute_constraints (DofConstraints & constraints,
 
  669                                    const unsigned int variable_number,
 
  680   if (elem->subactive())
 
  683   FEType fe_type = dof_map.variable_type(variable_number);
 
  684   fe_type.order = static_cast<Order>(fe_type.order + elem->p_level());
 
  687   std::vector<dof_id_type> my_dof_indices, parent_dof_indices;
 
  688   std::unique_ptr<const Elem> my_side, parent_side;
 
  692   for (
auto s : elem->side_index_range())
 
  693     if (elem->neighbor_ptr(s) != 
nullptr &&
 
  695       if (elem->neighbor_ptr(s)->level() < elem->level()) 
 
  699           const Elem * parent = elem->parent();
 
  706           elem->build_side_ptr(my_side, s);
 
  707           parent->build_side_ptr(parent_side, s);
 
  713           my_dof_indices.reserve (my_side->n_nodes());
 
  714           parent_dof_indices.reserve (parent_side->n_nodes());
 
  716           dof_map.dof_indices (my_side.get(), my_dof_indices,
 
  718           dof_map.dof_indices (parent_side.get(), parent_dof_indices,
 
  721           const unsigned int n_side_dofs =
 
  723           const unsigned int n_parent_side_dofs =
 
  725           for (
unsigned int my_dof=0; my_dof != n_side_dofs; my_dof++)
 
  727               libmesh_assert_less (my_dof, my_side->n_nodes());
 
  730               const dof_id_type my_dof_g = my_dof_indices[my_dof];
 
  734               bool self_constraint = 
false;
 
  735               for (
unsigned int their_dof=0;
 
  736                    their_dof != n_parent_side_dofs; their_dof++)
 
  738                   libmesh_assert_less (their_dof, parent_side->n_nodes());
 
  742                     parent_dof_indices[their_dof];
 
  744                   if (their_dof_g == my_dof_g)
 
  746                       self_constraint = 
true;
 
  762                 if (dof_map.is_constrained_dof(my_dof_g))
 
  765                 constraint_row = &(constraints[my_dof_g]);
 
  770               const Point & support_point = my_side->point(my_dof);
 
  778               for (
unsigned int their_dof=0;
 
  779                    their_dof != n_parent_side_dofs; their_dof++)
 
  781                   libmesh_assert_less (their_dof, parent_side->n_nodes());
 
  785                     parent_dof_indices[their_dof];
 
  795                   if ((
std::abs(their_dof_value) > 1.e-5) &&
 
  798                       constraint_row->insert(std::make_pair (their_dof_g,
 
  804                   else if (their_dof_value >= .999)
 
  805                     libmesh_assert_equal_to (my_dof_g, their_dof_g);
 
  811 #endif // #ifdef LIBMESH_ENABLE_AMR 
  822                                 const std::vector<Number> & elem_soln,
 
  823                                 std::vector<Number> & nodal_soln)
 
  824 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
 
  829                                 const std::vector<Number> & elem_soln,
 
  830                                 std::vector<Number> & nodal_soln)
 
  831 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
 
  836                                 const std::vector<Number> & elem_soln,
 
  837                                 std::vector<Number> & nodal_soln)
 
  838 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
 
  843                                 const std::vector<Number> & elem_soln,
 
  844                                 std::vector<Number> & nodal_soln)
 
  845 { lagrange_nodal_soln(elem, order, elem_soln, nodal_soln); }
 
  894 #ifdef LIBMESH_ENABLE_AMR 
  898                                           const unsigned int variable_number,
 
  900 { lagrange_compute_constraints(constraints, dof_map, variable_number, elem, 2); }
 
  905                                           const unsigned int variable_number,
 
  907 { lagrange_compute_constraints(constraints, dof_map, variable_number, elem, 3); }
 
  908 #endif // LIBMESH_ENABLE_AMR