21 #include "libmesh/fe.h" 
   22 #include "libmesh/inf_fe.h" 
   23 #include "libmesh/libmesh_logging.h" 
   24 #include "libmesh/auto_ptr.h"  
   26 #include "libmesh/boundary_info.h" 
   27 #include "libmesh/mesh_base.h" 
   28 #include "libmesh/dense_matrix.h" 
   29 #include "libmesh/dense_vector.h" 
   30 #include "libmesh/dof_map.h" 
   31 #include "libmesh/elem.h" 
   32 #include "libmesh/fe_interface.h" 
   33 #include "libmesh/numeric_vector.h" 
   34 #include "libmesh/periodic_boundary_base.h" 
   35 #include "libmesh/periodic_boundaries.h" 
   36 #include "libmesh/quadrature.h" 
   37 #include "libmesh/quadrature_gauss.h" 
   38 #include "libmesh/tensor_value.h" 
   39 #include "libmesh/threads.h" 
   40 #include "libmesh/fe_type.h" 
   48 #ifdef LIBMESH_ENABLE_PERIODIC 
   51 const Elem * primary_boundary_point_neighbor(
const Elem * elem,
 
   54                                              const std::set<boundary_id_type> & boundary_ids)
 
   58   const Elem * primary = elem;
 
   61   std::vector<boundary_id_type> bc_ids;
 
   64   std::unique_ptr<const Elem> periodic_side;
 
   66   std::set<const Elem *> point_neighbors;
 
   68   for (
const auto & pt_neighbor : point_neighbors)
 
   74       if ((pt_neighbor->level() > primary->
level()) ||
 
   75           (pt_neighbor->level() == primary->
level() &&
 
   76            pt_neighbor->id() < primary->
id()))
 
   82       bool vertex_on_periodic_side = 
false;
 
   83       for (
auto ns : pt_neighbor->side_index_range())
 
   87           bool on_relevant_boundary = 
false;
 
   88           for (
const auto & 
id : boundary_ids)
 
   89             if (std::find(bc_ids.begin(), bc_ids.end(), id) != bc_ids.end())
 
   90               on_relevant_boundary = 
true;
 
   92           if (!on_relevant_boundary)
 
   95           pt_neighbor->build_side_ptr(periodic_side, ns);
 
   96           if (!periodic_side->contains_point(p))
 
   99           vertex_on_periodic_side = 
true;
 
  103       if (vertex_on_periodic_side)
 
  104         primary = pt_neighbor;
 
  111 const Elem * primary_boundary_edge_neighbor(
const Elem * elem,
 
  115                                             const std::set<boundary_id_type> & boundary_ids)
 
  119   const Elem * primary = elem;
 
  121   std::set<const Elem *> edge_neighbors;
 
  125   std::vector<boundary_id_type> bc_ids;
 
  128   std::unique_ptr<const Elem> periodic_side;
 
  130   for (
const auto & e_neighbor : edge_neighbors)
 
  136       if ((e_neighbor->level() > primary->
level()) ||
 
  137           (e_neighbor->level() == primary->
level() &&
 
  138            e_neighbor->id() < primary->
id()))
 
  144       bool vertex_on_periodic_side = 
false;
 
  145       for (
auto ns : e_neighbor->side_index_range())
 
  149           bool on_relevant_boundary = 
false;
 
  150           for (
const auto & 
id : boundary_ids)
 
  151             if (std::find(bc_ids.begin(), bc_ids.end(), id) != bc_ids.end())
 
  152               on_relevant_boundary = 
true;
 
  154           if (!on_relevant_boundary)
 
  157           e_neighbor->build_side_ptr(periodic_side, ns);
 
  158           if (!(periodic_side->contains_point(p1) &&
 
  159                 periodic_side->contains_point(p2)))
 
  162           vertex_on_periodic_side = 
true;
 
  166       if (vertex_on_periodic_side)
 
  167         primary = e_neighbor;
 
  173 #endif // LIBMESH_ENABLE_PERIODIC 
  185 std::unique_ptr<FEGenericBase<Real>>
 
  197             return libmesh_make_unique<FE<0,CLOUGH>>(fet);
 
  200             return libmesh_make_unique<FE<0,HERMITE>>(fet);
 
  203             return libmesh_make_unique<FE<0,LAGRANGE>>(fet);
 
  206             return libmesh_make_unique<FE<0,L2_LAGRANGE>>(fet);
 
  209             return libmesh_make_unique<FE<0,HIERARCHIC>>(fet);
 
  212             return libmesh_make_unique<FE<0,L2_HIERARCHIC>>(fet);
 
  215             return libmesh_make_unique<FE<0,MONOMIAL>>(fet);
 
  217 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 
  219             return libmesh_make_unique<FE<0,SZABAB>>(fet);
 
  222             return libmesh_make_unique<FE<0,BERNSTEIN>>(fet);
 
  225             return libmesh_make_unique<FE<0,RATIONAL_BERNSTEIN>>(fet);
 
  229             return libmesh_make_unique<FEXYZ<0>>(fet);
 
  232             return libmesh_make_unique<FEScalar<0>>(fet);
 
  235             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  244             return libmesh_make_unique<FE<1,CLOUGH>>(fet);
 
  247             return libmesh_make_unique<FE<1,HERMITE>>(fet);
 
  250             return libmesh_make_unique<FE<1,LAGRANGE>>(fet);
 
  253             return libmesh_make_unique<FE<1,L2_LAGRANGE>>(fet);
 
  256             return libmesh_make_unique<FE<1,HIERARCHIC>>(fet);
 
  259             return libmesh_make_unique<FE<1,L2_HIERARCHIC>>(fet);
 
  262             return libmesh_make_unique<FE<1,MONOMIAL>>(fet);
 
  264 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 
  266             return libmesh_make_unique<FE<1,SZABAB>>(fet);
 
  269             return libmesh_make_unique<FE<1,BERNSTEIN>>(fet);
 
  272             return libmesh_make_unique<FE<1,RATIONAL_BERNSTEIN>>(fet);
 
  276             return libmesh_make_unique<FEXYZ<1>>(fet);
 
  279             return libmesh_make_unique<FEScalar<1>>(fet);
 
  282             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  293             return libmesh_make_unique<FE<2,CLOUGH>>(fet);
 
  296             return libmesh_make_unique<FE<2,HERMITE>>(fet);
 
  299             return libmesh_make_unique<FE<2,LAGRANGE>>(fet);
 
  302             return libmesh_make_unique<FE<2,L2_LAGRANGE>>(fet);
 
  305             return libmesh_make_unique<FE<2,HIERARCHIC>>(fet);
 
  308             return libmesh_make_unique<FE<2,L2_HIERARCHIC>>(fet);
 
  311             return libmesh_make_unique<FE<2,MONOMIAL>>(fet);
 
  313 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 
  315             return libmesh_make_unique<FE<2,SZABAB>>(fet);
 
  318             return libmesh_make_unique<FE<2,BERNSTEIN>>(fet);
 
  321             return libmesh_make_unique<FE<2,RATIONAL_BERNSTEIN>>(fet);
 
  325             return libmesh_make_unique<FEXYZ<2>>(fet);
 
  328             return libmesh_make_unique<FEScalar<2>>(fet);
 
  331             return libmesh_make_unique<FESubdivision>(fet);
 
  334             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  345             libmesh_error_msg(
"ERROR: Clough-Tocher elements currently only support 1D and 2D");
 
  348             return libmesh_make_unique<FE<3,HERMITE>>(fet);
 
  351             return libmesh_make_unique<FE<3,LAGRANGE>>(fet);
 
  354             return libmesh_make_unique<FE<3,L2_LAGRANGE>>(fet);
 
  357             return libmesh_make_unique<FE<3,HIERARCHIC>>(fet);
 
  360             return libmesh_make_unique<FE<3,L2_HIERARCHIC>>(fet);
 
  363             return libmesh_make_unique<FE<3,MONOMIAL>>(fet);
 
  365 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 
  367             return libmesh_make_unique<FE<3,SZABAB>>(fet);
 
  370             return libmesh_make_unique<FE<3,BERNSTEIN>>(fet);
 
  373             return libmesh_make_unique<FE<3,RATIONAL_BERNSTEIN>>(fet);
 
  377             return libmesh_make_unique<FEXYZ<3>>(fet);
 
  380             return libmesh_make_unique<FEScalar<3>>(fet);
 
  383             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  388       libmesh_error_msg(
"Invalid dimension dim = " << 
dim);
 
  395 std::unique_ptr<FEGenericBase<RealGradient>>
 
  407             return libmesh_make_unique<FELagrangeVec<0>>(fet);
 
  410             return libmesh_make_unique<FEMonomialVec<0>>(fet);
 
  413             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  421             return libmesh_make_unique<FELagrangeVec<1>>(fet);
 
  424             return libmesh_make_unique<FEMonomialVec<1>>(fet);
 
  427             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  435             return libmesh_make_unique<FELagrangeVec<2>>(fet);
 
  438             return libmesh_make_unique<FEMonomialVec<2>>(fet);
 
  441             return libmesh_make_unique<FENedelecOne<2>>(fet);
 
  444             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  452             return libmesh_make_unique<FELagrangeVec<3>>(fet);
 
  455             return libmesh_make_unique<FEMonomialVec<3>>(fet);
 
  458             return libmesh_make_unique<FENedelecOne<3>>(fet);
 
  461             libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
 
  466       libmesh_error_msg(
"Invalid dimension dim = " << 
dim);
 
  476 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
  480 std::unique_ptr<FEGenericBase<Real>>
 
  493             libmesh_error_msg(
"ERROR: Can't build an infinite element with FEFamily = " << fet.
radial_family);
 
  500                   return libmesh_make_unique<InfFE<1,JACOBI_20_00,CARTESIAN>>(fet);
 
  503                   libmesh_error_msg(
"ERROR: Can't build an infinite element with InfMapType = " << fet.
inf_map);
 
  512                   return libmesh_make_unique<InfFE<1,JACOBI_30_00,CARTESIAN>>(fet);
 
  515                   libmesh_error_msg(
"ERROR: Can't build an infinite element with InfMapType = " << fet.
inf_map);
 
  524                   return libmesh_make_unique<InfFE<1,LEGENDRE,CARTESIAN>>(fet);
 
  527                   libmesh_error_msg(
"ERROR: Can't build an infinite element with InfMapType = " << fet.
inf_map);
 
  536                   return libmesh_make_unique<InfFE<1,LAGRANGE,CARTESIAN>>(fet);
 
  539                   libmesh_error_msg(
"ERROR: Can't build an infinite element with InfMapType = " << fet.
inf_map);
 
  544             libmesh_error_msg(
"ERROR: Bad FEType.radial_family= " << fet.
radial_family);
 
  557             libmesh_error_msg(
"ERROR: Can't build an infinite element with FEFamily = " << fet.
radial_family);
 
  564                   return libmesh_make_unique<InfFE<2,JACOBI_20_00,CARTESIAN>>(fet);
 
  567                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  576                   return libmesh_make_unique<InfFE<2,JACOBI_30_00,CARTESIAN>>(fet);
 
  579                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  588                   return libmesh_make_unique<InfFE<2,LEGENDRE,CARTESIAN>>(fet);
 
  591                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  600                   return libmesh_make_unique<InfFE<2,LAGRANGE,CARTESIAN>>(fet);
 
  603                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  608             libmesh_error_msg(
"ERROR: Bad FEType.radial_family= " << fet.
radial_family);
 
  621             libmesh_error_msg(
"ERROR: Don't build an infinite element with FEFamily = " << fet.
radial_family);
 
  628                   return libmesh_make_unique<InfFE<3,JACOBI_20_00,CARTESIAN>>(fet);
 
  631                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  640                   return libmesh_make_unique<InfFE<3,JACOBI_30_00,CARTESIAN>>(fet);
 
  643                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  652                   return libmesh_make_unique<InfFE<3,LEGENDRE,CARTESIAN>>(fet);
 
  655                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  664                   return libmesh_make_unique<InfFE<3,LAGRANGE,CARTESIAN>>(fet);
 
  667                   libmesh_error_msg(
"ERROR: Don't build an infinite element with InfMapType = " << fet.
inf_map);
 
  672             libmesh_error_msg(
"ERROR: Bad FEType.radial_family= " << fet.
radial_family);
 
  677       libmesh_error_msg(
"Invalid dimension dim = " << 
dim);
 
  684 std::unique_ptr<FEGenericBase<RealGradient>>
 
  689   libmesh_not_implemented();
 
  690   return std::unique_ptr<FEVectorBase>();
 
  693 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
  696 template <
typename OutputType>
 
  698                                                          const std::vector<Point> & qp)
 
  706   LOG_SCOPE(
"compute_shape_functions()", 
"FE");
 
  708   this->determine_calculations();
 
  711     this->_fe_trans->map_phi(this->
dim, elem, qp, (*
this), this->phi);
 
  714     this->_fe_trans->map_dphi(this->
dim, elem, qp, (*
this), this->dphi,
 
  715                               this->dphidx, this->dphidy, this->dphidz);
 
  717 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  719     this->_fe_trans->map_d2phi(this->
dim, qp, (*
this), this->d2phi,
 
  720                                this->d2phidx2, this->d2phidxdy, this->d2phidxdz,
 
  721                                this->d2phidy2, this->d2phidydz, this->d2phidz2);
 
  722 #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES 
  726     this->_fe_trans->map_curl(this->
dim, elem, qp, (*
this), this->curl_phi);
 
  730     this->_fe_trans->map_div(this->
dim, elem, qp, (*
this), this->div_phi);
 
  734 template <
typename OutputType>
 
  739       os << 
" phi[" << i << 
"][" << j << 
"]=" << phi[i][j] << std::endl;
 
  745 template <
typename OutputType>
 
  750       os << 
" dphi[" << i << 
"][" << j << 
"]=" << dphi[i][j];
 
  755 template <
typename OutputType>
 
  758   this->calculations_started = 
true;
 
  762 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  763   if (!this->calculate_phi && !this->calculate_dphi &&
 
  764       !this->calculate_d2phi && !this->calculate_curl_phi &&
 
  765       !this->calculate_div_phi && !this->calculate_map)
 
  767       this->calculate_phi = this->calculate_dphi = this->calculate_d2phi = this->calculate_dphiref = 
true;
 
  770           this->calculate_curl_phi = 
true;
 
  771           this->calculate_div_phi  = 
true;
 
  775   if (!this->calculate_phi && !this->calculate_dphi &&
 
  776       !this->calculate_curl_phi && !this->calculate_div_phi &&
 
  777       !this->calculate_map)
 
  779       this->calculate_phi = this->calculate_dphi = this->calculate_dphiref = 
true;
 
  782           this->calculate_curl_phi = 
true;
 
  783           this->calculate_div_phi  = 
true;
 
  786 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 
  789   if (this->calculate_phi)
 
  790     this->_fe_trans->init_map_phi(*
this);
 
  792   if (this->calculate_dphiref)
 
  793     this->_fe_trans->init_map_dphi(*
this);
 
  795 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  796   if (this->calculate_d2phi)
 
  797     this->_fe_trans->init_map_d2phi(*
this);
 
  798 #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES 
  803 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  806 template <
typename OutputType>
 
  811       os << 
" d2phi[" << i << 
"][" << j << 
"]=" << d2phi[i][j];
 
  818 #ifdef LIBMESH_ENABLE_AMR 
  820 template <
typename OutputType>
 
  826                                                 const unsigned int var,
 
  827                                                 const bool use_old_dof_indices)
 
  830   std::vector<unsigned int> new_side_dofs, old_side_dofs;
 
  833   unsigned int dim = elem->
dim();
 
  836   const unsigned int n_children = elem->
n_children();
 
  841   std::unique_ptr<FEGenericBase<OutputShape>> fe
 
  843   std::unique_ptr<FEGenericBase<OutputShape>> fe_coarse
 
  849   std::vector<Point> coarse_qpoints;
 
  853   const std::vector<std::vector<OutputShape>> & phi_values =
 
  855   const std::vector<std::vector<OutputShape>> & phi_coarse =
 
  856     fe_coarse->get_phi();
 
  860   const std::vector<std::vector<OutputGradient>> * dphi_values =
 
  862   const std::vector<std::vector<OutputGradient>> * dphi_coarse =
 
  869       const std::vector<std::vector<OutputGradient>> &
 
  870         ref_dphi_values = fe->get_dphi();
 
  871       dphi_values = &ref_dphi_values;
 
  872       const std::vector<std::vector<OutputGradient>> &
 
  873         ref_dphi_coarse = fe_coarse->get_dphi();
 
  874       dphi_coarse = &ref_dphi_coarse;
 
  878   const std::vector<Real> & JxW =
 
  883   const std::vector<Point> & xyz_values =
 
  888   FEType fe_type = base_fe_type, temp_fe_type;
 
  890   fe_type.
order = static_cast<Order>(fe_type.
order +
 
  897   const unsigned int new_n_dofs =
 
  901   std::vector<char> dof_is_fixed(new_n_dofs, 
false); 
 
  902   std::vector<int> free_dof(new_n_dofs, 0);
 
  918     std::vector<dof_id_type> node_dof_indices;
 
  919     if (use_old_dof_indices)
 
  924     unsigned int current_dof = 0;
 
  925     for (
unsigned int n=0; n!= 
n_nodes; ++n)
 
  929         const unsigned int my_nc =
 
  934             current_dof += my_nc;
 
  938         temp_fe_type = base_fe_type;
 
  952         const unsigned int nc =
 
  955         for (
unsigned int i=0; i!= nc; ++i)
 
  958               old_vector(node_dof_indices[current_dof]);
 
  959             dof_is_fixed[current_dof] = 
true;
 
  972         const unsigned int n_new_side_dofs =
 
  973           cast_int<unsigned int>(new_side_dofs.size());
 
  977         unsigned int free_dofs = 0;
 
  978         for (
unsigned int i=0; i != n_new_side_dofs; ++i)
 
  979           if (!dof_is_fixed[new_side_dofs[i]])
 
  980             free_dof[free_dofs++] = i;
 
  988         for (
unsigned int c=0; c != n_children; ++c)
 
  994             std::vector<dof_id_type> child_dof_indices;
 
  995             if (use_old_dof_indices)
 
  997                                        child_dof_indices, var);
 
 1000                                    child_dof_indices, var);
 
 1001             const unsigned int child_n_dofs =
 
 1002               cast_int<unsigned int>
 
 1003               (child_dof_indices.size());
 
 1005             temp_fe_type = base_fe_type;
 
 1006             temp_fe_type.
order =
 
 1007               static_cast<Order>(temp_fe_type.order +
 
 1011                                       temp_fe_type, e, old_side_dofs);
 
 1015             fe->attach_quadrature_rule (qedgerule.get());
 
 1016             fe->edge_reinit (child, e);
 
 1017             const unsigned int n_qp = qedgerule->n_points();
 
 1022             fe_coarse->reinit(elem, &coarse_qpoints);
 
 1025             for (
unsigned int qp=0; qp<n_qp; qp++)
 
 1035                 for (
unsigned int i=0; i<child_n_dofs;
 
 1039                       (old_vector(child_dof_indices[i])*
 
 1042                       finegrad += (*dphi_values)[i][qp] *
 
 1043                         old_vector(child_dof_indices[i]);
 
 1047                 for (
unsigned int sidei=0, freei=0; sidei != n_new_side_dofs; ++sidei)
 
 1049                     unsigned int i = new_side_dofs[sidei];
 
 1051                     if (dof_is_fixed[i])
 
 1053                     for (
unsigned int sidej=0, freej=0; sidej != n_new_side_dofs; ++sidej)
 
 1056                           new_side_dofs[sidej];
 
 1057                         if (dof_is_fixed[j])
 
 1060                                                        phi_coarse[j][qp]) *
 
 1065                                                        phi_coarse[j][qp]) *
 
 1069                             if (dof_is_fixed[j])
 
 1072                                                            (*dphi_coarse)[j][qp]) *
 
 1077                                                            (*dphi_coarse)[j][qp]) *
 
 1080                         if (!dof_is_fixed[j])
 
 1095         for (
unsigned int i=0; i != free_dofs; ++i)
 
 1097             Number & ui = Ue(new_side_dofs[free_dof[i]]);
 
 1101             dof_is_fixed[new_side_dofs[free_dof[i]]] = 
true;
 
 1112         const unsigned int n_new_side_dofs =
 
 1113           cast_int<unsigned int>(new_side_dofs.size());
 
 1117         unsigned int free_dofs = 0;
 
 1118         for (
unsigned int i=0; i != n_new_side_dofs; ++i)
 
 1119           if (!dof_is_fixed[new_side_dofs[i]])
 
 1120             free_dof[free_dofs++] = i;
 
 1128         for (
unsigned int c=0; c != n_children; ++c)
 
 1134             std::vector<dof_id_type> child_dof_indices;
 
 1135             if (use_old_dof_indices)
 
 1137                                        child_dof_indices, var);
 
 1140                                    child_dof_indices, var);
 
 1141             const unsigned int child_n_dofs =
 
 1142               cast_int<unsigned int>
 
 1143               (child_dof_indices.size());
 
 1145             temp_fe_type = base_fe_type;
 
 1146             temp_fe_type.
order =
 
 1147               static_cast<Order>(temp_fe_type.order +
 
 1151                                       temp_fe_type, s, old_side_dofs);
 
 1155             fe->attach_quadrature_rule (qsiderule.get());
 
 1156             fe->reinit (child, s);
 
 1157             const unsigned int n_qp = qsiderule->n_points();
 
 1162             fe_coarse->reinit(elem, &coarse_qpoints);
 
 1165             for (
unsigned int qp=0; qp<n_qp; qp++)
 
 1175                 for (
unsigned int i=0; i<child_n_dofs;
 
 1179                       old_vector(child_dof_indices[i]) *
 
 1182                       finegrad += (*dphi_values)[i][qp] *
 
 1183                         old_vector(child_dof_indices[i]);
 
 1187                 for (
unsigned int sidei=0, freei=0; sidei != n_new_side_dofs; ++sidei)
 
 1189                     unsigned int i = new_side_dofs[sidei];
 
 1191                     if (dof_is_fixed[i])
 
 1193                     for (
unsigned int sidej=0, freej=0; sidej != n_new_side_dofs; ++sidej)
 
 1196                           new_side_dofs[sidej];
 
 1197                         if (dof_is_fixed[j])
 
 1200                                                        phi_coarse[j][qp]) *
 
 1205                                                        phi_coarse[j][qp]) *
 
 1209                             if (dof_is_fixed[j])
 
 1212                                                            (*dphi_coarse)[j][qp]) *
 
 1217                                                            (*dphi_coarse)[j][qp]) *
 
 1220                         if (!dof_is_fixed[j])
 
 1234         for (
unsigned int i=0; i != free_dofs; ++i)
 
 1236             Number & ui = Ue(new_side_dofs[free_dof[i]]);
 
 1240             dof_is_fixed[new_side_dofs[free_dof[i]]] = 
true;
 
 1248   unsigned int free_dofs = 0;
 
 1249   for (
unsigned int i=0; i != new_n_dofs; ++i)
 
 1250     if (!dof_is_fixed[i])
 
 1251       free_dof[free_dofs++] = i;
 
 1260       std::vector<dof_id_type> child_dof_indices;
 
 1261       if (use_old_dof_indices)
 
 1263                                  child_dof_indices, var);
 
 1266                              child_dof_indices, var);
 
 1267       const unsigned int child_n_dofs =
 
 1268         cast_int<unsigned int>
 
 1269         (child_dof_indices.size());
 
 1273       fe->attach_quadrature_rule (qrule.get());
 
 1274       fe->reinit (&child);
 
 1275       const unsigned int n_qp = qrule->n_points();
 
 1279       fe_coarse->reinit(elem, &coarse_qpoints);
 
 1282       for (
unsigned int qp=0; qp<n_qp; qp++)
 
 1292           for (
unsigned int i=0; i<child_n_dofs; i++)
 
 1295                 (old_vector(child_dof_indices[i]) *
 
 1298                 finegrad += (*dphi_values)[i][qp] *
 
 1299                   old_vector(child_dof_indices[i]);
 
 1303           for (
unsigned int i=0, freei=0;
 
 1304                i != new_n_dofs; ++i)
 
 1307               if (dof_is_fixed[i])
 
 1309               for (
unsigned int j=0, freej=0; j !=
 
 1312                   if (dof_is_fixed[j])
 
 1315                                                  phi_coarse[j][qp]) *
 
 1320                                                  phi_coarse[j][qp]) *
 
 1324                       if (dof_is_fixed[j])
 
 1327                                                      (*dphi_coarse)[j][qp]) *
 
 1332                                                      (*dphi_coarse)[j][qp]) *
 
 1335                   if (!dof_is_fixed[j])
 
 1349   for (
unsigned int i=0; i != free_dofs; ++i)
 
 1351       Number & ui = Ue(free_dof[i]);
 
 1358       dof_is_fixed[free_dof[i]] = 
true;
 
 1364   for (
unsigned int i=0; i != new_n_dofs; ++i)
 
 1371 template <
typename OutputType>
 
 1377                                                 const bool use_old_dof_indices)
 
 1381   for (
unsigned int v=0; v != dof_map.
n_variables(); ++v)
 
 1385       coarsened_dof_values(old_vector, dof_map, elem, Usub,
 
 1386                            v, use_old_dof_indices);
 
 1394 template <
typename OutputType>
 
 1398                                                      const unsigned int variable_number,
 
 1403   const unsigned int Dim = elem->
dim();
 
 1417   std::unique_ptr<FEGenericBase<OutputShape>> my_fe
 
 1426   std::unique_ptr<FEGenericBase<OutputShape>> neigh_fe
 
 1430   my_fe->attach_quadrature_rule (&my_qface);
 
 1431   std::vector<Point> neigh_qface;
 
 1433   const std::vector<Real> & JxW = my_fe->get_JxW();
 
 1434   const std::vector<Point> & q_point = my_fe->get_xyz();
 
 1435   const std::vector<std::vector<OutputShape>> & phi = my_fe->get_phi();
 
 1436   const std::vector<std::vector<OutputShape>> & neigh_phi =
 
 1437     neigh_fe->get_phi();
 
 1438   const std::vector<Point> * face_normals = 
nullptr;
 
 1439   const std::vector<std::vector<OutputGradient>> * dphi = 
nullptr;
 
 1440   const std::vector<std::vector<OutputGradient>> * neigh_dphi = 
nullptr;
 
 1442   std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
 
 1443   std::vector<unsigned int> my_side_dofs, neigh_side_dofs;
 
 1447       const std::vector<Point> & ref_face_normals =
 
 1448         my_fe->get_normals();
 
 1449       face_normals = &ref_face_normals;
 
 1450       const std::vector<std::vector<OutputGradient>> & ref_dphi =
 
 1453       const std::vector<std::vector<OutputGradient>> & ref_neigh_dphi =
 
 1454         neigh_fe->get_dphi();
 
 1455       neigh_dphi = &ref_neigh_dphi;
 
 1460   std::vector<DenseVector<Real>> Ue;
 
 1482           libmesh_assert_less (s_neigh, neigh->
n_neighbors());
 
 1488           const unsigned int min_p_level =
 
 1493           const unsigned int old_elem_level = elem->
p_level();
 
 1494           if (elem->
p_level() != min_p_level)
 
 1495             my_fe->set_fe_order(my_fe->get_fe_type().order.get_order() - old_elem_level + min_p_level);
 
 1496           const unsigned int old_neigh_level = neigh->
p_level();
 
 1497           if (old_neigh_level != min_p_level)
 
 1498             neigh_fe->set_fe_order(neigh_fe->get_fe_type().order.get_order() - old_neigh_level + min_p_level);
 
 1500           my_fe->reinit(elem, s);
 
 1508           my_dof_indices.reserve    (elem->
n_nodes());
 
 1509           neigh_dof_indices.reserve (neigh->
n_nodes());
 
 1518           const unsigned int n_qp = my_qface.n_points();
 
 1522           neigh_fe->reinit(neigh, &neigh_qface);
 
 1526           FEType elem_fe_type = base_fe_type;
 
 1527           if (old_elem_level != min_p_level)
 
 1529           FEType neigh_fe_type = base_fe_type;
 
 1530           if (old_neigh_level != min_p_level)
 
 1535           const unsigned int n_side_dofs =
 
 1536             cast_int<unsigned int>(my_side_dofs.size());
 
 1537           libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());
 
 1540           for (
auto i : my_side_dofs)
 
 1541             libmesh_assert_less(i, my_dof_indices.size());
 
 1542           for (
auto i : neigh_side_dofs)
 
 1543             libmesh_assert_less(i, neigh_dof_indices.size());
 
 1546           Ke.
resize (n_side_dofs, n_side_dofs);
 
 1547           Ue.resize(n_side_dofs);
 
 1551           for (
unsigned int is = 0; 
is != n_side_dofs; ++
is)
 
 1553               const unsigned int i = my_side_dofs[
is];
 
 1554               for (
unsigned int js = 0; js != n_side_dofs; ++js)
 
 1556                   const unsigned int j = my_side_dofs[js];
 
 1557                   for (
unsigned int qp = 0; qp != n_qp; ++qp)
 
 1561                         Ke(
is,js) += JxW[qp] *
 
 1563                                                      (*face_normals)[qp],
 
 1565                                                      (*face_normals)[qp]);
 
 1572           for (
unsigned int is = 0; 
is != n_side_dofs; ++
is)
 
 1574               const unsigned int i = neigh_side_dofs[
is];
 
 1576               for (
unsigned int js = 0; js != n_side_dofs; ++js)
 
 1578                   const unsigned int j = my_side_dofs[js];
 
 1579                   for (
unsigned int qp = 0; qp != n_qp; ++qp)
 
 1587                                                      (*face_normals)[qp],
 
 1589                                                      (*face_normals)[qp]);
 
 1595           for (
unsigned int js = 0; js != n_side_dofs; ++js)
 
 1597               const unsigned int j = my_side_dofs[js];
 
 1603               bool self_constraint = 
false;
 
 1604               for (
unsigned int is = 0; 
is != n_side_dofs; ++
is)
 
 1606                   const unsigned int i = neigh_side_dofs[
is];
 
 1607                   const dof_id_type their_dof_g = neigh_dof_indices[i];
 
 1610                   if (their_dof_g == my_dof_g)
 
 1613                       const Real their_dof_value = Ue[
is](js);
 
 1614                       libmesh_assert_less (
std::abs(their_dof_value-1.),
 
 1617                       for (
unsigned int k = 0; k != n_side_dofs; ++k)
 
 1623                       self_constraint = 
true;
 
 1628               if (self_constraint)
 
 1642                 constraint_row = &(constraints[my_dof_g]);
 
 1646               for (
unsigned int is = 0; 
is != n_side_dofs; ++
is)
 
 1648                   const unsigned int i = neigh_side_dofs[
is];
 
 1649                   const dof_id_type their_dof_g = neigh_dof_indices[i];
 
 1651                   libmesh_assert_not_equal_to (their_dof_g, my_dof_g);
 
 1653                   const Real their_dof_value = Ue[
is](js);
 
 1658                   constraint_row->insert(std::make_pair(their_dof_g,
 
 1663           my_fe->set_fe_order(my_fe->get_fe_type().order.get_order() + old_elem_level - min_p_level);
 
 1664           neigh_fe->set_fe_order(neigh_fe->get_fe_type().order.get_order() + old_neigh_level - min_p_level);
 
 1671       const unsigned int min_p_level =
 
 1673       if (min_p_level < elem->p_level())
 
 1684 #endif // #ifdef LIBMESH_ENABLE_AMR 
 1688 #ifdef LIBMESH_ENABLE_PERIODIC 
 1689 template <
typename OutputType>
 
 1697                               const unsigned int variable_number,
 
 1701   if (boundaries.empty())
 
 1710   const unsigned int Dim = elem->
dim();
 
 1714   const unsigned int sys_number = dof_map.
sys_number();
 
 1719   std::unique_ptr<FEGenericBase<OutputShape>> my_fe
 
 1729   const Real primary_hmin = elem->
hmin();
 
 1731   std::unique_ptr<FEGenericBase<OutputShape>> neigh_fe
 
 1735   my_fe->attach_quadrature_rule (&my_qface);
 
 1736   std::vector<Point> neigh_qface;
 
 1738   const std::vector<Real> & JxW = my_fe->get_JxW();
 
 1739   const std::vector<Point> & q_point = my_fe->get_xyz();
 
 1740   const std::vector<std::vector<OutputShape>> & phi = my_fe->get_phi();
 
 1741   const std::vector<std::vector<OutputShape>> & neigh_phi =
 
 1742     neigh_fe->get_phi();
 
 1743   const std::vector<Point> * face_normals = 
nullptr;
 
 1744   const std::vector<std::vector<OutputGradient>> * dphi = 
nullptr;
 
 1745   const std::vector<std::vector<OutputGradient>> * neigh_dphi = 
nullptr;
 
 1746   std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
 
 1747   std::vector<unsigned int> my_side_dofs, neigh_side_dofs;
 
 1751       const std::vector<Point> & ref_face_normals =
 
 1752         my_fe->get_normals();
 
 1753       face_normals = &ref_face_normals;
 
 1754       const std::vector<std::vector<OutputGradient>> & ref_dphi =
 
 1757       const std::vector<std::vector<OutputGradient>> & ref_neigh_dphi =
 
 1758         neigh_fe->get_dphi();
 
 1759       neigh_dphi = &ref_neigh_dphi;
 
 1764   std::vector<DenseVector<Real>> Ue;
 
 1767   std::vector<boundary_id_type> bc_ids;
 
 1771   const unsigned short int max_ns = elem->
n_sides();
 
 1772   for (
unsigned short int s = 0; s != max_ns; ++s)
 
 1779       for (
const auto & boundary_id : bc_ids)
 
 1787               const Elem * neigh = boundaries.
neighbor(boundary_id, *point_locator, elem, s);
 
 1789               if (neigh == 
nullptr)
 
 1790                 libmesh_error_msg(
"PeriodicBoundaries point locator object returned nullptr!");
 
 1798                   unsigned int s_neigh =
 
 1802 #ifdef LIBMESH_ENABLE_AMR 
 1807                   const unsigned int min_p_level =
 
 1815                   const unsigned int old_elem_level = elem->
p_level();
 
 1816                   if (old_elem_level != min_p_level)
 
 1817                     (const_cast<Elem *>(elem))->hack_p_level(min_p_level);
 
 1818                   const unsigned int old_neigh_level = neigh->
p_level();
 
 1819                   if (old_neigh_level != min_p_level)
 
 1820                     (const_cast<Elem *>(neigh))->hack_p_level(min_p_level);
 
 1821 #endif // #ifdef LIBMESH_ENABLE_AMR 
 1829                   my_fe->reinit(elem, s);
 
 1839                   std::vector<std::vector<dof_id_type>> neigh_dof_indices_all_variables;
 
 1842                       const std::set<unsigned int> & variables = periodic->
get_variables();
 
 1843                       neigh_dof_indices_all_variables.resize(variables.size());
 
 1844                       unsigned int index = 0;
 
 1845                       for(
unsigned int var : variables)
 
 1847                           dof_map.
dof_indices (neigh, neigh_dof_indices_all_variables[index],
 
 1853                   const unsigned int n_qp = my_qface.n_points();
 
 1857                   std::vector<Point> neigh_point(q_point.size());
 
 1864                   neigh_fe->reinit(neigh, &neigh_qface);
 
 1873 #ifdef LIBMESH_ENABLE_AMR 
 1874                   if (elem->
p_level() != old_elem_level)
 
 1875                     (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
 
 1876                   if (neigh->
p_level() != old_neigh_level)
 
 1877                     (const_cast<Elem *>(neigh))->hack_p_level(old_neigh_level);
 
 1878 #endif // #ifdef LIBMESH_ENABLE_AMR 
 1880                   const unsigned int n_side_dofs =
 
 1881                     cast_int<unsigned int>
 
 1882                     (my_side_dofs.size());
 
 1883                   libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());
 
 1885                   Ke.
resize (n_side_dofs, n_side_dofs);
 
 1886                   Ue.resize(n_side_dofs);
 
 1890                   for (
unsigned int is = 0; 
is != n_side_dofs; ++
is)
 
 1892                       const unsigned int i = my_side_dofs[
is];
 
 1893                       for (
unsigned int js = 0; js != n_side_dofs; ++js)
 
 1895                           const unsigned int j = my_side_dofs[js];
 
 1896                           for (
unsigned int qp = 0; qp != n_qp; ++qp)
 
 1898                               Ke(
is,js) += JxW[qp] *
 
 1902                                 Ke(
is,js) += JxW[qp] *
 
 1904                                                              (*face_normals)[qp],
 
 1906                                                              (*face_normals)[qp]);
 
 1913                   for (
unsigned int is = 0; 
is != n_side_dofs; ++
is)
 
 1915                       const unsigned int i = neigh_side_dofs[
is];
 
 1917                       for (
unsigned int js = 0; js != n_side_dofs; ++js)
 
 1919                           const unsigned int j = my_side_dofs[js];
 
 1920                           for (
unsigned int qp = 0; qp != n_qp; ++qp)
 
 1928                                                              (*face_normals)[qp],
 
 1930                                                              (*face_normals)[qp]);
 
 1984                   std::set<dof_id_type> my_constrained_dofs;
 
 1987                   std::vector<boundary_id_type> new_bc_ids;
 
 2001                           std::set<boundary_id_type> point_bcids;
 
 2003                           for (
unsigned int new_s = 0;
 
 2004                                new_s != max_ns; ++new_s)
 
 2011                               for (
const auto & new_boundary_id : new_bc_ids)
 
 2014                                   if (new_periodic && new_periodic->
is_my_variable(variable_number))
 
 2015                                     point_bcids.insert(new_boundary_id);
 
 2021                           if (primary_boundary_point_neighbor
 
 2027                           std::set<boundary_id_type> point_pairedids;
 
 2028                           for (
const auto & new_boundary_id : point_bcids)
 
 2035                           const Elem * primary_elem = 
nullptr;
 
 2036                           const Elem * main_neigh = 
nullptr;
 
 2037                           Point main_pt = my_node,
 
 2038                             primary_pt = my_node;
 
 2040                           for (
const auto & new_boundary_id : point_bcids)
 
 2046                               const Point neigh_pt =
 
 2059                                 primary_elem = elem;
 
 2061                               const Elem * primary_neigh =
 
 2062                                 primary_boundary_point_neighbor(neigh, neigh_pt,
 
 2068                               if (new_boundary_id == boundary_id)
 
 2070                                   main_neigh = primary_neigh;
 
 2077                               if ((primary_neigh->
level() > primary_elem->
level()) ||
 
 2082                                   (primary_neigh->
level() == primary_elem->
level() &&
 
 2083                                    primary_neigh->
id() > primary_elem->
id()) ||
 
 2087                                   (primary_neigh == primary_elem &&
 
 2088                                    (neigh_pt > primary_pt)))
 
 2091                               primary_elem = primary_neigh;
 
 2092                               primary_pt = neigh_pt;
 
 2095                           if (!primary_elem ||
 
 2096                               primary_elem != main_neigh ||
 
 2097                               primary_pt != main_pt)
 
 2103                           unsigned int e=0, ne = elem->
n_edges();
 
 2104                           for (; e != ne; ++e)
 
 2109                           libmesh_assert_less (e, elem->
n_edges());
 
 2138                           std::set<boundary_id_type> edge_bcids;
 
 2140                           for (
unsigned int new_s = 0;
 
 2141                                new_s != max_ns; ++new_s)
 
 2149                               for (
const auto & new_boundary_id : new_bc_ids)
 
 2152                                   if (new_periodic && new_periodic->
is_my_variable(variable_number))
 
 2153                                     edge_bcids.insert(new_boundary_id);
 
 2159                           if (primary_boundary_edge_neighbor
 
 2165                           std::set<boundary_id_type> edge_pairedids;
 
 2166                           for (
const auto & new_boundary_id : edge_bcids)
 
 2173                           const Elem * primary_elem = 
nullptr;
 
 2174                           const Elem * main_neigh = 
nullptr;
 
 2175                           Point main_pt1 = *e1,
 
 2180                           for (
const auto & new_boundary_id : edge_bcids)
 
 2194                                   neigh_pt2.absolute_fuzzy_equals
 
 2201                                 primary_elem = elem;
 
 2203                               const Elem * primary_neigh = primary_boundary_edge_neighbor
 
 2204                                 (neigh, neigh_pt1, neigh_pt2,
 
 2209                               if (new_boundary_id == boundary_id)
 
 2211                                   main_neigh = primary_neigh;
 
 2212                                   main_pt1 = neigh_pt1;
 
 2213                                   main_pt2 = neigh_pt2;
 
 2223                               if (primary_neigh == primary_elem)
 
 2225                                   if (primary_pt1 > primary_pt2)
 
 2227                                   if (neigh_pt1 > neigh_pt2)
 
 2230                                   if (neigh_pt2 >= primary_pt2)
 
 2238                               if ((primary_neigh->
level() > primary_elem->
level()) ||
 
 2243                                   (primary_neigh->
level() == primary_elem->
level() &&
 
 2244                                    primary_neigh->
id() > primary_elem->
id()))
 
 2247                               primary_elem = primary_neigh;
 
 2248                               primary_pt1 = neigh_pt1;
 
 2249                               primary_pt2 = neigh_pt2;
 
 2252                           if (!primary_elem ||
 
 2253                               primary_elem != main_neigh ||
 
 2254                               primary_pt1 != main_pt1 ||
 
 2255                               primary_pt2 != main_pt2)
 
 2266                               const Point neigh_pt =
 
 2268                               if (neigh_pt > my_node)
 
 2282                                neigh->
id() > elem->
id()))
 
 2290                       const unsigned int n_comp =
 
 2291                         my_node.
n_comp(sys_number, variable_number);
 
 2293                       for (
unsigned int i=0; i != n_comp; ++i)
 
 2294                         my_constrained_dofs.insert
 
 2296                            (sys_number, variable_number, i));
 
 2333                   for (
unsigned int js = 0; js != n_side_dofs; ++js)
 
 2339                       const unsigned int j = my_side_dofs[js];
 
 2344                       if (!my_constrained_dofs.count(my_dof_g))
 
 2358                         constraint_row = &(constraints[my_dof_g]);
 
 2362                       for (
unsigned int is = 0; 
is != n_side_dofs; ++
is)
 
 2364                           const unsigned int i = neigh_side_dofs[
is];
 
 2365                           const dof_id_type their_dof_g = neigh_dof_indices[i];
 
 2372                           const Real their_dof_value = Ue[
is](js);
 
 2374                           if (their_dof_g == my_dof_g)
 
 2376                               libmesh_assert_less (
std::abs(their_dof_value-1.), 1.e-5);
 
 2377                               for (
unsigned int k = 0; k != n_side_dofs; ++k)
 
 2387                               constraint_row->insert(std::make_pair(their_dof_g,
 
 2398                               const std::set<unsigned int> & variables = periodic->
get_variables();
 
 2399                               neigh_dof_indices_all_variables.resize(variables.size());
 
 2400                               unsigned int index = 0;
 
 2401                               for(
unsigned int other_var : variables)
 
 2403                                   libmesh_assert_msg(base_fe_type == dof_map.
variable_type(other_var), 
"FE types must match for all variables involved in constraint");
 
 2406                                   constraint_row->insert(std::make_pair(neigh_dof_indices_all_variables[index][i],
 
 2407                                                                         var_weighting*their_dof_value));
 
 2419 #ifdef LIBMESH_ENABLE_AMR 
 2420               const unsigned int min_p_level =
 
 2422               if (min_p_level < elem->p_level())
 
 2430 #endif // #ifdef LIBMESH_ENABLE_AMR 
 2436 #endif // LIBMESH_ENABLE_PERIODIC