Esempio n. 1
0
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);
}
Esempio n. 2
0
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];
        }
  }

}
Esempio n. 3
0
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];
        }
  }

}
Esempio n. 4
0
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");

}
Esempio n. 5
0
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;
    }
}