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 56 const 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;
116 const 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;
178 #endif // LIBMESH_ENABLE_PERIODIC 190 std::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,HIERARCHIC>>(fet);
217 return std::make_unique<FE<0,L2_HIERARCHIC>>(fet);
220 return std::make_unique<FE<0,SIDE_HIERARCHIC>>(fet);
223 return std::make_unique<FE<0,MONOMIAL>>(fet);
225 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 227 return std::make_unique<FE<0,SZABAB>>(fet);
230 return std::make_unique<FE<0,BERNSTEIN>>(fet);
233 return std::make_unique<FE<0,RATIONAL_BERNSTEIN>>(fet);
237 return std::make_unique<FEXYZ<0>>(fet);
240 return std::make_unique<FEScalar<0>>(fet);
252 return std::make_unique<FE<1,CLOUGH>>(fet);
255 return std::make_unique<FE<1,HERMITE>>(fet);
258 return std::make_unique<FE<1,LAGRANGE>>(fet);
261 return std::make_unique<FE<1,L2_LAGRANGE>>(fet);
264 return std::make_unique<FE<1,HIERARCHIC>>(fet);
267 return std::make_unique<FE<1,L2_HIERARCHIC>>(fet);
270 return std::make_unique<FE<1,SIDE_HIERARCHIC>>(fet);
273 return std::make_unique<FE<1,MONOMIAL>>(fet);
275 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 277 return std::make_unique<FE<1,SZABAB>>(fet);
280 return std::make_unique<FE<1,BERNSTEIN>>(fet);
283 return std::make_unique<FE<1,RATIONAL_BERNSTEIN>>(fet);
287 return std::make_unique<FEXYZ<1>>(fet);
290 return std::make_unique<FEScalar<1>>(fet);
304 return std::make_unique<FE<2,CLOUGH>>(fet);
307 return std::make_unique<FE<2,HERMITE>>(fet);
310 return std::make_unique<FE<2,LAGRANGE>>(fet);
313 return std::make_unique<FE<2,L2_LAGRANGE>>(fet);
316 return std::make_unique<FE<2,HIERARCHIC>>(fet);
319 return std::make_unique<FE<2,L2_HIERARCHIC>>(fet);
322 return std::make_unique<FE<2,SIDE_HIERARCHIC>>(fet);
325 return std::make_unique<FE<2,MONOMIAL>>(fet);
327 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 329 return std::make_unique<FE<2,SZABAB>>(fet);
332 return std::make_unique<FE<2,BERNSTEIN>>(fet);
335 return std::make_unique<FE<2,RATIONAL_BERNSTEIN>>(fet);
339 return std::make_unique<FEXYZ<2>>(fet);
342 return std::make_unique<FEScalar<2>>(fet);
345 return std::make_unique<FESubdivision>(fet);
359 libmesh_error_msg(
"ERROR: Clough-Tocher elements currently only support 1D and 2D");
362 return std::make_unique<FE<3,HERMITE>>(fet);
365 return std::make_unique<FE<3,LAGRANGE>>(fet);
368 return std::make_unique<FE<3,L2_LAGRANGE>>(fet);
371 return std::make_unique<FE<3,HIERARCHIC>>(fet);
374 return std::make_unique<FE<3,L2_HIERARCHIC>>(fet);
377 return std::make_unique<FE<3,SIDE_HIERARCHIC>>(fet);
380 return std::make_unique<FE<3,MONOMIAL>>(fet);
382 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 384 return std::make_unique<FE<3,SZABAB>>(fet);
387 return std::make_unique<FE<3,BERNSTEIN>>(fet);
390 return std::make_unique<FE<3,RATIONAL_BERNSTEIN>>(fet);
394 return std::make_unique<FEXYZ<3>>(fet);
397 return std::make_unique<FEScalar<3>>(fet);
405 libmesh_error_msg(
"Invalid dimension dim = " <<
dim);
412 std::unique_ptr<FEGenericBase<RealGradient>>
424 return std::make_unique<FEHierarchicVec<0>>(fet);
427 return std::make_unique<FEL2HierarchicVec<0>>(fet);
430 return std::make_unique<FELagrangeVec<0>>(fet);
433 return std::make_unique<FEL2LagrangeVec<0>>(fet);
436 return std::make_unique<FEMonomialVec<0>>(fet);
447 return std::make_unique<FEHierarchicVec<1>>(fet);
450 return std::make_unique<FEL2HierarchicVec<1>>(fet);
453 return std::make_unique<FELagrangeVec<1>>(fet);
456 return std::make_unique<FEL2LagrangeVec<1>>(fet);
459 return std::make_unique<FEMonomialVec<1>>(fet);
470 return std::make_unique<FEHierarchicVec<2>>(fet);
473 return std::make_unique<FEL2HierarchicVec<2>>(fet);
476 return std::make_unique<FELagrangeVec<2>>(fet);
479 return std::make_unique<FEL2LagrangeVec<2>>(fet);
482 return std::make_unique<FEMonomialVec<2>>(fet);
485 return std::make_unique<FENedelecOne<2>>(fet);
488 return std::make_unique<FERaviartThomas<2>>(fet);
491 return std::make_unique<FEL2RaviartThomas<2>>(fet);
502 return std::make_unique<FEHierarchicVec<3>>(fet);
505 return std::make_unique<FEL2HierarchicVec<3>>(fet);
508 return std::make_unique<FELagrangeVec<3>>(fet);
511 return std::make_unique<FEL2LagrangeVec<3>>(fet);
514 return std::make_unique<FEMonomialVec<3>>(fet);
517 return std::make_unique<FENedelecOne<3>>(fet);
520 return std::make_unique<FERaviartThomas<3>>(fet);
523 return std::make_unique<FEL2RaviartThomas<3>>(fet);
531 libmesh_error_msg(
"Invalid dimension dim = " <<
dim);
541 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 545 std::unique_ptr<FEGenericBase<Real>>
565 return std::make_unique<InfFE<1,JACOBI_20_00,CARTESIAN>>(fet);
577 return std::make_unique<InfFE<1,JACOBI_30_00,CARTESIAN>>(fet);
589 return std::make_unique<InfFE<1,LEGENDRE,CARTESIAN>>(fet);
601 return std::make_unique<InfFE<1,LAGRANGE,CARTESIAN>>(fet);
629 return std::make_unique<InfFE<2,JACOBI_20_00,CARTESIAN>>(fet);
641 return std::make_unique<InfFE<2,JACOBI_30_00,CARTESIAN>>(fet);
653 return std::make_unique<InfFE<2,LEGENDRE,CARTESIAN>>(fet);
665 return std::make_unique<InfFE<2,LAGRANGE,CARTESIAN>>(fet);
693 return std::make_unique<InfFE<3,JACOBI_20_00,CARTESIAN>>(fet);
705 return std::make_unique<InfFE<3,JACOBI_30_00,CARTESIAN>>(fet);
717 return std::make_unique<InfFE<3,LEGENDRE,CARTESIAN>>(fet);
729 return std::make_unique<InfFE<3,LAGRANGE,CARTESIAN>>(fet);
742 libmesh_error_msg(
"Invalid dimension dim = " <<
dim);
749 std::unique_ptr<FEGenericBase<RealGradient>>
754 libmesh_not_implemented();
755 return std::unique_ptr<FEVectorBase>();
758 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 761 template <
typename OutputType>
763 const std::vector<Point> & qp)
771 LOG_SCOPE(
"compute_shape_functions()",
"FE");
773 this->determine_calculations();
776 this->_fe_trans->map_phi(this->
dim, elem, qp, (*
this), this->phi, this->_add_p_level_in_reinit);
779 this->_fe_trans->map_dphi(this->
dim, elem, qp, (*
this), this->dphi,
780 this->dphidx, this->dphidy, this->dphidz);
782 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 784 this->_fe_trans->map_d2phi(this->
dim, qp, (*
this), this->d2phi,
785 this->d2phidx2, this->d2phidxdy, this->d2phidxdz,
786 this->d2phidy2, this->d2phidydz, this->d2phidz2);
787 #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES 791 this->_fe_trans->map_curl(this->
dim, elem, qp, (*
this), this->curl_phi);
795 this->_fe_trans->map_div(this->
dim, elem, qp, (*
this), this->div_phi);
807 LOG_SCOPE(
"compute_dual_shape_coeffs()",
"FE");
809 const unsigned int sz=phi_vals.size();
810 libmesh_error_msg_if(!sz,
"ERROR: cannot compute dual shape coefficients with empty phi values");
813 dual_coeff.resize(sz, sz);
819 D(i,i) += JxW[qp]*phi_vals[i][qp];
821 A(i,j) += JxW[qp]*phi_vals[i][qp]*phi_vals[j][qp];
830 A.cholesky_solve(Dcol, coeffcol);
833 dual_coeff(row, j)=coeffcol(row);
841 LOG_SCOPE(
"compute_dual_shape_functions()",
"FE");
853 dual_dphi[j][qp] = 0;
854 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 856 dual_d2phi[j][qp] = 0;
865 dual_phi[j][qp] += dual_coeff(i, j) * phi[i][qp];
867 dual_dphi[j][qp] += dual_coeff(i, j) * dphi[i][qp];
868 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 870 dual_d2phi[j][qp] += dual_coeff(i, j) * d2phi[i][qp];
875 template <
typename OutputType>
880 os <<
" phi[" << i <<
"][" << j <<
"]=" << phi[i][j] << std::endl;
883 template <
typename OutputType>
888 os <<
" dual_phi[" << i <<
"][" << j <<
"]=" << dual_phi[i][j] << std::endl;
894 template <
typename OutputType>
899 os <<
" dphi[" << i <<
"][" << j <<
"]=" << dphi[i][j];
902 template <
typename OutputType>
907 os <<
" dual_dphi[" << i <<
"][" << j <<
"]=" << dual_dphi[i][j];
912 template <
typename OutputType>
915 this->calculations_started =
true;
921 #ifdef LIBMESH_ENABLE_DEPRECATED 922 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 923 if (!this->calculate_nothing &&
924 !this->calculate_phi && !this->calculate_dphi &&
925 !this->calculate_dphiref &&
926 !this->calculate_d2phi && !this->calculate_curl_phi &&
927 !this->calculate_div_phi && !this->calculate_map)
929 libmesh_deprecated();
930 this->calculate_phi = this->calculate_dphi = this->calculate_d2phi = this->calculate_dphiref =
true;
933 this->calculate_curl_phi =
true;
934 this->calculate_div_phi =
true;
938 if (!this->calculate_nothing &&
939 !this->calculate_phi && !this->calculate_dphi &&
940 !this->calculate_dphiref &&
941 !this->calculate_curl_phi && !this->calculate_div_phi &&
942 !this->calculate_map)
944 libmesh_deprecated();
945 this->calculate_phi = this->calculate_dphi = this->calculate_dphiref =
true;
948 this->calculate_curl_phi =
true;
949 this->calculate_div_phi =
true;
952 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 954 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 956 this->calculate_phi || this->calculate_dphi ||
957 this->calculate_d2phi ||
958 this->calculate_dphiref ||
959 this->calculate_curl_phi || this->calculate_div_phi ||
960 this->calculate_map);
963 this->calculate_phi || this->calculate_dphi ||
964 this->calculate_dphiref ||
965 this->calculate_curl_phi || this->calculate_div_phi ||
966 this->calculate_map);
967 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 968 #endif // LIBMESH_ENABLE_DEPRECATED 971 if (this->calculate_phi)
972 this->_fe_trans->init_map_phi(*
this);
974 if (this->calculate_dphiref)
975 this->_fe_trans->init_map_dphi(*
this);
977 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 978 if (this->calculate_d2phi)
979 this->_fe_trans->init_map_d2phi(*
this);
980 #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES 985 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 988 template <
typename OutputType>
993 os <<
" d2phi[" << i <<
"][" << j <<
"]=" << d2phi[i][j];
996 template <
typename OutputType>
1001 os <<
" dual_d2phi[" << i <<
"][" << j <<
"]=" << dual_d2phi[i][j];
1008 #ifdef LIBMESH_ENABLE_AMR 1010 template <
typename OutputType>
1016 const unsigned int var,
1017 const bool use_old_dof_indices)
1020 std::vector<unsigned int> new_side_dofs, old_side_dofs;
1023 unsigned int dim = elem->
dim();
1026 const unsigned int n_children = elem->
n_children();
1031 std::unique_ptr<FEGenericBase<OutputShape>> fe
1033 std::unique_ptr<FEGenericBase<OutputShape>> fe_coarse
1039 std::vector<Point> coarse_qpoints;
1043 const std::vector<std::vector<OutputShape>> & phi_values =
1045 const std::vector<std::vector<OutputShape>> & phi_coarse =
1046 fe_coarse->get_phi();
1050 const std::vector<std::vector<OutputGradient>> * dphi_values =
1052 const std::vector<std::vector<OutputGradient>> * dphi_coarse =
1059 const std::vector<std::vector<OutputGradient>> &
1060 ref_dphi_values = fe->get_dphi();
1061 dphi_values = &ref_dphi_values;
1062 const std::vector<std::vector<OutputGradient>> &
1063 ref_dphi_coarse = fe_coarse->get_dphi();
1064 dphi_coarse = &ref_dphi_coarse;
1068 const std::vector<Real> & JxW =
1073 const std::vector<Point> & xyz_values =
1080 const unsigned int new_n_dofs =
1084 std::vector<char> dof_is_fixed(new_n_dofs,
false);
1085 std::vector<int> free_dof(new_n_dofs, 0);
1101 std::vector<dof_id_type> node_dof_indices;
1102 if (use_old_dof_indices)
1105 dof_map.
dof_indices (elem, node_dof_indices, var);
1107 unsigned int current_dof = 0;
1108 for (
unsigned int n=0; n!=
n_nodes; ++n)
1112 const unsigned int my_nc =
1116 current_dof += my_nc;
1125 int extra_order = 0;
1128 const unsigned int nc =
1130 for (
unsigned int i=0; i!= nc; ++i)
1133 old_vector(node_dof_indices[current_dof]);
1134 dof_is_fixed[current_dof] =
true;
1140 FEType fe_type = base_fe_type, temp_fe_type;
1150 const unsigned int n_new_side_dofs =
1151 cast_int<unsigned int>(new_side_dofs.size());
1155 unsigned int free_dofs = 0;
1156 for (
unsigned int i=0; i != n_new_side_dofs; ++i)
1157 if (!dof_is_fixed[new_side_dofs[i]])
1158 free_dof[free_dofs++] = i;
1166 for (
unsigned int c=0; c != n_children; ++c)
1172 std::vector<dof_id_type> child_dof_indices;
1173 if (use_old_dof_indices)
1175 child_dof_indices, var);
1178 child_dof_indices, var);
1179 const unsigned int child_n_dofs =
1180 cast_int<unsigned int>
1181 (child_dof_indices.size());
1183 temp_fe_type = base_fe_type;
1184 temp_fe_type.
order = temp_fe_type.order + child->
p_level();
1187 temp_fe_type, e, old_side_dofs);
1191 fe->attach_quadrature_rule (qedgerule.get());
1192 fe->edge_reinit (child, e);
1193 const unsigned int n_qp = qedgerule->n_points();
1198 fe_coarse->reinit(elem, &coarse_qpoints);
1201 for (
unsigned int qp=0; qp<n_qp; qp++)
1211 for (
unsigned int i=0; i<child_n_dofs;
1215 (old_vector(child_dof_indices[i])*
1218 finegrad += (*dphi_values)[i][qp] *
1219 old_vector(child_dof_indices[i]);
1223 for (
unsigned int sidei=0, freei=0; sidei != n_new_side_dofs; ++sidei)
1225 unsigned int i = new_side_dofs[sidei];
1227 if (dof_is_fixed[i])
1229 for (
unsigned int sidej=0, freej=0; sidej != n_new_side_dofs; ++sidej)
1232 new_side_dofs[sidej];
1233 if (dof_is_fixed[j])
1236 phi_coarse[j][qp]) *
1241 phi_coarse[j][qp]) *
1245 if (dof_is_fixed[j])
1248 (*dphi_coarse)[j][qp]) *
1253 (*dphi_coarse)[j][qp]) *
1256 if (!dof_is_fixed[j])
1271 for (
unsigned int i=0; i != free_dofs; ++i)
1273 Number & ui = Ue(new_side_dofs[free_dof[i]]);
1277 dof_is_fixed[new_side_dofs[free_dof[i]]] =
true;
1288 const unsigned int n_new_side_dofs =
1289 cast_int<unsigned int>(new_side_dofs.size());
1293 unsigned int free_dofs = 0;
1294 for (
unsigned int i=0; i != n_new_side_dofs; ++i)
1295 if (!dof_is_fixed[new_side_dofs[i]])
1296 free_dof[free_dofs++] = i;
1304 for (
unsigned int c=0; c != n_children; ++c)
1310 std::vector<dof_id_type> child_dof_indices;
1311 if (use_old_dof_indices)
1313 child_dof_indices, var);
1316 child_dof_indices, var);
1317 const unsigned int child_n_dofs =
1318 cast_int<unsigned int>
1319 (child_dof_indices.size());
1321 temp_fe_type = base_fe_type;
1322 temp_fe_type.
order = temp_fe_type.order + child->
p_level();
1325 temp_fe_type, s, old_side_dofs);
1329 fe->attach_quadrature_rule (qsiderule.get());
1330 fe->reinit (child, s);
1331 const unsigned int n_qp = qsiderule->n_points();
1336 fe_coarse->reinit(elem, &coarse_qpoints);
1339 for (
unsigned int qp=0; qp<n_qp; qp++)
1349 for (
unsigned int i=0; i<child_n_dofs;
1353 old_vector(child_dof_indices[i]) *
1356 finegrad += (*dphi_values)[i][qp] *
1357 old_vector(child_dof_indices[i]);
1361 for (
unsigned int sidei=0, freei=0; sidei != n_new_side_dofs; ++sidei)
1363 unsigned int i = new_side_dofs[sidei];
1365 if (dof_is_fixed[i])
1367 for (
unsigned int sidej=0, freej=0; sidej != n_new_side_dofs; ++sidej)
1370 new_side_dofs[sidej];
1371 if (dof_is_fixed[j])
1374 phi_coarse[j][qp]) *
1379 phi_coarse[j][qp]) *
1383 if (dof_is_fixed[j])
1386 (*dphi_coarse)[j][qp]) *
1391 (*dphi_coarse)[j][qp]) *
1394 if (!dof_is_fixed[j])
1408 for (
unsigned int i=0; i != free_dofs; ++i)
1410 Number & ui = Ue(new_side_dofs[free_dof[i]]);
1414 dof_is_fixed[new_side_dofs[free_dof[i]]] =
true;
1422 unsigned int free_dofs = 0;
1423 for (
unsigned int i=0; i != new_n_dofs; ++i)
1424 if (!dof_is_fixed[i])
1425 free_dof[free_dofs++] = i;
1434 std::vector<dof_id_type> child_dof_indices;
1435 if (use_old_dof_indices)
1437 child_dof_indices, var);
1440 child_dof_indices, var);
1441 const unsigned int child_n_dofs =
1442 cast_int<unsigned int>
1443 (child_dof_indices.size());
1447 fe->attach_quadrature_rule (qrule.get());
1448 fe->reinit (&child);
1449 const unsigned int n_qp = qrule->n_points();
1453 fe_coarse->reinit(elem, &coarse_qpoints);
1456 for (
unsigned int qp=0; qp<n_qp; qp++)
1466 for (
unsigned int i=0; i<child_n_dofs; i++)
1469 (old_vector(child_dof_indices[i]) *
1472 finegrad += (*dphi_values)[i][qp] *
1473 old_vector(child_dof_indices[i]);
1477 for (
unsigned int i=0, freei=0;
1478 i != new_n_dofs; ++i)
1481 if (dof_is_fixed[i])
1483 for (
unsigned int j=0, freej=0; j !=
1486 if (dof_is_fixed[j])
1489 phi_coarse[j][qp]) *
1494 phi_coarse[j][qp]) *
1498 if (dof_is_fixed[j])
1501 (*dphi_coarse)[j][qp]) *
1506 (*dphi_coarse)[j][qp]) *
1509 if (!dof_is_fixed[j])
1523 for (
unsigned int i=0; i != free_dofs; ++i)
1525 Number & ui = Ue(free_dof[i]);
1532 dof_is_fixed[free_dof[i]] =
true;
1538 for (
unsigned int i=0; i != new_n_dofs; ++i)
1545 template <
typename OutputType>
1551 const bool use_old_dof_indices)
1559 coarsened_dof_values(old_vector, dof_map, elem, Usub,
1560 v, use_old_dof_indices);
1568 template <
typename OutputType>
1572 const unsigned int variable_number,
1577 const unsigned int Dim = elem->
dim();
1592 std::unique_ptr<FEGenericBase<OutputShape>> my_fe
1594 my_fe->add_p_level_in_reinit(add_p_level);
1608 libmesh_not_implemented();
1610 std::unique_ptr<FEGenericBase<OutputShape>> neigh_fe
1612 neigh_fe->add_p_level_in_reinit(add_p_level);
1615 my_fe->attach_quadrature_rule (&my_qface);
1616 std::vector<Point> neigh_qface;
1618 const std::vector<Real> & JxW = my_fe->get_JxW();
1619 const std::vector<Point> & q_point = my_fe->get_xyz();
1620 const std::vector<std::vector<OutputShape>> & phi = my_fe->get_phi();
1621 const std::vector<std::vector<OutputShape>> & neigh_phi =
1622 neigh_fe->get_phi();
1623 const std::vector<Point> * face_normals =
nullptr;
1624 const std::vector<std::vector<OutputGradient>> * dphi =
nullptr;
1625 const std::vector<std::vector<OutputGradient>> * neigh_dphi =
nullptr;
1627 std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
1628 std::vector<unsigned int> my_side_dofs, neigh_side_dofs;
1632 const std::vector<Point> & ref_face_normals =
1633 my_fe->get_normals();
1634 face_normals = &ref_face_normals;
1635 const std::vector<std::vector<OutputGradient>> & ref_dphi =
1638 const std::vector<std::vector<OutputGradient>> & ref_neigh_dphi =
1639 neigh_fe->get_dphi();
1640 neigh_dphi = &ref_neigh_dphi;
1645 std::vector<DenseVector<Real>> Ue;
1667 libmesh_assert_less (s_neigh, neigh->
n_neighbors());
1673 const unsigned int min_p_level = add_p_level *
1677 const unsigned int old_elem_level = add_p_level * elem->
p_level();
1678 if (old_elem_level != min_p_level)
1679 my_fe->set_fe_order(my_fe->get_fe_type().order.get_order() + min_p_level - old_elem_level);
1680 const unsigned int old_neigh_level = add_p_level * neigh->
p_level();
1681 if (old_neigh_level != min_p_level)
1682 neigh_fe->set_fe_order(neigh_fe->get_fe_type().order.get_order() + min_p_level - old_neigh_level);
1684 my_fe->reinit(elem, s);
1692 my_dof_indices.reserve (elem->
n_nodes());
1693 neigh_dof_indices.reserve (neigh->
n_nodes());
1702 const unsigned int n_qp = my_qface.n_points();
1706 neigh_fe->reinit(neigh, &neigh_qface);
1710 FEType elem_fe_type = base_fe_type;
1711 if (old_elem_level != min_p_level)
1713 FEType neigh_fe_type = base_fe_type;
1714 if (old_neigh_level != min_p_level)
1719 const unsigned int n_side_dofs =
1720 cast_int<unsigned int>(my_side_dofs.size());
1721 libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());
1724 for (
auto i : my_side_dofs)
1725 libmesh_assert_less(i, my_dof_indices.size());
1726 for (
auto i : neigh_side_dofs)
1727 libmesh_assert_less(i, neigh_dof_indices.size());
1730 Ke.
resize (n_side_dofs, n_side_dofs);
1731 Ue.resize(n_side_dofs);
1735 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1737 const unsigned int i = my_side_dofs[
is];
1738 for (
unsigned int js = 0; js != n_side_dofs; ++js)
1740 const unsigned int j = my_side_dofs[js];
1741 for (
unsigned int qp = 0; qp != n_qp; ++qp)
1745 Ke(
is,js) += JxW[qp] *
1747 (*face_normals)[qp],
1749 (*face_normals)[qp]);
1756 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1758 const unsigned int i = neigh_side_dofs[
is];
1760 for (
unsigned int js = 0; js != n_side_dofs; ++js)
1762 const unsigned int j = my_side_dofs[js];
1763 for (
unsigned int qp = 0; qp != n_qp; ++qp)
1771 (*face_normals)[qp],
1773 (*face_normals)[qp]);
1779 for (
unsigned int js = 0; js != n_side_dofs; ++js)
1781 const unsigned int j = my_side_dofs[js];
1787 bool self_constraint =
false;
1788 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1790 const unsigned int i = neigh_side_dofs[
is];
1791 const dof_id_type their_dof_g = neigh_dof_indices[i];
1794 if (their_dof_g == my_dof_g)
1797 const Real their_dof_value = Ue[
is](js);
1798 libmesh_assert_less (std::abs(their_dof_value-1.),
1801 for (
unsigned int k = 0; k != n_side_dofs; ++k)
1803 std::abs(Ue[k](js)) <
1807 self_constraint =
true;
1812 if (self_constraint)
1826 constraint_row = &(constraints[my_dof_g]);
1830 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
1832 const unsigned int i = neigh_side_dofs[
is];
1833 const dof_id_type their_dof_g = neigh_dof_indices[i];
1835 libmesh_assert_not_equal_to (their_dof_g, my_dof_g);
1837 const Real their_dof_value = Ue[
is](js);
1839 if (std::abs(their_dof_value) < 10*
TOLERANCE)
1842 constraint_row->emplace(their_dof_g, their_dof_value);
1846 my_fe->set_fe_order(my_fe->get_fe_type().order.get_order() + old_elem_level - min_p_level);
1847 neigh_fe->set_fe_order(neigh_fe->get_fe_type().order.get_order() + old_neigh_level - min_p_level);
1856 const unsigned int min_p_level =
1858 if (min_p_level < elem->p_level())
1870 #endif // #ifdef LIBMESH_ENABLE_AMR 1874 #ifdef LIBMESH_ENABLE_PERIODIC 1875 template <
typename OutputType>
1883 const unsigned int variable_number,
1887 if (boundaries.empty())
1897 libmesh_not_implemented();
1899 const unsigned int Dim = elem->
dim();
1903 const unsigned int sys_number = dof_map.
sys_number();
1908 std::unique_ptr<FEGenericBase<OutputShape>> my_fe
1918 const Real primary_hmin = elem->
hmin();
1920 std::unique_ptr<FEGenericBase<OutputShape>> neigh_fe
1924 my_fe->attach_quadrature_rule (&my_qface);
1925 std::vector<Point> neigh_qface;
1927 const std::vector<Real> & JxW = my_fe->get_JxW();
1928 const std::vector<Point> & q_point = my_fe->get_xyz();
1929 const std::vector<std::vector<OutputShape>> & phi = my_fe->get_phi();
1930 const std::vector<std::vector<OutputShape>> & neigh_phi =
1931 neigh_fe->get_phi();
1932 const std::vector<Point> * face_normals =
nullptr;
1933 const std::vector<std::vector<OutputGradient>> * dphi =
nullptr;
1934 const std::vector<std::vector<OutputGradient>> * neigh_dphi =
nullptr;
1935 std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
1936 std::vector<unsigned int> my_side_dofs, neigh_side_dofs;
1940 const std::vector<Point> & ref_face_normals =
1941 my_fe->get_normals();
1942 face_normals = &ref_face_normals;
1943 const std::vector<std::vector<OutputGradient>> & ref_dphi =
1946 const std::vector<std::vector<OutputGradient>> & ref_neigh_dphi =
1947 neigh_fe->get_dphi();
1948 neigh_dphi = &ref_neigh_dphi;
1953 std::vector<DenseVector<Real>> Ue;
1956 std::vector<boundary_id_type> bc_ids;
1960 const unsigned short int max_ns = elem->
n_sides();
1961 for (
unsigned short int s = 0; s != max_ns; ++s)
1968 for (
const auto & boundary_id : bc_ids)
1977 unsigned int s_neigh;
1978 const Elem * neigh = boundaries.
neighbor(boundary_id, *point_locator, elem, s, &s_neigh);
1980 libmesh_error_msg_if(neigh ==
nullptr,
1981 "PeriodicBoundaries point locator object returned nullptr!");
1989 #ifdef LIBMESH_ENABLE_AMR 1994 const unsigned int min_p_level =
2002 const unsigned int old_elem_level = elem->
p_level();
2003 if (old_elem_level != min_p_level)
2004 (
const_cast<Elem *
>(elem))->hack_p_level(min_p_level);
2005 const unsigned int old_neigh_level = neigh->
p_level();
2006 if (old_neigh_level != min_p_level)
2007 (
const_cast<Elem *
>(neigh))->hack_p_level(min_p_level);
2008 #endif // #ifdef LIBMESH_ENABLE_AMR 2016 my_fe->reinit(elem, s);
2026 std::vector<std::vector<dof_id_type>> neigh_dof_indices_all_variables;
2029 const std::set<unsigned int> & variables = periodic->
get_variables();
2030 neigh_dof_indices_all_variables.resize(variables.size());
2031 unsigned int index = 0;
2032 for(
unsigned int var : variables)
2034 dof_map.
dof_indices (neigh, neigh_dof_indices_all_variables[index],
2040 const unsigned int n_qp = my_qface.n_points();
2044 std::vector<Point> neigh_point(q_point.size());
2051 neigh_fe->reinit(neigh, &neigh_qface);
2060 #ifdef LIBMESH_ENABLE_AMR 2061 if (elem->
p_level() != old_elem_level)
2062 (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
2063 if (neigh->
p_level() != old_neigh_level)
2064 (const_cast<Elem *>(neigh))->hack_p_level(old_neigh_level);
2065 #endif // #ifdef LIBMESH_ENABLE_AMR 2067 const unsigned int n_side_dofs =
2068 cast_int<unsigned int>
2069 (my_side_dofs.size());
2070 libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());
2072 Ke.
resize (n_side_dofs, n_side_dofs);
2073 Ue.resize(n_side_dofs);
2077 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
2079 const unsigned int i = my_side_dofs[
is];
2080 for (
unsigned int js = 0; js != n_side_dofs; ++js)
2082 const unsigned int j = my_side_dofs[js];
2083 for (
unsigned int qp = 0; qp != n_qp; ++qp)
2085 Ke(
is,js) += JxW[qp] *
2089 Ke(
is,js) += JxW[qp] *
2091 (*face_normals)[qp],
2093 (*face_normals)[qp]);
2100 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
2102 const unsigned int i = neigh_side_dofs[
is];
2104 for (
unsigned int js = 0; js != n_side_dofs; ++js)
2106 const unsigned int j = my_side_dofs[js];
2107 for (
unsigned int qp = 0; qp != n_qp; ++qp)
2115 (*face_normals)[qp],
2117 (*face_normals)[qp]);
2171 std::set<dof_id_type> my_constrained_dofs;
2174 std::vector<boundary_id_type> new_bc_ids;
2188 std::set<boundary_id_type> point_bcids;
2190 for (
unsigned int new_s = 0;
2191 new_s != max_ns; ++new_s)
2198 for (
const auto & new_boundary_id : new_bc_ids)
2201 if (new_periodic && new_periodic->
is_my_variable(variable_number))
2202 point_bcids.insert(new_boundary_id);
2208 if (primary_boundary_point_neighbor
2214 std::set<boundary_id_type> point_pairedids;
2215 for (
const auto & new_boundary_id : point_bcids)
2222 const Elem * primary_elem =
nullptr;
2223 const Elem * main_neigh =
nullptr;
2224 Point main_pt = my_node,
2225 primary_pt = my_node;
2227 for (
const auto & new_boundary_id : point_bcids)
2233 const Point neigh_pt =
2246 primary_elem = elem;
2248 const Elem * primary_neigh =
2249 primary_boundary_point_neighbor(neigh, neigh_pt,
2255 if (new_boundary_id == boundary_id)
2257 main_neigh = primary_neigh;
2264 if ((primary_neigh->
level() > primary_elem->
level()) ||
2269 (primary_neigh->
level() == primary_elem->
level() &&
2270 primary_neigh->
id() > primary_elem->
id()) ||
2274 (primary_neigh == primary_elem &&
2275 (neigh_pt > primary_pt)))
2278 primary_elem = primary_neigh;
2279 primary_pt = neigh_pt;
2282 if (!primary_elem ||
2283 primary_elem != main_neigh ||
2284 primary_pt != main_pt)
2290 unsigned int e=0, ne = elem->
n_edges();
2291 for (; e != ne; ++e)
2296 libmesh_assert_less (e, elem->
n_edges());
2325 std::set<boundary_id_type> edge_bcids;
2327 for (
unsigned int new_s = 0;
2328 new_s != max_ns; ++new_s)
2336 for (
const auto & new_boundary_id : new_bc_ids)
2339 if (new_periodic && new_periodic->
is_my_variable(variable_number))
2340 edge_bcids.insert(new_boundary_id);
2346 if (primary_boundary_edge_neighbor
2352 std::set<boundary_id_type> edge_pairedids;
2353 for (
const auto & new_boundary_id : edge_bcids)
2360 const Elem * primary_elem =
nullptr;
2361 const Elem * main_neigh =
nullptr;
2362 Point main_pt1 = *e1,
2367 for (
const auto & new_boundary_id : edge_bcids)
2381 neigh_pt2.absolute_fuzzy_equals
2388 primary_elem = elem;
2390 const Elem * primary_neigh = primary_boundary_edge_neighbor
2391 (neigh, neigh_pt1, neigh_pt2,
2396 if (new_boundary_id == boundary_id)
2398 main_neigh = primary_neigh;
2399 main_pt1 = neigh_pt1;
2400 main_pt2 = neigh_pt2;
2410 if (primary_neigh == primary_elem)
2412 if (primary_pt1 > primary_pt2)
2413 std::swap(primary_pt1, primary_pt2);
2414 if (neigh_pt1 > neigh_pt2)
2415 std::swap(neigh_pt1, neigh_pt2);
2417 if (neigh_pt2 >= primary_pt2)
2425 if ((primary_neigh->
level() > primary_elem->
level()) ||
2430 (primary_neigh->
level() == primary_elem->
level() &&
2431 primary_neigh->
id() > primary_elem->
id()))
2434 primary_elem = primary_neigh;
2435 primary_pt1 = neigh_pt1;
2436 primary_pt2 = neigh_pt2;
2439 if (!primary_elem ||
2440 primary_elem != main_neigh ||
2441 primary_pt1 != main_pt1 ||
2442 primary_pt2 != main_pt2)
2453 const Point neigh_pt =
2455 if (neigh_pt > my_node)
2469 neigh->
id() > elem->
id()))
2477 const unsigned int n_comp =
2478 my_node.
n_comp(sys_number, variable_number);
2480 for (
unsigned int i=0; i != n_comp; ++i)
2481 my_constrained_dofs.insert
2483 (sys_number, variable_number, i));
2520 for (
unsigned int js = 0; js != n_side_dofs; ++js)
2526 const unsigned int j = my_side_dofs[js];
2531 if (!my_constrained_dofs.count(my_dof_g))
2545 constraint_row = &(constraints[my_dof_g]);
2549 for (
unsigned int is = 0;
is != n_side_dofs; ++
is)
2551 const unsigned int i = neigh_side_dofs[
is];
2552 const dof_id_type their_dof_g = neigh_dof_indices[i];
2559 const Real their_dof_value = Ue[
is](js);
2561 if (their_dof_g == my_dof_g)
2563 libmesh_assert_less (std::abs(their_dof_value-1.), 1.e-5);
2564 for (
unsigned int k = 0; k != n_side_dofs; ++k)
2569 if (std::abs(their_dof_value) < 10*
TOLERANCE)
2574 constraint_row->emplace(their_dof_g, their_dof_value);
2584 const std::set<unsigned int> & variables = periodic->
get_variables();
2585 neigh_dof_indices_all_variables.resize(variables.size());
2586 unsigned int index = 0;
2587 for(
unsigned int other_var : variables)
2589 libmesh_assert_msg(base_fe_type == dof_map.
variable_type(other_var),
"FE types must match for all variables involved in constraint");
2592 constraint_row->emplace(neigh_dof_indices_all_variables[index][i],
2593 var_weighting*their_dof_value);
2605 #ifdef LIBMESH_ENABLE_AMR 2606 const unsigned int min_p_level =
2608 if (min_p_level < elem->p_level())
2616 #endif // #ifdef LIBMESH_ENABLE_AMR 2621 #endif // LIBMESH_ENABLE_PERIODIC
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
FEFamily family
The type of finite element.
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
A Node is like a Point, but with more information.
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
virtual void zero() override final
Set every element in the vector to 0.
unsigned int n_comp(const unsigned int s, const unsigned int var) const
virtual void print_dphi(std::ostream &os) const override
Prints the value of each shape function's derivative at each quadrature point.
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...
virtual bool is_face(const unsigned int i) const =0
bool has_transformation_matrix() const
IntRange< unsigned short > side_index_range() const
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
virtual void zero() override final
Sets all elements of the matrix to 0 and resets any decomposition flag which may have been previously...
static constexpr Real TOLERANCE
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)
We're using a class instead of a typedef to allow forward declarations and future flexibility...
const std::set< unsigned int > & get_variables() const
Get the set of variables for this periodic boundary condition.
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
void resize(const unsigned int n)
Resize the vector.
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...
const FEType & variable_type(const unsigned int c) const
This is the base class from which all geometric element types are derived.
boundary_id_type pairedboundary
PeriodicBoundaryBase * boundary(boundary_id_type id)
static FEFieldType field_type(const FEType &fe_type)
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
Order default_quadrature_order() const
virtual unsigned int n_children() const =0
unsigned int p_level() const
OrderWrapper order
The approximation order of the element.
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 ...
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.
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
unsigned int min_p_level_by_neighbor(const Elem *neighbor, unsigned int current_min) const
unsigned int sys_number() const
This is the MeshBase class.
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
const Variable & variable(const unsigned int c) const override
bool should_p_refine_var(unsigned int var) const
Whether the given variable should be p-refined.
IntRange< unsigned short > edge_index_range() const
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...
This class handles the numbering of degrees of freedom on a mesh.
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
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 ...
const dof_id_type n_nodes
This class defines the notion of a variable in the system.
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...
const Node & node_ref(const unsigned int i) const
virtual Real hmin() const
virtual unsigned int n_nodes() const =0
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
unsigned int n_variables() const override
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 void print_phi(std::ostream &os) const override
Prints the value of each shape function at each quadrature point.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
bool is_constrained_dof(const dof_id_type dof) const
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
virtual void print_dual_dphi(std::ostream &os) const override
PetscErrorCode PetscInt const PetscInt IS * is
InfMapType inf_map
The coordinate mapping type of the infinite element.
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...
This is the base class for point locators.
bool active_on_subdomain(subdomain_id_type sid) const
virtual unsigned int n_edges() const =0
TensorTools::MakeNumber< OutputShape >::type OutputNumber
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
virtual_for_inffe void determine_calculations()
Determine which values are to be calculated, for both the FE itself and for the FEMap.
const DenseMatrix< Real > & get_transformation_matrix() const
Get the transformation matrix, if it is defined.
unsigned int max_descendant_p_level() const
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...
FEFamily radial_family
The type of approximation in radial direction.
int get_order() const
Explicitly request the order as an int.
std::string enum_to_string(const T e)
static unsigned int n_dofs_at_node(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int n)
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
unsigned int level() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
virtual unsigned short dim() const =0
FEContinuity
defines an enum for finite element types to libmesh_assert a certain level (or type? Hcurl?) of continuity.
const Node * node_ptr(const unsigned int i) const
virtual bool is_vertex(const unsigned int i) const =0
unsigned int n_neighbors() const
bool is_my_variable(unsigned int var_num) const
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...
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.
void resize(const unsigned int new_m, const unsigned int new_n)
Resizes the matrix to the specified size and calls zero().
void append(const DenseVector< T2 > &other_vector)
Append additional entries to (resizing, but unchanging) the vector.
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...
virtual void print_dual_phi(std::ostream &os) const override
const Elem * neighbor(boundary_id_type boundary_id, const PointLocatorBase &point_locator, const Elem *e, unsigned int side, unsigned int *neigh_side=nullptr) const
This class implements specific orders of Gauss quadrature.
IntRange< unsigned short > node_index_range() const
static std::unique_ptr< FEGenericBase > build_InfFE(const unsigned int dim, const FEType &type)
Builds a specific infinite element type.
The base class for defining periodic boundaries.
Defines a dense vector for use in Finite Element-type computations.
void cholesky_solve(const DenseVector< T2 > &b, DenseVector< T2 > &x)
For symmetric positive definite (SPD) matrices.
virtual bool infinite() const =0
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_dual_d2phi(std::ostream &os) const override
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...
A Point defines a location in LIBMESH_DIM dimensional Real space.
The constraint matrix storage format.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
virtual bool is_child_on_edge(const unsigned int c, const unsigned int e) const
virtual bool is_edge(const unsigned int i) const =0
This class forms the foundation from which generic finite elements may be derived.
const Elem * child_ptr(unsigned int i) const
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...
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), for one variable vn.
const FEType & type() const
spin_mutex spin_mtx
A convenient spin mutex object which can be used for obtaining locks.