21#include "libmesh/fe.h"
22#include "libmesh/inf_fe.h"
23#include "libmesh/libmesh_logging.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/int_range.h"
34#include "libmesh/numeric_vector.h"
35#include "libmesh/periodic_boundary_base.h"
36#include "libmesh/periodic_boundaries.h"
37#include "libmesh/quadrature.h"
38#include "libmesh/quadrature_gauss.h"
39#include "libmesh/tensor_value.h"
40#include "libmesh/threads.h"
41#include "libmesh/fe_type.h"
42#include "libmesh/enum_to_string.h"
53#ifdef LIBMESH_ENABLE_PERIODIC
56const Elem * primary_boundary_point_neighbor(
const Elem * elem,
59 const std::set<boundary_id_type> & boundary_ids)
63 const Elem * primary = elem;
66 std::vector<boundary_id_type> bc_ids;
69 std::unique_ptr<const Elem> periodic_side;
71 std::set<const Elem *> point_neighbors;
73 for (
const auto & pt_neighbor : point_neighbors)
79 if ((pt_neighbor->level() > primary->
level()) ||
80 (pt_neighbor->level() == primary->
level() &&
81 pt_neighbor->id() < primary->
id()))
87 bool vertex_on_periodic_side =
false;
88 for (
auto ns : pt_neighbor->side_index_range())
92 bool on_relevant_boundary =
false;
93 for (
const auto &
id : boundary_ids)
94 if (
std::find(bc_ids.begin(), bc_ids.end(), id) != bc_ids.end())
95 on_relevant_boundary = true;
97 if (!on_relevant_boundary)
100 pt_neighbor->build_side_ptr(periodic_side, ns);
101 if (!periodic_side->contains_point(p))
104 vertex_on_periodic_side =
true;
108 if (vertex_on_periodic_side)
109 primary = pt_neighbor;
116const Elem * primary_boundary_edge_neighbor(
const Elem * elem,
120 const std::set<boundary_id_type> & boundary_ids)
124 const Elem * primary = elem;
126 std::set<const Elem *> edge_neighbors;
130 std::vector<boundary_id_type> bc_ids;
133 std::unique_ptr<const Elem> periodic_side;
135 for (
const auto & e_neighbor : edge_neighbors)
141 if ((e_neighbor->level() > primary->
level()) ||
142 (e_neighbor->level() == primary->
level() &&
143 e_neighbor->id() < primary->
id()))
149 bool vertex_on_periodic_side =
false;
150 for (
auto ns : e_neighbor->side_index_range())
154 bool on_relevant_boundary =
false;
155 for (
const auto &
id : boundary_ids)
156 if (
std::find(bc_ids.begin(), bc_ids.end(), id) != bc_ids.end())
157 on_relevant_boundary = true;
159 if (!on_relevant_boundary)
162 e_neighbor->build_side_ptr(periodic_side, ns);
163 if (!(periodic_side->contains_point(p1) &&
164 periodic_side->contains_point(p2)))
167 vertex_on_periodic_side =
true;
171 if (vertex_on_periodic_side)
172 primary = e_neighbor;
190std::unique_ptr<FEGenericBase<Real>>
202 return std::make_unique<FE<0,CLOUGH>>(fet);
205 return std::make_unique<FE<0,HERMITE>>(fet);
208 return std::make_unique<FE<0,LAGRANGE>>(fet);
211 return std::make_unique<FE<0,L2_LAGRANGE>>(fet);
214 return std::make_unique<FE<0,L2_LAGRANGE_GLL>>(fet);
217 return std::make_unique<FE<0,HIERARCHIC>>(fet);
220 return std::make_unique<FE<0,L2_HIERARCHIC>>(fet);
223 return std::make_unique<FE<0,SIDE_HIERARCHIC>>(fet);
226 return std::make_unique<FE<0,MONOMIAL>>(fet);
228#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
230 return std::make_unique<FE<0,SZABAB>>(fet);
233 return std::make_unique<FE<0,BERNSTEIN>>(fet);
236 return std::make_unique<FE<0,RATIONAL_BERNSTEIN>>(fet);
240 return std::make_unique<FEXYZ<0>>(fet);
243 return std::make_unique<FEScalar<0>>(fet);
255 return std::make_unique<FE<1,CLOUGH>>(fet);
258 return std::make_unique<FE<1,HERMITE>>(fet);
261 return std::make_unique<FE<1,LAGRANGE>>(fet);
264 return std::make_unique<FE<1,L2_LAGRANGE>>(fet);
267 return std::make_unique<FE<1,L2_LAGRANGE_GLL>>(fet);
270 return std::make_unique<FE<1,HIERARCHIC>>(fet);
273 return std::make_unique<FE<1,L2_HIERARCHIC>>(fet);
276 return std::make_unique<FE<1,SIDE_HIERARCHIC>>(fet);
279 return std::make_unique<FE<1,MONOMIAL>>(fet);
281#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
283 return std::make_unique<FE<1,SZABAB>>(fet);
286 return std::make_unique<FE<1,BERNSTEIN>>(fet);
289 return std::make_unique<FE<1,RATIONAL_BERNSTEIN>>(fet);
293 return std::make_unique<FEXYZ<1>>(fet);
296 return std::make_unique<FEScalar<1>>(fet);
310 return std::make_unique<FE<2,CLOUGH>>(fet);
313 return std::make_unique<FE<2,HERMITE>>(fet);
316 return std::make_unique<FE<2,LAGRANGE>>(fet);
319 return std::make_unique<FE<2,L2_LAGRANGE>>(fet);
322 return std::make_unique<FE<2,L2_LAGRANGE_GLL>>(fet);
325 return std::make_unique<FE<2,HIERARCHIC>>(fet);
328 return std::make_unique<FE<2,L2_HIERARCHIC>>(fet);
331 return std::make_unique<FE<2,SIDE_HIERARCHIC>>(fet);
334 return std::make_unique<FE<2,MONOMIAL>>(fet);
336#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
338 return std::make_unique<FE<2,SZABAB>>(fet);
341 return std::make_unique<FE<2,BERNSTEIN>>(fet);
344 return std::make_unique<FE<2,RATIONAL_BERNSTEIN>>(fet);
348 return std::make_unique<FEXYZ<2>>(fet);
351 return std::make_unique<FEScalar<2>>(fet);
354 return std::make_unique<FESubdivision>(fet);
368 libmesh_error_msg(
"ERROR: Clough-Tocher elements currently only support 1D and 2D");
371 return std::make_unique<FE<3,HERMITE>>(fet);
374 return std::make_unique<FE<3,LAGRANGE>>(fet);
377 return std::make_unique<FE<3,L2_LAGRANGE>>(fet);
380 return std::make_unique<FE<3,L2_LAGRANGE_GLL>>(fet);
383 return std::make_unique<FE<3,HIERARCHIC>>(fet);
386 return std::make_unique<FE<3,L2_HIERARCHIC>>(fet);
389 return std::make_unique<FE<3,SIDE_HIERARCHIC>>(fet);
392 return std::make_unique<FE<3,MONOMIAL>>(fet);
394#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
396 return std::make_unique<FE<3,SZABAB>>(fet);
399 return std::make_unique<FE<3,BERNSTEIN>>(fet);
402 return std::make_unique<FE<3,RATIONAL_BERNSTEIN>>(fet);
406 return std::make_unique<FEXYZ<3>>(fet);
409 return std::make_unique<FEScalar<3>>(fet);
417 libmesh_error_msg(
"Invalid dimension dim = " <<
dim);
424std::unique_ptr<FEGenericBase<RealGradient>>
436 return std::make_unique<FEHierarchicVec<0>>(fet);
439 return std::make_unique<FEL2HierarchicVec<0>>(fet);
442 return std::make_unique<FELagrangeVec<0>>(fet);
445 return std::make_unique<FEL2LagrangeVec<0>>(fet);
448 return std::make_unique<FEMonomialVec<0>>(fet);
459 return std::make_unique<FEHierarchicVec<1>>(fet);
462 return std::make_unique<FEL2HierarchicVec<1>>(fet);
465 return std::make_unique<FELagrangeVec<1>>(fet);
468 return std::make_unique<FEL2LagrangeVec<1>>(fet);
471 return std::make_unique<FEMonomialVec<1>>(fet);
482 return std::make_unique<FEHierarchicVec<2>>(fet);
485 return std::make_unique<FEL2HierarchicVec<2>>(fet);
488 return std::make_unique<FELagrangeVec<2>>(fet);
491 return std::make_unique<FEL2LagrangeVec<2>>(fet);
494 return std::make_unique<FEMonomialVec<2>>(fet);
497 return std::make_unique<FENedelecOne<2>>(fet);
500 return std::make_unique<FERaviartThomas<2>>(fet);
503 return std::make_unique<FEL2RaviartThomas<2>>(fet);
514 return std::make_unique<FEHierarchicVec<3>>(fet);
517 return std::make_unique<FEL2HierarchicVec<3>>(fet);
520 return std::make_unique<FELagrangeVec<3>>(fet);
523 return std::make_unique<FEL2LagrangeVec<3>>(fet);
526 return std::make_unique<FEMonomialVec<3>>(fet);
529 return std::make_unique<FENedelecOne<3>>(fet);
532 return std::make_unique<FERaviartThomas<3>>(fet);
535 return std::make_unique<FEL2RaviartThomas<3>>(fet);
543 libmesh_error_msg(
"Invalid dimension dim = " <<
dim);
553#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
557std::unique_ptr<FEGenericBase<Real>>
577 return std::make_unique<InfFE<1,JACOBI_20_00,CARTESIAN>>(fet);
589 return std::make_unique<InfFE<1,JACOBI_30_00,CARTESIAN>>(fet);
601 return std::make_unique<InfFE<1,LEGENDRE,CARTESIAN>>(fet);
613 return std::make_unique<InfFE<1,LAGRANGE,CARTESIAN>>(fet);
641 return std::make_unique<InfFE<2,JACOBI_20_00,CARTESIAN>>(fet);
653 return std::make_unique<InfFE<2,JACOBI_30_00,CARTESIAN>>(fet);
665 return std::make_unique<InfFE<2,LEGENDRE,CARTESIAN>>(fet);
677 return std::make_unique<InfFE<2,LAGRANGE,CARTESIAN>>(fet);
705 return std::make_unique<InfFE<3,JACOBI_20_00,CARTESIAN>>(fet);
717 return std::make_unique<InfFE<3,JACOBI_30_00,CARTESIAN>>(fet);
729 return std::make_unique<InfFE<3,LEGENDRE,CARTESIAN>>(fet);
741 return std::make_unique<InfFE<3,LAGRANGE,CARTESIAN>>(fet);
754 libmesh_error_msg(
"Invalid dimension dim = " <<
dim);
761std::unique_ptr<FEGenericBase<RealGradient>>
766 libmesh_not_implemented();
767 return std::unique_ptr<FEVectorBase>();
773template <
typename OutputType>
775 const std::vector<Point> & qp)
783 LOG_ONE_ENTITY_SCOPE(
"compute_shape_functions()",
"FE");
785 this->determine_calculations();
788 this->_fe_trans->map_phi(this->dim, elem, qp, (*
this), this->phi, this->_add_p_level_in_reinit);
791 this->_fe_trans->map_dphi(this->dim, elem, qp, (*
this), this->dphi,
792 this->dphidx, this->dphidy, this->dphidz);
794#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
796 this->_fe_trans->map_d2phi(this->dim, qp, (*
this), this->d2phi,
797 this->d2phidx2, this->d2phidxdy, this->d2phidxdz,
798 this->d2phidy2, this->d2phidydz, this->d2phidz2);
803 this->_fe_trans->map_curl(this->dim, elem, qp, (*
this), this->curl_phi);
807 this->_fe_trans->map_div(this->dim, elem, qp, (*
this), this->div_phi);
819 LOG_SCOPE(
"compute_dual_shape_coeffs()",
"FE");
821 const unsigned int sz=phi_vals.size();
822 libmesh_error_msg_if(!sz,
"ERROR: cannot compute dual shape coefficients with empty phi values");
825 dual_coeff.resize(sz, sz);
831 D(i,i) += JxW[qp]*phi_vals[i][qp];
833 A(i,j) += JxW[qp]*phi_vals[i][qp]*phi_vals[j][qp];
847 (((_elem->type() ==
TRI6 || _elem->type() ==
TRI7) && sz == 6) ||
848 (_elem->type() ==
QUAD8 && sz == 8)))
853 for (
const auto m :
make_range(_elem->n_vertices(), sz))
854 for (
const auto v :
make_range(_elem->n_second_order_adjacent_vertices(m)))
856 const auto vertex = _elem->second_order_adjacent_vertex(m, v);
857 D(vertex, vertex) += alpha*D(m,m);
858 D(vertex, m) -= alpha*D(m,m);
868 A.cholesky_solve(Dcol, coeffcol);
871 dual_coeff(row, j)=coeffcol(row);
879 LOG_SCOPE(
"compute_dual_shape_functions()",
"FE");
891 dual_dphi[j][qp] = 0;
892#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
894 dual_d2phi[j][qp] = 0;
903 dual_phi[j][qp] += dual_coeff(i, j) * phi[i][qp];
905 dual_dphi[j][qp] += dual_coeff(i, j) * dphi[i][qp];
906#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
908 dual_d2phi[j][qp] += dual_coeff(i, j) * d2phi[i][qp];
913template <
typename OutputType>
918 os <<
" phi[" << i <<
"][" << j <<
"]=" << phi[i][j] << std::endl;
921template <
typename OutputType>
926 os <<
" dual_phi[" << i <<
"][" << j <<
"]=" << dual_phi[i][j] << std::endl;
932template <
typename OutputType>
937 os <<
" dphi[" << i <<
"][" << j <<
"]=" << dphi[i][j];
940template <
typename OutputType>
945 os <<
" dual_dphi[" << i <<
"][" << j <<
"]=" << dual_dphi[i][j];
950template <
typename OutputType>
953 this->calculations_started =
true;
958 this->calculate_nothing || this->calculate_phi || this->calculate_dphi ||
959 this->calculate_dphiref || this->calculate_curl_phi || this->calculate_div_phi ||
962#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
963 requested_ok = requested_ok || this->calculate_d2phi;
966 libmesh_error_msg_if(
968 "You must call one or more of the FE accessors "
969 "(e.g. get_phi(), get_dphi(), get_nothing()) "
970 "_before_ calling reinit()!");
973 if (this->calculate_phi)
974 this->_fe_trans->init_map_phi(*
this);
976 if (this->calculate_dphiref)
977 this->_fe_trans->init_map_dphi(*
this);
979#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
980 if (this->calculate_d2phi)
981 this->_fe_trans->init_map_d2phi(*
this);
987#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
990template <
typename OutputType>
995 os <<
" d2phi[" << i <<
"][" << j <<
"]=" << d2phi[i][j];
998template <
typename OutputType>
1003 os <<
" dual_d2phi[" << i <<
"][" << j <<
"]=" << dual_d2phi[i][j];
1010#ifdef LIBMESH_ENABLE_AMR
1012template <
typename OutputType>
1018 const unsigned int var,
1019 const bool use_old_dof_indices)
1022 std::vector<unsigned int> new_side_dofs, old_side_dofs;
1025 unsigned int dim = elem->
dim();
1028 const unsigned int n_children = elem->
n_children();
1033 std::unique_ptr<FEGenericBase<OutputShape>> fe
1035 std::unique_ptr<FEGenericBase<OutputShape>> fe_coarse
1041 std::vector<Point> coarse_qpoints;
1045 const std::vector<std::vector<OutputShape>> & phi_values =
1047 const std::vector<std::vector<OutputShape>> & phi_coarse =
1048 fe_coarse->get_phi();
1052 const std::vector<std::vector<OutputGradient>> * dphi_values =
1054 const std::vector<std::vector<OutputGradient>> * dphi_coarse =
1061 const std::vector<std::vector<OutputGradient>> &
1062 ref_dphi_values = fe->get_dphi();
1063 dphi_values = &ref_dphi_values;
1064 const std::vector<std::vector<OutputGradient>> &
1065 ref_dphi_coarse = fe_coarse->get_dphi();
1066 dphi_coarse = &ref_dphi_coarse;
1070 const std::vector<Real> & JxW =
1075 const std::vector<Point> & xyz_values =
1082 const unsigned int new_n_dofs =
1086 std::vector<char> dof_is_fixed(new_n_dofs,
false);
1087 std::vector<int> free_dof(new_n_dofs, 0);
1103 std::vector<dof_id_type> node_dof_indices;
1104 if (use_old_dof_indices)
1107 dof_map.
dof_indices (elem, node_dof_indices, var);
1109 unsigned int current_dof = 0;
1110 for (
unsigned int n=0; n!=
n_nodes; ++n)
1114 const unsigned int my_nc =
1118 current_dof += my_nc;
1127 int extra_order = 0;
1130 const unsigned int nc =
1132 for (
unsigned int i=0; i!= nc; ++i)
1135 old_vector(node_dof_indices[current_dof]);
1136 dof_is_fixed[current_dof] =
true;
1142 FEType fe_type = base_fe_type, temp_fe_type;
1152 const unsigned int n_new_side_dofs =
1153 cast_int<unsigned int>(new_side_dofs.size());
1157 unsigned int free_dofs = 0;
1158 for (
unsigned int i=0; i != n_new_side_dofs; ++i)
1159 if (!dof_is_fixed[new_side_dofs[i]])
1160 free_dof[free_dofs++] = i;
1168 for (
unsigned int c=0; c != n_children; ++c)
1174 std::vector<dof_id_type> child_dof_indices;
1175 if (use_old_dof_indices)
1177 child_dof_indices, var);
1180 child_dof_indices, var);
1181 const unsigned int child_n_dofs =
1182 cast_int<unsigned int>
1183 (child_dof_indices.size());
1185 temp_fe_type = base_fe_type;
1186 temp_fe_type.
order = temp_fe_type.order + child->
p_level();
1189 temp_fe_type, e, old_side_dofs);
1193 fe->attach_quadrature_rule (qedgerule.get());
1194 fe->edge_reinit (child, e);
1195 const unsigned int n_qp = qedgerule->n_points();
1200 fe_coarse->reinit(elem, &coarse_qpoints);
1203 for (
unsigned int qp=0; qp<n_qp; qp++)
1213 for (
unsigned int i=0; i<child_n_dofs;
1217 (old_vector(child_dof_indices[i])*
1220 finegrad += (*dphi_values)[i][qp] *
1221 old_vector(child_dof_indices[i]);
1225 for (
unsigned int sidei=0, freei=0; sidei != n_new_side_dofs; ++sidei)
1227 unsigned int i = new_side_dofs[sidei];
1229 if (dof_is_fixed[i])
1231 for (
unsigned int sidej=0, freej=0; sidej != n_new_side_dofs; ++sidej)
1234 new_side_dofs[sidej];
1235 if (dof_is_fixed[j])
1238 phi_coarse[j][qp]) *
1243 phi_coarse[j][qp]) *
1247 if (dof_is_fixed[j])
1250 (*dphi_coarse)[j][qp]) *
1255 (*dphi_coarse)[j][qp]) *
1258 if (!dof_is_fixed[j])
1273 for (
unsigned int i=0; i != free_dofs; ++i)
1275 Number & ui = Ue(new_side_dofs[free_dof[i]]);
1279 dof_is_fixed[new_side_dofs[free_dof[i]]] =
true;
1290 const unsigned int n_new_side_dofs =
1291 cast_int<unsigned int>(new_side_dofs.size());
1295 unsigned int free_dofs = 0;
1296 for (
unsigned int i=0; i != n_new_side_dofs; ++i)
1297 if (!dof_is_fixed[new_side_dofs[i]])
1298 free_dof[free_dofs++] = i;
1306 for (
unsigned int c=0; c != n_children; ++c)
1312 std::vector<dof_id_type> child_dof_indices;
1313 if (use_old_dof_indices)
1315 child_dof_indices, var);
1318 child_dof_indices, var);
1319 const unsigned int child_n_dofs =
1320 cast_int<unsigned int>
1321 (child_dof_indices.size());
1323 temp_fe_type = base_fe_type;
1324 temp_fe_type.
order = temp_fe_type.order + child->
p_level();
1327 temp_fe_type, s, old_side_dofs);
1331 fe->attach_quadrature_rule (qsiderule.get());
1332 fe->reinit (child, s);
1333 const unsigned int n_qp = qsiderule->n_points();
1338 fe_coarse->reinit(elem, &coarse_qpoints);
1341 for (
unsigned int qp=0; qp<n_qp; qp++)
1351 for (
unsigned int i=0; i<child_n_dofs;
1355 old_vector(child_dof_indices[i]) *
1358 finegrad += (*dphi_values)[i][qp] *
1359 old_vector(child_dof_indices[i]);
1363 for (
unsigned int sidei=0, freei=0; sidei != n_new_side_dofs; ++sidei)
1365 unsigned int i = new_side_dofs[sidei];
1367 if (dof_is_fixed[i])
1369 for (
unsigned int sidej=0, freej=0; sidej != n_new_side_dofs; ++sidej)
1372 new_side_dofs[sidej];
1373 if (dof_is_fixed[j])
1376 phi_coarse[j][qp]) *
1381 phi_coarse[j][qp]) *
1385 if (dof_is_fixed[j])
1388 (*dphi_coarse)[j][qp]) *
1393 (*dphi_coarse)[j][qp]) *
1396 if (!dof_is_fixed[j])
1410 for (
unsigned int i=0; i != free_dofs; ++i)
1412 Number & ui = Ue(new_side_dofs[free_dof[i]]);
1416 dof_is_fixed[new_side_dofs[free_dof[i]]] =
true;
1424 unsigned int free_dofs = 0;
1425 for (
unsigned int i=0; i != new_n_dofs; ++i)
1426 if (!dof_is_fixed[i])
1427 free_dof[free_dofs++] = i;
1436 std::vector<dof_id_type> child_dof_indices;
1437 if (use_old_dof_indices)
1439 child_dof_indices, var);
1442 child_dof_indices, var);
1443 const unsigned int child_n_dofs =
1444 cast_int<unsigned int>
1445 (child_dof_indices.size());
1449 fe->attach_quadrature_rule (qrule.get());
1450 fe->reinit (&child);
1451 const unsigned int n_qp = qrule->n_points();
1455 fe_coarse->reinit(elem, &coarse_qpoints);
1458 for (
unsigned int qp=0; qp<n_qp; qp++)
1468 for (
unsigned int i=0; i<child_n_dofs; i++)
1471 (old_vector(child_dof_indices[i]) *
1474 finegrad += (*dphi_values)[i][qp] *
1475 old_vector(child_dof_indices[i]);
1479 for (
unsigned int i=0, freei=0;
1480 i != new_n_dofs; ++i)
1483 if (dof_is_fixed[i])
1485 for (
unsigned int j=0, freej=0; j !=
1488 if (dof_is_fixed[j])
1491 phi_coarse[j][qp]) *
1496 phi_coarse[j][qp]) *
1500 if (dof_is_fixed[j])
1503 (*dphi_coarse)[j][qp]) *
1508 (*dphi_coarse)[j][qp]) *
1511 if (!dof_is_fixed[j])
1525 for (
unsigned int i=0; i != free_dofs; ++i)
1527 Number & ui = Ue(free_dof[i]);
1534 dof_is_fixed[free_dof[i]] =
true;
1540 for (
unsigned int i=0; i != new_n_dofs; ++i)
1547template <
typename OutputType>
1553 const bool use_old_dof_indices)
1561 coarsened_dof_values(old_vector, dof_map, elem, Usub,
1562 v, use_old_dof_indices);
1570template <
typename OutputType>
1574 const unsigned int variable_number,
1579 const unsigned int Dim = elem->
dim();
1594 std::unique_ptr<FEGenericBase<OutputShape>> my_fe
1596 my_fe->add_p_level_in_reinit(add_p_level);
1610 libmesh_not_implemented();
1612 std::unique_ptr<FEGenericBase<OutputShape>> neigh_fe
1614 neigh_fe->add_p_level_in_reinit(add_p_level);
1617 my_fe->attach_quadrature_rule (&my_qface);
1618 std::vector<Point> neigh_qface;
1620 const std::vector<Real> & JxW = my_fe->get_JxW();
1621 const std::vector<Point> & q_point = my_fe->get_xyz();
1622 const std::vector<std::vector<OutputShape>> & phi = my_fe->get_phi();
1623 const std::vector<std::vector<OutputShape>> & neigh_phi =
1624 neigh_fe->get_phi();
1625 const std::vector<Point> * face_normals =
nullptr;
1626 const std::vector<std::vector<OutputGradient>> * dphi =
nullptr;
1627 const std::vector<std::vector<OutputGradient>> * neigh_dphi =
nullptr;
1629 std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
1630 std::vector<unsigned int> my_side_dofs, neigh_side_dofs;
1634 const std::vector<Point> & ref_face_normals =
1635 my_fe->get_normals();
1636 face_normals = &ref_face_normals;
1637 const std::vector<std::vector<OutputGradient>> & ref_dphi =
1640 const std::vector<std::vector<OutputGradient>> & ref_neigh_dphi =
1641 neigh_fe->get_dphi();
1642 neigh_dphi = &ref_neigh_dphi;
1647 std::vector<DenseVector<Real>> Ue;
1669 libmesh_assert_less (s_neigh, neigh->
n_neighbors());
1675 const unsigned int min_p_level = add_p_level *
1679 const unsigned int old_elem_level = add_p_level * elem->
p_level();
1680 if (old_elem_level != min_p_level)
1681 my_fe->set_fe_order(my_fe->get_fe_type().order.get_order() + min_p_level - old_elem_level);
1682 const unsigned int old_neigh_level = add_p_level * neigh->
p_level();
1683 if (old_neigh_level != min_p_level)
1684 neigh_fe->set_fe_order(neigh_fe->get_fe_type().order.get_order() + min_p_level - old_neigh_level);
1686 my_fe->reinit(elem, s);
1694 my_dof_indices.reserve (elem->
n_nodes());
1695 neigh_dof_indices.reserve (neigh->
n_nodes());
1704 const unsigned int n_qp = my_qface.
n_points();
1708 neigh_fe->reinit(neigh, &neigh_qface);
1712 FEType elem_fe_type = base_fe_type;
1713 if (old_elem_level != min_p_level)
1715 FEType neigh_fe_type = base_fe_type;
1716 if (old_neigh_level != min_p_level)
1721 const unsigned int n_side_dofs =
1722 cast_int<unsigned int>(my_side_dofs.size());
1723 libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());
1726 for (
auto i : my_side_dofs)
1727 libmesh_assert_less(i, my_dof_indices.size());
1728 for (
auto i : neigh_side_dofs)
1729 libmesh_assert_less(i, neigh_dof_indices.size());
1732 Ke.
resize (n_side_dofs, n_side_dofs);
1733 Ue.resize(n_side_dofs);
1737 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1739 const unsigned int i = my_side_dofs[
is];
1740 for (
unsigned int js = 0; js != n_side_dofs; ++js)
1742 const unsigned int j = my_side_dofs[js];
1743 for (
unsigned int qp = 0; qp != n_qp; ++qp)
1747 Ke(
is,js) += JxW[qp] *
1749 (*face_normals)[qp],
1751 (*face_normals)[qp]);
1758 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1760 const unsigned int i = neigh_side_dofs[
is];
1762 for (
unsigned int js = 0; js != n_side_dofs; ++js)
1764 const unsigned int j = my_side_dofs[js];
1765 for (
unsigned int qp = 0; qp != n_qp; ++qp)
1773 (*face_normals)[qp],
1775 (*face_normals)[qp]);
1781 for (
unsigned int js = 0; js != n_side_dofs; ++js)
1783 const unsigned int j = my_side_dofs[js];
1789 bool self_constraint =
false;
1790 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1792 const unsigned int i = neigh_side_dofs[
is];
1793 const dof_id_type their_dof_g = neigh_dof_indices[i];
1796 if (their_dof_g == my_dof_g)
1799 const Real their_dof_value = Ue[
is](js);
1800 libmesh_assert_less (std::abs(their_dof_value-1.),
1803 for (
unsigned int k = 0; k != n_side_dofs; ++k)
1805 std::abs(Ue[k](js)) <
1809 self_constraint =
true;
1814 if (self_constraint)
1828 constraint_row = &(constraints[my_dof_g]);
1832 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1834 const unsigned int i = neigh_side_dofs[
is];
1835 const dof_id_type their_dof_g = neigh_dof_indices[i];
1837 libmesh_assert_not_equal_to (their_dof_g, my_dof_g);
1839 const Real their_dof_value = Ue[
is](js);
1841 if (std::abs(their_dof_value) < 10*
TOLERANCE)
1844 constraint_row->emplace(their_dof_g, their_dof_value);
1848 my_fe->set_fe_order(my_fe->get_fe_type().order.get_order() + old_elem_level - min_p_level);
1849 neigh_fe->set_fe_order(neigh_fe->get_fe_type().order.get_order() + old_neigh_level - min_p_level);
1858 const unsigned int min_p_level =
1860 if (min_p_level < elem->p_level())
1876#ifdef LIBMESH_ENABLE_PERIODIC
1877template <
typename OutputType>
1885 const unsigned int variable_number,
1889 if (boundaries.empty())
1899 libmesh_not_implemented();
1901 const unsigned int Dim = elem->
dim();
1905 const unsigned int sys_number = dof_map.
sys_number();
1910 std::unique_ptr<FEGenericBase<OutputShape>> my_fe
1920 const Real primary_hmin = elem->
hmin();
1922 std::unique_ptr<FEGenericBase<OutputShape>> neigh_fe
1926 my_fe->attach_quadrature_rule (&my_qface);
1927 std::vector<Point> neigh_qface;
1929 const std::vector<Real> & JxW = my_fe->get_JxW();
1930 const std::vector<Point> & q_point = my_fe->get_xyz();
1931 const std::vector<std::vector<OutputShape>> & phi = my_fe->get_phi();
1932 const std::vector<std::vector<OutputShape>> & neigh_phi =
1933 neigh_fe->get_phi();
1934 const std::vector<Point> * face_normals =
nullptr;
1935 const std::vector<std::vector<OutputGradient>> * dphi =
nullptr;
1936 const std::vector<std::vector<OutputGradient>> * neigh_dphi =
nullptr;
1937 std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
1938 std::vector<unsigned int> my_side_dofs, neigh_side_dofs;
1942 const std::vector<Point> & ref_face_normals =
1943 my_fe->get_normals();
1944 face_normals = &ref_face_normals;
1945 const std::vector<std::vector<OutputGradient>> & ref_dphi =
1948 const std::vector<std::vector<OutputGradient>> & ref_neigh_dphi =
1949 neigh_fe->get_dphi();
1950 neigh_dphi = &ref_neigh_dphi;
1955 std::vector<DenseVector<Real>> Ue;
1958 std::vector<boundary_id_type> bc_ids;
1962 const unsigned short int max_ns = elem->
n_sides();
1963 for (
unsigned short int s = 0; s != max_ns; ++s)
1970 for (
const auto & boundary_id : bc_ids)
1979 unsigned int s_neigh;
1980 const Elem * neigh = boundaries.
neighbor(boundary_id, *point_locator, elem, s, &s_neigh);
1982 libmesh_error_msg_if(neigh ==
nullptr,
1983 "PeriodicBoundaries point locator object returned nullptr!");
1991#ifdef LIBMESH_ENABLE_AMR
1996 const unsigned int min_p_level =
2004 const unsigned int old_elem_level = elem->
p_level();
2005 if (old_elem_level != min_p_level)
2006 (
const_cast<Elem *
>(elem))->hack_p_level(min_p_level);
2007 const unsigned int old_neigh_level = neigh->
p_level();
2008 if (old_neigh_level != min_p_level)
2009 (
const_cast<Elem *
>(neigh))->hack_p_level(min_p_level);
2018 my_fe->reinit(elem, s);
2028 std::vector<std::vector<dof_id_type>> neigh_dof_indices_all_variables;
2031 const std::set<unsigned int> & variables = periodic->
get_variables();
2032 neigh_dof_indices_all_variables.resize(variables.size());
2033 unsigned int index = 0;
2034 for(
unsigned int var : variables)
2036 dof_map.
dof_indices (neigh, neigh_dof_indices_all_variables[index],
2042 const unsigned int n_qp = my_qface.
n_points();
2046 std::vector<Point> neigh_point(q_point.size());
2053 neigh_fe->reinit(neigh, &neigh_qface);
2062#ifdef LIBMESH_ENABLE_AMR
2063 if (elem->
p_level() != old_elem_level)
2064 (
const_cast<Elem *
>(elem))->hack_p_level(old_elem_level);
2065 if (neigh->
p_level() != old_neigh_level)
2066 (
const_cast<Elem *
>(neigh))->hack_p_level(old_neigh_level);
2069 const unsigned int n_side_dofs =
2070 cast_int<unsigned int>
2071 (my_side_dofs.size());
2072 libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());
2074 Ke.
resize (n_side_dofs, n_side_dofs);
2075 Ue.resize(n_side_dofs);
2079 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
2081 const unsigned int i = my_side_dofs[
is];
2082 for (
unsigned int js = 0; js != n_side_dofs; ++js)
2084 const unsigned int j = my_side_dofs[js];
2085 for (
unsigned int qp = 0; qp != n_qp; ++qp)
2087 Ke(
is,js) += JxW[qp] *
2091 Ke(
is,js) += JxW[qp] *
2093 (*face_normals)[qp],
2095 (*face_normals)[qp]);
2102 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
2104 const unsigned int i = neigh_side_dofs[
is];
2106 for (
unsigned int js = 0; js != n_side_dofs; ++js)
2108 const unsigned int j = my_side_dofs[js];
2109 for (
unsigned int qp = 0; qp != n_qp; ++qp)
2117 (*face_normals)[qp],
2119 (*face_normals)[qp]);
2173 std::set<dof_id_type> my_constrained_dofs;
2176 std::vector<boundary_id_type> new_bc_ids;
2190 std::set<boundary_id_type> point_bcids;
2192 for (
unsigned int new_s = 0;
2193 new_s != max_ns; ++new_s)
2200 for (
const auto & new_boundary_id : new_bc_ids)
2203 if (new_periodic && new_periodic->
is_my_variable(variable_number))
2204 point_bcids.insert(new_boundary_id);
2210 if (primary_boundary_point_neighbor
2216 std::set<boundary_id_type> point_pairedids;
2217 for (
const auto & new_boundary_id : point_bcids)
2224 const Elem * primary_elem =
nullptr;
2225 const Elem * main_neigh =
nullptr;
2226 Point main_pt = my_node,
2227 primary_pt = my_node;
2229 for (
const auto & new_boundary_id : point_bcids)
2235 const Point neigh_pt =
2248 primary_elem = elem;
2250 const Elem * primary_neigh =
2251 primary_boundary_point_neighbor(neigh, neigh_pt,
2257 if (new_boundary_id == boundary_id)
2259 main_neigh = primary_neigh;
2266 if ((primary_neigh->
level() > primary_elem->
level()) ||
2271 (primary_neigh->
level() == primary_elem->
level() &&
2272 primary_neigh->
id() > primary_elem->
id()) ||
2276 (primary_neigh == primary_elem &&
2277 (neigh_pt > primary_pt)))
2280 primary_elem = primary_neigh;
2281 primary_pt = neigh_pt;
2284 if (!primary_elem ||
2285 primary_elem != main_neigh ||
2286 primary_pt != main_pt)
2292 unsigned int e=0, ne = elem->
n_edges();
2293 for (; e != ne; ++e)
2298 libmesh_assert_less (e, elem->
n_edges());
2327 std::set<boundary_id_type> edge_bcids;
2329 for (
unsigned int new_s = 0;
2330 new_s != max_ns; ++new_s)
2338 for (
const auto & new_boundary_id : new_bc_ids)
2341 if (new_periodic && new_periodic->
is_my_variable(variable_number))
2342 edge_bcids.insert(new_boundary_id);
2348 if (primary_boundary_edge_neighbor
2354 std::set<boundary_id_type> edge_pairedids;
2355 for (
const auto & new_boundary_id : edge_bcids)
2362 const Elem * primary_elem =
nullptr;
2363 const Elem * main_neigh =
nullptr;
2364 Point main_pt1 = *e1,
2369 for (
const auto & new_boundary_id : edge_bcids)
2383 neigh_pt2.absolute_fuzzy_equals
2390 primary_elem = elem;
2392 const Elem * primary_neigh = primary_boundary_edge_neighbor
2393 (neigh, neigh_pt1, neigh_pt2,
2398 if (new_boundary_id == boundary_id)
2400 main_neigh = primary_neigh;
2401 main_pt1 = neigh_pt1;
2402 main_pt2 = neigh_pt2;
2412 if (primary_neigh == primary_elem)
2414 if (primary_pt1 > primary_pt2)
2415 std::swap(primary_pt1, primary_pt2);
2416 if (neigh_pt1 > neigh_pt2)
2417 std::swap(neigh_pt1, neigh_pt2);
2419 if (neigh_pt2 >= primary_pt2)
2427 if ((primary_neigh->
level() > primary_elem->
level()) ||
2432 (primary_neigh->
level() == primary_elem->
level() &&
2433 primary_neigh->
id() > primary_elem->
id()))
2436 primary_elem = primary_neigh;
2437 primary_pt1 = neigh_pt1;
2438 primary_pt2 = neigh_pt2;
2441 if (!primary_elem ||
2442 primary_elem != main_neigh ||
2443 primary_pt1 != main_pt1 ||
2444 primary_pt2 != main_pt2)
2455 const Point neigh_pt =
2457 if (neigh_pt > my_node)
2471 neigh->
id() > elem->
id()))
2479 const unsigned int n_comp =
2480 my_node.
n_comp(sys_number, variable_number);
2482 for (
unsigned int i=0; i != n_comp; ++i)
2483 my_constrained_dofs.insert
2485 (sys_number, variable_number, i));
2522 for (
unsigned int js = 0; js != n_side_dofs; ++js)
2528 const unsigned int j = my_side_dofs[js];
2533 if (!my_constrained_dofs.count(my_dof_g))
2547 constraint_row = &(constraints[my_dof_g]);
2551 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
2553 const unsigned int i = neigh_side_dofs[
is];
2554 const dof_id_type their_dof_g = neigh_dof_indices[i];
2561 const Real their_dof_value = Ue[
is](js);
2563 if (their_dof_g == my_dof_g)
2565 libmesh_assert_less (std::abs(their_dof_value-1.), 1.e-5);
2566 for (
unsigned int k = 0; k != n_side_dofs; ++k)
2571 if (std::abs(their_dof_value) < 10*
TOLERANCE)
2576 constraint_row->emplace(their_dof_g, their_dof_value);
2586 const std::set<unsigned int> & variables = periodic->
get_variables();
2587 neigh_dof_indices_all_variables.resize(variables.size());
2588 unsigned int index = 0;
2589 for(
unsigned int other_var : variables)
2591 libmesh_assert_msg(base_fe_type == dof_map.
variable_type(other_var),
"FE types must match for all variables involved in constraint");
2594 constraint_row->emplace(neigh_dof_indices_all_variables[index][i],
2595 var_weighting*their_dof_value);
2607#ifdef LIBMESH_ENABLE_AMR
2608 const unsigned int min_p_level =
2610 if (min_p_level < elem->p_level())
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
void boundary_ids(const Node *node, std::vector< boundary_id_type > &vec_to_fill) const
Fills a user-provided std::vector with the boundary ids associated with Node node.
Defines a dense matrix for use in Finite Element-type computations.
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
For symmetric positive definite (SPD) matrices.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
virtual void zero() override final
Sets all elements of the matrix to 0 and resets any decomposition flag which may have been previously...
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
virtual void zero() override final
Set every element in the vector to 0.
void append(const DenseVector< T2 > &other_vector)
Append additional entries to (resizing, but unchanging) the vector.
The constraint matrix storage format.
This class handles the numbering of degrees of freedom on a mesh.
void constrain_p_dofs(unsigned int var, const Elem *elem, unsigned int s, unsigned int p)
Constrains degrees of freedom on side s of element elem which correspond to variable number var and t...
unsigned int n_variables() const override
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
const FEType & variable_type(const unsigned int i) const
unsigned int sys_number() const
bool is_constrained_dof(const dof_id_type dof) const
const Variable & variable(const unsigned int c) const override
void old_dof_indices(const Elem &elem, unsigned int n, std::vector< dof_id_type > &di, const unsigned int vn) const
Appends to the vector di the old global degree of freedom indices for elem.node_ref(n),...
unsigned int n_comp(const unsigned int s, const unsigned int var) const
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
This is the base class from which all geometric element types are derived.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
const Node & node_ref(const unsigned int i) const
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
virtual unsigned int n_nodes() const =0
const Elem * child_ptr(unsigned int i) const
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
unsigned int n_neighbors() const
virtual bool is_face(const unsigned int i) const =0
void find_point_neighbors(const Point &p, std::set< const Elem * > &neighbor_set) const
This function finds all active elements (including this one) which are in the same manifold as this e...
virtual Real hmin() const
virtual unsigned short dim() const =0
void find_edge_neighbors(const Point &p1, const Point &p2, std::set< const Elem * > &neighbor_set) const
This function finds all active elements in the same manifold as this element which touch the current ...
subdomain_id_type subdomain_id() const
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
virtual bool is_edge(const unsigned int i) const =0
unsigned int level() const
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
const Node * node_ptr(const unsigned int i) const
IntRange< unsigned short > edge_index_range() const
virtual bool is_vertex(const unsigned int i) const =0
virtual unsigned int n_children() const =0
unsigned int max_descendant_p_level() const
IntRange< unsigned short > node_index_range() const
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
virtual unsigned int n_edges() const =0
virtual unsigned int n_sides() const =0
unsigned int p_level() const
const Elem * neighbor_ptr(unsigned int i) const
virtual bool infinite() const =0
IntRange< unsigned short > side_index_range() const
This class forms the foundation from which generic finite elements may be derived.
virtual_for_inffe void determine_calculations()
Determine which values are to be calculated, for both the FE itself and for the FEMap.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
void compute_dual_shape_coeffs(const std::vector< Real > &JxW, const std::vector< std::vector< OutputShape > > &phi)
Compute the dual basis coefficients dual_coeff we rely on the JxW (or weights) and the phi values,...
virtual void print_dphi(std::ostream &os) const override
Prints the value of each shape function's derivative at each quadrature point.
static void coarsened_dof_values(const NumericVector< Number > &global_vector, const DofMap &dof_map, const Elem *coarse_elem, DenseVector< Number > &coarse_dofs, const unsigned int var, const bool use_old_dof_indices=false)
Creates a local projection on coarse_elem, based on the DoF values in global_vector for it's children...
static void compute_proj_constraints(DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
Computes the constraint matrix contributions (for non-conforming adapted meshes) corresponding to var...
static std::unique_ptr< FEGenericBase > build_InfFE(const unsigned int dim, const FEType &type)
Builds a specific infinite element type.
virtual void print_dual_d2phi(std::ostream &os) const override
virtual void print_d2phi(std::ostream &os) const override
Prints the value of each shape function's second derivatives at each quadrature point.
virtual void print_phi(std::ostream &os) const override
Prints the value of each shape function at each quadrature point.
static void compute_periodic_constraints(DofConstraints &constraints, DofMap &dof_map, const PeriodicBoundaries &boundaries, const MeshBase &mesh, const PointLocatorBase *point_locator, const unsigned int variable_number, const Elem *elem)
Computes the constraint matrix contributions (for meshes with periodic boundary conditions) correspon...
virtual void print_dual_phi(std::ostream &os) const override
TensorTools::MakeNumber< OutputShape >::type OutputNumber
virtual void compute_shape_functions(const Elem *elem, const std::vector< Point > &qp) override
After having updated the jacobian and the transformation from local to global coordinates in FEMap::c...
virtual void print_dual_dphi(std::ostream &os) const override
void compute_dual_shape_functions()
Compute dual_phi, dual_dphi, dual_d2phi It is only valid for this to be called after reinit has occur...
static void dofs_on_side(const Elem *const elem, const unsigned int dim, const FEType &fe_t, unsigned int s, std::vector< unsigned int > &di, const bool add_p_level=true)
Fills the vector di with the local degree of freedom indices associated with side s of element elem A...
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
static void dofs_on_edge(const Elem *const elem, const unsigned int dim, const FEType &fe_t, unsigned int e, std::vector< unsigned int > &di, const bool add_p_level=true)
Fills the vector di with the local degree of freedom indices associated with edge e of element elem A...
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
InfMapType inf_map
The coordinate mapping type of the infinite element.
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Order default_quadrature_order() const
OrderWrapper order
The approximation order of the element (at 0 p-refinement level).
bool p_refinement
Whether or not the finite elements for this type increase their p refinement level on geometric eleme...
FEFamily radial_family
The type of approximation in radial direction.
FEFamily family
The type of finite element.
This is the MeshBase class.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
A Node is like a Point, but with more information.
Provides a uniform interface to vector storage schemes for different linear algebra libraries.
int get_order() const
Explicitly request the order as an int.
We're using a class instead of a typedef to allow forward declarations and future flexibility.
PeriodicBoundaryBase * boundary(boundary_id_type id)
const Elem * neighbor(boundary_id_type boundary_id, const PointLocatorBase &point_locator, const Elem *e, unsigned int side, unsigned int *neigh_side=nullptr) const
The base class for defining periodic boundaries.
bool has_transformation_matrix() const
const DenseMatrix< Real > & get_transformation_matrix() const
Get the transformation matrix, if it is defined.
bool is_my_variable(unsigned int var_num) const
const std::set< unsigned int > & get_variables() const
Get the set of variables for this periodic boundary condition.
virtual Point get_corresponding_pos(const Point &pt) const =0
This function should be overridden by derived classes to define how one finds corresponding nodes on ...
boundary_id_type pairedboundary
This is the base class for point locators.
A Point defines a location in LIBMESH_DIM dimensional Real space.
unsigned int n_points() const
This class implements specific orders of Gauss quadrature.
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
This class defines the notion of a variable in the system.
bool active_on_subdomain(subdomain_id_type sid) const
const FEType & type() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.
std::string enum_to_string(const T e)
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
std::map< dof_id_type, Real, std::less< dof_id_type >, Threads::scalable_allocator< std::pair< const dof_id_type, Real > > > DofConstraintRow
A row of the Dof constraint matrix.
PetscErrorCode PetscInt const PetscInt IS * is
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
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...
const dof_id_type n_nodes