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.