20#include "libmesh/cell_prism6.h"
21#include "libmesh/edge_edge2.h"
22#include "libmesh/face_quad4.h"
23#include "libmesh/face_tri3.h"
24#include "libmesh/enum_io_package.h"
25#include "libmesh/enum_order.h"
26#include "libmesh/fe_lagrange_shape_1D.h"
39void cell_integral(
const Elem * elem, T & t);
59struct NodalVolumeIntegral
65 static const unsigned int i0[] = {0, 0, 0, 1, 1, 1};
66 static const unsigned int i1[] = {0, 1, 2, 0, 1, 2};
69 auto tri3_phi = [](
int i,
Real x,
Real y)
83 libmesh_error_msg(
"Invalid shape function index i = " << i);
87 for (
int i=0; i<6; ++i)
97 std::array<Real, 6> V {};
143 const unsigned int s)
const
145 libmesh_assert_less (s,
n_sides());
154 libmesh_assert_less(s,
n_sides());
155 auto trim = (s > 0 && s < 4) ? 0 : 1;
162 libmesh_assert_less(e,
n_edges());
167 const unsigned int e)
const
169 libmesh_assert_less (e,
n_edges());
198 libmesh_assert_less (i, this->
n_sides());
200 std::unique_ptr<Elem> face;
207 face = std::make_unique<Tri3>();
214 face = std::make_unique<Quad4>();
218 libmesh_error_msg(
"Invalid side i = " << i);
222 for (
auto n : face->node_index_range())
225 face->set_interior_parent(
this);
226 face->inherit_data_from(*
this);
234 const unsigned int i)
237 side->set_interior_parent(
this);
238 side->inherit_data_from(*
this);
245 return this->simple_build_edge_ptr<Edge2,Prism6>(i);
252 this->simple_build_edge_ptr<Prism6>(edge, i,
EDGE2);
259 std::vector<dof_id_type> & conn)
const
294 libmesh_error_msg(
"Unsupported IO package " << iop);
300#ifdef LIBMESH_ENABLE_AMR
307 { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0},
308 { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0},
309 { 0.5, 0.0, 0.5, 0.0, 0.0, 0.0},
310 { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0},
311 { .25, .25, 0.0, .25, .25, 0.0},
312 { .25, 0.0, .25, .25, 0.0, .25}
318 { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0},
319 { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0},
320 { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0},
321 { .25, .25, 0.0, .25, .25, 0.0},
322 { 0.0, 0.5, 0.0, 0.0, 0.5, 0.0},
323 { 0.0, .25, .25, 0.0, .25, .25}
329 { 0.5, 0.0, 0.5, 0.0, 0.0, 0.0},
330 { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0},
331 { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0},
332 { .25, 0.0, .25, .25, 0.0, .25},
333 { 0.0, .25, .25, 0.0, .25, .25},
334 { 0.0, 0.0, 0.5, 0.0, 0.0, 0.5}
340 { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0},
341 { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0},
342 { 0.5, 0.0, 0.5, 0.0, 0.0, 0.0},
343 { .25, .25, 0.0, .25, .25, 0.0},
344 { 0.0, .25, .25, 0.0, .25, .25},
345 { .25, 0.0, .25, .25, 0.0, .25}
351 { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0},
352 { .25, .25, 0.0, .25, .25, 0.0},
353 { .25, 0.0, .25, .25, 0.0, .25},
354 { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0},
355 { 0.0, 0.0, 0.0, 0.5, 0.5, 0.0},
356 { 0.0, 0.0, 0.0, 0.5, 0.0, 0.5}
362 { .25, .25, 0.0, .25, .25, 0.0},
363 { 0.0, 0.5, 0.0, 0.0, 0.5, 0.0},
364 { 0.0, .25, .25, 0.0, .25, .25},
365 { 0.0, 0.0, 0.0, 0.5, 0.5, 0.0},
366 { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0},
367 { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}
373 { .25, 0.0, .25, .25, 0.0, .25},
374 { 0.0, .25, .25, 0.0, .25, .25},
375 { 0.0, 0.0, 0.5, 0.0, 0.0, 0.5},
376 { 0.0, 0.0, 0.0, 0.5, 0.0, 0.5},
377 { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5},
378 { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}
384 { .25, .25, 0.0, .25, .25, 0.0},
385 { 0.0, .25, .25, 0.0, .25, .25},
386 { .25, 0.0, .25, .25, 0.0, .25},
387 { 0.0, 0.0, 0.0, 0.5, 0.5, 0.0},
388 { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5},
389 { 0.0, 0.0, 0.0, 0.5, 0.0, 0.5}
399 NodalVolumeIntegral nvi;
400 cell_integral(
this, nvi);
406 for (
int i=0; i<6; ++i)
408 cp += this->
point(i) * nvi.V[i];
422 cell_integral(
this, vi);
436 libmesh_assert_less (perm_num, 6);
437 const unsigned int side = perm_num % 2;
438 const unsigned int rotate = perm_num / 2;
440 for (
unsigned int i = 0; i != rotate; ++i)
482 libmesh_assert_less (s, 5);
483 if (s == 0 || s == 4)
491 libmesh_assert_less (s, 5);
504 return pointing_out.
unit();
519 const Point normal_at_vertex = current_edge.
cross(next_edge);
520 normal += normal_at_vertex;
521 current_edge = next_edge;
524 return normal.
unit();
527 libmesh_error_msg(
"Invalid side s = " << s);
537void cell_integral(
const Elem * elem, T & t)
548 -x0/2 + x1/2 - x3/2 + x4/2,
549 x0/2 - x1/2 - x3/2 + x4/2,
556 -x0/2 + x2/2 - x3/2 + x5/2,
557 x0/2 - x2/2 - x3/2 + x5/2,
564 x0/2 - x2/2 - x3/2 + x5/2,
565 x0/2 - x1/2 - x3/2 + x4/2
575 static const Real w2D[N2D] =
577 1.5902069087198858469718450103758e-01_R,
578 9.0979309128011415302815498962418e-02_R,
579 1.5902069087198858469718450103758e-01_R,
580 9.0979309128011415302815498962418e-02_R
583 static const Real xi[N2D] =
585 1.5505102572168219018027159252941e-01_R,
586 6.4494897427831780981972840747059e-01_R,
587 1.5505102572168219018027159252941e-01_R,
588 6.4494897427831780981972840747059e-01_R
591 static const Real eta[N2D] =
593 1.7855872826361642311703513337422e-01_R,
594 7.5031110222608118177475598324603e-02_R,
595 6.6639024601470138670269327409637e-01_R,
596 2.8001991549907407200279599420481e-01_R
604 static const Real zeta[N1D] =
606 -std::sqrt(
Real(3))/3,
607 std::sqrt(
Real(3))/3.
610 for (
int i=0; i<N2D; ++i)
613 Point dx_dzeta_q = dx_dzeta[0] + eta[i]*dx_dzeta[1] + xi[i]*dx_dzeta[2];
615 for (
int j=0; j<N1D; ++j)
619 dx_dxi_q = dx_dxi[0] + zeta[j]*dx_dxi[1],
620 dx_deta_q = dx_deta[0] + zeta[j]*dx_deta[1];
623 t.accumulate_qp(xi[i], eta[i], zeta[j], w2D[i] *
triple_product(dx_dxi_q, dx_deta_q, dx_dzeta_q));
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
Defines a Cartesian bounding box by the two corner extremum.
This is the base class from which all geometric element types are derived.
virtual BoundingBox loose_bounding_box() const
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
const Point & point(const unsigned int i) const
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Node ** _nodes
Pointers to the nodes we are connected to.
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
void swap2boundarysides(unsigned short s1, unsigned short s2, BoundaryInfo *boundary_info) const
Swaps two sides in boundary_info, if it is non-null.
ElemMappingType mapping_type() const
void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three node_ptrs, "rotating" them.
virtual Real volume() const
void swap2boundaryedges(unsigned short e1, unsigned short e2, BoundaryInfo *boundary_info) const
Swaps two edges in boundary_info, if it is non-null.
dof_id_type node_id(const unsigned int i) const
A Point defines a location in LIBMESH_DIM dimensional Real space.
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
static constexpr unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
virtual Order default_order() const override
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override
Builds a EDGE2 or INFEDGE2 built coincident with face i.
virtual bool is_face(const unsigned int i) const override
virtual BoundingBox loose_bounding_box() const override
Builds a bounding box out of the nodal positions.
virtual Point true_centroid() const override
An Optimized numerical quadrature approach for computing the centroid of the Prism6.
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
virtual unsigned int n_sub_elem() const override
virtual bool is_edge(const unsigned int i) const override
virtual bool has_affine_map() const override
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index.
static const unsigned int side_elems_map[num_sides][nodes_per_side]
This maps the child elements with the associated side of the parent element.
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
static const int nodes_per_edge
virtual Real volume() const override
Specialized function for computing the element volume.
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const override
static const int nodes_per_side
static const int num_nodes
Geometric constants for Prism6.
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
ElemType side_type(const unsigned int s) const override final
virtual bool is_vertex(const unsigned int i) const override
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
Builds a QUAD4 or TRI3 built coincident with face i.
virtual Point side_vertex_average_normal(const unsigned int s) const override final
static constexpr unsigned int edge_nodes_map[num_edges][nodes_per_edge]
This maps the node of the edge to element node numbers.
virtual unsigned int n_edges() const override final
static const int num_children
virtual unsigned int n_sides() const override final
static const int num_sides
Geometric constants for all Prisms.
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
LIBMESH_DEVICE_INLINE TypeVector< T > unit() const
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
The libMesh namespace provides an interface to certain functionality in the library.
IOPackage
libMesh interfaces with several different software packages for the purposes of creating,...
LIBMESH_DEVICE_INLINE T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
ElemType
Defines an enum for geometric element types.
Real fe_lagrange_1D_linear_shape(const unsigned int i, const Real xi)
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
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...