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);
60 const std::unique_ptr<const Elem> side(inf_elem->
build_side_ptr(s));
63 elem_type = inf_elem->
type();
66 bool radial_qrule_initialized =
false;
72 current_fe_type.radial_order = 0;
74 if (current_fe_type.radial_order != fe_type.radial_order)
78 current_fe_type.radial_order = fe_type.radial_order;
88 base_qrule=
QBase::build(qrule->type(), side->dim(), qrule->get_order());
94 base_qrule->init(side->type(), side->p_level());
96 radial_qrule_initialized =
true;
100 if (this->get_type() != inf_elem->
type() ||
101 base_fe->shapes_need_reinit() ||
102 radial_qrule_initialized)
103 this->init_face_shape_functions (qrule->get_points(), side.get());
107 this->_fe_map->compute_face_map(this->
dim, _total_qrule_weights, side.get());
110 const std::vector<Real> JxW_int(this->_fe_map->get_JxW());
114 std::vector<Point> qp;
115 this->inverse_map (inf_elem, this->_fe_map->get_xyz(), qp, tolerance);
129 this->reinit (inf_elem, &qp);
132 this->_fe_map->get_JxW() = JxW_int;
139 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
143 const std::vector<Point> *
const pts,
144 const std::vector<Real> *
const )
148 libmesh_not_implemented_msg(
"ERROR: Edge conditions for infinite elements not implemented!");
151 libmesh_not_implemented_msg(
"ERROR: User-specified points for infinite elements not implemented!");
157 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
159 const Elem * inf_side)
164 libmesh_assert_equal_to (Dim, 3);
167 this->init_radial_shape_functions(inf_side);
171 this->update_base_elem(inf_side);
174 this->update_base_elem(inf_side->
parent());
177 base_qrule->init(base_elem->type(), inf_side->
p_level());
183 libmesh_assert_equal_to (Dim, 3);
185 base_fe->attach_quadrature_rule(base_qrule.get());
190 base_fe->attach_quadrature_rule(base_qrule.get());
194 base_fe->_fe_map->get_xyz();
195 base_fe->_fe_map->get_JxW();
198 base_fe->init_base_shape_functions(base_fe->qrule->get_points(),
202 const unsigned int n_radial_qp =
203 cast_int<unsigned int>(som.size());
204 const unsigned int n_base_qp = base_qrule->n_points();
205 const unsigned int n_total_qp = n_radial_qp * n_base_qp;
208 _total_qrule_weights.resize(n_total_qp);
214 const Order base_mapping_order ( base_elem->default_order() );
218 const unsigned int n_radial_mapping_sf =
219 inf_side->
infinite() ? cast_int<unsigned int>(radial_map.size()) : 1;
221 const unsigned int n_base_mapping_shape_functions =
224 const unsigned int n_total_mapping_shape_functions =
225 n_radial_mapping_sf * n_base_mapping_shape_functions;
229 _radial_node_index.resize (n_total_mapping_shape_functions);
230 _base_node_index.resize (n_total_mapping_shape_functions);
237 for (
unsigned int n=0; n<n_total_mapping_shape_functions; n++)
239 compute_node_indices (inf_face_elem_type,
242 _radial_node_index[n]);
244 libmesh_assert_less (_base_node_index[n], n_base_mapping_shape_functions);
245 libmesh_assert_less (_radial_node_index[n], n_radial_mapping_sf);
250 for (
unsigned int n=0; n<n_total_mapping_shape_functions; n++)
252 _base_node_index[n] = n;
253 _radial_node_index[n] = 0;
258 std::vector<std::vector<Real>> & psi_map = this->_fe_map->get_psi();
259 std::vector<std::vector<Real>> & dpsidxi_map = this->_fe_map->get_dpsidxi();
260 std::vector<std::vector<Real>> & dpsideta_map = this->_fe_map->get_dpsideta();
261 psi_map.resize (n_total_mapping_shape_functions);
262 dpsidxi_map.resize (n_total_mapping_shape_functions);
263 dpsideta_map.resize (n_total_mapping_shape_functions);
264 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
265 std::vector<std::vector<Real>> & d2psidxi2_map = this->_fe_map->get_d2psidxi2();
266 std::vector<std::vector<Real>> & d2psidxideta_map = this->_fe_map->get_d2psidxideta();
267 std::vector<std::vector<Real>> & d2psideta2_map = this->_fe_map->get_d2psideta2();
268 d2psidxi2_map.resize (n_total_mapping_shape_functions);
269 d2psidxideta_map.resize (n_total_mapping_shape_functions);
270 d2psideta2_map.resize (n_total_mapping_shape_functions);
273 for (
unsigned int i=0; i<n_total_mapping_shape_functions; i++)
275 psi_map[i].resize (n_total_qp);
276 dpsidxi_map[i].resize (n_total_qp);
277 dpsideta_map[i].resize (n_total_qp);
278 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
279 d2psidxi2_map[i].resize (n_total_qp);
280 d2psidxideta_map[i].resize(n_total_qp);
281 d2psideta2_map[i].resize (n_total_qp);
288 const std::vector<std::vector<Real>> & S_map = (base_fe->get_fe_map()).get_phi_map();
289 const std::vector<std::vector<Real>> & Ss_map = (base_fe->get_fe_map()).get_dphidxi_map();
291 for (
unsigned int rp=0; rp<n_radial_qp; rp++)
292 for (
unsigned int bp=0; bp<n_base_qp; bp++)
293 for (
unsigned int ti=0; ti<n_total_mapping_shape_functions; ti++)
296 const unsigned int bi = _base_node_index [ti];
297 const unsigned int ri = _radial_node_index[ti];
298 psi_map [ti][bp+rp*n_base_qp] = S_map [bi][bp] * radial_map [ri][rp];
299 dpsidxi_map [ti][bp+rp*n_base_qp] = Ss_map[bi][bp] * radial_map [ri][rp];
300 dpsideta_map [ti][bp+rp*n_base_qp] = S_map [bi][bp] * dradialdv_map[ri][rp];
303 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
304 d2psidxi2_map [ti][bp+rp*n_base_qp] = 0.;
305 d2psidxideta_map [ti][bp+rp*n_base_qp] = 0.;
306 d2psideta2_map [ti][bp+rp*n_base_qp] = 0.;
313 const std::vector<std::vector<Real>> & S_map = (base_fe->get_fe_map()).get_phi_map();
314 const std::vector<std::vector<Real>> & Ss_map = (base_fe->get_fe_map()).get_dphidxi_map();
315 const std::vector<std::vector<Real>> & St_map = (base_fe->get_fe_map()).get_dphideta_map();
316 for (
unsigned int bp=0; bp<n_base_qp; bp++)
317 for (
unsigned int ti=0; ti<n_total_mapping_shape_functions; ti++)
319 psi_map [ti][bp] = S_map[ti][bp] ;
320 dpsidxi_map [ti][bp] = Ss_map[ti][bp] ;
321 dpsideta_map [ti][bp] = St_map[ti][bp] ;
322 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
323 d2psidxi2_map [ti][bp] = 0.;
324 d2psidxideta_map [ti][bp] = 0.;
325 d2psideta2_map [ti][bp] = 0.;
333 const std::vector<Real> & radial_qw = radial_qrule->get_weights();
334 const std::vector<Real> & base_qw = base_qrule->get_weights();
336 libmesh_assert_equal_to (radial_qw.size(), n_radial_qp);
337 libmesh_assert_equal_to (base_qw.size(), n_base_qp);
339 for (
unsigned int rp=0; rp<n_radial_qp; rp++)
340 for (
unsigned int bp=0; bp<n_base_qp; bp++)
342 _total_qrule_weights[bp + rp*n_base_qp] = radial_qw[rp] * base_qw[bp];
368 #endif //ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS