48 _fe_map(
FEMap::build(fet) ),
50 calculations_started(false),
52 calculate_dphi(false),
53 calculate_d2phi(false),
54 calculate_curl_phi(false),
55 calculate_div_phi(false),
56 calculate_dphiref(false),
61 shapes_on_quadrature(false)
82 return libmesh_make_unique<FE<0,CLOUGH>>(fet);
85 return libmesh_make_unique<FE<0,HERMITE>>(fet);
88 return libmesh_make_unique<FE<0,LAGRANGE>>(fet);
91 return libmesh_make_unique<FE<0,LAGRANGE_VEC>>(fet);
94 return libmesh_make_unique<FE<0,L2_LAGRANGE>>(fet);
97 return libmesh_make_unique<FE<0,HIERARCHIC>>(fet);
100 return libmesh_make_unique<FE<0,L2_HIERARCHIC>>(fet);
103 return libmesh_make_unique<FE<0,MONOMIAL>>(fet);
105 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 107 return libmesh_make_unique<FE<0,SZABAB>>(fet);
110 return libmesh_make_unique<FE<0,BERNSTEIN>>(fet);
114 return libmesh_make_unique<FEXYZ<0>>(fet);
117 return libmesh_make_unique<FEScalar<0>>(fet);
120 libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
129 return libmesh_make_unique<FE<1,CLOUGH>>(fet);
132 return libmesh_make_unique<FE<1,HERMITE>>(fet);
135 return libmesh_make_unique<FE<1,LAGRANGE>>(fet);
138 return libmesh_make_unique<FE<1,LAGRANGE_VEC>>(fet);
141 return libmesh_make_unique<FE<1,L2_LAGRANGE>>(fet);
144 return libmesh_make_unique<FE<1,HIERARCHIC>>(fet);
147 return libmesh_make_unique<FE<1,L2_HIERARCHIC>>(fet);
150 return libmesh_make_unique<FE<1,MONOMIAL>>(fet);
152 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 154 return libmesh_make_unique<FE<1,SZABAB>>(fet);
157 return libmesh_make_unique<FE<1,BERNSTEIN>>(fet);
161 return libmesh_make_unique<FEXYZ<1>>(fet);
164 return libmesh_make_unique<FEScalar<1>>(fet);
167 libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
178 return libmesh_make_unique<FE<2,CLOUGH>>(fet);
181 return libmesh_make_unique<FE<2,HERMITE>>(fet);
184 return libmesh_make_unique<FE<2,LAGRANGE>>(fet);
187 return libmesh_make_unique<FE<2,LAGRANGE_VEC>>(fet);
190 return libmesh_make_unique<FE<2,L2_LAGRANGE>>(fet);
193 return libmesh_make_unique<FE<2,HIERARCHIC>>(fet);
196 return libmesh_make_unique<FE<2,L2_HIERARCHIC>>(fet);
199 return libmesh_make_unique<FE<2,MONOMIAL>>(fet);
201 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 203 return libmesh_make_unique<FE<2,SZABAB>>(fet);
206 return libmesh_make_unique<FE<2,BERNSTEIN>>(fet);
210 return libmesh_make_unique<FEXYZ<2>>(fet);
213 return libmesh_make_unique<FEScalar<2>>(fet);
216 return libmesh_make_unique<FENedelecOne<2>>(fet);
219 return libmesh_make_unique<FESubdivision>(fet);
222 libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
233 libmesh_error_msg(
"ERROR: Clough-Tocher elements currently only support 1D and 2D");
236 return libmesh_make_unique<FE<3,HERMITE>>(fet);
239 return libmesh_make_unique<FE<3,LAGRANGE>>(fet);
242 return libmesh_make_unique<FE<3,LAGRANGE_VEC>>(fet);
245 return libmesh_make_unique<FE<3,L2_LAGRANGE>>(fet);
248 return libmesh_make_unique<FE<3,HIERARCHIC>>(fet);
251 return libmesh_make_unique<FE<3,L2_HIERARCHIC>>(fet);
254 return libmesh_make_unique<FE<3,MONOMIAL>>(fet);
256 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES 258 return libmesh_make_unique<FE<3,SZABAB>>(fet);
261 return libmesh_make_unique<FE<3,BERNSTEIN>>(fet);
265 return libmesh_make_unique<FEXYZ<3>>(fet);
268 return libmesh_make_unique<FEScalar<3>>(fet);
271 return libmesh_make_unique<FENedelecOne<3>>(fet);
274 libmesh_error_msg(
"ERROR: Bad FEType.family= " << fet.
family);
279 libmesh_error_msg(
"Invalid dimension dim = " <<
dim);
290 nodes[0] =
Point (-1.,0.,0.);
291 nodes[1] =
Point (1.,0.,0.);
297 nodes[0] =
Point (-1.,0.,0.);
298 nodes[1] =
Point (1.,0.,0.);
299 nodes[2] =
Point (0.,0.,0.);
306 nodes[0] =
Point (0.,0.,0.);
307 nodes[1] =
Point (1.,0.,0.);
308 nodes[2] =
Point (0.,1.,0.);
314 nodes[0] =
Point (0.,0.,0.);
315 nodes[1] =
Point (1.,0.,0.);
316 nodes[2] =
Point (0.,1.,0.);
317 nodes[3] =
Point (.5,0.,0.);
318 nodes[4] =
Point (.5,.5,0.);
319 nodes[5] =
Point (0.,.5,0.);
326 nodes[0] =
Point (-1.,-1.,0.);
327 nodes[1] =
Point (1.,-1.,0.);
328 nodes[2] =
Point (1.,1.,0.);
329 nodes[3] =
Point (-1.,1.,0.);
336 nodes[0] =
Point (-1.,-1.,0.);
337 nodes[1] =
Point (1.,-1.,0.);
338 nodes[2] =
Point (1.,1.,0.);
339 nodes[3] =
Point (-1.,1.,0.);
340 nodes[4] =
Point (0.,-1.,0.);
341 nodes[5] =
Point (1.,0.,0.);
342 nodes[6] =
Point (0.,1.,0.);
343 nodes[7] =
Point (-1.,0.,0.);
349 nodes[0] =
Point (-1.,-1.,0.);
350 nodes[1] =
Point (1.,-1.,0.);
351 nodes[2] =
Point (1.,1.,0.);
352 nodes[3] =
Point (-1.,1.,0.);
353 nodes[4] =
Point (0.,-1.,0.);
354 nodes[5] =
Point (1.,0.,0.);
355 nodes[6] =
Point (0.,1.,0.);
356 nodes[7] =
Point (-1.,0.,0.);
357 nodes[8] =
Point (0.,0.,0.);
363 nodes[0] =
Point (0.,0.,0.);
364 nodes[1] =
Point (1.,0.,0.);
365 nodes[2] =
Point (0.,1.,0.);
366 nodes[3] =
Point (0.,0.,1.);
372 nodes[0] =
Point (0.,0.,0.);
373 nodes[1] =
Point (1.,0.,0.);
374 nodes[2] =
Point (0.,1.,0.);
375 nodes[3] =
Point (0.,0.,1.);
376 nodes[4] =
Point (.5,0.,0.);
377 nodes[5] =
Point (.5,.5,0.);
378 nodes[6] =
Point (0.,.5,0.);
379 nodes[7] =
Point (0.,0.,.5);
380 nodes[8] =
Point (.5,0.,.5);
381 nodes[9] =
Point (0.,.5,.5);
387 nodes[0] =
Point (-1.,-1.,-1.);
388 nodes[1] =
Point (1.,-1.,-1.);
389 nodes[2] =
Point (1.,1.,-1.);
390 nodes[3] =
Point (-1.,1.,-1.);
391 nodes[4] =
Point (-1.,-1.,1.);
392 nodes[5] =
Point (1.,-1.,1.);
393 nodes[6] =
Point (1.,1.,1.);
394 nodes[7] =
Point (-1.,1.,1.);
400 nodes[0] =
Point (-1.,-1.,-1.);
401 nodes[1] =
Point (1.,-1.,-1.);
402 nodes[2] =
Point (1.,1.,-1.);
403 nodes[3] =
Point (-1.,1.,-1.);
404 nodes[4] =
Point (-1.,-1.,1.);
405 nodes[5] =
Point (1.,-1.,1.);
406 nodes[6] =
Point (1.,1.,1.);
407 nodes[7] =
Point (-1.,1.,1.);
408 nodes[8] =
Point (0.,-1.,-1.);
409 nodes[9] =
Point (1.,0.,-1.);
410 nodes[10] =
Point (0.,1.,-1.);
411 nodes[11] =
Point (-1.,0.,-1.);
412 nodes[12] =
Point (-1.,-1.,0.);
413 nodes[13] =
Point (1.,-1.,0.);
414 nodes[14] =
Point (1.,1.,0.);
415 nodes[15] =
Point (-1.,1.,0.);
416 nodes[16] =
Point (0.,-1.,1.);
417 nodes[17] =
Point (1.,0.,1.);
418 nodes[18] =
Point (0.,1.,1.);
419 nodes[19] =
Point (-1.,0.,1.);
425 nodes[0] =
Point (-1.,-1.,-1.);
426 nodes[1] =
Point (1.,-1.,-1.);
427 nodes[2] =
Point (1.,1.,-1.);
428 nodes[3] =
Point (-1.,1.,-1.);
429 nodes[4] =
Point (-1.,-1.,1.);
430 nodes[5] =
Point (1.,-1.,1.);
431 nodes[6] =
Point (1.,1.,1.);
432 nodes[7] =
Point (-1.,1.,1.);
433 nodes[8] =
Point (0.,-1.,-1.);
434 nodes[9] =
Point (1.,0.,-1.);
435 nodes[10] =
Point (0.,1.,-1.);
436 nodes[11] =
Point (-1.,0.,-1.);
437 nodes[12] =
Point (-1.,-1.,0.);
438 nodes[13] =
Point (1.,-1.,0.);
439 nodes[14] =
Point (1.,1.,0.);
440 nodes[15] =
Point (-1.,1.,0.);
441 nodes[16] =
Point (0.,-1.,1.);
442 nodes[17] =
Point (1.,0.,1.);
443 nodes[18] =
Point (0.,1.,1.);
444 nodes[19] =
Point (-1.,0.,1.);
445 nodes[20] =
Point (0.,0.,-1.);
446 nodes[21] =
Point (0.,-1.,0.);
447 nodes[22] =
Point (1.,0.,0.);
448 nodes[23] =
Point (0.,1.,0.);
449 nodes[24] =
Point (-1.,0.,0.);
450 nodes[25] =
Point (0.,0.,1.);
451 nodes[26] =
Point (0.,0.,0.);
457 nodes[0] =
Point (0.,0.,-1.);
458 nodes[1] =
Point (1.,0.,-1.);
459 nodes[2] =
Point (0.,1.,-1.);
460 nodes[3] =
Point (0.,0.,1.);
461 nodes[4] =
Point (1.,0.,1.);
462 nodes[5] =
Point (0.,1.,1.);
468 nodes[0] =
Point (0.,0.,-1.);
469 nodes[1] =
Point (1.,0.,-1.);
470 nodes[2] =
Point (0.,1.,-1.);
471 nodes[3] =
Point (0.,0.,1.);
472 nodes[4] =
Point (1.,0.,1.);
473 nodes[5] =
Point (0.,1.,1.);
474 nodes[6] =
Point (.5,0.,-1.);
475 nodes[7] =
Point (.5,.5,-1.);
476 nodes[8] =
Point (0.,.5,-1.);
477 nodes[9] =
Point (0.,0.,0.);
478 nodes[10] =
Point (1.,0.,0.);
479 nodes[11] =
Point (0.,1.,0.);
480 nodes[12] =
Point (.5,0.,1.);
481 nodes[13] =
Point (.5,.5,1.);
482 nodes[14] =
Point (0.,.5,1.);
488 nodes[0] =
Point (0.,0.,-1.);
489 nodes[1] =
Point (1.,0.,-1.);
490 nodes[2] =
Point (0.,1.,-1.);
491 nodes[3] =
Point (0.,0.,1.);
492 nodes[4] =
Point (1.,0.,1.);
493 nodes[5] =
Point (0.,1.,1.);
494 nodes[6] =
Point (.5,0.,-1.);
495 nodes[7] =
Point (.5,.5,-1.);
496 nodes[8] =
Point (0.,.5,-1.);
497 nodes[9] =
Point (0.,0.,0.);
498 nodes[10] =
Point (1.,0.,0.);
499 nodes[11] =
Point (0.,1.,0.);
500 nodes[12] =
Point (.5,0.,1.);
501 nodes[13] =
Point (.5,.5,1.);
502 nodes[14] =
Point (0.,.5,1.);
503 nodes[15] =
Point (.5,0.,0.);
504 nodes[16] =
Point (.5,.5,0.);
505 nodes[17] =
Point (0.,.5,0.);
511 nodes[0] =
Point (-1.,-1.,0.);
512 nodes[1] =
Point (1.,-1.,0.);
513 nodes[2] =
Point (1.,1.,0.);
514 nodes[3] =
Point (-1.,1.,0.);
515 nodes[4] =
Point (0.,0.,1.);
523 nodes[0] =
Point (-1.,-1.,0.);
524 nodes[1] =
Point (1.,-1.,0.);
525 nodes[2] =
Point (1.,1.,0.);
526 nodes[3] =
Point (-1.,1.,0.);
529 nodes[4] =
Point (0.,0.,1.);
532 nodes[5] =
Point (0.,-1.,0.);
533 nodes[6] =
Point (1.,0.,0.);
534 nodes[7] =
Point (0.,1.,0.);
535 nodes[8] =
Point (-1,0.,0.);
538 nodes[9] =
Point (-.5,-.5,.5);
539 nodes[10] =
Point (.5,-.5,.5);
540 nodes[11] =
Point (.5,.5,.5);
541 nodes[12] =
Point (-.5,.5,.5);
550 nodes[0] =
Point (-1.,-1.,0.);
551 nodes[1] =
Point (1.,-1.,0.);
552 nodes[2] =
Point (1.,1.,0.);
553 nodes[3] =
Point (-1.,1.,0.);
556 nodes[4] =
Point (0.,0.,1.);
559 nodes[5] =
Point (0.,-1.,0.);
560 nodes[6] =
Point (1.,0.,0.);
561 nodes[7] =
Point (0.,1.,0.);
562 nodes[8] =
Point (-1,0.,0.);
565 nodes[9] =
Point (-.5,-.5,.5);
566 nodes[10] =
Point (.5,-.5,.5);
567 nodes[11] =
Point (.5,.5,.5);
568 nodes[12] =
Point (-.5,.5,.5);
571 nodes[13] =
Point (0.,0.,0.);
577 libmesh_error_msg(
"ERROR: Unknown element type " << itemType);
583 libmesh_assert_greater_equal (eps, 0.);
585 const Real xi = p(0);
587 const Real eta = p(1);
592 const Real zeta = p(2);
594 const Real zeta = 0.;
601 return (!xi && !eta && !zeta);
608 if ((xi >= -1.-eps) &&
622 if ((xi >= 0.-eps) &&
624 ((xi + eta) <= 1.+eps))
638 if ((xi >= -1.-eps) &&
654 if ((xi >= 0.-eps) &&
657 ((xi + eta + zeta) <= 1.+eps))
679 if ((xi >= -1.-eps) &&
700 if ((xi >= 0.-eps) &&
704 ((xi + eta) <= 1.+eps))
723 if ((-eta - 1. + zeta <= 0.+eps) &&
724 ( xi - 1. + zeta <= 0.+eps) &&
725 ( eta - 1. + zeta <= 0.+eps) &&
726 ( -xi - 1. + zeta <= 0.+eps) &&
733 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 739 if ((xi >= -1.-eps) &&
755 if ((xi >= 0.-eps) &&
759 ((xi + eta) <= 1.+eps))
769 libmesh_error_msg(
"ERROR: Unknown element type " << t);
795 os <<
"phi[i][j]: Shape function i at quadrature pt. j" << std::endl;
798 os <<
"dphi[i][j]: Shape function i's gradient at quadrature pt. j" << std::endl;
801 os <<
"XYZ locations of the quadrature pts." << std::endl;
804 os <<
"Values of JxW at the quadrature pts." << std::endl;
817 #ifdef LIBMESH_ENABLE_AMR 819 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 823 libmesh_assert(elem);
825 const unsigned int Dim = elem->
dim();
839 std::vector<const Node *> my_nodes, parent_nodes;
840 std::unique_ptr<const Elem> my_side, parent_side;
856 libmesh_assert(parent);
861 const unsigned int n_side_nodes = my_side->n_nodes();
864 my_nodes.reserve (n_side_nodes);
865 parent_nodes.clear();
866 parent_nodes.reserve (n_side_nodes);
868 for (
unsigned int n=0; n != n_side_nodes; ++n)
869 my_nodes.push_back(my_side->node_ptr(n));
871 for (
unsigned int n=0; n != n_side_nodes; ++n)
872 parent_nodes.push_back(parent_side->node_ptr(n));
874 for (
unsigned int my_side_n=0;
875 my_side_n < n_side_nodes;
880 const Node * my_node = my_nodes[my_side_n];
883 const Point & support_point = *my_node;
891 for (
unsigned int their_side_n=0;
892 their_side_n < n_side_nodes;
897 const Node * their_node = parent_nodes[their_side_n];
898 libmesh_assert(their_node);
910 if (their_mag > 0.999)
912 libmesh_assert_equal_to (my_node, their_node);
913 libmesh_assert_less (
std::abs(their_value - 1.), 0.001);
922 if (their_mag < 1.e-5)
932 constraint_row.insert(std::make_pair (their_node,
948 constraint_row.insert(std::make_pair (their_node,
956 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 958 #endif // #ifdef LIBMESH_ENABLE_AMR 962 #ifdef LIBMESH_ENABLE_PERIODIC 964 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS 972 if (boundaries.empty())
975 libmesh_assert(elem);
981 const unsigned int Dim = elem->
dim();
987 std::vector<const Node *> my_nodes, neigh_nodes;
988 std::unique_ptr<const Elem> my_side, neigh_side;
992 std::vector<boundary_id_type> bc_ids;
998 mesh.get_boundary_info().boundary_ids (elem, s, bc_ids);
999 for (
const auto & boundary_id : bc_ids)
1004 libmesh_assert(point_locator);
1007 const Elem * neigh = boundaries.
neighbor(boundary_id, *point_locator, elem, s);
1015 unsigned int s_neigh =
1019 #ifdef LIBMESH_ENABLE_AMR 1020 libmesh_assert(neigh->
active());
1021 #endif // #ifdef LIBMESH_ENABLE_AMR 1026 const unsigned int n_side_nodes = my_side->n_nodes();
1029 my_nodes.reserve (n_side_nodes);
1030 neigh_nodes.clear();
1031 neigh_nodes.reserve (n_side_nodes);
1033 for (
unsigned int n=0; n != n_side_nodes; ++n)
1034 my_nodes.push_back(my_side->node_ptr(n));
1036 for (
unsigned int n=0; n != n_side_nodes; ++n)
1037 neigh_nodes.push_back(neigh_side->node_ptr(n));
1043 std::vector<bool> skip_constraint(n_side_nodes,
false);
1045 for (
unsigned int my_side_n=0;
1046 my_side_n < n_side_nodes;
1051 const Node * my_node = my_nodes[my_side_n];
1066 if (constraints.count(my_node))
1068 skip_constraint[my_side_n] =
true;
1074 for (
unsigned int their_side_n=0;
1075 their_side_n < n_side_nodes;
1080 const Node * their_node = neigh_nodes[their_side_n];
1089 if (!constraints.count(their_node))
1093 constraints[their_node].first;
1095 for (
unsigned int orig_side_n=0;
1096 orig_side_n < n_side_nodes;
1101 const Node * orig_node = my_nodes[orig_side_n];
1103 if (their_constraint_row.count(orig_node))
1104 skip_constraint[orig_side_n] =
true;
1109 for (
unsigned int my_side_n=0;
1110 my_side_n < n_side_nodes;
1115 if (skip_constraint[my_side_n])
1118 const Node * my_node = my_nodes[my_side_n];
1128 for (
unsigned int their_side_n=0;
1129 their_side_n < n_side_nodes;
1134 const Node * their_node = neigh_nodes[their_side_n];
1135 libmesh_assert(their_node);
1150 constraints[my_node].first;
1152 constraint_row.insert(std::make_pair(their_node,
1162 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS 1164 #endif // LIBMESH_ENABLE_PERIODIC
Manages the family, order, etc. parameters for a given FE.
virtual void print_phi(std::ostream &os) const =0
const Elem * parent() const
A geometric point in (x,y,z) space associated with a DOF.
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
const unsigned int invalid_uint
static void compute_node_constraints(NodeConstraints &constraints, const Elem *elem)
IntRange< unsigned short > side_index_range() const
Maps between boundary ids and PeriodicBoundaryBase objects.
The base class for all geometric element types.
boundary_id_type pairedboundary
PeriodicBoundaryBase * boundary(boundary_id_type id)
FEAbstract(const unsigned int dim, const FEType &fet)
static bool on_reference_element(const Point &p, const ElemType t, const Real eps=TOLERANCE)
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
virtual Point get_corresponding_pos(const Point &pt) const =0
virtual void print_dphi(std::ostream &os) const =0
void print_xyz(std::ostream &os) const
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
static void get_refspace_nodes(const ElemType t, std::vector< Point > &nodes)
static Point inverse_map(const unsigned int dim, const FEType &fe_t, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
void print_JxW(std::ostream &os) const
void print_info(std::ostream &os) const
const Elem * neighbor_ptr(unsigned int i) const
unsigned int level() const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Elem * neighbor(boundary_id_type boundary_id, const PointLocatorBase &point_locator, const Elem *e, unsigned int side) const
virtual unsigned short dim() const =0
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Base class for all PeriodicBoundary implementations.
std::map< const Node *, Real, std::less< const Node * >, Threads::scalable_allocator< std::pair< const Node *const, Real > > > NodeConstraintRow
std::unique_ptr< FEMap > _fe_map
virtual Order default_order() const =0
Computes finite element mapping function values, gradients, etc.
std::ostream & operator<<(std::ostream &os, const FEAbstract &fe)
A geometric point in (x,y,z) space.
static void compute_periodic_node_constraints(NodeConstraints &constraints, const PeriodicBoundaries &boundaries, const MeshBase &mesh, const PointLocatorBase *point_locator, const Elem *elem)
const RemoteElem * remote_elem