<commit_before>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 <NAME>, <NAME>, <NAME>
  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
  
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
  
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA



// Local includes
#include "fe.h"
#include "elem.h"
#include "libmesh_logging.h"
#include "fe_macro.h"
#include "quadrature.h"


namespace libMesh
{


// ------------------------------------------------------------
// FE class members
template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_shape_functions () const
{
  return FE<Dim,T>::n_dofs (elem_type,
           static_cast<Order>(fe_type.order + _p_level));
}


template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::attach_quadrature_rule (QBase* q)
{
  libmesh_assert (q != NULL); 
  qrule = q;
  // make sure we don't cache results from a previous quadrature rule
  elem_type = INVALID_ELEM;
  return;
}


template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_quadrature_points () const
{ 
  libmesh_assert (qrule != NULL);  
  return qrule->n_points(); 
}


template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::dofs_on_side(const Elem* const elem,
			     const Order o,
			     unsigned int s,
			     std::vector<unsigned int>& di)
{
  libmesh_assert(elem != NULL);
  libmesh_assert(s < elem->n_sides());

  di.clear();
  unsigned int nodenum = 0;
  const unsigned int n_nodes = elem->n_nodes();
  for (unsigned int n = 0; n != n_nodes; ++n)
    {
      const unsigned int n_dofs = n_dofs_at_node(elem->type(),
						 static_cast<Order>(o + elem->p_level()), n);
      if (elem->is_node_on_side(n, s))
	for (unsigned int i = 0; i != n_dofs; ++i)
	  di.push_back(nodenum++);
      else
	nodenum += n_dofs;
    }
}



template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::dofs_on_edge(const Elem* const elem,
			     const Order o,
			     unsigned int e,
			     std::vector<unsigned int>& di)
{
  libmesh_assert(elem != NULL);
  libmesh_assert(e < elem->n_edges());

  di.clear();
  unsigned int nodenum = 0;
  const unsigned int n_nodes = elem->n_nodes();
  for (unsigned int n = 0; n != n_nodes; ++n)
    {
      const unsigned int n_dofs = n_dofs_at_node(elem->type(),
						 static_cast<Order>(o + elem->p_level()), n);
      if (elem->is_node_on_edge(n, e))
	for (unsigned int i = 0; i != n_dofs; ++i)
	  di.push_back(nodenum++);
      else
	nodenum += n_dofs;
    }
}



template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::reinit(const Elem* elem,
		       const std::vector<Point>* const pts)
{
  libmesh_assert (elem != NULL);

  // 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
      elem_type = elem->type();
      _p_level = elem->p_level();

      // Initialize the shape functions
      this->init_shape_functions (*pts, elem);

      // The shape functions do not correspond to the qrule
      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 (qrule   != NULL);
      qrule->init(elem->type(), elem->p_level());

      if (elem_type != elem->type() ||
          _p_level != elem->p_level() ||
          !shapes_on_quadrature)
        {
          // Set the type and p level for this element
          elem_type = elem->type();
          _p_level = elem->p_level();
          // Initialize the shape functions
          this->init_shape_functions (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(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)) !=
                    (cached_nodes[n] - cached_nodes[0]))
                  {
                    cached_nodes_still_fit = false;
                    break;
                  }
              }

          if (this->shapes_need_reinit() && !cached_nodes_still_fit)
            {
              this->init_shape_functions (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
      shapes_on_quadrature = true;
    }
  
  // Compute the map for this element.  In the future we can specify
  // different types of maps<commit_msg>add relative tolerance check for fe chaching<commit_after>// $Id$

// The libMesh Finite Element Library.
// Copyright (C) 2002-2008 <NAME>, <NAME>, <NAME>
  
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
  
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
  
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA



// Local includes
#include "fe.h"
#include "elem.h"
#include "libmesh_logging.h"
#include "fe_macro.h"
#include "quadrature.h"


namespace libMesh
{


// ------------------------------------------------------------
// FE class members
template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_shape_functions () const
{
  return FE<Dim,T>::n_dofs (elem_type,
           static_cast<Order>(fe_type.order + _p_level));
}


template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::attach_quadrature_rule (QBase* q)
{
  libmesh_assert (q != NULL); 
  qrule = q;
  // make sure we don't cache results from a previous quadrature rule
  elem_type = INVALID_ELEM;
  return;
}


template <unsigned int Dim, FEFamily T>
unsigned int FE<Dim,T>::n_quadrature_points () const
{ 
  libmesh_assert (qrule != NULL);  
  return qrule->n_points(); 
}


template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::dofs_on_side(const Elem* const elem,
			     const Order o,
			     unsigned int s,
			     std::vector<unsigned int>& di)
{
  libmesh_assert(elem != NULL);
  libmesh_assert(s < elem->n_sides());

  di.clear();
  unsigned int nodenum = 0;
  const unsigned int n_nodes = elem->n_nodes();
  for (unsigned int n = 0; n != n_nodes; ++n)
    {
      const unsigned int n_dofs = n_dofs_at_node(elem->type(),
						 static_cast<Order>(o + elem->p_level()), n);
      if (elem->is_node_on_side(n, s))
	for (unsigned int i = 0; i != n_dofs; ++i)
	  di.push_back(nodenum++);
      else
	nodenum += n_dofs;
    }
}



template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::dofs_on_edge(const Elem* const elem,
			     const Order o,
			     unsigned int e,
			     std::vector<unsigned int>& di)
{
  libmesh_assert(elem != NULL);
  libmesh_assert(e < elem->n_edges());

  di.clear();
  unsigned int nodenum = 0;
  const unsigned int n_nodes = elem->n_nodes();
  for (unsigned int n = 0; n != n_nodes; ++n)
    {
      const unsigned int n_dofs = n_dofs_at_node(elem->type(),
						 static_cast<Order>(o + elem->p_level()), n);
      if (elem->is_node_on_edge(n, e))
	for (unsigned int i = 0; i != n_dofs; ++i)
	  di.push_back(nodenum++);
      else
	nodenum += n_dofs;
    }
}



template <unsigned int Dim, FEFamily T>
void FE<Dim,T>::reinit(const Elem* elem,
		       const std::vector<Point>* const pts)
{
  libmesh_assert (elem != NULL);

  // 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
      elem_type = elem->type();
      _p_level = elem->p_level();

      // Initialize the shape functions
      this->init_shape_functions (*pts, elem);

      // The shape functions do not correspond to the qrule
      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 (qrule   != NULL);
      qrule->init(elem->type(), elem->p_level());

      if (elem_type != elem->type() ||
          _p_level != elem->p_level() ||
          !shapes_on_quadrature)
        {
          // Set the type and p level for this element
          elem_type = elem->type();
          _p_level = elem->p_level();
          // Initialize the shape functions
          this->init_shape_functions (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(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->init_shape_functions (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
      shapes_on_quadrature = true;
    }
  
  // Compute the map for this element.  In the future we can specify
  // different types of maps
{'fraction_non_alphanumeric': 0.12613981762917933, 'fraction_numerical': 0.006332320162107396, 'mean_word_length': 2.309583682592903, 'pattern_counts': {'":': 0, '<': 53, '<?xml version=': 0, '>': 125, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5185458', 'n_tokens_mistral': 3831, 'n_tokens_neox': 3617, 'n_words': 1144}