21 #include "libmesh/libmesh_config.h" 23 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 25 #include "libmesh/inf_fe.h" 26 #include "libmesh/fe.h" 27 #include "libmesh/quadrature_gauss.h" 28 #include "libmesh/elem.h" 29 #include "libmesh/libmesh_logging.h" 30 #include "libmesh/int_range.h" 31 #include "libmesh/type_tensor.h" 32 #include "libmesh/fe_interface.h" 42 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
46 calculate_map_scaled(false),
47 calculate_phi_scaled(false),
48 calculate_dphi_scaled(false),
51 _n_total_approx_sf (0),
60 current_fe_type (
FEType(fet.order,
78 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
85 const Order radial_int_order =
static_cast<Order>(2 * (
static_cast<unsigned int>(fe_type.radial_order.get_order()) + 1) +2);
86 const unsigned int qrule_dim = q->
get_dim();
92 base_fe->attach_quadrature_rule(base_qrule.get());
96 radial_qrule = std::make_unique<QGauss>(1, radial_int_order);
108 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
119 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
121 const std::vector<Point> *
const pts,
122 const std::vector<Real> *
const weights)
129 this->determine_calculations();
134 libmesh_assert_equal_to (base_fe->qrule, base_qrule.get());
137 bool init_shape_functions_required =
false;
140 if (current_fe_type.radial_order != fe_type.radial_order)
142 current_fe_type.radial_order = fe_type.radial_order;
147 radial_qrule->init(
EDGE2);
150 this->init_radial_shape_functions(inf_elem);
152 init_shape_functions_required=
true;
156 bool update_base_elem_required=
true;
163 ((this->get_type() != inf_elem->
type()) ||
164 (base_fe->shapes_need_reinit())))
169 this->_elem = inf_elem;
170 this->_elem_type = inf_elem->
type();
171 this->update_base_elem(inf_elem);
172 update_base_elem_required=
false;
175 base_qrule->init(*base_elem);
176 init_shape_functions_required=
true;
180 this->_elem = inf_elem;
187 if (update_base_elem_required)
188 this->update_base_elem(inf_elem);
190 if (calculate_phi_scaled || calculate_dphi_scaled || calculate_phi || calculate_dphi)
192 base_fe->init_base_shape_functions(base_fe->qrule->get_points(),
197 base_fe->_fe_map->compute_map (base_fe->dim, base_fe->qrule->get_weights(),
198 base_elem.get(), base_fe->calculate_d2phi);
199 base_fe->compute_shape_functions(base_elem.get(), base_fe->qrule->get_points());
203 if (init_shape_functions_required)
204 this->init_shape_functions (radial_qrule->get_points(),
205 base_fe->qrule->get_points(),
210 this->compute_shape_functions (inf_elem,
211 base_fe->qrule->get_points(),
212 radial_qrule->get_points()
220 this->_elem = inf_elem;
221 this->_elem_type = inf_elem->
type();
228 std::vector<Point> radial_pts;
232 radial_pts.push_back(
radius);
233 unsigned int n_radial_pts=1;
234 unsigned int n_angular_pts=1;
237 radius = (*pts)[p](Dim-1);
240 if (std::abs(radial_pts[n_radial_pts-1](0) -
radius) > 1e-4)
243 if (p == (n_radial_pts)*n_angular_pts)
245 radial_pts.push_back(
radius);
250 libmesh_error_msg(
"We assumed that the "<<pts->size()
251 <<
" points are of tensor-product type with " 252 <<n_radial_pts<<
" radial points and " 253 <<n_angular_pts<<
" angular points."<<std::endl
254 <<
"But apparently point "<<p+1
255 <<
" does not fit that scheme: Its radius is " 256 <<
radius <<
"but should have " 257 <<radial_pts[n_radial_pts*n_angular_pts-p]<<
".");
263 else if (n_radial_pts == 1)
274 libmesh_error_msg(
"Calling reinit() with an empty point list is prohibited.\n");
277 const std::size_t radial_pts_size = radial_pts.size();
278 const std::size_t base_pts_size = pts->size() / radial_pts_size;
280 libmesh_assert_equal_to
281 (base_pts_size * radial_pts_size, pts->size());
284 std::vector<Point> base_pts;
285 base_pts.reserve(base_pts_size);
286 for (std::size_t p=0; p != base_pts_size; ++p)
288 Point pt = (*pts)[p];
290 base_pts.push_back(pt);
294 this->init_radial_shape_functions(inf_elem, &radial_pts);
297 this->update_base_elem(inf_elem);
303 this->determine_calculations();
305 base_fe->reinit( base_elem.get(), &base_pts);
307 this->init_shape_functions (radial_pts, base_pts, inf_elem);
310 if (weights !=
nullptr)
312 this->compute_shape_functions (inf_elem,base_pts,radial_pts);
316 this->compute_shape_functions (inf_elem, base_pts, radial_pts);
321 if (this->calculate_dual)
322 libmesh_not_implemented_msg(
"Dual shape support for infinite elements is " 323 "not currently implemented");
328 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
331 this->calculations_started =
true;
336 this->calculate_nothing || this->calculate_phi ||
337 this->calculate_dphi || this->calculate_dphiref ||
338 this->calculate_phi_scaled || this->calculate_dphi_scaled ||
339 this->calculate_xyz || this->calculate_jxw ||
340 this->calculate_map_scaled || this->calculate_map ||
341 this->calculate_curl_phi || this->calculate_div_phi;
343 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 344 requested_ok = requested_ok || this->calculate_d2phi;
347 libmesh_error_msg_if(
349 "You must call one or more of the FE accessors " 350 "(e.g. get_phi(), get_dphi(), get_nothing()) " 351 "_before_ calling reinit()!");
355 this->calculate_map =
true;
356 if (this->calculate_dphi)
357 this->calculate_map =
true;
358 if (this->calculate_dphi_scaled)
359 this->calculate_map_scaled =
true;
362 if (calculate_xyz && !calculate_map)
363 this->calculate_map_scaled =
true;
364 base_fe->calculate_phi = this->calculate_phi || this->calculate_phi_scaled
365 || this->calculate_dphi || this->calculate_dphi_scaled;
366 base_fe->calculate_dphi = this->calculate_dphi || this->calculate_dphi_scaled;
367 if (this->calculate_map || this->calculate_map_scaled
368 || this->calculate_dphiref)
370 base_fe->calculate_dphiref =
true;
374 base_fe->determine_calculations();
376 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 377 if (this->calculate_d2phi)
378 libmesh_not_implemented();
379 #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES 384 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
388 const std::vector<Point> * radial_pts)
394 LOG_SCOPE(
"init_radial_shape_functions()",
"InfFE");
397 const Order radial_approx_order = fe_type.radial_order;
398 const unsigned int n_radial_approx_shape_functions =
401 const std::size_t n_radial_qp =
402 radial_pts ? radial_pts->size() : radial_qrule->n_points();
403 const std::vector<Point> & radial_qp =
404 radial_pts ? *radial_pts : radial_qrule->get_points();
407 if (calculate_phi || calculate_dphi || calculate_phi_scaled || calculate_dphi_scaled)
409 mode.resize (n_radial_approx_shape_functions);
410 for (
unsigned int i=0; i<n_radial_approx_shape_functions; ++i)
411 mode[i].resize (n_radial_qp);
414 for (
unsigned int i=0; i<n_radial_approx_shape_functions; ++i)
415 for (std::size_t p=0; p<n_radial_qp; ++p)
419 if (calculate_dphi || calculate_dphi_scaled)
421 dmodedv.resize (n_radial_approx_shape_functions);
422 for (
unsigned int i=0; i<n_radial_approx_shape_functions; ++i)
423 dmodedv[i].resize (n_radial_qp);
426 for (
unsigned int i=0; i<n_radial_approx_shape_functions; ++i)
427 for (std::size_t p=0; p<n_radial_qp; ++p)
432 if (calculate_phi || calculate_phi_scaled || calculate_dphi || calculate_dphi_scaled)
434 som.resize (n_radial_qp);
436 for (std::size_t p=0; p<n_radial_qp; ++p)
439 if (calculate_dphi || calculate_dphi_scaled)
441 dsomdv.resize (n_radial_qp);
443 for (std::size_t p=0; p<n_radial_qp; ++p)
450 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
452 const std::vector<Point> & base_qp,
453 const Elem * inf_elem)
458 LOG_SCOPE(
"init_shape_functions()",
"InfFE");
462 const std::size_t n_radial_qp = radial_qp.size();
464 if (calculate_phi || calculate_dphi || calculate_phi_scaled || calculate_dphi_scaled)
465 libmesh_assert_equal_to(n_radial_approx_sf, mode.size());
466 if (calculate_phi || calculate_dphi || calculate_dphi_scaled)
467 libmesh_assert_equal_to(som.size(), n_radial_qp);
483 unsigned int n_base_approx_shape_functions;
485 n_base_approx_shape_functions =
488 n_base_approx_shape_functions = 1;
493 n_radial_approx_sf * n_base_approx_shape_functions;
497 const unsigned int n_base_qp = cast_int<unsigned int>(base_qp.size());
500 _n_total_qp = n_radial_qp * n_base_qp;
507 _radial_shape_index.resize(_n_total_approx_sf);
508 _base_shape_index.resize(_n_total_approx_sf);
511 for (
unsigned int n=0; n<_n_total_approx_sf; ++n)
513 compute_shape_indices (this->fe_type,
516 _base_shape_index[n],
517 _radial_shape_index[n]);
518 libmesh_assert_less (_base_shape_index[n], n_base_approx_shape_functions);
519 libmesh_assert_less (_radial_shape_index[n], n_radial_approx_sf);
537 if (calculate_phi || calculate_dphi)
538 weight.resize (_n_total_qp);
539 if (calculate_phi_scaled || calculate_dphi_scaled)
540 weightxr_sq.resize (_n_total_qp);
541 if (calculate_dphi || calculate_dphi_scaled)
542 dweightdv.resize (n_radial_qp);
544 dweight.resize (_n_total_qp);
545 if (calculate_dphi_scaled)
546 dweightxr_sq.resize(_n_total_qp);
548 if (calculate_dphi || calculate_dphi_scaled)
549 dphase.resize (_n_total_qp);
553 _total_qrule_weights.resize(_n_total_qp,1);
558 if (calculate_map_scaled)
559 JxWxdecay.resize(_n_total_qp);
561 JxW.resize(_n_total_qp);
562 if (calculate_map_scaled || calculate_map)
564 xyz.resize(_n_total_qp);
565 dxidx_map_scaled.resize(_n_total_qp);
566 dxidy_map_scaled.resize(_n_total_qp);
567 dxidz_map_scaled.resize(_n_total_qp);
568 detadx_map_scaled.resize(_n_total_qp);
569 detady_map_scaled.resize(_n_total_qp);
570 detadz_map_scaled.resize(_n_total_qp);
571 dzetadx_map_scaled.resize(_n_total_qp);
572 dzetady_map_scaled.resize(_n_total_qp);
573 dzetadz_map_scaled.resize(_n_total_qp);
577 dxidx_map.resize(_n_total_qp);
578 dxidy_map.resize(_n_total_qp);
579 dxidz_map.resize(_n_total_qp);
580 detadx_map.resize(_n_total_qp);
581 detady_map.resize(_n_total_qp);
582 detadz_map.resize(_n_total_qp);
583 dzetadx_map.resize(_n_total_qp);
584 dzetady_map.resize(_n_total_qp);
585 dzetadz_map.resize(_n_total_qp);
588 phi.resize (_n_total_approx_sf);
589 if (calculate_phi_scaled)
590 phixr.resize (_n_total_approx_sf);
593 dphi.resize (_n_total_approx_sf);
594 dphidx.resize (_n_total_approx_sf);
595 dphidy.resize (_n_total_approx_sf);
596 dphidz.resize (_n_total_approx_sf);
599 if (calculate_dphi_scaled)
601 dphixr.resize (_n_total_approx_sf);
602 dphixr_sq.resize(_n_total_approx_sf);
604 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 608 libmesh_not_implemented();
609 d2phi.resize (_n_total_approx_sf);
610 d2phidx2.resize (_n_total_approx_sf);
611 d2phidxdy.resize (_n_total_approx_sf);
612 d2phidxdz.resize (_n_total_approx_sf);
613 d2phidy2.resize (_n_total_approx_sf);
614 d2phidydz.resize (_n_total_approx_sf);
615 d2phidz2.resize (_n_total_approx_sf);
616 d2phidxi2.resize (_n_total_approx_sf);
620 d2phidxideta.resize(_n_total_approx_sf);
621 d2phideta2.resize(_n_total_approx_sf);
626 d2phidetadzeta.resize(_n_total_approx_sf);
627 d2phidxidzeta.resize(_n_total_approx_sf);
628 d2phidzeta2.resize(_n_total_approx_sf);
631 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 633 if (calculate_dphi || calculate_dphi_scaled)
635 dphidxi.resize (_n_total_approx_sf);
638 dphideta.resize(_n_total_approx_sf);
641 dphidzeta.resize(_n_total_approx_sf);
650 for (
unsigned int i=0; i<_n_total_approx_sf; ++i)
651 phi[i].resize (_n_total_qp);
654 for (
unsigned int i=0; i<_n_total_approx_sf; ++i)
656 dphi[i].resize (_n_total_qp);
657 dphidx[i].resize (_n_total_qp);
658 dphidy[i].resize (_n_total_qp);
659 dphidz[i].resize (_n_total_qp);
662 if (calculate_phi_scaled)
663 for (
unsigned int i=0; i<_n_total_approx_sf; ++i)
665 phixr[i].resize (_n_total_qp);
667 if (calculate_dphi_scaled)
668 for (
unsigned int i=0; i<_n_total_approx_sf; ++i)
670 dphixr[i].resize(_n_total_qp);
671 dphixr_sq[i].resize(_n_total_qp);
673 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 675 for (
unsigned int i=0; i<_n_total_approx_sf; ++i)
677 d2phi[i].resize (_n_total_qp);
678 d2phidx2[i].resize (_n_total_qp);
679 d2phidxdy[i].resize (_n_total_qp);
680 d2phidxdz[i].resize (_n_total_qp);
681 d2phidy2[i].resize (_n_total_qp);
682 d2phidydz[i].resize (_n_total_qp);
683 d2phidy2[i].resize (_n_total_qp);
684 d2phidxi2[i].resize (_n_total_qp);
688 d2phidxideta[i].resize (_n_total_qp);
689 d2phideta2[i].resize (_n_total_qp);
693 d2phidxidzeta[i].resize (_n_total_qp);
694 d2phidetadzeta[i].resize (_n_total_qp);
695 d2phidzeta2[i].resize (_n_total_qp);
698 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 700 if (calculate_dphi || calculate_dphi_scaled)
701 for (
unsigned int i=0; i<_n_total_approx_sf; ++i)
703 dphidxi[i].resize (_n_total_qp);
706 dphideta[i].resize (_n_total_qp);
709 dphidzeta[i].resize (_n_total_qp);
719 libmesh_assert_equal_to (radial_qp.size(), n_radial_qp);
721 if (radial_qrule && base_qrule)
723 const std::vector<Real> & radial_qw = radial_qrule->get_weights();
724 const std::vector<Real> & base_qw = base_qrule->get_weights();
725 libmesh_assert_equal_to (radial_qw.size(), n_radial_qp);
726 libmesh_assert_equal_to (base_qw.size(), n_base_qp);
728 for (
unsigned int rp=0; rp<n_radial_qp; ++rp)
729 for (
unsigned int bp=0; bp<n_base_qp; ++bp)
730 _total_qrule_weights[bp + rp*n_base_qp] = radial_qw[rp] * base_qw[bp];
734 for (
unsigned int rp=0; rp<n_radial_qp; ++rp)
736 if (calculate_phi || calculate_dphi)
737 for (
unsigned int bp=0; bp<n_base_qp; ++bp)
740 if ( calculate_phi_scaled)
741 for (
unsigned int bp=0; bp<n_base_qp; ++bp)
744 if ( calculate_dphi || calculate_dphi_scaled)
752 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
754 const std::vector<Point> & base_qp,
755 const std::vector<Point> & radial_qp
761 libmesh_assert_equal_to (base_elem->type(),
765 LOG_SCOPE(
"compute_shape_functions()",
"InfFE");
769 const std::size_t n_radial_qp = radial_qp.size();
770 const unsigned int n_base_qp = base_qp.size();
772 libmesh_assert_equal_to (_n_total_qp, n_radial_qp*n_base_qp);
773 libmesh_assert_equal_to (_n_total_qp, _total_qrule_weights.size());
776 libmesh_assert_equal_to(n_radial_qp, som.size());
778 if (this->calculate_map || this->calculate_map_scaled)
782 const std::vector<std::vector<Real>> & S_map = (base_fe->get_fe_map()).get_phi_map();
783 if (S_map[0].size() > 0)
784 libmesh_assert_equal_to(n_base_qp, S_map[0].size());
787 libmesh_assert_equal_to(n_radial_qp, radial_qrule->n_points());
789 libmesh_assert_equal_to(n_base_qp, base_qrule->n_points());
790 libmesh_assert_equal_to(_n_total_qp % n_radial_qp, 0);
805 unsigned int elem_dim = inf_elem->
dim();
812 libmesh_not_implemented();
817 std::vector<std::vector<Real>> S (0);
818 std::vector<std::vector<Real>> Ss(0);
819 std::vector<std::vector<Real>> St(0);
821 std::vector<Real> base_dxidx (0);
822 std::vector<Real> base_dxidy (0);
823 std::vector<Real> base_dxidz (0);
824 std::vector<Real> base_detadx(0);
825 std::vector<Real> base_detady(0);
826 std::vector<Real> base_detadz(0);
828 std::vector<Point> base_xyz (0);
830 if (calculate_phi || calculate_phi_scaled ||
831 calculate_dphi || calculate_dphi_scaled)
835 if (calculate_map || calculate_map_scaled)
837 Ss = base_fe->dphidxi;
838 St = base_fe->dphideta;
840 base_dxidx = base_fe->get_dxidx();
841 base_dxidy = base_fe->get_dxidy();
842 base_dxidz = base_fe->get_dxidz();
843 base_detadx = base_fe->get_detadx();
844 base_detady = base_fe->get_detady();
845 base_detadz = base_fe->get_detadz();
847 base_xyz = base_fe->get_xyz();
850 ElemType base_type= base_elem->type();
854 libmesh_assert_equal_to (phi.size(), _n_total_approx_sf);
857 libmesh_assert_equal_to (dphidxi.size(), _n_total_approx_sf);
858 libmesh_assert_equal_to (dphideta.size(), _n_total_approx_sf);
859 libmesh_assert_equal_to (dphidzeta.size(), _n_total_approx_sf);
864 for (
unsigned int rp=0; rp<n_radial_qp; ++rp)
865 for (
unsigned int bp=0; bp<n_base_qp; ++bp)
875 if (calculate_map || calculate_map_scaled)
877 xyz[tp] =
InfFEMap::map(elem_dim, inf_elem,
Point(base_qp[bp](0),base_qp[bp](1),radial_qp[rp](0)));
879 const Point r(xyz[tp]-origin);
880 a=(base_xyz[bp]-origin).
norm();
886 libmesh_assert_less(std::abs(som[rp] -a/r_norm) , 1e-7);
892 Point e_xi(base_dxidx[bp],
895 Point e_eta(base_detadx[bp],
902 grad_a_scaled=unit_r - normal/(normal*unit_r);
904 const Real dxi_er=base_dxidx[bp]* unit_r(0) + base_dxidy[bp] *unit_r(1) + base_dxidz[bp] *unit_r(2);
905 const Real deta_er=base_detadx[bp]*unit_r(0) + base_detady[bp]*unit_r(1) + base_detadz[bp]*unit_r(2);
909 if (!base_elem->has_affine_map())
919 const unsigned int n_sf = base_elem->n_nodes();
921 for (
unsigned int i=0; i< n_sf; ++i)
924 base_elem->default_order(),
925 i, 0, base_qp[bp]) * e_xi
927 base_elem->default_order(),
928 i, 1, base_qp[bp]) * e_eta);
930 tmp += (base_elem->node_ref(i) -origin).
norm()* dL_da_i;
934 grad_a_scaled = ( tmp - (tmp*unit_r)*unit_r ) / ( 1. - tmp*unit_r);
939 dxidx_map_scaled[tp] = (grad_a_scaled(0) - unit_r(0))*dxi_er +base_dxidx[bp];
940 dxidy_map_scaled[tp] = (grad_a_scaled(1) - unit_r(1))*dxi_er +base_dxidy[bp];
941 dxidz_map_scaled[tp] = (grad_a_scaled(2) - unit_r(2))*dxi_er +base_dxidz[bp];
944 detadx_map_scaled[tp] = (grad_a_scaled(0) - unit_r(0))*deta_er + base_detadx[bp];
945 detady_map_scaled[tp] = (grad_a_scaled(1) - unit_r(1))*deta_er + base_detady[bp];
946 detadz_map_scaled[tp] = (grad_a_scaled(2) - unit_r(2))*deta_er + base_detadz[bp];
949 dzetadx_map_scaled[tp] =-2./a*(grad_a_scaled(0) - unit_r(0));
950 dzetady_map_scaled[tp] =-2./a*(grad_a_scaled(1) - unit_r(1));
951 dzetadz_map_scaled[tp] =-2./a*(grad_a_scaled(2) - unit_r(2));
957 dxidx_map[tp] = a/r_norm * dxidx_map_scaled[tp];
958 dxidy_map[tp] = a/r_norm * dxidy_map_scaled[tp];
959 dxidz_map[tp] = a/r_norm * dxidz_map_scaled[tp];
961 detadx_map[tp] = a/r_norm * detadx_map_scaled[tp];
962 detady_map[tp] = a/r_norm * detady_map_scaled[tp];
963 detadz_map[tp] = a/r_norm * detadz_map_scaled[tp];
967 dzetadx_map[tp] =-2.*a/(r_norm*r_norm)*(grad_a_scaled(0) - unit_r(0));
968 dzetady_map[tp] =-2.*a/(r_norm*r_norm)*(grad_a_scaled(1) - unit_r(1));
969 dzetadz_map[tp] =-2.*a/(r_norm*r_norm)*(grad_a_scaled(2) - unit_r(2));
973 Real inv_jac = (dxidx_map[tp]*( detady_map[tp]*dzetadz_map[tp]- dzetady_map[tp]*detadz_map[tp]) +
974 detadx_map[tp]*(dzetady_map[tp]* dxidz_map[tp]- dxidy_map[tp]*dzetadz_map[tp]) +
975 dzetadx_map[tp]*( dxidy_map[tp]*detadz_map[tp]- detady_map[tp]* dxidz_map[tp]));
977 if (inv_jac <= 1e-10)
979 libmesh_error_msg(
"ERROR: negative inverse Jacobian " \
988 JxW[tp] = _total_qrule_weights[tp]/inv_jac;
992 if (calculate_map_scaled)
994 Real inv_jacxR_pow4 = (dxidx_map_scaled[tp] *( detady_map_scaled[tp]*dzetadz_map_scaled[tp]
995 - dzetady_map_scaled[tp]* detadz_map_scaled[tp]) +
996 detadx_map_scaled[tp] *( dzetady_map_scaled[tp]* dxidz_map_scaled[tp]
997 - dxidy_map_scaled[tp]*dzetadz_map_scaled[tp]) +
998 dzetadx_map_scaled[tp]*( dxidy_map_scaled[tp]* detadz_map_scaled[tp]
999 -detady_map_scaled[tp]* dxidz_map_scaled[tp]));
1000 if (inv_jacxR_pow4 <= 1e-7)
1002 libmesh_error_msg(
"ERROR: negative weighted inverse Jacobian " \
1010 JxWxdecay[tp] = _total_qrule_weights[tp]/inv_jacxR_pow4;
1016 if (calculate_dphi || calculate_dphi_scaled)
1017 dphase[tp] = unit_r - grad_a_scaled*a/r_norm;
1021 dweight[tp](0) = dweightdv[rp] * dzetadx_map[tp];
1022 dweight[tp](1) = dweightdv[rp] * dzetady_map[tp];
1023 dweight[tp](2) = dweightdv[rp] * dzetadz_map[tp];
1025 if (calculate_dphi_scaled)
1027 dweightxr_sq[tp](0) = dweightdv[rp] * dzetadx_map_scaled[tp];
1028 dweightxr_sq[tp](1) = dweightdv[rp] * dzetady_map_scaled[tp];
1029 dweightxr_sq[tp](2) = dweightdv[rp] * dzetadz_map_scaled[tp];
1032 if (calculate_phi || calculate_phi_scaled || calculate_dphi || calculate_dphi_scaled)
1034 for (
unsigned int i=0; i <_n_total_approx_sf ; ++i)
1037 unsigned int bi = _base_shape_index [i];
1038 unsigned int ri = _radial_shape_index[i];
1040 phi [i][tp] = S [bi][bp] * mode[ri][rp] * som[rp];
1042 if (calculate_phi_scaled)
1043 phixr [i][tp] = S [bi][bp] * mode[ri][rp];
1045 if (calculate_dphi || calculate_dphi_scaled)
1047 dphidxi [i][tp] = Ss[bi][bp] * mode[ri][rp] * som[rp];
1048 dphideta [i][tp] = St[bi][bp] * mode[ri][rp] * som[rp];
1049 dphidzeta[i][tp] = S [bi][bp]
1050 * (dmodedv[ri][rp] * som[rp] + mode[ri][rp] * dsomdv[rp]);
1058 dphidx[i][tp] = (dphidxi[i][tp]*dxidx_map[tp] +
1059 dphideta[i][tp]*detadx_map[tp] +
1060 dphidzeta[i][tp]*dzetadx_map[tp]);
1064 dphidy[i][tp] = (dphidxi[i][tp]*dxidy_map[tp] +
1065 dphideta[i][tp]*detady_map[tp] +
1066 dphidzeta[i][tp]*dzetady_map[tp]);
1070 dphidz[i][tp] = (dphidxi[i][tp]*dxidz_map[tp] +
1071 dphideta[i][tp]*detadz_map[tp] +
1072 dphidzeta[i][tp]*dzetadz_map[tp]);
1075 if (calculate_dphi_scaled)
1078 dphixr[i][tp](0)= (dphidxi[i][tp]*dxidx_map_scaled[tp] +
1079 dphideta[i][tp]*detadx_map_scaled[tp] +
1080 dphidzeta[i][tp]*dzetadx_map_scaled[tp]*som[rp]);
1082 dphixr[i][tp](1) = (dphidxi[i][tp]*dxidy_map_scaled[tp] +
1083 dphideta[i][tp]*detady_map_scaled[tp] +
1084 dphidzeta[i][tp]*dzetady_map_scaled[tp]*som[rp]);
1086 dphixr[i][tp](2) = (dphidxi[i][tp]*dxidz_map_scaled[tp] +
1087 dphideta[i][tp]*detadz_map_scaled[tp] +
1088 dphidzeta[i][tp]*dzetadz_map_scaled[tp]*som[rp]);
1090 const Real dphidxixr = Ss[bi][bp] * mode[ri][rp];
1091 const Real dphidetaxr= St[bi][bp] * mode[ri][rp];
1093 dphixr_sq[i][tp](0)= (dphidxixr*dxidx_map_scaled[tp] +
1094 dphidetaxr*detadx_map_scaled[tp] +
1095 dphidzeta[i][tp]*dzetadx_map_scaled[tp]);
1097 dphixr_sq[i][tp](1) = (dphidxixr*dxidy_map_scaled[tp] +
1098 dphidetaxr*detady_map_scaled[tp] +
1099 dphidzeta[i][tp]*dzetady_map_scaled[tp]);
1101 dphixr_sq[i][tp](2) = (dphidxixr*dxidz_map_scaled[tp] +
1102 dphidetaxr*detadz_map_scaled[tp] +
1103 dphidzeta[i][tp]*dzetadz_map_scaled[tp]);
1114 libmesh_error_msg(
"Unsupported dim = " <<
dim);
1120 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
1124 libmesh_not_implemented();
1132 #include "libmesh/inf_fe_instantiate_1D.h" 1133 #include "libmesh/inf_fe_instantiate_2D.h" 1134 #include "libmesh/inf_fe_instantiate_3D.h" 1138 #endif //ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
virtual void determine_calculations() override
Determine which values are to be calculated, for both the FE itself and for the FEMap.
ElemType
Defines an enum for geometric element types.
static ElemType get_elem_type(const ElemType type)
Order
defines an enum for polynomial orders.
A specific instantiation of the FEBase class.
static unsigned int n_dofs(const unsigned int dim, const FEType &fe_t, const ElemType t)
static unsigned int n_dofs(const Order o_radial)
virtual Point origin() const
static Point map(const unsigned int dim, const Elem *inf_elem, const Point &reference_point)
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
static Real decay_deriv(const unsigned int dim, const Real)
static Real Dxr_sq(const Real)
void init_shape_functions(const std::vector< Point > &radial_qp, const std::vector< Point > &base_qp, const Elem *inf_elem)
Initialize all the data fields like weight, mode, phi, dphidxi, dphideta, dphidzeta, etc.
This is the base class from which all geometric element types are derived.
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
static std::unique_ptr< const Elem > build_elem(const Elem *inf_elem)
Build the base element of an infinite element.
virtual QuadratureType type() const =0
static Real D(const Real v)
A specific instantiation of the FEBase class.
friend class InfFE
Make all InfFE<Dim,T_radial,T_map> classes friends of each other, so that the protected eval() may be...
std::unique_ptr< FEBase > base_fe
Have a FE<Dim-1,T_base> handy for base approximation.
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
static Real decay(const unsigned int dim, const Real v)
unsigned int get_dim() const
InfMapType inf_map
The coordinate mapping type of the infinite element.
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
virtual bool shapes_need_reinit() const override
void init_radial_shape_functions(const Elem *inf_elem, const std::vector< Point > *radial_pts=nullptr)
Some of the member data only depend on the radial part of the infinite element.
FEFamily radial_family
The type of approximation in radial direction.
void compute_shape_functions(const Elem *inf_elem, const std::vector< Point > &base_qp, const std::vector< Point > &radial_qp)
After having updated the jacobian and the transformation from local to global coordinates in FEAbstra...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual unsigned short dim() const =0
static Real D_deriv(const Real v)
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 void attach_quadrature_rule(QBase *q) override
The use of quadrature rules with the InfFE class is somewhat different from the approach of the FE cl...
FEType fe_type
The finite element type for this object.
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
The QBase class provides the basic functionality from which various quadrature rules can be derived...
This class forms the foundation from which generic finite elements may be derived.
void update_base_elem(const Elem *inf_elem)
Updates the protected member base_elem to the appropriate base element for the given inf_elem...