コード例 #1
0
ファイル: fe_xyz_boundary.C プロジェクト: friedmud/libmesh
void FEXYZ<Dim>::reinit(const Elem * elem,
                        const unsigned int s,
                        const Real,
                        const std::vector<Point> * const pts,
                        const std::vector<Real> * const weights)
{
  libmesh_assert(elem);
  libmesh_assert (this->qrule != libmesh_nullptr || pts != libmesh_nullptr);
  // We don't do this for 1D elements!
  libmesh_assert_not_equal_to (Dim, 1);

  // Build the side of interest
  const UniquePtr<const Elem> side(elem->build_side_ptr(s));

  // Initialize the shape functions at the user-specified
  // points
  if (pts != libmesh_nullptr)
    {
      // We can't get away without recomputing shape functions next
      // time
      this->shapes_on_quadrature = false;

      // Set the element type
      this->elem_type = elem->type();

      // Initialize the face shape functions
      this->_fe_map->template init_face_shape_functions<Dim>(*pts,  side.get());
      if (weights != libmesh_nullptr)
        {
          this->compute_face_values (elem, side.get(), *weights);
        }
      else
        {
          std::vector<Real> dummy_weights (pts->size(), 1.);
          // Compute data on the face for integration
          this->compute_face_values (elem, side.get(), dummy_weights);
        }
    }
  else
    {
      // initialize quadrature rule
      this->qrule->init(side->type(), elem->p_level());

      {
        // Set the element type
        this->elem_type = elem->type();

        // Initialize the face shape functions
        this->_fe_map->template init_face_shape_functions<Dim>(this->qrule->get_points(),  side.get());
      }
      // We can't get away without recomputing shape functions next
      // time
      this->shapes_on_quadrature = false;
      // Compute data on the face for integration
      this->compute_face_values (elem, side.get(), this->qrule->get_weights());
    }
}
コード例 #2
0
ファイル: fe.C プロジェクト: bwspenc/libmesh
void FE<Dim,T>::reinit(const Elem* elem,
                       const std::vector<Point>* const pts,
                       const std::vector<Real>* const weights)
{
  libmesh_assert(elem);

  // Try to avoid calling init_shape_functions
  // even when shapes_need_reinit
  bool cached_nodes_still_fit = false;

  // Initialize the shape functions at the user-specified
  // points
  if (pts != NULL)
    {
      // Set the type and p level for this element
      this->elem_type = elem->type();
      this->_p_level = elem->p_level();

      // Initialize the shape functions
      this->_fe_map->template init_reference_to_physical_map<Dim>(*pts, elem);
      this->init_shape_functions (*pts, elem);

      // The shape functions do not correspond to the qrule
      this->shapes_on_quadrature = false;
    }

  // If there are no user specified points, we use the
  // quadrature rule

  // update the type in accordance to the current cell
  // and reinit if the cell type has changed or (as in
  // the case of the hierarchics) the shape functions need
  // reinit, since they depend on the particular element shape
  else
    {
      libmesh_assert(this->qrule);
      this->qrule->init(elem->type(), elem->p_level());

      if(this->qrule->shapes_need_reinit())
        this->shapes_on_quadrature = false;

      if (this->elem_type != elem->type() ||
          this->_p_level != elem->p_level() ||
          !this->shapes_on_quadrature)
        {
          // Set the type and p level for this element
          this->elem_type = elem->type();
          this->_p_level = elem->p_level();
          // Initialize the shape functions
          this->_fe_map->template init_reference_to_physical_map<Dim>(this->qrule->get_points(), elem);
          this->init_shape_functions (this->qrule->get_points(), elem);

          if (this->shapes_need_reinit())
            {
              cached_nodes.resize(elem->n_nodes());
              for (unsigned int n = 0; n != elem->n_nodes(); ++n)
                {
                  cached_nodes[n] = elem->point(n);
                }
            }
        }
      else
        {
          // libmesh_assert_greater (elem->n_nodes(), 1);

          cached_nodes_still_fit = true;
          if (cached_nodes.size() != elem->n_nodes())
            cached_nodes_still_fit = false;
          else
            for (unsigned int n = 1; n < elem->n_nodes(); ++n)
              {
                if (!(elem->point(n) - elem->point(0)).relative_fuzzy_equals(
                                                                             (cached_nodes[n] - cached_nodes[0]), 1e-13))
                  {
                    cached_nodes_still_fit = false;
                    break;
                  }
              }

          if (this->shapes_need_reinit() && !cached_nodes_still_fit)
            {
              this->_fe_map->template init_reference_to_physical_map<Dim>(this->qrule->get_points(), elem);
              this->init_shape_functions (this->qrule->get_points(), elem);
              cached_nodes.resize(elem->n_nodes());
              for (unsigned int n = 0; n != elem->n_nodes(); ++n)
                cached_nodes[n] = elem->point(n);
            }
        }

      // The shape functions correspond to the qrule
      this->shapes_on_quadrature = true;
    }

  // Compute the map for this element.  In the future we can specify
  // different types of maps
  if (pts != NULL)
    {
      if (weights != NULL)
        {
          this->_fe_map->compute_map (this->dim,*weights, elem);
        }
      else
        {
          std::vector<Real> dummy_weights (pts->size(), 1.);
          this->_fe_map->compute_map (this->dim,dummy_weights, elem);
        }
    }
  else
    {
      this->_fe_map->compute_map (this->dim,this->qrule->get_weights(), elem);
    }

  // Compute the shape functions and the derivatives at all of the
  // quadrature points.
  if (!cached_nodes_still_fit)
    {
      if (pts != NULL)
        this->compute_shape_functions (elem,*pts);
      else
        this->compute_shape_functions(elem,this->qrule->get_points());
    }
}
コード例 #3
0
ファイル: fe_boundary.C プロジェクト: ArtisticCoding/libmesh
void FE<Dim,T>::edge_reinit(const Elem* elem,
                            const unsigned int e,
                            const Real tolerance,
                            const std::vector<Point>* const pts,
                            const std::vector<Real>* const weights)
{
  libmesh_assert(elem);
  libmesh_assert (this->qrule != NULL || pts != NULL);
  // We don't do this for 1D elements!
  libmesh_assert_not_equal_to (Dim, 1);

  // Build the side of interest
  const UniquePtr<Elem> edge(elem->build_edge(e));

  // Initialize the shape functions at the user-specified
  // points
  if (pts != NULL)
    {
      // The shape functions do not correspond to the qrule
      this->shapes_on_quadrature = false;

      // Initialize the edge shape functions
      this->_fe_map->template init_edge_shape_functions<Dim> (*pts, edge.get());

      // Compute the Jacobian*Weight on the face for integration
      if (weights != NULL)
        {
          this->_fe_map->compute_edge_map (Dim, *weights, edge.get());
        }
      else
        {
          std::vector<Real> dummy_weights (pts->size(), 1.);
          this->_fe_map->compute_edge_map (Dim, dummy_weights, edge.get());
        }
    }
  // If there are no user specified points, we use the
  // quadrature rule
  else
    {
      // initialize quadrature rule
      this->qrule->init(edge->type(), elem->p_level());

      if(this->qrule->shapes_need_reinit())
        this->shapes_on_quadrature = false;

      // We might not need to reinitialize the shape functions
      if ((this->get_type() != elem->type())                   ||
          (edge->type() != static_cast<int>(last_edge))        || // Comparison between enum and unsigned, cast the unsigned to int
          this->shapes_need_reinit()                           ||
          !this->shapes_on_quadrature)
        {
          // Set the element type
          this->elem_type = elem->type();

          // Set the last_edge
          last_edge = edge->type();

          // Initialize the edge shape functions
          this->_fe_map->template init_edge_shape_functions<Dim> (this->qrule->get_points(), edge.get());
        }

      // Compute the Jacobian*Weight on the face for integration
      this->_fe_map->compute_edge_map (Dim, this->qrule->get_weights(), edge.get());

      // The shape functions correspond to the qrule
      this->shapes_on_quadrature = true;
    }

  // make a copy of the Jacobian for integration
  const std::vector<Real> JxW_int(this->_fe_map->get_JxW());

  // Find where the integration points are located on the
  // full element.
  std::vector<Point> qp;
  this->inverse_map (elem, this->_fe_map->get_xyz(), qp, tolerance);

  // compute the shape function and derivative values
  // at the points qp
  this->reinit  (elem, &qp);

  // copy back old data
  this->_fe_map->get_JxW() = JxW_int;
}
コード例 #4
0
ファイル: fe_boundary.C プロジェクト: ArtisticCoding/libmesh
void FE<Dim,T>::reinit(const Elem* elem,
                       const unsigned int s,
                       const Real /* tolerance */,
                       const std::vector<Point>* const pts,
                       const std::vector<Real>* const weights)
{
  libmesh_assert(elem);
  libmesh_assert (this->qrule != NULL || pts != NULL);
  // We now do this for 1D elements!
  // libmesh_assert_not_equal_to (Dim, 1);

  // Build the side of interest
  const UniquePtr<Elem> side(elem->build_side(s));

  // Find the max p_level to select
  // the right quadrature rule for side integration
  unsigned int side_p_level = elem->p_level();
  if (elem->neighbor(s) != NULL)
    side_p_level = std::max(side_p_level, elem->neighbor(s)->p_level());

  // Initialize the shape functions at the user-specified
  // points
  if (pts != NULL)
    {
      // The shape functions do not correspond to the qrule
      this->shapes_on_quadrature = false;

      // Initialize the face shape functions
      this->_fe_map->template init_face_shape_functions<Dim>(*pts, side.get());

      // Compute the Jacobian*Weight on the face for integration
      if (weights != NULL)
        {
          this->_fe_map->compute_face_map (Dim, *weights, side.get());
        }
      else
        {
          std::vector<Real> dummy_weights (pts->size(), 1.);
          this->_fe_map->compute_face_map (Dim, dummy_weights, side.get());
        }
    }
  // If there are no user specified points, we use the
  // quadrature rule
  else
    {
      // initialize quadrature rule
      this->qrule->init(side->type(), side_p_level);

      if(this->qrule->shapes_need_reinit())
        this->shapes_on_quadrature = false;

      // FIXME - could this break if the same FE object was used
      // for both volume and face integrals? - RHS
      // We might not need to reinitialize the shape functions
      if ((this->get_type() != elem->type())    ||
          (side->type() != last_side)           ||
          (this->get_p_level() != side_p_level) ||
          this->shapes_need_reinit()            ||
          !this->shapes_on_quadrature)
        {
          // Set the element type and p_level
          this->elem_type = elem->type();

          // Set the last_side
          last_side = side->type();

          // Set the last p level
          this->_p_level = side_p_level;

          // Initialize the face shape functions
          this->_fe_map->template init_face_shape_functions<Dim>(this->qrule->get_points(),  side.get());
        }

      // Compute the Jacobian*Weight on the face for integration
      this->_fe_map->compute_face_map (Dim, this->qrule->get_weights(), side.get());

      // The shape functions correspond to the qrule
      this->shapes_on_quadrature = true;
    }

  // make a copy of the Jacobian for integration
  const std::vector<Real> JxW_int(this->_fe_map->get_JxW());

  // make a copy of shape on quadrature info
  bool shapes_on_quadrature_side = this->shapes_on_quadrature;

  // Find where the integration points are located on the
  // full element.
  const std::vector<Point>* ref_qp;
  if (pts != NULL)
    ref_qp = pts;
  else
    ref_qp = &this->qrule->get_points();

  std::vector<Point> qp;
  this->side_map(elem, side.get(), s, *ref_qp, qp);

  // compute the shape function and derivative values
  // at the points qp
  this->reinit  (elem, &qp);

  this->shapes_on_quadrature = shapes_on_quadrature_side;

  // copy back old data
  this->_fe_map->get_JxW() = JxW_int;
}
コード例 #5
0
ファイル: inf_fe.C プロジェクト: YSB330/libmesh
void InfFE<Dim,T_radial,T_map>::reinit(const Elem * inf_elem,
                                       const std::vector<Point> * const pts,
                                       const std::vector<Real> * const weights)
{
  libmesh_assert(base_fe);
  libmesh_assert(base_fe->qrule);
  libmesh_assert_equal_to (base_fe->qrule, base_qrule);
  libmesh_assert(radial_qrule);
  libmesh_assert(inf_elem);

  if (pts == libmesh_nullptr)
    {
      bool init_shape_functions_required = false;

      // -----------------------------------------------------------------
      // init the radial data fields only when the radial order changes
      if (current_fe_type.radial_order != fe_type.radial_order)
        {
          current_fe_type.radial_order = fe_type.radial_order;

          // Watch out: this call to QBase->init() only works for
          // current_fe_type = const!   To allow variable Order,
          // the init() of QBase has to be modified...
          radial_qrule->init(EDGE2);

          // initialize the radial shape functions
          this->init_radial_shape_functions(inf_elem);

          init_shape_functions_required=true;
        }


      bool update_base_elem_required=true;

      // -----------------------------------------------------------------
      // update the type in accordance to the current cell
      // and reinit if the cell type has changed or (as in
      // the case of the hierarchics) the shape functions
      // depend on the particular element and need a reinit
      if (  ( Dim != 1) &&
            (  (this->get_type() != inf_elem->type())  ||
               (base_fe->shapes_need_reinit())  )  )
        {
          // store the new element type, update base_elem
          // here.  Through \p update_base_elem_required,
          // remember whether it has to be updated (see below).
          elem_type = inf_elem->type();
          this->update_base_elem(inf_elem);
          update_base_elem_required=false;

          // initialize the base quadrature rule for the new element
          base_qrule->init(base_elem->type());

          // initialize the shape functions in the base
          base_fe->init_base_shape_functions(base_fe->qrule->get_points(),
                                             base_elem);

          init_shape_functions_required=true;
        }


      // when either the radial or base part change,
      // we have to init the whole fields
      if (init_shape_functions_required)
        this->init_shape_functions (inf_elem);

      // computing the distance only works when we have the current
      // base_elem stored.  This happens when fe_type is const,
      // the inf_elem->type remains the same.  Then we have to
      // update the base elem _here_.
      if (update_base_elem_required)
        this->update_base_elem(inf_elem);

      // compute dist (depends on geometry, therefore has to be updated for
      // each and every new element), throw radial and base part together
      this->combine_base_radial (inf_elem);

      this->_fe_map->compute_map (this->dim, _total_qrule_weights, inf_elem, this->calculate_d2phi);

      // Compute the shape functions and the derivatives
      // at all quadrature points.
      this->compute_shape_functions (inf_elem,base_fe->qrule->get_points());
    }

  else // if pts != libmesh_nullptr
    {
      // update the elem_type
      elem_type = inf_elem->type();

      // init radial shapes
      this->init_radial_shape_functions(inf_elem);

      // update the base
      this->update_base_elem(inf_elem);

      // the finite element on the ifem base
      {
        UniquePtr<FEBase> ap_fb(FEBase::build(Dim-1, this->fe_type));
        if (base_fe != libmesh_nullptr)
          delete base_fe;
        base_fe = ap_fb.release();
      }

      // inite base shapes
      base_fe->init_base_shape_functions(*pts,
                                         base_elem);

      this->init_shape_functions (inf_elem);

      // combine the base and radial shapes
      this->combine_base_radial (inf_elem);

      // weights
      if (weights != libmesh_nullptr)
        {
          this->_fe_map->compute_map (this->dim, *weights, inf_elem, this->calculate_d2phi);
        }
      else
        {
          std::vector<Real> dummy_weights (pts->size(), 1.);
          this->_fe_map->compute_map (this->dim, dummy_weights, inf_elem, this->calculate_d2phi);
        }

      // finally compute the ifem shapes
      this->compute_shape_functions (inf_elem,*pts);
    }

}
コード例 #6
0
ファイル: fe.C プロジェクト: danac/libmesh
void FE<Dim,T>::reinit(const Elem* elem,
                       const std::vector<Point>* const pts,
                       const std::vector<Real>* const weights)
{
  // We can be called with no element.  If we're evaluating SCALAR
  // dofs we'll still have work to do.
  // libmesh_assert(elem);

  // Try to avoid calling init_shape_functions
  // even when shapes_need_reinit
  bool cached_nodes_still_fit = false;

  // Most of the hard work happens when we have an actual element
  if (elem)
    {
      // Initialize the shape functions at the user-specified
      // points
      if (pts != NULL)
        {
          // Set the type and p level for this element
          this->elem_type = elem->type();
          this->_p_level = elem->p_level();

          // Initialize the shape functions
          this->_fe_map->template init_reference_to_physical_map<Dim>
            (*pts, elem);
          this->init_shape_functions (*pts, elem);

          // The shape functions do not correspond to the qrule
          this->shapes_on_quadrature = false;
        }

      // If there are no user specified points, we use the
      // quadrature rule

      // update the type in accordance to the current cell
      // and reinit if the cell type has changed or (as in
      // the case of the hierarchics) the shape functions need
      // reinit, since they depend on the particular element shape
      else
        {
          libmesh_assert(this->qrule);
          this->qrule->init(elem->type(), elem->p_level());

          if(this->qrule->shapes_need_reinit())
            this->shapes_on_quadrature = false;

          if (this->elem_type != elem->type() ||
              this->_p_level != elem->p_level() ||
              !this->shapes_on_quadrature)
            {
              // Set the type and p level for this element
              this->elem_type = elem->type();
              this->_p_level = elem->p_level();
              // Initialize the shape functions
              this->_fe_map->template init_reference_to_physical_map<Dim>
                (this->qrule->get_points(), elem);
              this->init_shape_functions (this->qrule->get_points(), elem);

              if (this->shapes_need_reinit())
                {
                  cached_nodes.resize(elem->n_nodes());
                  for (unsigned int n = 0; n != elem->n_nodes(); ++n)
                    {
                      cached_nodes[n] = elem->point(n);
                    }
                }
            }
          else
            {
              // libmesh_assert_greater (elem->n_nodes(), 1);

              cached_nodes_still_fit = true;
              if (cached_nodes.size() != elem->n_nodes())
                cached_nodes_still_fit = false;
              else
                for (unsigned int n = 1; n < elem->n_nodes(); ++n)
                  {
                    if (!(elem->point(n) - elem->point(0)).relative_fuzzy_equals
                        ((cached_nodes[n] - cached_nodes[0]), 1e-13))
                      {
                        cached_nodes_still_fit = false;
                        break;
                      }
                  }

              if (this->shapes_need_reinit() && !cached_nodes_still_fit)
                {
                  this->_fe_map->template init_reference_to_physical_map<Dim>
                    (this->qrule->get_points(), elem);
                  this->init_shape_functions (this->qrule->get_points(), elem);
                  cached_nodes.resize(elem->n_nodes());
                  for (unsigned int n = 0; n != elem->n_nodes(); ++n)
                    cached_nodes[n] = elem->point(n);
                }
            }

          // The shape functions correspond to the qrule
          this->shapes_on_quadrature = true;
        }
    }
  else // With no defined elem, so mapping or caching to
       // be done, and our "quadrature rule" is one point for nonlocal
       // (SCALAR) variables and zero points for local variables.
    {
      this->elem_type = INVALID_ELEM;
      this->_p_level = 0;

      if (!pts)
        {
          if (T == SCALAR)
            {
              this->qrule->get_points() =
                std::vector<Point>(1,Point(0));

              this->qrule->get_weights() =
                std::vector<Real>(1,1);
            }
          else
            {
              this->qrule->get_points().clear();
              this->qrule->get_weights().clear();
            }

           this->init_shape_functions
             (this->qrule->get_points(), elem);
        }
      else
        this->init_shape_functions (*pts, elem);
    }

  // Compute the map for this element.
  if (pts != NULL)
    {
      if (weights != NULL)
        {
          this->_fe_map->compute_map (this->dim,*weights, elem);
        }
      else
        {
          std::vector<Real> dummy_weights (pts->size(), 1.);
          this->_fe_map->compute_map (this->dim,dummy_weights, elem);
        }
    }
  else
    {
      this->_fe_map->compute_map (this->dim,this->qrule->get_weights(), elem);
    }

  // Compute the shape functions and the derivatives at all of the
  // quadrature points.
  if (!cached_nodes_still_fit)
    {
      if (pts != NULL)
        this->compute_shape_functions (elem,*pts);
      else
        this->compute_shape_functions(elem,this->qrule->get_points());
    }
}