unsigned int InfFE<Dim,T_radial,T_map>::n_dofs_at_node (const FEType & fet, const ElemType inf_elem_type, const unsigned int n) { const ElemType base_et (Base::get_elem_type(inf_elem_type)); unsigned int n_base, n_radial; compute_node_indices(inf_elem_type, n, n_base, n_radial); // libMesh::out << "elem_type=" << inf_elem_type // << ", fet.radial_order=" << fet.radial_order // << ", n=" << n // << ", n_radial=" << n_radial // << ", n_base=" << n_base // << std::endl; if (Dim > 1) return FEInterface::n_dofs_at_node(Dim-1, fet, base_et, n_base) * Radial::n_dofs_at_node(fet.radial_order, n_radial); else return Radial::n_dofs_at_node(fet.radial_order, n_radial); }
void InfFE<Dim,T_radial,T_base>::init_face_shape_functions(const std::vector<Point>&, const Elem* inf_side) { libmesh_assert(inf_side); // Currently, this makes only sense in 3-D! libmesh_assert_equal_to (Dim, 3); // Initialiize the radial shape functions this->init_radial_shape_functions(inf_side); // Initialize the base shape functions this->update_base_elem(inf_side); // Initialize the base quadratur rule base_qrule->init(base_elem->type(), inf_side->p_level()); // base_fe still corresponds to the (dim-1)-dimensional base of the InfFE object, // so update the fe_base. { libmesh_assert_equal_to (Dim, 3); AutoPtr<FEBase> ap_fb(FEBase::build(Dim-2, this->fe_type)); if (base_fe != NULL) delete base_fe; base_fe = ap_fb.release(); base_fe->attach_quadrature_rule(base_qrule); } // initialize the shape functions on the base base_fe->init_base_shape_functions(base_fe->qrule->get_points(), base_elem); // the number of quadrature points const unsigned int n_radial_qp = libmesh_cast_int<unsigned int>(som.size()); const unsigned int n_base_qp = base_qrule->n_points(); const unsigned int n_total_qp = n_radial_qp * n_base_qp; // the quadratur weigths _total_qrule_weights.resize(n_total_qp); // now inite the shapes for boundary work { // The element type and order to use in the base map const Order base_mapping_order ( base_elem->default_order() ); const ElemType base_mapping_elem_type ( base_elem->type() ); // the number of mapping shape functions // (Lagrange shape functions are used for mapping in the base) const unsigned int n_radial_mapping_sf = libmesh_cast_int<unsigned int>(radial_map.size()); const unsigned int n_base_mapping_shape_functions = Base::n_base_mapping_sf(base_mapping_elem_type, base_mapping_order); const unsigned int n_total_mapping_shape_functions = n_radial_mapping_sf * n_base_mapping_shape_functions; // initialize the node and shape numbering maps { _radial_node_index.resize (n_total_mapping_shape_functions); _base_node_index.resize (n_total_mapping_shape_functions); const ElemType inf_face_elem_type (inf_side->type()); // fill the node index map for (unsigned int n=0; n<n_total_mapping_shape_functions; n++) { compute_node_indices (inf_face_elem_type, n, _base_node_index[n], _radial_node_index[n]); libmesh_assert_less (_base_node_index[n], n_base_mapping_shape_functions); libmesh_assert_less (_radial_node_index[n], n_radial_mapping_sf); } } // rezise map data fields { std::vector<std::vector<Real> >& psi_map = this->_fe_map->get_psi(); std::vector<std::vector<Real> >& dpsidxi_map = this->_fe_map->get_dpsidxi(); std::vector<std::vector<Real> >& d2psidxi2_map = this->_fe_map->get_d2psidxi2(); psi_map.resize (n_total_mapping_shape_functions); dpsidxi_map.resize (n_total_mapping_shape_functions); d2psidxi2_map.resize (n_total_mapping_shape_functions); // if (Dim == 3) { std::vector<std::vector<Real> >& dpsideta_map = this->_fe_map->get_dpsideta(); std::vector<std::vector<Real> >& d2psidxideta_map = this->_fe_map->get_d2psidxideta(); std::vector<std::vector<Real> >& d2psideta2_map = this->_fe_map->get_d2psideta2(); dpsideta_map.resize (n_total_mapping_shape_functions); d2psidxideta_map.resize (n_total_mapping_shape_functions); d2psideta2_map.resize (n_total_mapping_shape_functions); } for (unsigned int i=0; i<n_total_mapping_shape_functions; i++) { psi_map[i].resize (n_total_qp); dpsidxi_map[i].resize (n_total_qp); d2psidxi2_map[i].resize (n_total_qp); // if (Dim == 3) { std::vector<std::vector<Real> >& dpsideta_map = this->_fe_map->get_dpsideta(); std::vector<std::vector<Real> >& d2psidxideta_map = this->_fe_map->get_d2psidxideta(); std::vector<std::vector<Real> >& d2psideta2_map = this->_fe_map->get_d2psideta2(); dpsideta_map[i].resize (n_total_qp); d2psidxideta_map[i].resize (n_total_qp); d2psideta2_map[i].resize (n_total_qp); } } } // compute shape maps { const std::vector<std::vector<Real> >& S_map = (base_fe->get_fe_map()).get_phi_map(); const std::vector<std::vector<Real> >& Ss_map = (base_fe->get_fe_map()).get_dphidxi_map(); std::vector<std::vector<Real> >& psi_map = this->_fe_map->get_psi(); std::vector<std::vector<Real> >& dpsidxi_map = this->_fe_map->get_dpsidxi(); std::vector<std::vector<Real> >& dpsideta_map = this->_fe_map->get_dpsideta(); for (unsigned int rp=0; rp<n_radial_qp; rp++) // over radial qp's for (unsigned int bp=0; bp<n_base_qp; bp++) // over base qp's for (unsigned int ti=0; ti<n_total_mapping_shape_functions; ti++) // over all mapping shapes { // let the index vectors take care of selecting the appropriate base/radial mapping shape const unsigned int bi = _base_node_index [ti]; const unsigned int ri = _radial_node_index[ti]; psi_map [ti][bp+rp*n_base_qp] = S_map [bi][bp] * radial_map [ri][rp]; dpsidxi_map [ti][bp+rp*n_base_qp] = Ss_map[bi][bp] * radial_map [ri][rp]; dpsideta_map [ti][bp+rp*n_base_qp] = S_map [bi][bp] * dradialdv_map[ri][rp]; // second derivatives are not implemented for infinite elements // d2psidxi2_map [ti][bp+rp*n_base_qp] = 0.; // d2psidxideta_map [ti][bp+rp*n_base_qp] = 0.; // d2psideta2_map [ti][bp+rp*n_base_qp] = 0.; } } } // quadrature rule weights { const std::vector<Real>& radial_qw = radial_qrule->get_weights(); const std::vector<Real>& base_qw = base_qrule->get_weights(); libmesh_assert_equal_to (radial_qw.size(), n_radial_qp); libmesh_assert_equal_to (base_qw.size(), n_base_qp); for (unsigned int rp=0; rp<n_radial_qp; rp++) for (unsigned int bp=0; bp<n_base_qp; bp++) { _total_qrule_weights[ bp+rp*n_base_qp ] = radial_qw[rp] * base_qw[bp]; } } }
void InfFE<Dim,T_radial,T_base>::init_face_shape_functions(const std::vector<Point> &, const Elem * inf_side) { libmesh_assert(inf_side); // Currently, this makes only sense in 3-D! libmesh_assert_equal_to (Dim, 3); // Initialize the radial shape functions this->init_radial_shape_functions(inf_side); // Initialize the base shape functions if (inf_side->infinite()) this->update_base_elem(inf_side); else // in this case, I need the 2D base this->update_base_elem(inf_side->parent()); // Initialize the base quadrature rule base_qrule->init(base_elem->type(), inf_side->p_level()); // base_fe still corresponds to the (dim-1)-dimensional base of the InfFE object, // so update the fe_base. if (inf_side->infinite()) { libmesh_assert_equal_to (Dim, 3); base_fe = FEBase::build(Dim-2, this->fe_type); base_fe->attach_quadrature_rule(base_qrule.get()); } else { base_fe = FEBase::build(Dim-1, this->fe_type); base_fe->attach_quadrature_rule(base_qrule.get()); } //before initializing, we should say what to compute: base_fe->_fe_map->get_xyz(); base_fe->_fe_map->get_JxW(); // initialize the shape functions on the base base_fe->init_base_shape_functions(base_fe->qrule->get_points(), base_elem.get()); // the number of quadrature points const unsigned int n_radial_qp = cast_int<unsigned int>(som.size()); const unsigned int n_base_qp = base_qrule->n_points(); const unsigned int n_total_qp = n_radial_qp * n_base_qp; // the quadrature weights _total_qrule_weights.resize(n_total_qp); // now init the shapes for boundary work { // The element type and order to use in the base map const Order base_mapping_order ( base_elem->default_order() ); const ElemType base_mapping_elem_type ( base_elem->type() ); // the number of mapping shape functions. For base side it is 1. // (Lagrange shape functions are used for mapping in the base) const unsigned int n_radial_mapping_sf = inf_side->infinite() ? cast_int<unsigned int>(radial_map.size()) : 1; const unsigned int n_base_mapping_shape_functions = Base::n_base_mapping_sf(base_mapping_elem_type, base_mapping_order); const unsigned int n_total_mapping_shape_functions = n_radial_mapping_sf * n_base_mapping_shape_functions; // initialize the node and shape numbering maps _radial_node_index.resize (n_total_mapping_shape_functions); _base_node_index.resize (n_total_mapping_shape_functions); if (inf_side->infinite()) { const ElemType inf_face_elem_type (inf_side->type()); // fill the node index map for (unsigned int n=0; n<n_total_mapping_shape_functions; n++) { compute_node_indices (inf_face_elem_type, n, _base_node_index[n], _radial_node_index[n]); libmesh_assert_less (_base_node_index[n], n_base_mapping_shape_functions); libmesh_assert_less (_radial_node_index[n], n_radial_mapping_sf); } } else { for (unsigned int n=0; n<n_total_mapping_shape_functions; n++) { _base_node_index[n] = n; _radial_node_index[n] = 0; } } // resize map data fields std::vector<std::vector<Real>> & psi_map = this->_fe_map->get_psi(); std::vector<std::vector<Real>> & dpsidxi_map = this->_fe_map->get_dpsidxi(); std::vector<std::vector<Real>> & dpsideta_map = this->_fe_map->get_dpsideta(); psi_map.resize (n_total_mapping_shape_functions); dpsidxi_map.resize (n_total_mapping_shape_functions); dpsideta_map.resize (n_total_mapping_shape_functions); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES std::vector<std::vector<Real>> & d2psidxi2_map = this->_fe_map->get_d2psidxi2(); std::vector<std::vector<Real>> & d2psidxideta_map = this->_fe_map->get_d2psidxideta(); std::vector<std::vector<Real>> & d2psideta2_map = this->_fe_map->get_d2psideta2(); d2psidxi2_map.resize (n_total_mapping_shape_functions); d2psidxideta_map.resize (n_total_mapping_shape_functions); d2psideta2_map.resize (n_total_mapping_shape_functions); #endif for (unsigned int i=0; i<n_total_mapping_shape_functions; i++) { psi_map[i].resize (n_total_qp); dpsidxi_map[i].resize (n_total_qp); dpsideta_map[i].resize (n_total_qp); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES d2psidxi2_map[i].resize (n_total_qp); #endif } // compute shape maps if (inf_side->infinite()) { const std::vector<std::vector<Real>> & S_map = (base_fe->get_fe_map()).get_phi_map(); const std::vector<std::vector<Real>> & Ss_map = (base_fe->get_fe_map()).get_dphidxi_map(); for (unsigned int rp=0; rp<n_radial_qp; rp++) // over radial qps for (unsigned int bp=0; bp<n_base_qp; bp++) // over base qps for (unsigned int ti=0; ti<n_total_mapping_shape_functions; ti++) // over all mapping shapes { // let the index vectors take care of selecting the appropriate base/radial mapping shape const unsigned int bi = _base_node_index [ti]; const unsigned int ri = _radial_node_index[ti]; psi_map [ti][bp+rp*n_base_qp] = S_map [bi][bp] * radial_map [ri][rp]; dpsidxi_map [ti][bp+rp*n_base_qp] = Ss_map[bi][bp] * radial_map [ri][rp]; dpsideta_map [ti][bp+rp*n_base_qp] = S_map [bi][bp] * dradialdv_map[ri][rp]; // second derivatives are not implemented for infinite elements #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES d2psidxi2_map [ti][bp+rp*n_base_qp] = 0.; d2psidxideta_map [ti][bp+rp*n_base_qp] = 0.; d2psideta2_map [ti][bp+rp*n_base_qp] = 0.; #endif } } else { const std::vector<std::vector<Real>> & S_map = (base_fe->get_fe_map()).get_phi_map(); const std::vector<std::vector<Real>> & Ss_map = (base_fe->get_fe_map()).get_dphidxi_map(); const std::vector<std::vector<Real>> & St_map = (base_fe->get_fe_map()).get_dphideta_map(); for (unsigned int bp=0; bp<n_base_qp; bp++) // over base qps for (unsigned int ti=0; ti<n_total_mapping_shape_functions; ti++) // over all mapping shapes { psi_map [ti][bp] = S_map[ti][bp] ; dpsidxi_map [ti][bp] = Ss_map[ti][bp] ; dpsideta_map [ti][bp] = St_map[ti][bp] ; #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES d2psidxi2_map [ti][bp] = 0.; d2psidxideta_map [ti][bp] = 0.; d2psideta2_map [ti][bp] = 0.; #endif } } } // quadrature rule weights { const std::vector<Real> & radial_qw = radial_qrule->get_weights(); const std::vector<Real> & base_qw = base_qrule->get_weights(); libmesh_assert_equal_to (radial_qw.size(), n_radial_qp); libmesh_assert_equal_to (base_qw.size(), n_base_qp); for (unsigned int rp=0; rp<n_radial_qp; rp++) for (unsigned int bp=0; bp<n_base_qp; bp++) { _total_qrule_weights[bp + rp*n_base_qp] = radial_qw[rp] * base_qw[bp]; } } }
void InfFE<Dim,T_radial,T_map>::init_shape_functions(const Elem * inf_elem) { libmesh_assert(inf_elem); // Start logging the radial shape function initialization START_LOG("init_shape_functions()", "InfFE"); // ----------------------------------------------------------------- // fast access to some const int's for the radial data const unsigned int n_radial_mapping_sf = cast_int<unsigned int>(radial_map.size()); const unsigned int n_radial_approx_sf = cast_int<unsigned int>(mode.size()); const unsigned int n_radial_qp = cast_int<unsigned int>(som.size()); // ----------------------------------------------------------------- // initialize most of the things related to mapping // The element type and order to use in the base map const Order base_mapping_order ( base_elem->default_order() ); const ElemType base_mapping_elem_type ( base_elem->type() ); // the number of base shape functions used to construct the map // (Lagrange shape functions are used for mapping in the base) unsigned int n_base_mapping_shape_functions = Base::n_base_mapping_sf(base_mapping_elem_type, base_mapping_order); const unsigned int n_total_mapping_shape_functions = n_radial_mapping_sf * n_base_mapping_shape_functions; // ----------------------------------------------------------------- // initialize most of the things related to physical approximation unsigned int n_base_approx_shape_functions; if (Dim > 1) n_base_approx_shape_functions = base_fe->n_shape_functions(); else n_base_approx_shape_functions = 1; const unsigned int n_total_approx_shape_functions = n_radial_approx_sf * n_base_approx_shape_functions; // update class member field _n_total_approx_sf = n_total_approx_shape_functions; // The number of the base quadrature points. const unsigned int n_base_qp = base_qrule->n_points(); // The total number of quadrature points. const unsigned int n_total_qp = n_radial_qp * n_base_qp; // update class member field _n_total_qp = n_total_qp; // ----------------------------------------------------------------- // initialize the node and shape numbering maps { // these vectors work as follows: the i-th entry stores // the associated base/radial node number _radial_node_index.resize (n_total_mapping_shape_functions); _base_node_index.resize (n_total_mapping_shape_functions); // similar for the shapes: the i-th entry stores // the associated base/radial shape number _radial_shape_index.resize (n_total_approx_shape_functions); _base_shape_index.resize (n_total_approx_shape_functions); const ElemType inf_elem_type (inf_elem->type()); // fill the node index map for (unsigned int n=0; n<n_total_mapping_shape_functions; n++) { compute_node_indices (inf_elem_type, n, _base_node_index[n], _radial_node_index[n]); libmesh_assert_less (_base_node_index[n], n_base_mapping_shape_functions); libmesh_assert_less (_radial_node_index[n], n_radial_mapping_sf); } // fill the shape index map for (unsigned int n=0; n<n_total_approx_shape_functions; n++) { compute_shape_indices (this->fe_type, inf_elem_type, n, _base_shape_index[n], _radial_shape_index[n]); libmesh_assert_less (_base_shape_index[n], n_base_approx_shape_functions); libmesh_assert_less (_radial_shape_index[n], n_radial_approx_sf); } } // ----------------------------------------------------------------- // resize the base data fields dist.resize(n_base_mapping_shape_functions); // ----------------------------------------------------------------- // resize the total data fields // the phase term varies with xi, eta and zeta(v): store it for _all_ qp // // when computing the phase, we need the base approximations // therefore, initialize the phase here, but evaluate it // in combine_base_radial(). // // the weight, though, is only needed at the radial quadrature points, n_radial_qp. // but for a uniform interface to the protected data fields // the weight data field (which are accessible from the outside) are expanded to n_total_qp. weight.resize (n_total_qp); dweightdv.resize (n_total_qp); dweight.resize (n_total_qp); dphase.resize (n_total_qp); dphasedxi.resize (n_total_qp); dphasedeta.resize (n_total_qp); dphasedzeta.resize (n_total_qp); // this vector contains the integration weights for the combined quadrature rule _total_qrule_weights.resize(n_total_qp); // ----------------------------------------------------------------- // InfFE's data fields phi, dphi, dphidx, phi_map etc hold the _total_ // shape and mapping functions, respectively { phi.resize (n_total_approx_shape_functions); dphi.resize (n_total_approx_shape_functions); dphidx.resize (n_total_approx_shape_functions); dphidy.resize (n_total_approx_shape_functions); dphidz.resize (n_total_approx_shape_functions); dphidxi.resize (n_total_approx_shape_functions); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES libmesh_do_once(libMesh::err << "Second derivatives for Infinite elements" << " are not yet implemented!" << std::endl); d2phi.resize (n_total_approx_shape_functions); d2phidx2.resize (n_total_approx_shape_functions); d2phidxdy.resize (n_total_approx_shape_functions); d2phidxdz.resize (n_total_approx_shape_functions); d2phidy2.resize (n_total_approx_shape_functions); d2phidydz.resize (n_total_approx_shape_functions); d2phidz2.resize (n_total_approx_shape_functions); d2phidxi2.resize (n_total_approx_shape_functions); if (Dim > 1) { d2phidxideta.resize (n_total_approx_shape_functions); d2phideta2.resize (n_total_approx_shape_functions); } if (Dim > 2) { d2phidetadzeta.resize (n_total_approx_shape_functions); d2phidxidzeta.resize (n_total_approx_shape_functions); d2phidzeta2.resize (n_total_approx_shape_functions); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) dphideta.resize (n_total_approx_shape_functions); if (Dim == 3) dphidzeta.resize (n_total_approx_shape_functions); std::vector<std::vector<Real> > & phi_map = this->_fe_map->get_phi_map(); std::vector<std::vector<Real> > & dphidxi_map = this->_fe_map->get_dphidxi_map(); phi_map.resize (n_total_mapping_shape_functions); dphidxi_map.resize (n_total_mapping_shape_functions); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES std::vector<std::vector<Real> > & d2phidxi2_map = this->_fe_map->get_d2phidxi2_map(); d2phidxi2_map.resize (n_total_mapping_shape_functions); if (Dim > 1) { std::vector<std::vector<Real> > & d2phidxideta_map = this->_fe_map->get_d2phidxideta_map(); std::vector<std::vector<Real> > & d2phideta2_map = this->_fe_map->get_d2phideta2_map(); d2phidxideta_map.resize (n_total_mapping_shape_functions); d2phideta2_map.resize (n_total_mapping_shape_functions); } if (Dim == 3) { std::vector<std::vector<Real> > & d2phidxidzeta_map = this->_fe_map->get_d2phidxidzeta_map(); std::vector<std::vector<Real> > & d2phidetadzeta_map = this->_fe_map->get_d2phidetadzeta_map(); std::vector<std::vector<Real> > & d2phidzeta2_map = this->_fe_map->get_d2phidzeta2_map(); d2phidxidzeta_map.resize (n_total_mapping_shape_functions); d2phidetadzeta_map.resize (n_total_mapping_shape_functions); d2phidzeta2_map.resize (n_total_mapping_shape_functions); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) { std::vector<std::vector<Real> > & dphideta_map = this->_fe_map->get_dphideta_map(); dphideta_map.resize (n_total_mapping_shape_functions); } if (Dim == 3) { std::vector<std::vector<Real> > & dphidzeta_map = this->_fe_map->get_dphidzeta_map(); dphidzeta_map.resize (n_total_mapping_shape_functions); } } // ----------------------------------------------------------------- // collect all the for loops, where inner vectors are // resized to the appropriate number of quadrature points { for (unsigned int i=0; i<n_total_approx_shape_functions; i++) { phi[i].resize (n_total_qp); dphi[i].resize (n_total_qp); dphidx[i].resize (n_total_qp); dphidy[i].resize (n_total_qp); dphidz[i].resize (n_total_qp); dphidxi[i].resize (n_total_qp); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES d2phi[i].resize (n_total_qp); d2phidx2[i].resize (n_total_qp); d2phidxdy[i].resize (n_total_qp); d2phidxdz[i].resize (n_total_qp); d2phidy2[i].resize (n_total_qp); d2phidydz[i].resize (n_total_qp); d2phidy2[i].resize (n_total_qp); d2phidxi2[i].resize (n_total_qp); if (Dim > 1) { d2phidxideta[i].resize (n_total_qp); d2phideta2[i].resize (n_total_qp); } if (Dim > 2) { d2phidxidzeta[i].resize (n_total_qp); d2phidetadzeta[i].resize (n_total_qp); d2phidzeta2[i].resize (n_total_qp); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) dphideta[i].resize (n_total_qp); if (Dim == 3) dphidzeta[i].resize (n_total_qp); } for (unsigned int i=0; i<n_total_mapping_shape_functions; i++) { std::vector<std::vector<Real> > & phi_map = this->_fe_map->get_phi_map(); std::vector<std::vector<Real> > & dphidxi_map = this->_fe_map->get_dphidxi_map(); phi_map[i].resize (n_total_qp); dphidxi_map[i].resize (n_total_qp); #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES std::vector<std::vector<Real> > & d2phidxi2_map = this->_fe_map->get_d2phidxi2_map(); d2phidxi2_map[i].resize (n_total_qp); if (Dim > 1) { std::vector<std::vector<Real> > & d2phidxideta_map = this->_fe_map->get_d2phidxideta_map(); std::vector<std::vector<Real> > & d2phideta2_map = this->_fe_map->get_d2phideta2_map(); d2phidxideta_map[i].resize (n_total_qp); d2phideta2_map[i].resize (n_total_qp); } if (Dim > 2) { std::vector<std::vector<Real> > & d2phidxidzeta_map = this->_fe_map->get_d2phidxidzeta_map(); std::vector<std::vector<Real> > & d2phidetadzeta_map = this->_fe_map->get_d2phidetadzeta_map(); std::vector<std::vector<Real> > & d2phidzeta2_map = this->_fe_map->get_d2phidzeta2_map(); d2phidxidzeta_map[i].resize (n_total_qp); d2phidetadzeta_map[i].resize (n_total_qp); d2phidzeta2_map[i].resize (n_total_qp); } #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES if (Dim > 1) { std::vector<std::vector<Real> > & dphideta_map = this->_fe_map->get_dphideta_map(); dphideta_map[i].resize (n_total_qp); } if (Dim == 3) { std::vector<std::vector<Real> > & dphidzeta_map = this->_fe_map->get_dphidzeta_map(); dphidzeta_map[i].resize (n_total_qp); } } } { // ----------------------------------------------------------------- // (a) compute scalar values at _all_ quadrature points -- for uniform // access from the outside to these fields // (b) form a std::vector<Real> which contains the appropriate weights // of the combined quadrature rule! const std::vector<Point> & radial_qp = radial_qrule->get_points(); libmesh_assert_equal_to (radial_qp.size(), n_radial_qp); const std::vector<Real> & radial_qw = radial_qrule->get_weights(); const std::vector<Real> & base_qw = base_qrule->get_weights(); libmesh_assert_equal_to (radial_qw.size(), n_radial_qp); libmesh_assert_equal_to (base_qw.size(), n_base_qp); for (unsigned int rp=0; rp<n_radial_qp; rp++) for (unsigned int bp=0; bp<n_base_qp; bp++) { weight [ bp+rp*n_base_qp ] = Radial::D (radial_qp[rp](0)); dweightdv[ bp+rp*n_base_qp ] = Radial::D_deriv (radial_qp[rp](0)); _total_qrule_weights[ bp+rp*n_base_qp ] = radial_qw[rp] * base_qw[bp]; } } /** * Stop logging the radial shape function initialization */ STOP_LOG("init_shape_functions()", "InfFE"); }
void InfFE<Dim,T_radial,T_map>::compute_node_indices_fast (const ElemType inf_elem_type, const unsigned int outer_node_index, unsigned int & base_node, unsigned int & radial_node) { libmesh_assert_not_equal_to (inf_elem_type, INVALID_ELEM); static std::vector<unsigned int> _static_base_node_index; static std::vector<unsigned int> _static_radial_node_index; /* * fast counterpart to compute_node_indices(), uses local static buffers * to store the index maps. The class member * \p _compute_node_indices_fast_current_elem_type remembers * the current element type. * * Note that there exist non-static members storing the * same data. However, you never know what element type * is currently used by the \p InfFE object, and what * request is currently directed to the static \p InfFE * members (which use \p compute_node_indices_fast()). * So separate these. * * check whether the work for this elemtype has already * been done. If so, use this index. Otherwise, refresh * the buffer to this element type. */ if (inf_elem_type==_compute_node_indices_fast_current_elem_type) { base_node = _static_base_node_index [outer_node_index]; radial_node = _static_radial_node_index[outer_node_index]; return; } else { // store the map for _all_ nodes for this element type _compute_node_indices_fast_current_elem_type = inf_elem_type; unsigned int n_nodes = libMesh::invalid_uint; switch (inf_elem_type) { case INFEDGE2: { n_nodes = 2; break; } case INFQUAD4: { n_nodes = 4; break; } case INFQUAD6: { n_nodes = 6; break; } case INFHEX8: { n_nodes = 8; break; } case INFHEX16: { n_nodes = 16; break; } case INFHEX18: { n_nodes = 18; break; } case INFPRISM6: { n_nodes = 6; break; } case INFPRISM12: { n_nodes = 12; break; } default: libmesh_error_msg("ERROR: Bad infinite element type=" << inf_elem_type << ", node=" << outer_node_index); } _static_base_node_index.resize (n_nodes); _static_radial_node_index.resize(n_nodes); for (unsigned int n=0; n<n_nodes; n++) compute_node_indices (inf_elem_type, n, _static_base_node_index [outer_node_index], _static_radial_node_index[outer_node_index]); // and return for the specified node base_node = _static_base_node_index [outer_node_index]; radial_node = _static_radial_node_index[outer_node_index]; return; } }