24 #include "libmesh/libmesh_config.h"    25 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS    26 #include "libmesh/inf_fe.h"    27 #include "libmesh/inf_fe_macro.h"    28 #include "libmesh/quadrature.h"    29 #include "libmesh/enum_quadrature_type.h"    30 #include "libmesh/elem.h"    36 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
    40                                         const std::vector<Point> * 
const pts,
    41                                         const std::vector<Real> * 
const weights)
    43   if (weights != 
nullptr)
    44     libmesh_not_implemented_msg(
"ERROR: User-specified weights for infinite elements are not implemented!");
    47     libmesh_not_implemented_msg(
"ERROR: User-specified points for infinite elements are not implemented!");
    50   libmesh_assert_not_equal_to (Dim, 1);
    56   const std::unique_ptr<const Elem> side(inf_elem->
build_side_ptr(s));
    59   this->_elem = inf_elem;
    60   this->_elem_type = inf_elem->
type();
    63   bool radial_qrule_initialized = 
false;
    69     current_fe_type.radial_order = 0;
    75     libmesh_not_implemented();
    77   if (current_fe_type.radial_order != fe_type.radial_order)
    81           current_fe_type.radial_order = fe_type.radial_order;
    88           radial_qrule->init(
NODEELEM, 0, 
true);
    91           base_qrule=
QBase::build(qrule->type(), side->dim(), qrule->get_order());
    93           unsigned int side_p_level = inf_elem->
p_level();
    96           base_qrule->init(*side, side_p_level);
    98       radial_qrule_initialized = 
true;
   102   if (this->get_type() != inf_elem->
type() ||
   103       base_fe->shapes_need_reinit()        ||
   104       radial_qrule_initialized)
   105     this->init_face_shape_functions (qrule->get_points(), side.get());
   110   compute_face_functions();
   116 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
   120                                              const std::vector<Point> * 
const pts,
   121                                              const std::vector<Real> * 
const )
   125   libmesh_not_implemented_msg(
"ERROR: Edge conditions for infinite elements not implemented!");
   128     libmesh_not_implemented_msg(
"ERROR: User-specified points for infinite elements not implemented!");
   134 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
   136                                                            const Elem * inf_side)
   141   libmesh_assert_equal_to (Dim, 3);
   144   this->init_radial_shape_functions(inf_side);
   148     this->update_base_elem(inf_side);
   154   base_qrule->init(*base_elem, inf_side->
p_level());
   161       base_fe->attach_quadrature_rule(base_qrule.get());
   166       base_fe->attach_quadrature_rule(base_qrule.get());
   169   if (this->calculate_map || this->calculate_map_scaled)
   172       base_fe->_fe_map->get_xyz();
   173       base_fe->_fe_map->get_JxW();
   176   if (calculate_phi || calculate_dphi || calculate_phi_scaled || calculate_dphi_scaled)
   178     base_fe->init_base_shape_functions(base_fe->qrule->get_points(),
   182   const unsigned int n_radial_qp = radial_qrule->n_points();
   183   const unsigned int n_base_qp   = base_qrule->n_points();
   184   const unsigned int n_total_qp  = n_radial_qp * n_base_qp;
   188     libmesh_assert_equal_to(n_radial_qp, som.size());
   191     libmesh_assert_equal_to (n_radial_qp, 1);
   195   _total_qrule_weights.resize(n_total_qp);
   196   std::vector<Point> qp(n_total_qp);
   202       libmesh_not_implemented();
   206       const std::vector<Real> & radial_qw = radial_qrule->get_weights();
   207       const std::vector<Real> & base_qw   = base_qrule->get_weights();
   208       const std::vector<Point> & radial_qp = radial_qrule->get_points();
   209       const std::vector<Point> & base_qp   = base_qrule->get_points();
   211       libmesh_assert_equal_to (radial_qw.size(), n_radial_qp);
   212       libmesh_assert_equal_to (base_qw.size(), n_base_qp);
   214       for (
unsigned int rp=0; rp<n_radial_qp; rp++)
   215         for (
unsigned int bp=0; bp<n_base_qp; bp++)
   217             _total_qrule_weights[bp + rp*n_base_qp] = radial_qw[rp] * base_qw[bp];
   221               qp[bp + rp*n_base_qp]=
Point(base_qp[bp](0),
   225               qp[bp + rp*n_base_qp]=
Point(base_qp[bp](0),
   235 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
   239   if (!calculate_map && !calculate_map_scaled)
   242   const unsigned int n_qp = cast_int<unsigned int>(_total_qrule_weights.size());
   243   this->normals.resize(n_qp);
   247       this->tangents.resize(n_qp);
   248       for (
unsigned int p=0; p<n_qp; ++p)
   249         this->tangents[p].resize(LIBMESH_DIM-1);
   253       libMesh::err << 
"tangents have no sense in 1-dimensional elements!"<<std::endl;
   254       libmesh_error_msg(
"Exiting...");
   260   unsigned int base_dim =base_fe->dim;
   270         libmesh_not_implemented();
   277           for (
unsigned int p=0; p<n_qp; ++p)
   293               const std::vector<Real> & base_dxidx = base_fe->get_dxidx();
   294               const std::vector<Real> & base_dxidy = base_fe->get_dxidy();
   295               const std::vector<Real> & base_dxidz = base_fe->get_dxidz();
   296               const std::vector<Real> & base_detadx = base_fe->get_detadx();
   297               const std::vector<Real> & base_detady = base_fe->get_detady();
   298               const std::vector<Real> & base_detadz = base_fe->get_detadz();
   300               const Real g11 = (base_dxidx[p]*base_dxidx[p] +
   301                                 base_dxidy[p]*base_dxidy[p] +
   302                                 base_dxidz[p]*base_dxidz[p]);
   303               const Real g12 = (base_dxidx[p]*base_detadx[p] +
   304                                 base_dxidy[p]*base_detady[p] +
   305                                 base_dxidz[p]*base_detadz[p]);
   306               const Real g21 = g12;
   307               const Real g22 = (base_detadx[p]*base_detadx[p] +
   308                                 base_detady[p]*base_detady[p] +
   309                                 base_detadz[p]*base_detadz[p]);
   311               const Real det = (g11*g22 - g12*g21);
   313               Point dxyzdxi_map((g22*base_dxidx[p]-g21*base_detadx[p])/det,
   314                                 (g22*base_dxidy[p]-g21*base_detady[p])/det,
   315                                 (g22*base_dxidz[p]-g21*base_detadz[p])/det);
   317               Point dxyzdeta_map((g11*base_detadx[p] - g12*base_dxidx[p])/det,
   318                                  (g11*base_detady[p] - g12*base_dxidy[p])/det,
   319                                  (g11*base_detadz[p] - g12*base_dxidz[p])/det);
   321               this->tangents[p][0] = dxyzdxi_map.
unit();
   323               this->tangents[p][1] = (dxyzdeta_map - (dxyzdeta_map*tangents[p][0])*tangents[p][0] ).
unit();
   325               this->normals[p]     = tangents[p][0].
cross(tangents[p][1]).unit();
   329                 this->JxW[p] = _total_qrule_weights[p]/std::sqrt(det);
   331               if (calculate_map_scaled)
   332                 this->JxWxdecay[p] = _total_qrule_weights[p]/std::sqrt(det);
   335         else if (base_dim == Dim -2)
   337             libmesh_not_implemented();
   342             libmesh_not_implemented();
   347       libmesh_error_msg(
"Unsupported dim = " << 
dim);
   374 #endif //ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
const Elem * interior_parent() const
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i)=0
INSTANTIATE_INF_FE_MBRF(1, CARTESIAN, void, reinit(const Elem *, const unsigned int, const Real, const std::vector< Point > *const, const std::vector< Real > *const))
This is the base class from which all geometric element types are derived. 
unsigned int p_level() const
The libMesh namespace provides an interface to certain functionality in the library. 
void init_face_shape_functions(const std::vector< Point > &, const Elem *inf_side)
Initialize all the data fields like weight, phi, etc for the side s. 
void compute_face_functions()
TypeVector< T > unit() const
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type. 
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
const Elem * neighbor_ptr(unsigned int i) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void edge_reinit(const Elem *elem, const unsigned int edge, const Real tolerance=TOLERANCE, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr) override
Not implemented yet. 
static std::unique_ptr< QBase > build(std::string_view name, const unsigned int dim, const Order order=INVALID_ORDER)
Builds a specific quadrature rule based on the name string. 
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr) override
This is at the core of this class. 
virtual bool infinite() const =0
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.