$extrastylesheet
libMesh::FEGenericBase< OutputType > Class Template Reference

#include <fe_base.h>

Inheritance diagram for libMesh::FEGenericBase< OutputType >:

List of all members.

Public Types

typedef OutputType OutputShape
typedef
TensorTools::IncrementRank
< OutputShape >::type 
OutputGradient
typedef
TensorTools::IncrementRank
< OutputGradient >::type 
OutputTensor
typedef
TensorTools::DecrementRank
< OutputShape >::type 
OutputDivergence
typedef
TensorTools::MakeNumber
< OutputShape >::type 
OutputNumber
typedef
TensorTools::IncrementRank
< OutputNumber >::type 
OutputNumberGradient
typedef
TensorTools::IncrementRank
< OutputNumberGradient >::type 
OutputNumberTensor
typedef
TensorTools::DecrementRank
< OutputNumber >::type 
OutputNumberDivergence

Public Member Functions

virtual ~FEGenericBase ()
const std::vector< std::vector
< OutputShape > > & 
get_phi () const
const std::vector< std::vector
< OutputGradient > > & 
get_dphi () const
const std::vector< std::vector
< OutputShape > > & 
get_curl_phi () const
const std::vector< std::vector
< OutputDivergence > > & 
get_div_phi () const
const std::vector< std::vector
< OutputShape > > & 
get_dphidx () const
const std::vector< std::vector
< OutputShape > > & 
get_dphidy () const
const std::vector< std::vector
< OutputShape > > & 
get_dphidz () const
const std::vector< std::vector
< OutputShape > > & 
get_dphidxi () const
const std::vector< std::vector
< OutputShape > > & 
get_dphideta () const
const std::vector< std::vector
< OutputShape > > & 
get_dphidzeta () const
const std::vector< std::vector
< OutputTensor > > & 
get_d2phi () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidx2 () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidxdy () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidxdz () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidy2 () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidydz () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidz2 () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidxi2 () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidxideta () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidxidzeta () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phideta2 () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidetadzeta () const
const std::vector< std::vector
< OutputShape > > & 
get_d2phidzeta2 () const
const std::vector
< OutputGradient > & 
get_dphase () const
const std::vector< Real > & get_Sobolev_weight () const
const std::vector< RealGradient > & get_Sobolev_dweight () const
void print_phi (std::ostream &os) const
void print_dphi (std::ostream &os) const
void print_d2phi (std::ostream &os) const
template<>
UniquePtr< FEGenericBase
< RealGradient > > 
build (const unsigned int dim, const FEType &fet)
template<>
UniquePtr< FEGenericBase< Real > > build_InfFE (const unsigned int dim, const FEType &fet)
template<>
UniquePtr< FEGenericBase
< RealGradient > > 
build_InfFE (const unsigned int, const FEType &)
virtual void reinit (const Elem *elem, const std::vector< Point > *const pts=NULL, const std::vector< Real > *const weights=NULL)=0
virtual void reinit (const Elem *elem, const unsigned int side, const Real tolerance=TOLERANCE, const std::vector< Point > *const pts=NULL, const std::vector< Real > *const weights=NULL)=0
virtual void edge_reinit (const Elem *elem, const unsigned int edge, const Real tolerance=TOLERANCE, const std::vector< Point > *pts=NULL, const std::vector< Real > *weights=NULL)=0
virtual void side_map (const Elem *elem, const Elem *side, const unsigned int s, const std::vector< Point > &reference_side_points, std::vector< Point > &reference_points)=0
const std::vector< Point > & get_xyz () const
const std::vector< Real > & get_JxW () const
const std::vector< RealGradient > & get_dxyzdxi () const
const std::vector< RealGradient > & get_dxyzdeta () const
const std::vector< RealGradient > & get_dxyzdzeta () const
const std::vector< RealGradient > & get_d2xyzdxi2 () const
const std::vector< RealGradient > & get_d2xyzdeta2 () const
const std::vector< RealGradient > & get_d2xyzdzeta2 () const
const std::vector< RealGradient > & get_d2xyzdxideta () const
const std::vector< RealGradient > & get_d2xyzdxidzeta () const
const std::vector< RealGradient > & get_d2xyzdetadzeta () const
const std::vector< Real > & get_dxidx () const
const std::vector< Real > & get_dxidy () const
const std::vector< Real > & get_dxidz () const
const std::vector< Real > & get_detadx () const
const std::vector< Real > & get_detady () const
const std::vector< Real > & get_detadz () const
const std::vector< Real > & get_dzetadx () const
const std::vector< Real > & get_dzetady () const
const std::vector< Real > & get_dzetadz () const
const std::vector< std::vector
< Point > > & 
get_tangents () const
const std::vector< Point > & get_normals () const
const std::vector< Real > & get_curvatures () const
virtual void attach_quadrature_rule (QBase *q)=0
virtual unsigned int n_shape_functions () const =0
virtual unsigned int n_quadrature_points () const =0
ElemType get_type () const
unsigned int get_p_level () const
FEType get_fe_type () const
Order get_order () const
virtual FEContinuity get_continuity () const =0
virtual bool is_hierarchic () const =0
FEFamily get_family () const
const FEMapget_fe_map () const
void print_JxW (std::ostream &os) const
void print_xyz (std::ostream &os) const
void print_info (std::ostream &os) const

Static Public Member Functions

static UniquePtr< FEGenericBasebuild (const unsigned int dim, const FEType &type)
static UniquePtr< FEGenericBasebuild_InfFE (const unsigned int dim, const FEType &type)
static void compute_proj_constraints (DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
static void coarsened_dof_values (const NumericVector< Number > &global_vector, const DofMap &dof_map, const Elem *coarse_elem, DenseVector< Number > &coarse_dofs, const unsigned int var, const bool use_old_dof_indices=false)
static void compute_periodic_constraints (DofConstraints &constraints, DofMap &dof_map, const PeriodicBoundaries &boundaries, const MeshBase &mesh, const PointLocatorBase *point_locator, const unsigned int variable_number, const Elem *elem)
template<>
UniquePtr< FEGenericBase< Real > > build (const unsigned int dim, const FEType &fet)
static bool on_reference_element (const Point &p, const ElemType t, const Real eps=TOLERANCE)
static void get_refspace_nodes (const ElemType t, std::vector< Point > &nodes)
static void compute_node_constraints (NodeConstraints &constraints, const Elem *elem)
static void compute_periodic_node_constraints (NodeConstraints &constraints, const PeriodicBoundaries &boundaries, const MeshBase &mesh, const PointLocatorBase *point_locator, const Elem *elem)
static void print_info (std::ostream &out=libMesh::out)
static std::string get_info ()
static unsigned int n_objects ()
static void enable_print_counter_info ()
static void disable_print_counter_info ()

Protected Types

typedef std::map< std::string,
std::pair< unsigned int,
unsigned int > > 
Counts

Protected Member Functions

 FEGenericBase (const unsigned int dim, const FEType &fet)
virtual void init_base_shape_functions (const std::vector< Point > &qp, const Elem *e)=0
virtual void compute_shape_functions (const Elem *elem, const std::vector< Point > &qp)
virtual bool shapes_need_reinit () const =0
void increment_constructor_count (const std::string &name)
void increment_destructor_count (const std::string &name)

Protected Attributes

UniquePtr
< FETransformationBase
< OutputType > > 
_fe_trans
std::vector< std::vector
< OutputShape > > 
phi
std::vector< std::vector
< OutputGradient > > 
dphi
std::vector< std::vector
< OutputShape > > 
curl_phi
std::vector< std::vector
< OutputDivergence > > 
div_phi
std::vector< std::vector
< OutputShape > > 
dphidxi
std::vector< std::vector
< OutputShape > > 
dphideta
std::vector< std::vector
< OutputShape > > 
dphidzeta
std::vector< std::vector
< OutputShape > > 
dphidx
std::vector< std::vector
< OutputShape > > 
dphidy
std::vector< std::vector
< OutputShape > > 
dphidz
std::vector< std::vector
< OutputTensor > > 
d2phi
std::vector< std::vector
< OutputShape > > 
d2phidxi2
std::vector< std::vector
< OutputShape > > 
d2phidxideta
std::vector< std::vector
< OutputShape > > 
d2phidxidzeta
std::vector< std::vector
< OutputShape > > 
d2phideta2
std::vector< std::vector
< OutputShape > > 
d2phidetadzeta
std::vector< std::vector
< OutputShape > > 
d2phidzeta2
std::vector< std::vector
< OutputShape > > 
d2phidx2
std::vector< std::vector
< OutputShape > > 
d2phidxdy
std::vector< std::vector
< OutputShape > > 
d2phidxdz
std::vector< std::vector
< OutputShape > > 
d2phidy2
std::vector< std::vector
< OutputShape > > 
d2phidydz
std::vector< std::vector
< OutputShape > > 
d2phidz2
std::vector< OutputGradientdphase
std::vector< RealGradientdweight
std::vector< Realweight
UniquePtr< FEMap_fe_map
const unsigned int dim
bool calculations_started
bool calculate_phi
bool calculate_dphi
bool calculate_d2phi
bool calculate_curl_phi
bool calculate_div_phi
bool calculate_dphiref
const FEType fe_type
ElemType elem_type
unsigned int _p_level
QBaseqrule
bool shapes_on_quadrature

Static Protected Attributes

static Counts _counts
static Threads::atomic
< unsigned int > 
_n_objects
static Threads::spin_mutex _mutex
static bool _enable_print_counter = true

Friends

class InfFE
std::ostream & operator<< (std::ostream &os, const FEAbstract &fe)

Detailed Description

template<typename OutputType>
class libMesh::FEGenericBase< OutputType >

This class forms the foundation from which generic finite elements may be derived. In the current implementation the templated derived class FE offers a wide variety of commonly used finite element concepts. Check there for details.

Use the FEGenericBase<OutputType>::build() method to create an object of any of the derived classes which is compatible with OutputType.

Note that the amount of virtual members is kept to a minimum, and the sophisticated template scheme of FE is quite likely to offer acceptably fast code.

All calls to static members of the FE classes should be requested through the FEInterface. This interface class offers sort-of runtime polymorphism for the templated finite element classes. Even internal library classes, like DofMap, request the number of dof's through this interface class. Note that this also enables the co-existence of various element-based schemes. This class is well 'at the heart' of the library, so things in here should better remain unchanged.

Author:
Benjamin S. Kirk, 2002

Definition at line 102 of file fe_base.h.


Member Typedef Documentation

typedef std::map<std::string, std::pair<unsigned int, unsigned int> > libMesh::ReferenceCounter::Counts [protected, inherited]

Data structure to log the information. The log is identified by the class name.

Definition at line 113 of file reference_counter.h.

template<typename OutputType>
typedef TensorTools::DecrementRank<OutputShape>::type libMesh::FEGenericBase< OutputType >::OutputDivergence

Definition at line 139 of file fe_base.h.

template<typename OutputType>
typedef TensorTools::IncrementRank<OutputShape>::type libMesh::FEGenericBase< OutputType >::OutputGradient

Definition at line 137 of file fe_base.h.

template<typename OutputType>
typedef TensorTools::MakeNumber<OutputShape>::type libMesh::FEGenericBase< OutputType >::OutputNumber

Definition at line 140 of file fe_base.h.

template<typename OutputType>
typedef TensorTools::DecrementRank<OutputNumber>::type libMesh::FEGenericBase< OutputType >::OutputNumberDivergence

Definition at line 143 of file fe_base.h.

template<typename OutputType>
typedef TensorTools::IncrementRank<OutputNumber>::type libMesh::FEGenericBase< OutputType >::OutputNumberGradient

Definition at line 141 of file fe_base.h.

template<typename OutputType>
typedef TensorTools::IncrementRank<OutputNumberGradient>::type libMesh::FEGenericBase< OutputType >::OutputNumberTensor

Definition at line 142 of file fe_base.h.

template<typename OutputType>
typedef TensorTools::IncrementRank<OutputGradient>::type libMesh::FEGenericBase< OutputType >::OutputTensor

Definition at line 138 of file fe_base.h.


Constructor & Destructor Documentation

template<typename OutputType >
libMesh::FEGenericBase< OutputType >::FEGenericBase ( const unsigned int  dim,
const FEType fet 
) [inline, protected]

Constructor. Optionally initializes required data structures. Protected so that this base class cannot be explicitly instantiated.

Definition at line 673 of file fe_base.h.

                                                            :
  FEAbstract(d,fet),
  _fe_trans( FETransformationBase<OutputType>::build(fet) ),
  phi(),
  dphi(),
  curl_phi(),
  div_phi(),
  dphidxi(),
  dphideta(),
  dphidzeta(),
  dphidx(),
  dphidy(),
  dphidz()
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
  ,d2phi(),
  d2phidxi2(),
  d2phidxideta(),
  d2phidxidzeta(),
  d2phideta2(),
  d2phidetadzeta(),
  d2phidzeta2(),
  d2phidx2(),
  d2phidxdy(),
  d2phidxdz(),
  d2phidy2(),
  d2phidydz(),
  d2phidz2()
#endif
#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
  ,dphase(),
  dweight(),
  weight()
#endif
{
}
template<typename OutputType >
libMesh::FEGenericBase< OutputType >::~FEGenericBase ( ) [inline, virtual]

Destructor.

Definition at line 714 of file fe_base.h.

{
}

Member Function Documentation

template<>
UniquePtr< FEGenericBase< Real > > libMesh::FEGenericBase< Real >::build ( const unsigned int  dim,
const FEType type 
) [static]

Builds a specific finite element type. A UniquePtr<FEAbstract> is returned to prevent a memory leak. This way the user need not remember to delete the object.

Reimplemented from libMesh::FEAbstract.

Definition at line 184 of file fe_base.C.

References libMesh::BERNSTEIN, libMesh::CLOUGH, libMesh::FEType::family, libMesh::HERMITE, libMesh::HIERARCHIC, libMesh::L2_HIERARCHIC, libMesh::L2_LAGRANGE, libMesh::LAGRANGE, libMesh::MONOMIAL, libMesh::SCALAR, libMesh::SUBDIVISION, libMesh::SZABAB, and libMesh::XYZ.

{
  switch (dim)
    {
      // 0D
    case 0:
      {
        switch (fet.family)
          {
          case CLOUGH:
            return UniquePtr<FEBase>(new FE<0,CLOUGH>(fet));

          case HERMITE:
            return UniquePtr<FEBase>(new FE<0,HERMITE>(fet));

          case LAGRANGE:
            return UniquePtr<FEBase>(new FE<0,LAGRANGE>(fet));

          case L2_LAGRANGE:
            return UniquePtr<FEBase>(new FE<0,L2_LAGRANGE>(fet));

          case HIERARCHIC:
            return UniquePtr<FEBase>(new FE<0,HIERARCHIC>(fet));

          case L2_HIERARCHIC:
            return UniquePtr<FEBase>(new FE<0,L2_HIERARCHIC>(fet));

          case MONOMIAL:
            return UniquePtr<FEBase>(new FE<0,MONOMIAL>(fet));

#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
          case SZABAB:
            return UniquePtr<FEBase>(new FE<0,SZABAB>(fet));

          case BERNSTEIN:
            return UniquePtr<FEBase>(new FE<0,BERNSTEIN>(fet));
#endif

          case XYZ:
            return UniquePtr<FEBase>(new FEXYZ<0>(fet));

          case SCALAR:
            return UniquePtr<FEBase>(new FEScalar<0>(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }
      // 1D
    case 1:
      {
        switch (fet.family)
          {
          case CLOUGH:
            return UniquePtr<FEBase>(new FE<1,CLOUGH>(fet));

          case HERMITE:
            return UniquePtr<FEBase>(new FE<1,HERMITE>(fet));

          case LAGRANGE:
            return UniquePtr<FEBase>(new FE<1,LAGRANGE>(fet));

          case L2_LAGRANGE:
            return UniquePtr<FEBase>(new FE<1,L2_LAGRANGE>(fet));

          case HIERARCHIC:
            return UniquePtr<FEBase>(new FE<1,HIERARCHIC>(fet));

          case L2_HIERARCHIC:
            return UniquePtr<FEBase>(new FE<1,L2_HIERARCHIC>(fet));

          case MONOMIAL:
            return UniquePtr<FEBase>(new FE<1,MONOMIAL>(fet));

#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
          case SZABAB:
            return UniquePtr<FEBase>(new FE<1,SZABAB>(fet));

          case BERNSTEIN:
            return UniquePtr<FEBase>(new FE<1,BERNSTEIN>(fet));
#endif

          case XYZ:
            return UniquePtr<FEBase>(new FEXYZ<1>(fet));

          case SCALAR:
            return UniquePtr<FEBase>(new FEScalar<1>(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }


      // 2D
    case 2:
      {
        switch (fet.family)
          {
          case CLOUGH:
            return UniquePtr<FEBase>(new FE<2,CLOUGH>(fet));

          case HERMITE:
            return UniquePtr<FEBase>(new FE<2,HERMITE>(fet));

          case LAGRANGE:
            return UniquePtr<FEBase>(new FE<2,LAGRANGE>(fet));

          case L2_LAGRANGE:
            return UniquePtr<FEBase>(new FE<2,L2_LAGRANGE>(fet));

          case HIERARCHIC:
            return UniquePtr<FEBase>(new FE<2,HIERARCHIC>(fet));

          case L2_HIERARCHIC:
            return UniquePtr<FEBase>(new FE<2,L2_HIERARCHIC>(fet));

          case MONOMIAL:
            return UniquePtr<FEBase>(new FE<2,MONOMIAL>(fet));

#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
          case SZABAB:
            return UniquePtr<FEBase>(new FE<2,SZABAB>(fet));

          case BERNSTEIN:
            return UniquePtr<FEBase>(new FE<2,BERNSTEIN>(fet));
#endif

          case XYZ:
            return UniquePtr<FEBase>(new FEXYZ<2>(fet));

          case SCALAR:
            return UniquePtr<FEBase>(new FEScalar<2>(fet));

          case SUBDIVISION:
            return UniquePtr<FEBase>(new FESubdivision(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }


      // 3D
    case 3:
      {
        switch (fet.family)
          {
          case CLOUGH:
            libmesh_error_msg("ERROR: Clough-Tocher elements currently only support 1D and 2D");

          case HERMITE:
            return UniquePtr<FEBase>(new FE<3,HERMITE>(fet));

          case LAGRANGE:
            return UniquePtr<FEBase>(new FE<3,LAGRANGE>(fet));

          case L2_LAGRANGE:
            return UniquePtr<FEBase>(new FE<3,L2_LAGRANGE>(fet));

          case HIERARCHIC:
            return UniquePtr<FEBase>(new FE<3,HIERARCHIC>(fet));

          case L2_HIERARCHIC:
            return UniquePtr<FEBase>(new FE<3,L2_HIERARCHIC>(fet));

          case MONOMIAL:
            return UniquePtr<FEBase>(new FE<3,MONOMIAL>(fet));

#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
          case SZABAB:
            return UniquePtr<FEBase>(new FE<3,SZABAB>(fet));

          case BERNSTEIN:
            return UniquePtr<FEBase>(new FE<3,BERNSTEIN>(fet));
#endif

          case XYZ:
            return UniquePtr<FEBase>(new FEXYZ<3>(fet));

          case SCALAR:
            return UniquePtr<FEBase>(new FEScalar<3>(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }

    default:
      libmesh_error_msg("Invalid dimension dim = " << dim);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<FEBase>();
}
template<>
UniquePtr< FEGenericBase< RealGradient > > libMesh::FEGenericBase< RealGradient >::build ( const unsigned int  dim,
const FEType type 
)

Builds a specific finite element type. A UniquePtr<FEAbstract> is returned to prevent a memory leak. This way the user need not remember to delete the object.

Reimplemented from libMesh::FEAbstract.

Definition at line 385 of file fe_base.C.

References libMesh::FEType::family, libMesh::LAGRANGE_VEC, and libMesh::NEDELEC_ONE.

{
  switch (dim)
    {
      // 0D
    case 0:
      {
        switch (fet.family)
          {
          case LAGRANGE_VEC:
            return UniquePtr<FEVectorBase>(new FELagrangeVec<0>(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }
    case 1:
      {
        switch (fet.family)
          {
          case LAGRANGE_VEC:
            return UniquePtr<FEVectorBase>(new FELagrangeVec<1>(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }
    case 2:
      {
        switch (fet.family)
          {
          case LAGRANGE_VEC:
            return UniquePtr<FEVectorBase>(new FELagrangeVec<2>(fet));

          case NEDELEC_ONE:
            return UniquePtr<FEVectorBase>(new FENedelecOne<2>(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }
    case 3:
      {
        switch (fet.family)
          {
          case LAGRANGE_VEC:
            return UniquePtr<FEVectorBase>(new FELagrangeVec<3>(fet));

          case NEDELEC_ONE:
            return UniquePtr<FEVectorBase>(new FENedelecOne<3>(fet));

          default:
            libmesh_error_msg("ERROR: Bad FEType.family= " << fet.family);
          }
      }

    default:
      libmesh_error_msg("Invalid dimension dim = " << dim);
    } // switch(dim)

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<FEVectorBase>();
}
template<typename OutputType>
static UniquePtr<FEGenericBase> libMesh::FEGenericBase< OutputType >::build_InfFE ( const unsigned int  dim,
const FEType type 
) [static]

Builds a specific infinite element type. A UniquePtr<FEGenericBase> is returned to prevent a memory leak. This way the user need not remember to delete the object.

The build call will fail if the OutputShape of this class is not compatible with the output required for the requested type

template<>
UniquePtr< FEGenericBase< Real > > libMesh::FEGenericBase< Real >::build_InfFE ( const unsigned int  dim,
const FEType fet 
)

Definition at line 461 of file fe_base.C.

References libMesh::CARTESIAN, libMesh::FEType::inf_map, libMesh::INFINITE_MAP, libMesh::JACOBI_20_00, libMesh::JACOBI_30_00, libMesh::LAGRANGE, libMesh::LEGENDRE, and libMesh::FEType::radial_family.

{
  switch (dim)
    {

      // 1D
    case 1:
      {
        switch (fet.radial_family)
          {
          case INFINITE_MAP:
            libmesh_error_msg("ERROR: Can't build an infinite element with FEFamily = " << fet.radial_family);

          case JACOBI_20_00:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<1,JACOBI_20_00,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Can't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case JACOBI_30_00:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<1,JACOBI_30_00,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Can't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case LEGENDRE:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<1,LEGENDRE,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Can't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case LAGRANGE:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<1,LAGRANGE,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Can't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          default:
            libmesh_error_msg("ERROR: Bad FEType.radial_family= " << fet.radial_family);
          }
      }




      // 2D
    case 2:
      {
        switch (fet.radial_family)
          {
          case INFINITE_MAP:
            libmesh_error_msg("ERROR: Can't build an infinite element with FEFamily = " << fet.radial_family);

          case JACOBI_20_00:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<2,JACOBI_20_00,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case JACOBI_30_00:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<2,JACOBI_30_00,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case LEGENDRE:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<2,LEGENDRE,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case LAGRANGE:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<2,LAGRANGE,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          default:
            libmesh_error_msg("ERROR: Bad FEType.radial_family= " << fet.radial_family);
          }
      }




      // 3D
    case 3:
      {
        switch (fet.radial_family)
          {
          case INFINITE_MAP:
            libmesh_error_msg("ERROR: Don't build an infinite element with FEFamily = " << fet.radial_family);

          case JACOBI_20_00:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<3,JACOBI_20_00,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case JACOBI_30_00:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<3,JACOBI_30_00,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case LEGENDRE:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<3,LEGENDRE,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          case LAGRANGE:
            {
              switch (fet.inf_map)
                {
                case CARTESIAN:
                  return UniquePtr<FEBase>(new InfFE<3,LAGRANGE,CARTESIAN>(fet));

                default:
                  libmesh_error_msg("ERROR: Don't build an infinite element with InfMapType = " << fet.inf_map);
                }
            }

          default:
            libmesh_error_msg("ERROR: Bad FEType.radial_family= " << fet.radial_family);
          }
      }

    default:
      libmesh_error_msg("Invalid dimension dim = " << dim);
    }

  libmesh_error_msg("We'll never get here!");
  return UniquePtr<FEBase>();
}
template<>
UniquePtr< FEGenericBase< RealGradient > > libMesh::FEGenericBase< RealGradient >::build_InfFE ( const unsigned  int,
const FEType  
)

Definition at line 668 of file fe_base.C.

{
  // No vector types defined... YET.
  libmesh_not_implemented();
  return UniquePtr<FEVectorBase>();
}
template<typename OutputType >
void libMesh::FEGenericBase< OutputType >::coarsened_dof_values ( const NumericVector< Number > &  global_vector,
const DofMap dof_map,
const Elem coarse_elem,
DenseVector< Number > &  coarse_dofs,
const unsigned int  var,
const bool  use_old_dof_indices = false 
) [static]

Creates a local projection on coarse_elem, based on the DoF values in global_vector for it's children.

Definition at line 787 of file fe_base.C.

References std::abs(), libMesh::C_ONE, libMesh::Elem::child(), libMesh::DenseMatrix< T >::cholesky_solve(), libMesh::FEType::default_quadrature_rule(), libMesh::Elem::dim(), libMesh::DISCONTINUOUS, libMesh::DofMap::dof_indices(), libMesh::FEInterface::dofs_on_edge(), libMesh::FEInterface::dofs_on_side(), libMesh::TensorTools::inner_product(), libMesh::FEInterface::inverse_map(), libMesh::Elem::is_child_on_edge(), libMesh::Elem::is_child_on_side(), libMesh::Elem::is_vertex(), libMesh::libmesh_assert(), libMesh::Elem::max_descendant_p_level(), libMesh::Elem::n_children(), libMesh::FEInterface::n_dofs(), libMesh::FEInterface::n_dofs_at_node(), libMesh::Elem::n_edges(), n_nodes, libMesh::Elem::n_nodes(), libMesh::Elem::n_sides(), libMesh::DofMap::old_dof_indices(), libMesh::FEType::order, libMesh::Elem::p_level(), libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::TOLERANCE, libMesh::Elem::type(), libMesh::DofMap::variable_type(), libMesh::DenseMatrix< T >::zero(), libMesh::DenseVector< T >::zero(), and libMesh::zero.

Referenced by libMesh::JumpErrorEstimator::estimate_error(), and libMesh::ExactErrorEstimator::estimate_error().

{
  // Side/edge local DOF indices
  std::vector<unsigned int> new_side_dofs, old_side_dofs;

  // FIXME: what about 2D shells in 3D space?
  unsigned int dim = elem->dim();

  // We use local FE objects for now
  // FIXME: we should use more, external objects instead for efficiency
  const FEType& base_fe_type = dof_map.variable_type(var);
  UniquePtr<FEGenericBase<OutputShape> > fe
    (FEGenericBase<OutputShape>::build(dim, base_fe_type));
  UniquePtr<FEGenericBase<OutputShape> > fe_coarse
    (FEGenericBase<OutputShape>::build(dim, base_fe_type));

  UniquePtr<QBase> qrule     (base_fe_type.default_quadrature_rule(dim));
  UniquePtr<QBase> qedgerule (base_fe_type.default_quadrature_rule(1));
  UniquePtr<QBase> qsiderule (base_fe_type.default_quadrature_rule(dim-1));
  std::vector<Point> coarse_qpoints;

  // The values of the shape functions at the quadrature
  // points
  const std::vector<std::vector<OutputShape> >& phi_values =
    fe->get_phi();
  const std::vector<std::vector<OutputShape> >& phi_coarse =
    fe_coarse->get_phi();

  // The gradients of the shape functions at the quadrature
  // points on the child element.
  const std::vector<std::vector<OutputGradient> > *dphi_values =
    NULL;
  const std::vector<std::vector<OutputGradient> > *dphi_coarse =
    NULL;

  const FEContinuity cont = fe->get_continuity();

  if (cont == C_ONE)
    {
      const std::vector<std::vector<OutputGradient> >&
        ref_dphi_values = fe->get_dphi();
      dphi_values = &ref_dphi_values;
      const std::vector<std::vector<OutputGradient> >&
        ref_dphi_coarse = fe_coarse->get_dphi();
      dphi_coarse = &ref_dphi_coarse;
    }

  // The Jacobian * quadrature weight at the quadrature points
  const std::vector<Real>& JxW =
    fe->get_JxW();

  // The XYZ locations of the quadrature points on the
  // child element
  const std::vector<Point>& xyz_values =
    fe->get_xyz();



  FEType fe_type = base_fe_type, temp_fe_type;
  const ElemType elem_type = elem->type();
  fe_type.order = static_cast<Order>(fe_type.order +
                                     elem->max_descendant_p_level());

  // Number of nodes on parent element
  const unsigned int n_nodes = elem->n_nodes();

  // Number of dofs on parent element
  const unsigned int new_n_dofs =
    FEInterface::n_dofs(dim, fe_type, elem_type);

  // Fixed vs. free DoFs on edge/face projections
  std::vector<char> dof_is_fixed(new_n_dofs, false); // bools
  std::vector<int> free_dof(new_n_dofs, 0);

  DenseMatrix<Real> Ke;
  DenseVector<Number> Fe;
  Ue.resize(new_n_dofs); Ue.zero();


  // When coarsening, in general, we need a series of
  // projections to ensure a unique and continuous
  // solution.  We start by interpolating nodes, then
  // hold those fixed and project edges, then
  // hold those fixed and project faces, then
  // hold those fixed and project interiors

  // Copy node values first
  {
    std::vector<dof_id_type> node_dof_indices;
    if (use_old_dof_indices)
      dof_map.old_dof_indices (elem, node_dof_indices, var);
    else
      dof_map.dof_indices (elem, node_dof_indices, var);

    unsigned int current_dof = 0;
    for (unsigned int n=0; n!= n_nodes; ++n)
      {
        // FIXME: this should go through the DofMap,
        // not duplicate dof_indices code badly!
        const unsigned int my_nc =
          FEInterface::n_dofs_at_node (dim, fe_type,
                                       elem_type, n);
        if (!elem->is_vertex(n))
          {
            current_dof += my_nc;
            continue;
          }

        temp_fe_type = base_fe_type;
        // We're assuming here that child n shares vertex n,
        // which is wrong on non-simplices right now
        // ... but this code isn't necessary except on elements
        // where p refinement creates more vertex dofs; we have
        // no such elements yet.
        /*
          if (elem->child(n)->p_level() < elem->p_level())
          {
          temp_fe_type.order =
          static_cast<Order>(temp_fe_type.order +
          elem->child(n)->p_level());
          }
        */
        const unsigned int nc =
          FEInterface::n_dofs_at_node (dim, temp_fe_type,
                                       elem_type, n);
        for (unsigned int i=0; i!= nc; ++i)
          {
            Ue(current_dof) =
              old_vector(node_dof_indices[current_dof]);
            dof_is_fixed[current_dof] = true;
            current_dof++;
          }
      }
  }

  // In 3D, project any edge values next
  if (dim > 2 && cont != DISCONTINUOUS)
    for (unsigned int e=0; e != elem->n_edges(); ++e)
      {
        FEInterface::dofs_on_edge(elem, dim, fe_type,
                                  e, new_side_dofs);

        // Some edge dofs are on nodes and already
        // fixed, others are free to calculate
        unsigned int free_dofs = 0;
        for (unsigned int i=0; i !=
               new_side_dofs.size(); ++i)
          if (!dof_is_fixed[new_side_dofs[i]])
            free_dof[free_dofs++] = i;
        Ke.resize (free_dofs, free_dofs); Ke.zero();
        Fe.resize (free_dofs); Fe.zero();
        // The new edge coefficients
        DenseVector<Number> Uedge(free_dofs);

        // Add projection terms from each child sharing
        // this edge
        for (unsigned int c=0; c != elem->n_children();
             ++c)
          {
            if (!elem->is_child_on_edge(c,e))
              continue;
            Elem *child = elem->child(c);

            std::vector<dof_id_type> child_dof_indices;
            if (use_old_dof_indices)
              dof_map.old_dof_indices (child,
                                       child_dof_indices, var);
            else
              dof_map.dof_indices (child,
                                   child_dof_indices, var);
            const unsigned int child_n_dofs =
              cast_int<unsigned int>
              (child_dof_indices.size());

            temp_fe_type = base_fe_type;
            temp_fe_type.order =
              static_cast<Order>(temp_fe_type.order +
                                 child->p_level());

            FEInterface::dofs_on_edge(child, dim,
                                      temp_fe_type, e, old_side_dofs);

            // Initialize both child and parent FE data
            // on the child's edge
            fe->attach_quadrature_rule (qedgerule.get());
            fe->edge_reinit (child, e);
            const unsigned int n_qp = qedgerule->n_points();

            FEInterface::inverse_map (dim, fe_type, elem,
                                      xyz_values, coarse_qpoints);

            fe_coarse->reinit(elem, &coarse_qpoints);

            // Loop over the quadrature points
            for (unsigned int qp=0; qp<n_qp; qp++)
              {
                // solution value at the quadrature point
                OutputNumber fineval = libMesh::zero;
                // solution grad at the quadrature point
                OutputNumberGradient finegrad;

                // Sum the solution values * the DOF
                // values at the quadrature point to
                // get the solution value and gradient.
                for (unsigned int i=0; i<child_n_dofs;
                     i++)
                  {
                    fineval +=
                      (old_vector(child_dof_indices[i])*
                       phi_values[i][qp]);
                    if (cont == C_ONE)
                      finegrad += (*dphi_values)[i][qp] *
                        old_vector(child_dof_indices[i]);
                  }

                // Form edge projection matrix
                for (unsigned int sidei=0, freei=0;
                     sidei != new_side_dofs.size();
                     ++sidei)
                  {
                    unsigned int i = new_side_dofs[sidei];
                    // fixed DoFs aren't test functions
                    if (dof_is_fixed[i])
                      continue;
                    for (unsigned int sidej=0, freej=0;
                         sidej != new_side_dofs.size();
                         ++sidej)
                      {
                        unsigned int j =
                          new_side_dofs[sidej];
                        if (dof_is_fixed[j])
                          Fe(freei) -=
                            TensorTools::inner_product(phi_coarse[i][qp],
                                                       phi_coarse[j][qp]) *
                            JxW[qp] * Ue(j);
                        else
                          Ke(freei,freej) +=
                            TensorTools::inner_product(phi_coarse[i][qp],
                                                       phi_coarse[j][qp]) *
                            JxW[qp];
                        if (cont == C_ONE)
                          {
                            if (dof_is_fixed[j])
                              Fe(freei) -=
                                TensorTools::inner_product((*dphi_coarse)[i][qp],
                                                           (*dphi_coarse)[j][qp]) *
                                JxW[qp] * Ue(j);
                            else
                              Ke(freei,freej) +=
                                TensorTools::inner_product((*dphi_coarse)[i][qp],
                                                           (*dphi_coarse)[j][qp]) *
                                JxW[qp];
                          }
                        if (!dof_is_fixed[j])
                          freej++;
                      }
                    Fe(freei) += TensorTools::inner_product(phi_coarse[i][qp],
                                                            fineval) * JxW[qp];
                    if (cont == C_ONE)
                      Fe(freei) +=
                        TensorTools::inner_product(finegrad, (*dphi_coarse)[i][qp]) * JxW[qp];
                    freei++;
                  }
              }
          }
        Ke.cholesky_solve(Fe, Uedge);

        // Transfer new edge solutions to element
        for (unsigned int i=0; i != free_dofs; ++i)
          {
            Number &ui = Ue(new_side_dofs[free_dof[i]]);
            libmesh_assert(std::abs(ui) < TOLERANCE ||
                           std::abs(ui - Uedge(i)) < TOLERANCE);
            ui = Uedge(i);
            dof_is_fixed[new_side_dofs[free_dof[i]]] =
              true;
          }
      }

  // Project any side values (edges in 2D, faces in 3D)
  if (dim > 1 && cont != DISCONTINUOUS)
    for (unsigned int s=0; s != elem->n_sides(); ++s)
      {
        FEInterface::dofs_on_side(elem, dim, fe_type,
                                  s, new_side_dofs);

        // Some side dofs are on nodes/edges and already
        // fixed, others are free to calculate
        unsigned int free_dofs = 0;
        for (unsigned int i=0; i !=
               new_side_dofs.size(); ++i)
          if (!dof_is_fixed[new_side_dofs[i]])
            free_dof[free_dofs++] = i;
        Ke.resize (free_dofs, free_dofs); Ke.zero();
        Fe.resize (free_dofs); Fe.zero();
        // The new side coefficients
        DenseVector<Number> Uside(free_dofs);

        // Add projection terms from each child sharing
        // this side
        for (unsigned int c=0; c != elem->n_children();
             ++c)
          {
            if (!elem->is_child_on_side(c,s))
              continue;
            Elem *child = elem->child(c);

            std::vector<dof_id_type> child_dof_indices;
            if (use_old_dof_indices)
              dof_map.old_dof_indices (child,
                                       child_dof_indices, var);
            else
              dof_map.dof_indices (child,
                                   child_dof_indices, var);
            const unsigned int child_n_dofs =
              cast_int<unsigned int>
              (child_dof_indices.size());

            temp_fe_type = base_fe_type;
            temp_fe_type.order =
              static_cast<Order>(temp_fe_type.order +
                                 child->p_level());

            FEInterface::dofs_on_side(child, dim,
                                      temp_fe_type, s, old_side_dofs);

            // Initialize both child and parent FE data
            // on the child's side
            fe->attach_quadrature_rule (qsiderule.get());
            fe->reinit (child, s);
            const unsigned int n_qp = qsiderule->n_points();

            FEInterface::inverse_map (dim, fe_type, elem,
                                      xyz_values, coarse_qpoints);

            fe_coarse->reinit(elem, &coarse_qpoints);

            // Loop over the quadrature points
            for (unsigned int qp=0; qp<n_qp; qp++)
              {
                // solution value at the quadrature point
                OutputNumber fineval = libMesh::zero;
                // solution grad at the quadrature point
                OutputNumberGradient finegrad;

                // Sum the solution values * the DOF
                // values at the quadrature point to
                // get the solution value and gradient.
                for (unsigned int i=0; i<child_n_dofs;
                     i++)
                  {
                    fineval +=
                      old_vector(child_dof_indices[i]) *
                      phi_values[i][qp];
                    if (cont == C_ONE)
                      finegrad += (*dphi_values)[i][qp] *
                        old_vector(child_dof_indices[i]);
                  }

                // Form side projection matrix
                for (unsigned int sidei=0, freei=0;
                     sidei != new_side_dofs.size();
                     ++sidei)
                  {
                    unsigned int i = new_side_dofs[sidei];
                    // fixed DoFs aren't test functions
                    if (dof_is_fixed[i])
                      continue;
                    for (unsigned int sidej=0, freej=0;
                         sidej != new_side_dofs.size();
                         ++sidej)
                      {
                        unsigned int j =
                          new_side_dofs[sidej];
                        if (dof_is_fixed[j])
                          Fe(freei) -=
                            TensorTools::inner_product(phi_coarse[i][qp],
                                                       phi_coarse[j][qp]) *
                            JxW[qp] * Ue(j);
                        else
                          Ke(freei,freej) +=
                            TensorTools::inner_product(phi_coarse[i][qp],
                                                       phi_coarse[j][qp]) *
                            JxW[qp];
                        if (cont == C_ONE)
                          {
                            if (dof_is_fixed[j])
                              Fe(freei) -=
                                TensorTools::inner_product((*dphi_coarse)[i][qp],
                                                           (*dphi_coarse)[j][qp]) *
                                JxW[qp] * Ue(j);
                            else
                              Ke(freei,freej) +=
                                TensorTools::inner_product((*dphi_coarse)[i][qp],
                                                           (*dphi_coarse)[j][qp]) *
                                JxW[qp];
                          }
                        if (!dof_is_fixed[j])
                          freej++;
                      }
                    Fe(freei) += TensorTools::inner_product(fineval, phi_coarse[i][qp]) * JxW[qp];
                    if (cont == C_ONE)
                      Fe(freei) +=
                        TensorTools::inner_product(finegrad, (*dphi_coarse)[i][qp]) * JxW[qp];
                    freei++;
                  }
              }
          }
        Ke.cholesky_solve(Fe, Uside);

        // Transfer new side solutions to element
        for (unsigned int i=0; i != free_dofs; ++i)
          {
            Number &ui = Ue(new_side_dofs[free_dof[i]]);
            libmesh_assert(std::abs(ui) < TOLERANCE ||
                           std::abs(ui - Uside(i)) < TOLERANCE);
            ui = Uside(i);
            dof_is_fixed[new_side_dofs[free_dof[i]]] =
              true;
          }
      }

  // Project the interior values, finally

  // Some interior dofs are on nodes/edges/sides and
  // already fixed, others are free to calculate
  unsigned int free_dofs = 0;
  for (unsigned int i=0; i != new_n_dofs; ++i)
    if (!dof_is_fixed[i])
      free_dof[free_dofs++] = i;
  Ke.resize (free_dofs, free_dofs); Ke.zero();
  Fe.resize (free_dofs); Fe.zero();
  // The new interior coefficients
  DenseVector<Number> Uint(free_dofs);

  // Add projection terms from each child
  for (unsigned int c=0; c != elem->n_children(); ++c)
    {
      Elem *child = elem->child(c);

      std::vector<dof_id_type> child_dof_indices;
      if (use_old_dof_indices)
        dof_map.old_dof_indices (child,
                                 child_dof_indices, var);
      else
        dof_map.dof_indices (child,
                             child_dof_indices, var);
      const unsigned int child_n_dofs =
        cast_int<unsigned int>
        (child_dof_indices.size());

      // Initialize both child and parent FE data
      // on the child's quadrature points
      fe->attach_quadrature_rule (qrule.get());
      fe->reinit (child);
      const unsigned int n_qp = qrule->n_points();

      FEInterface::inverse_map (dim, fe_type, elem,
                                xyz_values, coarse_qpoints);

      fe_coarse->reinit(elem, &coarse_qpoints);

      // Loop over the quadrature points
      for (unsigned int qp=0; qp<n_qp; qp++)
        {
          // solution value at the quadrature point
          OutputNumber fineval = libMesh::zero;
          // solution grad at the quadrature point
          OutputNumberGradient finegrad;

          // Sum the solution values * the DOF
          // values at the quadrature point to
          // get the solution value and gradient.
          for (unsigned int i=0; i<child_n_dofs; i++)
            {
              fineval +=
                (old_vector(child_dof_indices[i]) *
                 phi_values[i][qp]);
              if (cont == C_ONE)
                finegrad += (*dphi_values)[i][qp] *
                  old_vector(child_dof_indices[i]);
            }

          // Form interior projection matrix
          for (unsigned int i=0, freei=0;
               i != new_n_dofs; ++i)
            {
              // fixed DoFs aren't test functions
              if (dof_is_fixed[i])
                continue;
              for (unsigned int j=0, freej=0; j !=
                     new_n_dofs; ++j)
                {
                  if (dof_is_fixed[j])
                    Fe(freei) -=
                      TensorTools::inner_product(phi_coarse[i][qp],
                                                 phi_coarse[j][qp]) *
                      JxW[qp] * Ue(j);
                  else
                    Ke(freei,freej) +=
                      TensorTools::inner_product(phi_coarse[i][qp],
                                                 phi_coarse[j][qp]) *
                      JxW[qp];
                  if (cont == C_ONE)
                    {
                      if (dof_is_fixed[j])
                        Fe(freei) -=
                          TensorTools::inner_product((*dphi_coarse)[i][qp],
                                                     (*dphi_coarse)[j][qp]) *
                          JxW[qp] * Ue(j);
                      else
                        Ke(freei,freej) +=
                          TensorTools::inner_product((*dphi_coarse)[i][qp],
                                                     (*dphi_coarse)[j][qp]) *
                          JxW[qp];
                    }
                  if (!dof_is_fixed[j])
                    freej++;
                }
              Fe(freei) += TensorTools::inner_product(phi_coarse[i][qp], fineval) *
                JxW[qp];
              if (cont == C_ONE)
                Fe(freei) += TensorTools::inner_product(finegrad, (*dphi_coarse)[i][qp]) * JxW[qp];
              freei++;
            }
        }
    }
  Ke.cholesky_solve(Fe, Uint);

  // Transfer new interior solutions to element
  for (unsigned int i=0; i != free_dofs; ++i)
    {
      Number &ui = Ue(free_dof[i]);
      libmesh_assert(std::abs(ui) < TOLERANCE ||
                     std::abs(ui - Uint(i)) < TOLERANCE);
      ui = Uint(i);
      // We should be fixing all dofs by now; no need to keep track of
      // that unless we're debugging
#ifndef NDEBUG
      dof_is_fixed[free_dof[i]] = true;
#endif
    }

#ifndef NDEBUG
  // Make sure every DoF got reached!
  for (unsigned int i=0; i != new_n_dofs; ++i)
    libmesh_assert(dof_is_fixed[i]);
#endif
}
void libMesh::FEAbstract::compute_node_constraints ( NodeConstraints constraints,
const Elem elem 
) [static, inherited]

Computes the nodal constraint contributions (for non-conforming adapted meshes), using Lagrange geometry

Definition at line 788 of file fe_abstract.C.

References std::abs(), libMesh::Elem::build_side(), libMesh::Elem::default_order(), libMesh::Elem::dim(), libMesh::FEAbstract::fe_type, libMesh::FEInterface::inverse_map(), libMesh::LAGRANGE, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::FEInterface::n_dofs(), libMesh::Elem::n_sides(), libMesh::Elem::neighbor(), libMesh::Elem::parent(), libMesh::Real, libMesh::remote_elem, libMesh::FEInterface::shape(), libMesh::Threads::spin_mtx, and libMesh::Elem::subactive().

{
  libmesh_assert(elem);

  const unsigned int Dim = elem->dim();

  // Only constrain elements in 2,3D.
  if (Dim == 1)
    return;

  // Only constrain active and ancestor elements
  if (elem->subactive())
    return;

  // We currently always use LAGRANGE mappings for geometry
  const FEType fe_type(elem->default_order(), LAGRANGE);

  std::vector<const Node*> my_nodes, parent_nodes;

  // Look at the element faces.  Check to see if we need to
  // build constraints.
  for (unsigned int s=0; s<elem->n_sides(); s++)
    if (elem->neighbor(s) != NULL &&
        elem->neighbor(s) != remote_elem)
      if (elem->neighbor(s)->level() < elem->level()) // constrain dofs shared between
        {                                                     // this element and ones coarser
          // than this element.
          // Get pointers to the elements of interest and its parent.
          const Elem* parent = elem->parent();

          // This can't happen...  Only level-0 elements have NULL
          // parents, and no level-0 elements can be at a higher
          // level than their neighbors!
          libmesh_assert(parent);

          const UniquePtr<Elem> my_side     (elem->build_side(s));
          const UniquePtr<Elem> parent_side (parent->build_side(s));

          const unsigned int n_side_nodes = my_side->n_nodes();

          my_nodes.clear();
          my_nodes.reserve (n_side_nodes);
          parent_nodes.clear();
          parent_nodes.reserve (n_side_nodes);

          for (unsigned int n=0; n != n_side_nodes; ++n)
            my_nodes.push_back(my_side->get_node(n));

          for (unsigned int n=0; n != n_side_nodes; ++n)
            parent_nodes.push_back(parent_side->get_node(n));

          for (unsigned int my_side_n=0;
               my_side_n < n_side_nodes;
               my_side_n++)
            {
              libmesh_assert_less (my_side_n, FEInterface::n_dofs(Dim-1, fe_type, my_side->type()));

              const Node* my_node = my_nodes[my_side_n];

              // The support point of the DOF
              const Point& support_point = *my_node;

              // Figure out where my node lies on their reference element.
              const Point mapped_point = FEInterface::inverse_map(Dim-1, fe_type,
                                                                  parent_side.get(),
                                                                  support_point);

              // Compute the parent's side shape function values.
              for (unsigned int their_side_n=0;
                   their_side_n < n_side_nodes;
                   their_side_n++)
                {
                  libmesh_assert_less (their_side_n, FEInterface::n_dofs(Dim-1, fe_type, parent_side->type()));

                  const Node* their_node = parent_nodes[their_side_n];
                  libmesh_assert(their_node);

                  const Real their_value = FEInterface::shape(Dim-1,
                                                              fe_type,
                                                              parent_side->type(),
                                                              their_side_n,
                                                              mapped_point);

                  const Real their_mag = std::abs(their_value);
#ifdef DEBUG
                  // Protect for the case u_i ~= u_j,
                  // in which case i better equal j.
                  if (their_mag > 0.999)
                    {
                      libmesh_assert_equal_to (my_node, their_node);
                      libmesh_assert_less (std::abs(their_value - 1.), 0.001);
                    }
                  else
#endif
                    // To make nodal constraints useful for constructing
                    // sparsity patterns faster, we need to get EVERY
                    // POSSIBLE constraint coupling identified, even if
                    // there is no coupling in the isoparametric
                    // Lagrange case.
                    if (their_mag < 1.e-5)
                      {
                        // since we may be running this method concurrently
                        // on multiple threads we need to acquire a lock
                        // before modifying the shared constraint_row object.
                        Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                        // A reference to the constraint row.
                        NodeConstraintRow& constraint_row = constraints[my_node].first;

                        constraint_row.insert(std::make_pair (their_node,
                                                              0.));
                      }
                  // To get nodal coordinate constraints right, only
                  // add non-zero and non-identity values for Lagrange
                  // basis functions.
                    else // (1.e-5 <= their_mag <= .999)
                      {
                        // since we may be running this method concurrently
                        // on multiple threads we need to acquire a lock
                        // before modifying the shared constraint_row object.
                        Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                        // A reference to the constraint row.
                        NodeConstraintRow& constraint_row = constraints[my_node].first;

                        constraint_row.insert(std::make_pair (their_node,
                                                              their_value));
                      }
                }
            }
        }
}
template<typename OutputType >
void libMesh::FEGenericBase< OutputType >::compute_periodic_constraints ( DofConstraints constraints,
DofMap dof_map,
const PeriodicBoundaries boundaries,
const MeshBase mesh,
const PointLocatorBase point_locator,
const unsigned int  variable_number,
const Elem elem 
) [static]

Computes the constraint matrix contributions (for meshes with periodic boundary conditions) corresponding to variable number var_number, using generic projections.

Definition at line 1628 of file fe_base.C.

References std::abs(), libMesh::TypeVector< T >::absolute_fuzzy_equals(), libMesh::Elem::active(), libMesh::PeriodicBoundaries::boundary(), libMesh::BoundaryInfo::boundary_ids(), libMesh::C_ONE, libMesh::C_ZERO, libMesh::DenseMatrix< T >::cholesky_solve(), libMesh::DofMap::constrain_p_dofs(), libMesh::FEType::default_quadrature_order(), libMesh::Elem::dim(), libMesh::DISCONTINUOUS, libMesh::DofMap::dof_indices(), libMesh::DofObject::dof_number(), libMesh::FEInterface::dofs_on_side(), libMesh::MeshBase::get_boundary_info(), libMesh::PeriodicBoundaryBase::get_corresponding_pos(), libMesh::Elem::get_node(), libMesh::Elem::hmin(), libMesh::DofObject::id(), libMesh::TensorTools::inner_product(), libMesh::DofObject::invalid_id, libMesh::invalid_uint, libMesh::FEInterface::inverse_map(), libMesh::DofMap::is_constrained_dof(), libMesh::Elem::is_edge(), libMesh::Elem::is_face(), libMesh::PeriodicBoundaryBase::is_my_variable(), libMesh::Elem::is_node_on_edge(), libMesh::Elem::is_node_on_side(), libMesh::Elem::is_vertex(), libMesh::Elem::level(), libMesh::libmesh_assert(), std::min(), libMesh::Elem::min_p_level_by_neighbor(), libMesh::DofObject::n_comp(), libMesh::Elem::n_edges(), libMesh::Elem::n_nodes(), libMesh::Elem::n_sides(), libMesh::PeriodicBoundaries::neighbor(), libMesh::Elem::neighbor(), libMesh::Elem::p_level(), libMesh::PeriodicBoundaryBase::pairedboundary, libMesh::Real, libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::BoundaryInfo::side_with_boundary_id(), libMesh::Threads::spin_mtx, libMesh::swap(), libMesh::DofMap::sys_number(), libMesh::TOLERANCE, and libMesh::DofMap::variable_type().

{
  // Only bother if we truly have periodic boundaries
  if (boundaries.empty())
    return;

  libmesh_assert(elem);

  // Only constrain active elements with this method
  if (!elem->active())
    return;

  const unsigned int Dim = elem->dim();

  // We need sys_number and variable_number for DofObject methods
  // later
  const unsigned int sys_number = dof_map.sys_number();

  const FEType& base_fe_type = dof_map.variable_type(variable_number);

  // Construct FE objects for this element and its pseudo-neighbors.
  UniquePtr<FEGenericBase<OutputShape> > my_fe
    (FEGenericBase<OutputShape>::build(Dim, base_fe_type));
  const FEContinuity cont = my_fe->get_continuity();

  // We don't need to constrain discontinuous elements
  if (cont == DISCONTINUOUS)
    return;
  libmesh_assert (cont == C_ZERO || cont == C_ONE);

  // We'll use element size to generate relative tolerances later
  const Real primary_hmin = elem->hmin();

  UniquePtr<FEGenericBase<OutputShape> > neigh_fe
    (FEGenericBase<OutputShape>::build(Dim, base_fe_type));

  QGauss my_qface(Dim-1, base_fe_type.default_quadrature_order());
  my_fe->attach_quadrature_rule (&my_qface);
  std::vector<Point> neigh_qface;

  const std::vector<Real>& JxW = my_fe->get_JxW();
  const std::vector<Point>& q_point = my_fe->get_xyz();
  const std::vector<std::vector<OutputShape> >& phi = my_fe->get_phi();
  const std::vector<std::vector<OutputShape> >& neigh_phi =
    neigh_fe->get_phi();
  const std::vector<Point> *face_normals = NULL;
  const std::vector<std::vector<OutputGradient> > *dphi = NULL;
  const std::vector<std::vector<OutputGradient> > *neigh_dphi = NULL;
  std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
  std::vector<unsigned int> my_side_dofs, neigh_side_dofs;

  if (cont != C_ZERO)
    {
      const std::vector<Point>& ref_face_normals =
        my_fe->get_normals();
      face_normals = &ref_face_normals;
      const std::vector<std::vector<OutputGradient> >& ref_dphi =
        my_fe->get_dphi();
      dphi = &ref_dphi;
      const std::vector<std::vector<OutputGradient> >& ref_neigh_dphi =
        neigh_fe->get_dphi();
      neigh_dphi = &ref_neigh_dphi;
    }

  DenseMatrix<Real> Ke;
  DenseVector<Real> Fe;
  std::vector<DenseVector<Real> > Ue;

  // Look at the element faces.  Check to see if we need to
  // build constraints.
  for (unsigned short int s=0; s<elem->n_sides(); s++)
    {
      if (elem->neighbor(s))
        continue;

      const std::vector<boundary_id_type>& bc_ids =
        mesh.get_boundary_info().boundary_ids (elem, s);
      for (std::vector<boundary_id_type>::const_iterator id_it=bc_ids.begin(); id_it!=bc_ids.end(); ++id_it)
        {
          const boundary_id_type boundary_id = *id_it;
          const PeriodicBoundaryBase *periodic = boundaries.boundary(boundary_id);
          if (periodic && periodic->is_my_variable(variable_number))
            {
              libmesh_assert(point_locator);

              // Get pointers to the element's neighbor.
              const Elem* neigh = boundaries.neighbor(boundary_id, *point_locator, elem, s);

              if (neigh == NULL)
                libmesh_error_msg("PeriodicBoundaries point locator object returned NULL!");

              // periodic (and possibly h refinement) constraints:
              // constrain dofs shared between
              // this element and ones as coarse
              // as or coarser than this element.
              if (neigh->level() <= elem->level())
                {
                  unsigned int s_neigh =
                    mesh.get_boundary_info().side_with_boundary_id(neigh, periodic->pairedboundary);
                  libmesh_assert_not_equal_to (s_neigh, libMesh::invalid_uint);

#ifdef LIBMESH_ENABLE_AMR
                  // Find the minimum p level; we build the h constraint
                  // matrix with this and then constrain away all higher p
                  // DoFs.
                  libmesh_assert(neigh->active());
                  const unsigned int min_p_level =
                    std::min(elem->p_level(), neigh->p_level());

                  // we may need to make the FE objects reinit with the
                  // minimum shared p_level
                  // FIXME - I hate using const_cast<> and avoiding
                  // accessor functions; there's got to be a
                  // better way to do this!
                  const unsigned int old_elem_level = elem->p_level();
                  if (old_elem_level != min_p_level)
                    (const_cast<Elem *>(elem))->hack_p_level(min_p_level);
                  const unsigned int old_neigh_level = neigh->p_level();
                  if (old_neigh_level != min_p_level)
                    (const_cast<Elem *>(neigh))->hack_p_level(min_p_level);
#endif // #ifdef LIBMESH_ENABLE_AMR

                  // We can do a projection with a single integration,
                  // due to the assumption of nested finite element
                  // subspaces.
                  // FIXME: it might be more efficient to do nodes,
                  // then edges, then side, to reduce the size of the
                  // Cholesky factorization(s)
                  my_fe->reinit(elem, s);

                  dof_map.dof_indices (elem, my_dof_indices,
                                       variable_number);
                  dof_map.dof_indices (neigh, neigh_dof_indices,
                                       variable_number);

                  const unsigned int n_qp = my_qface.n_points();

                  // Translate the quadrature points over to the
                  // neighbor's boundary
                  std::vector<Point> neigh_point(q_point.size());
                  for (unsigned int i=0; i != neigh_point.size(); ++i)
                    neigh_point[i] = periodic->get_corresponding_pos(q_point[i]);

                  FEInterface::inverse_map (Dim, base_fe_type, neigh,
                                            neigh_point, neigh_qface);

                  neigh_fe->reinit(neigh, &neigh_qface);

                  // We're only concerned with DOFs whose values (and/or first
                  // derivatives for C1 elements) are supported on side nodes
                  FEInterface::dofs_on_side(elem, Dim, base_fe_type, s, my_side_dofs);
                  FEInterface::dofs_on_side(neigh, Dim, base_fe_type, s_neigh, neigh_side_dofs);

                  // We're done with functions that examine Elem::p_level(),
                  // so let's unhack those levels
#ifdef LIBMESH_ENABLE_AMR
                  if (elem->p_level() != old_elem_level)
                    (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
                  if (neigh->p_level() != old_neigh_level)
                    (const_cast<Elem *>(neigh))->hack_p_level(old_neigh_level);
#endif // #ifdef LIBMESH_ENABLE_AMR

                  const unsigned int n_side_dofs =
                    cast_int<unsigned int>
                    (my_side_dofs.size());
                  libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());

                  Ke.resize (n_side_dofs, n_side_dofs);
                  Ue.resize(n_side_dofs);

                  // Form the projection matrix, (inner product of fine basis
                  // functions against fine test functions)
                  for (unsigned int is = 0; is != n_side_dofs; ++is)
                    {
                      const unsigned int i = my_side_dofs[is];
                      for (unsigned int js = 0; js != n_side_dofs; ++js)
                        {
                          const unsigned int j = my_side_dofs[js];
                          for (unsigned int qp = 0; qp != n_qp; ++qp)
                            {
                              Ke(is,js) += JxW[qp] *
                                TensorTools::inner_product(phi[i][qp],
                                                           phi[j][qp]);
                              if (cont != C_ZERO)
                                Ke(is,js) += JxW[qp] *
                                  TensorTools::inner_product((*dphi)[i][qp] *
                                                             (*face_normals)[qp],
                                                             (*dphi)[j][qp] *
                                                             (*face_normals)[qp]);
                            }
                        }
                    }

                  // Form the right hand sides, (inner product of coarse basis
                  // functions against fine test functions)
                  for (unsigned int is = 0; is != n_side_dofs; ++is)
                    {
                      const unsigned int i = neigh_side_dofs[is];
                      Fe.resize (n_side_dofs);
                      for (unsigned int js = 0; js != n_side_dofs; ++js)
                        {
                          const unsigned int j = my_side_dofs[js];
                          for (unsigned int qp = 0; qp != n_qp; ++qp)
                            {
                              Fe(js) += JxW[qp] *
                                TensorTools::inner_product(neigh_phi[i][qp],
                                                           phi[j][qp]);
                              if (cont != C_ZERO)
                                Fe(js) += JxW[qp] *
                                  TensorTools::inner_product((*neigh_dphi)[i][qp] *
                                                             (*face_normals)[qp],
                                                             (*dphi)[j][qp] *
                                                             (*face_normals)[qp]);
                            }
                        }
                      Ke.cholesky_solve(Fe, Ue[is]);
                    }

                  // Make sure we're not adding recursive constraints
                  // due to the redundancy in the way we add periodic
                  // boundary constraints
                  //
                  // In order for this to work while threaded or on
                  // distributed meshes, we need a rigorous way to
                  // avoid recursive constraints.  Here it is:
                  //
                  // For vertex DoFs, if there is a "prior" element
                  // (i.e. a coarser element or an equally refined
                  // element with a lower id) on this boundary which
                  // contains the vertex point, then we will avoid
                  // generating constraints; the prior element (or
                  // something prior to it) may do so.  If we are the
                  // most prior (or "primary") element on this
                  // boundary sharing this point, then we look at the
                  // boundary periodic to us, we find the primary
                  // element there, and if that primary is coarser or
                  // equal-but-lower-id, then our vertex dofs are
                  // constrained in terms of that element.
                  //
                  // For edge DoFs, if there is a coarser element
                  // on this boundary sharing this edge, then we will
                  // avoid generating constraints (we will be
                  // constrained indirectly via AMR constraints
                  // connecting us to the coarser element's DoFs).  If
                  // we are the coarsest element sharing this edge,
                  // then we generate constraints if and only if we
                  // are finer than the coarsest element on the
                  // boundary periodic to us sharing the corresponding
                  // periodic edge, or if we are at equal level but
                  // our edge nodes have higher ids than the periodic
                  // edge nodes (sorted from highest to lowest, then
                  // compared lexicographically)
                  //
                  // For face DoFs, we generate constraints if we are
                  // finer than our periodic neighbor, or if we are at
                  // equal level but our element id is higher than its
                  // element id.
                  //
                  // If the primary neighbor is also the current elem
                  // (a 1-element-thick mesh) then we choose which
                  // vertex dofs to constrain via lexicographic
                  // ordering on point locations

                  // FIXME: This code doesn't yet properly handle
                  // cases where multiple different periodic BCs
                  // intersect.
                  std::set<dof_id_type> my_constrained_dofs;

                  for (unsigned int n = 0; n != elem->n_nodes(); ++n)
                    {
                      if (!elem->is_node_on_side(n,s))
                        continue;

                      const Node* my_node = elem->get_node(n);

                      if (elem->is_vertex(n))
                        {
                          // Find all boundary ids that include this
                          // point and have periodic boundary
                          // conditions for this variable
                          std::set<boundary_id_type> point_bcids;

                          for (unsigned int new_s = 0; new_s !=
                                 elem->n_sides(); ++new_s)
                            {
                              if (!elem->is_node_on_side(n,new_s))
                                continue;

                              const std::vector<boundary_id_type> new_bc_ids =
                                mesh.get_boundary_info().boundary_ids (elem, s);
                              for (std::vector<boundary_id_type>::const_iterator
                                     new_id_it=new_bc_ids.begin(); new_id_it!=new_bc_ids.end(); ++new_id_it)
                                {
                                  const boundary_id_type new_boundary_id = *new_id_it;
                                  const PeriodicBoundaryBase *new_periodic = boundaries.boundary(new_boundary_id);
                                  if (new_periodic && new_periodic->is_my_variable(variable_number))
                                    {
                                      point_bcids.insert(new_boundary_id);
                                    }
                                }
                            }

                          // See if this vertex has point neighbors to
                          // defer to
                          if (primary_boundary_point_neighbor
                              (elem, *my_node, mesh.get_boundary_info(), point_bcids)
                              != elem)
                            continue;

                          // Find the complementary boundary id set
                          std::set<boundary_id_type> point_pairedids;
                          for (std::set<boundary_id_type>::const_iterator i =
                                 point_bcids.begin(); i != point_bcids.end(); ++i)
                            {
                              const boundary_id_type new_boundary_id = *i;
                              const PeriodicBoundaryBase *new_periodic = boundaries.boundary(new_boundary_id);
                              point_pairedids.insert(new_periodic->pairedboundary);
                            }

                          // What do we want to constrain against?
                          const Elem* primary_elem = NULL;
                          const Elem* main_neigh = NULL;
                          Point main_pt = *my_node,
                            primary_pt = *my_node;

                          for (std::set<boundary_id_type>::const_iterator i =
                                 point_bcids.begin(); i != point_bcids.end(); ++i)
                            {
                              // Find the corresponding periodic point and
                              // its primary neighbor
                              const boundary_id_type new_boundary_id = *i;
                              const PeriodicBoundaryBase *new_periodic = boundaries.boundary(new_boundary_id);

                              const Point neigh_pt =
                                new_periodic->get_corresponding_pos(*my_node);

                              // If the point is getting constrained
                              // to itself by this PBC then we don't
                              // generate any constraints
                              if (neigh_pt.absolute_fuzzy_equals
                                  (*my_node, primary_hmin*TOLERANCE))
                                continue;

                              // Otherwise we'll have a constraint in
                              // one direction or another
                              if (!primary_elem)
                                primary_elem = elem;

                              const Elem *primary_neigh =
                                primary_boundary_point_neighbor(neigh, neigh_pt,
                                                                mesh.get_boundary_info(),
                                                                point_pairedids);

                              libmesh_assert(primary_neigh);

                              if (new_boundary_id == boundary_id)
                                {
                                  main_neigh = primary_neigh;
                                  main_pt = neigh_pt;
                                }

                              // Finer elements will get constrained in
                              // terms of coarser neighbors, not the
                              // other way around
                              if ((primary_neigh->level() > primary_elem->level()) ||

                                  // For equal-level elements, the one with
                                  // higher id gets constrained in terms of
                                  // the one with lower id
                                  (primary_neigh->level() == primary_elem->level() &&
                                   primary_neigh->id() > primary_elem->id()) ||

                                  // On a one-element-thick mesh, we compare
                                  // points to see what side gets constrained
                                  (primary_neigh == primary_elem &&
                                   (neigh_pt > primary_pt)))
                                continue;

                              primary_elem = primary_neigh;
                              primary_pt = neigh_pt;
                            }

                          if (!primary_elem ||
                              primary_elem != main_neigh ||
                              primary_pt != main_pt)
                            continue;
                        }
                      else if (elem->is_edge(n))
                        {
                          // Find which edge we're on
                          unsigned int e=0;
                          for (; e != elem->n_edges(); ++e)
                            {
                              if (elem->is_node_on_edge(n,e))
                                break;
                            }
                          libmesh_assert_less (e, elem->n_edges());

                          // Find the edge end nodes
                          Node *e1 = NULL,
                            *e2 = NULL;
                          for (unsigned int nn = 0; nn != elem->n_nodes(); ++nn)
                            {
                              if (nn == n)
                                continue;

                              if (elem->is_node_on_edge(nn, e))
                                {
                                  if (e1 == NULL)
                                    {
                                      e1 = elem->get_node(nn);
                                    }
                                  else
                                    {
                                      e2 = elem->get_node(nn);
                                      break;
                                    }
                                }
                            }
                          libmesh_assert (e1 && e2);

                          // Find all boundary ids that include this
                          // edge and have periodic boundary
                          // conditions for this variable
                          std::set<boundary_id_type> edge_bcids;

                          for (unsigned int new_s = 0; new_s !=
                                 elem->n_sides(); ++new_s)
                            {
                              if (!elem->is_node_on_side(n,new_s))
                                continue;

                              const std::vector<boundary_id_type>& new_bc_ids =
                                mesh.get_boundary_info().boundary_ids (elem, s);
                              for (std::vector<boundary_id_type>::const_iterator
                                     new_id_it=new_bc_ids.begin(); new_id_it!=new_bc_ids.end(); ++new_id_it)
                                {
                                  const boundary_id_type new_boundary_id = *new_id_it;
                                  const PeriodicBoundaryBase *new_periodic = boundaries.boundary(new_boundary_id);
                                  if (new_periodic && new_periodic->is_my_variable(variable_number))
                                    {
                                      edge_bcids.insert(new_boundary_id);
                                    }
                                }
                            }


                          // See if this edge has neighbors to defer to
                          if (primary_boundary_edge_neighbor
                              (elem, *e1, *e2, mesh.get_boundary_info(), edge_bcids)
                              != elem)
                            continue;

                          // Find the complementary boundary id set
                          std::set<boundary_id_type> edge_pairedids;
                          for (std::set<boundary_id_type>::const_iterator i =
                                 edge_bcids.begin(); i != edge_bcids.end(); ++i)
                            {
                              const boundary_id_type new_boundary_id = *i;
                              const PeriodicBoundaryBase *new_periodic = boundaries.boundary(new_boundary_id);
                              edge_pairedids.insert(new_periodic->pairedboundary);
                            }

                          // What do we want to constrain against?
                          const Elem* primary_elem = NULL;
                          const Elem* main_neigh = NULL;
                          Point main_pt1 = *e1,
                            main_pt2 = *e2,
                            primary_pt1 = *e1,
                            primary_pt2 = *e2;

                          for (std::set<boundary_id_type>::const_iterator i =
                                 edge_bcids.begin(); i != edge_bcids.end(); ++i)
                            {
                              // Find the corresponding periodic edge and
                              // its primary neighbor
                              const boundary_id_type new_boundary_id = *i;
                              const PeriodicBoundaryBase *new_periodic = boundaries.boundary(new_boundary_id);

                              Point neigh_pt1 = new_periodic->get_corresponding_pos(*e1),
                                neigh_pt2 = new_periodic->get_corresponding_pos(*e2);

                              // If the edge is getting constrained
                              // to itself by this PBC then we don't
                              // generate any constraints
                              if (neigh_pt1.absolute_fuzzy_equals
                                  (*e1, primary_hmin*TOLERANCE) &&
                                  neigh_pt2.absolute_fuzzy_equals
                                  (*e2, primary_hmin*TOLERANCE))
                                continue;

                              // Otherwise we'll have a constraint in
                              // one direction or another
                              if (!primary_elem)
                                primary_elem = elem;

                              const Elem *primary_neigh = primary_boundary_edge_neighbor
                                (neigh, neigh_pt1, neigh_pt2,
                                 mesh.get_boundary_info(), edge_pairedids);

                              libmesh_assert(primary_neigh);

                              if (new_boundary_id == boundary_id)
                                {
                                  main_neigh = primary_neigh;
                                  main_pt1 = neigh_pt1;
                                  main_pt2 = neigh_pt2;
                                }

                              // If we have a one-element thick mesh,
                              // we'll need to sort our points to get a
                              // consistent ordering rule
                              //
                              // Use >= in this test to make sure that,
                              // for angular constraints, no node gets
                              // constrained to itself.
                              if (primary_neigh == primary_elem)
                                {
                                  if (primary_pt1 > primary_pt2)
                                    std::swap(primary_pt1, primary_pt2);
                                  if (neigh_pt1 > neigh_pt2)
                                    std::swap(neigh_pt1, neigh_pt2);

                                  if (neigh_pt2 >= primary_pt2)
                                    continue;
                                }

                              // Otherwise:
                              // Finer elements will get constrained in
                              // terms of coarser ones, not the other way
                              // around
                              if ((primary_neigh->level() > primary_elem->level()) ||

                                  // For equal-level elements, the one with
                                  // higher id gets constrained in terms of
                                  // the one with lower id
                                  (primary_neigh->level() == primary_elem->level() &&
                                   primary_neigh->id() > primary_elem->id()))
                                continue;

                              primary_elem = primary_neigh;
                              primary_pt1 = neigh_pt1;
                              primary_pt2 = neigh_pt2;
                            }

                          if (!primary_elem ||
                              primary_elem != main_neigh ||
                              primary_pt1 != main_pt1 ||
                              primary_pt2 != main_pt2)
                            continue;
                        }
                      else if (elem->is_face(n))
                        {
                          // If we have a one-element thick mesh,
                          // use the ordering of the face node and its
                          // periodic counterpart to determine what
                          // gets constrained
                          if (neigh == elem)
                            {
                              const Point neigh_pt =
                                periodic->get_corresponding_pos(*my_node);
                              if (neigh_pt > *my_node)
                                continue;
                            }

                          // Otherwise:
                          // Finer elements will get constrained in
                          // terms of coarser ones, not the other way
                          // around
                          if ((neigh->level() > elem->level()) ||

                              // For equal-level elements, the one with
                              // higher id gets constrained in terms of
                              // the one with lower id
                              (neigh->level() == elem->level() &&
                               neigh->id() > elem->id()))
                            continue;
                        }

                      // If we made it here without hitting a continue
                      // statement, then we're at a node whose dofs
                      // should be constrained by this element's
                      // calculations.
                      const unsigned int n_comp =
                        my_node->n_comp(sys_number, variable_number);

                      for (unsigned int i=0; i != n_comp; ++i)
                        my_constrained_dofs.insert
                          (my_node->dof_number
                           (sys_number, variable_number, i));
                    }

                  // FIXME: old code for disambiguating periodic BCs:
                  // this is not threadsafe nor safe to run on a
                  // non-serialized mesh.
                  /*
                    std::vector<bool> recursive_constraint(n_side_dofs, false);

                    for (unsigned int is = 0; is != n_side_dofs; ++is)
                    {
                    const unsigned int i = neigh_side_dofs[is];
                    const dof_id_type their_dof_g = neigh_dof_indices[i];
                    libmesh_assert_not_equal_to (their_dof_g, DofObject::invalid_id);

                    {
                    Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                    if (!dof_map.is_constrained_dof(their_dof_g))
                    continue;
                    }

                    DofConstraintRow& their_constraint_row =
                    constraints[their_dof_g].first;

                    for (unsigned int js = 0; js != n_side_dofs; ++js)
                    {
                    const unsigned int j = my_side_dofs[js];
                    const dof_id_type my_dof_g = my_dof_indices[j];
                    libmesh_assert_not_equal_to (my_dof_g, DofObject::invalid_id);

                    if (their_constraint_row.count(my_dof_g))
                    recursive_constraint[js] = true;
                    }
                    }
                  */

                  for (unsigned int js = 0; js != n_side_dofs; ++js)
                    {
                      // FIXME: old code path
                      // if (recursive_constraint[js])
                      //  continue;

                      const unsigned int j = my_side_dofs[js];
                      const dof_id_type my_dof_g = my_dof_indices[j];
                      libmesh_assert_not_equal_to (my_dof_g, DofObject::invalid_id);

                      // FIXME: new code path
                      if (!my_constrained_dofs.count(my_dof_g))
                        continue;

                      DofConstraintRow* constraint_row;

                      // we may be running constraint methods concurretly
                      // on multiple threads, so we need a lock to
                      // ensure that this constraint is "ours"
                      {
                        Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                        if (dof_map.is_constrained_dof(my_dof_g))
                          continue;

                        constraint_row = &(constraints[my_dof_g]);
                        libmesh_assert(constraint_row->empty());
                      }

                      for (unsigned int is = 0; is != n_side_dofs; ++is)
                        {
                          const unsigned int i = neigh_side_dofs[is];
                          const dof_id_type their_dof_g = neigh_dof_indices[i];
                          libmesh_assert_not_equal_to (their_dof_g, DofObject::invalid_id);

                          // Periodic constraints should never be
                          // self-constraints
                          // libmesh_assert_not_equal_to (their_dof_g, my_dof_g);

                          const Real their_dof_value = Ue[is](js);

                          if (their_dof_g == my_dof_g)
                            {
                              libmesh_assert_less (std::abs(their_dof_value-1.), 1.e-5);
                              for (unsigned int k = 0; k != n_side_dofs; ++k)
                                libmesh_assert(k == is || std::abs(Ue[k](js)) < 1.e-5);
                              continue;
                            }

                          if (std::abs(their_dof_value) < 10*TOLERANCE)
                            continue;

                          constraint_row->insert(std::make_pair(their_dof_g,
                                                                their_dof_value));
                        }
                    }
                }
              // p refinement constraints:
              // constrain dofs shared between
              // active elements and neighbors with
              // lower polynomial degrees
#ifdef LIBMESH_ENABLE_AMR
              const unsigned int min_p_level =
                neigh->min_p_level_by_neighbor(elem, elem->p_level());
              if (min_p_level < elem->p_level())
                {
                  // Adaptive p refinement of non-hierarchic bases will
                  // require more coding
                  libmesh_assert(my_fe->is_hierarchic());
                  dof_map.constrain_p_dofs(variable_number, elem,
                                           s, min_p_level);
                }
#endif // #ifdef LIBMESH_ENABLE_AMR
            }
        }
    }
}
void libMesh::FEAbstract::compute_periodic_node_constraints ( NodeConstraints constraints,
const PeriodicBoundaries boundaries,
const MeshBase mesh,
const PointLocatorBase point_locator,
const Elem elem 
) [static, inherited]

Computes the node position constraint equation contributions (for meshes with periodic boundary conditions)

Definition at line 931 of file fe_abstract.C.

References libMesh::Elem::active(), libMesh::PeriodicBoundaries::boundary(), libMesh::BoundaryInfo::boundary_ids(), libMesh::Elem::build_side(), libMesh::Elem::default_order(), libMesh::Elem::dim(), libMesh::FEAbstract::fe_type, libMesh::MeshBase::get_boundary_info(), libMesh::PeriodicBoundaryBase::get_corresponding_pos(), libMesh::invalid_uint, libMesh::FEInterface::inverse_map(), libMesh::LAGRANGE, libMesh::Elem::level(), libMesh::libmesh_assert(), libMesh::FEInterface::n_dofs(), libMesh::Elem::n_sides(), libMesh::PeriodicBoundaries::neighbor(), libMesh::Elem::neighbor(), libMesh::PeriodicBoundaryBase::pairedboundary, libMesh::Real, libMesh::FEInterface::shape(), libMesh::BoundaryInfo::side_with_boundary_id(), and libMesh::Threads::spin_mtx.

{
  // Only bother if we truly have periodic boundaries
  if (boundaries.empty())
    return;

  libmesh_assert(elem);

  // Only constrain active elements with this method
  if (!elem->active())
    return;

  const unsigned int Dim = elem->dim();

  // We currently always use LAGRANGE mappings for geometry
  const FEType fe_type(elem->default_order(), LAGRANGE);

  std::vector<const Node*> my_nodes, neigh_nodes;

  // Look at the element faces.  Check to see if we need to
  // build constraints.
  for (unsigned short int s=0; s<elem->n_sides(); s++)
    {
      if (elem->neighbor(s))
        continue;

      const std::vector<boundary_id_type>& bc_ids =
        mesh.get_boundary_info().boundary_ids (elem, s);
      for (std::vector<boundary_id_type>::const_iterator id_it=bc_ids.begin(); id_it!=bc_ids.end(); ++id_it)
        {
          const boundary_id_type boundary_id = *id_it;
          const PeriodicBoundaryBase *periodic = boundaries.boundary(boundary_id);
          if (periodic)
            {
              libmesh_assert(point_locator);

              // Get pointers to the element's neighbor.
              const Elem* neigh = boundaries.neighbor(boundary_id, *point_locator, elem, s);

              // h refinement constraints:
              // constrain dofs shared between
              // this element and ones as coarse
              // as or coarser than this element.
              if (neigh->level() <= elem->level())
                {
                  unsigned int s_neigh =
                    mesh.get_boundary_info().side_with_boundary_id(neigh, periodic->pairedboundary);
                  libmesh_assert_not_equal_to (s_neigh, libMesh::invalid_uint);

#ifdef LIBMESH_ENABLE_AMR
                  libmesh_assert(neigh->active());
#endif // #ifdef LIBMESH_ENABLE_AMR

                  const UniquePtr<Elem> my_side    (elem->build_side(s));
                  const UniquePtr<Elem> neigh_side (neigh->build_side(s_neigh));

                  const unsigned int n_side_nodes = my_side->n_nodes();

                  my_nodes.clear();
                  my_nodes.reserve (n_side_nodes);
                  neigh_nodes.clear();
                  neigh_nodes.reserve (n_side_nodes);

                  for (unsigned int n=0; n != n_side_nodes; ++n)
                    my_nodes.push_back(my_side->get_node(n));

                  for (unsigned int n=0; n != n_side_nodes; ++n)
                    neigh_nodes.push_back(neigh_side->get_node(n));

                  // Make sure we're not adding recursive constraints
                  // due to the redundancy in the way we add periodic
                  // boundary constraints, or adding constraints to
                  // nodes that already have AMR constraints
                  std::vector<bool> skip_constraint(n_side_nodes, false);

                  for (unsigned int my_side_n=0;
                       my_side_n < n_side_nodes;
                       my_side_n++)
                    {
                      libmesh_assert_less (my_side_n, FEInterface::n_dofs(Dim-1, fe_type, my_side->type()));

                      const Node* my_node = my_nodes[my_side_n];

                      // Figure out where my node lies on their reference element.
                      const Point neigh_point = periodic->get_corresponding_pos(*my_node);

                      const Point mapped_point = FEInterface::inverse_map(Dim-1, fe_type,
                                                                          neigh_side.get(),
                                                                          neigh_point);

                      // If we've already got a constraint on this
                      // node, then the periodic constraint is
                      // redundant
                      {
                        Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                        if (constraints.count(my_node))
                          {
                            skip_constraint[my_side_n] = true;
                            continue;
                          }
                      }

                      // Compute the neighbors's side shape function values.
                      for (unsigned int their_side_n=0;
                           their_side_n < n_side_nodes;
                           their_side_n++)
                        {
                          libmesh_assert_less (their_side_n, FEInterface::n_dofs(Dim-1, fe_type, neigh_side->type()));

                          const Node* their_node = neigh_nodes[their_side_n];

                          // If there's a constraint on an opposing node,
                          // we need to see if it's constrained by
                          // *our side* making any periodic constraint
                          // on us recursive
                          {
                            Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                            if (!constraints.count(their_node))
                              continue;

                            const NodeConstraintRow& their_constraint_row =
                              constraints[their_node].first;

                            for (unsigned int orig_side_n=0;
                                 orig_side_n < n_side_nodes;
                                 orig_side_n++)
                              {
                                libmesh_assert_less (orig_side_n, FEInterface::n_dofs(Dim-1, fe_type, my_side->type()));

                                const Node* orig_node = my_nodes[orig_side_n];

                                if (their_constraint_row.count(orig_node))
                                  skip_constraint[orig_side_n] = true;
                              }
                          }
                        }
                    }
                  for (unsigned int my_side_n=0;
                       my_side_n < n_side_nodes;
                       my_side_n++)
                    {
                      libmesh_assert_less (my_side_n, FEInterface::n_dofs(Dim-1, fe_type, my_side->type()));

                      if (skip_constraint[my_side_n])
                        continue;

                      const Node* my_node = my_nodes[my_side_n];

                      // Figure out where my node lies on their reference element.
                      const Point neigh_point = periodic->get_corresponding_pos(*my_node);

                      // Figure out where my node lies on their reference element.
                      const Point mapped_point = FEInterface::inverse_map(Dim-1, fe_type,
                                                                          neigh_side.get(),
                                                                          neigh_point);

                      for (unsigned int their_side_n=0;
                           their_side_n < n_side_nodes;
                           their_side_n++)
                        {
                          libmesh_assert_less (their_side_n, FEInterface::n_dofs(Dim-1, fe_type, neigh_side->type()));

                          const Node* their_node = neigh_nodes[their_side_n];
                          libmesh_assert(their_node);

                          const Real their_value = FEInterface::shape(Dim-1,
                                                                      fe_type,
                                                                      neigh_side->type(),
                                                                      their_side_n,
                                                                      mapped_point);

                          // since we may be running this method concurrently
                          // on multiple threads we need to acquire a lock
                          // before modifying the shared constraint_row object.
                          {
                            Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                            NodeConstraintRow& constraint_row =
                              constraints[my_node].first;

                            constraint_row.insert(std::make_pair(their_node,
                                                                 their_value));
                          }
                        }
                    }
                }
            }
        }
    }
}
template<typename OutputType >
void libMesh::FEGenericBase< OutputType >::compute_proj_constraints ( DofConstraints constraints,
DofMap dof_map,
const unsigned int  variable_number,
const Elem elem 
) [static]

Computes the constraint matrix contributions (for non-conforming adapted meshes) corresponding to variable number var_number, using generic projections.

Definition at line 1346 of file fe_base.C.

References std::abs(), libMesh::Elem::active(), libMesh::C_ONE, libMesh::C_ZERO, libMesh::DenseMatrix< T >::cholesky_solve(), libMesh::DofMap::constrain_p_dofs(), libMesh::FEType::default_quadrature_order(), libMesh::Elem::dim(), libMesh::DISCONTINUOUS, libMesh::DofMap::dof_indices(), libMesh::FEInterface::dofs_on_side(), libMesh::TensorTools::inner_product(), libMesh::DofObject::invalid_id, libMesh::FEInterface::inverse_map(), libMesh::DofMap::is_constrained_dof(), libMesh::Elem::level(), libMesh::libmesh_assert(), std::min(), libMesh::Elem::min_p_level_by_neighbor(), libMesh::Elem::n_neighbors(), libMesh::Elem::n_nodes(), libMesh::Elem::n_sides(), libMesh::Elem::neighbor(), libMesh::Elem::p_level(), libMesh::Real, libMesh::DenseVector< T >::resize(), libMesh::DenseMatrix< T >::resize(), libMesh::Threads::spin_mtx, libMesh::TOLERANCE, libMesh::DofMap::variable_type(), and libMesh::Elem::which_neighbor_am_i().

Referenced by libMesh::FE< Dim, T >::compute_constraints().

{
  libmesh_assert(elem);

  const unsigned int Dim = elem->dim();

  // Only constrain elements in 2,3D.
  if (Dim == 1)
    return;

  // Only constrain active elements with this method
  if (!elem->active())
    return;

  const FEType& base_fe_type = dof_map.variable_type(variable_number);

  // Construct FE objects for this element and its neighbors.
  UniquePtr<FEGenericBase<OutputShape> > my_fe
    (FEGenericBase<OutputShape>::build(Dim, base_fe_type));
  const FEContinuity cont = my_fe->get_continuity();

  // We don't need to constrain discontinuous elements
  if (cont == DISCONTINUOUS)
    return;
  libmesh_assert (cont == C_ZERO || cont == C_ONE);

  UniquePtr<FEGenericBase<OutputShape> > neigh_fe
    (FEGenericBase<OutputShape>::build(Dim, base_fe_type));

  QGauss my_qface(Dim-1, base_fe_type.default_quadrature_order());
  my_fe->attach_quadrature_rule (&my_qface);
  std::vector<Point> neigh_qface;

  const std::vector<Real>& JxW = my_fe->get_JxW();
  const std::vector<Point>& q_point = my_fe->get_xyz();
  const std::vector<std::vector<OutputShape> >& phi = my_fe->get_phi();
  const std::vector<std::vector<OutputShape> >& neigh_phi =
    neigh_fe->get_phi();
  const std::vector<Point> *face_normals = NULL;
  const std::vector<std::vector<OutputGradient> > *dphi = NULL;
  const std::vector<std::vector<OutputGradient> > *neigh_dphi = NULL;

  std::vector<dof_id_type> my_dof_indices, neigh_dof_indices;
  std::vector<unsigned int> my_side_dofs, neigh_side_dofs;

  if (cont != C_ZERO)
    {
      const std::vector<Point>& ref_face_normals =
        my_fe->get_normals();
      face_normals = &ref_face_normals;
      const std::vector<std::vector<OutputGradient> >& ref_dphi =
        my_fe->get_dphi();
      dphi = &ref_dphi;
      const std::vector<std::vector<OutputGradient> >& ref_neigh_dphi =
        neigh_fe->get_dphi();
      neigh_dphi = &ref_neigh_dphi;
    }

  DenseMatrix<Real> Ke;
  DenseVector<Real> Fe;
  std::vector<DenseVector<Real> > Ue;

  // Look at the element faces.  Check to see if we need to
  // build constraints.
  for (unsigned int s=0; s<elem->n_sides(); s++)
    if (elem->neighbor(s) != NULL)
      {
        // Get pointers to the element's neighbor.
        const Elem* neigh = elem->neighbor(s);

        // h refinement constraints:
        // constrain dofs shared between
        // this element and ones coarser
        // than this element.
        if (neigh->level() < elem->level())
          {
            unsigned int s_neigh = neigh->which_neighbor_am_i(elem);
            libmesh_assert_less (s_neigh, neigh->n_neighbors());

            // Find the minimum p level; we build the h constraint
            // matrix with this and then constrain away all higher p
            // DoFs.
            libmesh_assert(neigh->active());
            const unsigned int min_p_level =
              std::min(elem->p_level(), neigh->p_level());

            // we may need to make the FE objects reinit with the
            // minimum shared p_level
            // FIXME - I hate using const_cast<> and avoiding
            // accessor functions; there's got to be a
            // better way to do this!
            const unsigned int old_elem_level = elem->p_level();
            if (old_elem_level != min_p_level)
              (const_cast<Elem *>(elem))->hack_p_level(min_p_level);
            const unsigned int old_neigh_level = neigh->p_level();
            if (old_neigh_level != min_p_level)
              (const_cast<Elem *>(neigh))->hack_p_level(min_p_level);

            my_fe->reinit(elem, s);

            // This function gets called element-by-element, so there
            // will be a lot of memory allocation going on.  We can
            // at least minimize this for the case of the dof indices
            // by efficiently preallocating the requisite storage.
            // n_nodes is not necessarily n_dofs, but it is better
            // than nothing!
            my_dof_indices.reserve    (elem->n_nodes());
            neigh_dof_indices.reserve (neigh->n_nodes());

            dof_map.dof_indices (elem, my_dof_indices,
                                 variable_number);
            dof_map.dof_indices (neigh, neigh_dof_indices,
                                 variable_number);

            const unsigned int n_qp = my_qface.n_points();

            FEInterface::inverse_map (Dim, base_fe_type, neigh,
                                      q_point, neigh_qface);

            neigh_fe->reinit(neigh, &neigh_qface);

            // We're only concerned with DOFs whose values (and/or first
            // derivatives for C1 elements) are supported on side nodes
            FEInterface::dofs_on_side(elem,  Dim, base_fe_type, s,       my_side_dofs);
            FEInterface::dofs_on_side(neigh, Dim, base_fe_type, s_neigh, neigh_side_dofs);

            // We're done with functions that examine Elem::p_level(),
            // so let's unhack those levels
            if (elem->p_level() != old_elem_level)
              (const_cast<Elem *>(elem))->hack_p_level(old_elem_level);
            if (neigh->p_level() != old_neigh_level)
              (const_cast<Elem *>(neigh))->hack_p_level(old_neigh_level);

            const unsigned int n_side_dofs =
              cast_int<unsigned int>(my_side_dofs.size());
            libmesh_assert_equal_to (n_side_dofs, neigh_side_dofs.size());

            Ke.resize (n_side_dofs, n_side_dofs);
            Ue.resize(n_side_dofs);

            // Form the projection matrix, (inner product of fine basis
            // functions against fine test functions)
            for (unsigned int is = 0; is != n_side_dofs; ++is)
              {
                const unsigned int i = my_side_dofs[is];
                for (unsigned int js = 0; js != n_side_dofs; ++js)
                  {
                    const unsigned int j = my_side_dofs[js];
                    for (unsigned int qp = 0; qp != n_qp; ++qp)
                      {
                        Ke(is,js) += JxW[qp] * TensorTools::inner_product(phi[i][qp], phi[j][qp]);
                        if (cont != C_ZERO)
                          Ke(is,js) += JxW[qp] *
                            TensorTools::inner_product((*dphi)[i][qp] *
                                                       (*face_normals)[qp],
                                                       (*dphi)[j][qp] *
                                                       (*face_normals)[qp]);
                      }
                  }
              }

            // Form the right hand sides, (inner product of coarse basis
            // functions against fine test functions)
            for (unsigned int is = 0; is != n_side_dofs; ++is)
              {
                const unsigned int i = neigh_side_dofs[is];
                Fe.resize (n_side_dofs);
                for (unsigned int js = 0; js != n_side_dofs; ++js)
                  {
                    const unsigned int j = my_side_dofs[js];
                    for (unsigned int qp = 0; qp != n_qp; ++qp)
                      {
                        Fe(js) += JxW[qp] *
                          TensorTools::inner_product(neigh_phi[i][qp],
                                                     phi[j][qp]);
                        if (cont != C_ZERO)
                          Fe(js) += JxW[qp] *
                            TensorTools::inner_product((*neigh_dphi)[i][qp] *
                                                       (*face_normals)[qp],
                                                       (*dphi)[j][qp] *
                                                       (*face_normals)[qp]);
                      }
                  }
                Ke.cholesky_solve(Fe, Ue[is]);
              }

            for (unsigned int js = 0; js != n_side_dofs; ++js)
              {
                const unsigned int j = my_side_dofs[js];
                const dof_id_type my_dof_g = my_dof_indices[j];
                libmesh_assert_not_equal_to (my_dof_g, DofObject::invalid_id);

                // Hunt for "constraining against myself" cases before
                // we bother creating a constraint row
                bool self_constraint = false;
                for (unsigned int is = 0; is != n_side_dofs; ++is)
                  {
                    const unsigned int i = neigh_side_dofs[is];
                    const dof_id_type their_dof_g = neigh_dof_indices[i];
                    libmesh_assert_not_equal_to (their_dof_g, DofObject::invalid_id);

                    if (their_dof_g == my_dof_g)
                      {
#ifndef NDEBUG
                        const Real their_dof_value = Ue[is](js);
                        libmesh_assert_less (std::abs(their_dof_value-1.),
                                             10*TOLERANCE);

                        for (unsigned int k = 0; k != n_side_dofs; ++k)
                          libmesh_assert(k == is ||
                                         std::abs(Ue[k](js)) <
                                         10*TOLERANCE);
#endif

                        self_constraint = true;
                        break;
                      }
                  }

                if (self_constraint)
                  continue;

                DofConstraintRow* constraint_row;

                // we may be running constraint methods concurrently
                // on multiple threads, so we need a lock to
                // ensure that this constraint is "ours"
                {
                  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);

                  if (dof_map.is_constrained_dof(my_dof_g))
                    continue;

                  constraint_row = &(constraints[my_dof_g]);
                  libmesh_assert(constraint_row->empty());
                }

                for (unsigned int is = 0; is != n_side_dofs; ++is)
                  {
                    const unsigned int i = neigh_side_dofs[is];
                    const dof_id_type their_dof_g = neigh_dof_indices[i];
                    libmesh_assert_not_equal_to (their_dof_g, DofObject::invalid_id);
                    libmesh_assert_not_equal_to (their_dof_g, my_dof_g);

                    const Real their_dof_value = Ue[is](js);

                    if (std::abs(their_dof_value) < 10*TOLERANCE)
                      continue;

                    constraint_row->insert(std::make_pair(their_dof_g,
                                                          their_dof_value));
                  }
              }
          }
        // p refinement constraints:
        // constrain dofs shared between
        // active elements and neighbors with
        // lower polynomial degrees
        const unsigned int min_p_level =
          neigh->min_p_level_by_neighbor(elem, elem->p_level());
        if (min_p_level < elem->p_level())
          {
            // Adaptive p refinement of non-hierarchic bases will
            // require more coding
            libmesh_assert(my_fe->is_hierarchic());
            dof_map.constrain_p_dofs(variable_number, elem,
                                     s, min_p_level);
          }
      }
}
template<typename OutputType >
void libMesh::FEGenericBase< OutputType >::compute_shape_functions ( const Elem elem,
const std::vector< Point > &  qp 
) [protected, virtual]

After having updated the jacobian and the transformation from local to global coordinates in FEAbstract::compute_map(), the first derivatives of the shape functions are transformed to global coordinates, giving dphi, dphidx, dphidy, and dphidz. This method should rarely be re-defined in derived classes, but still should be usable for children. Therefore, keep it protected.

Implements libMesh::FEAbstract.

Reimplemented in libMesh::FEXYZ< Dim >, and libMesh::InfFE< Dim, T_radial, T_map >.

Definition at line 680 of file fe_base.C.

References libMesh::START_LOG().

{
  //-------------------------------------------------------------------------
  // Compute the shape function values (and derivatives)
  // at the Quadrature points.  Note that the actual values
  // have already been computed via init_shape_functions

  // Start logging the shape function computation
  START_LOG("compute_shape_functions()", "FE");

  calculations_started = true;

  // If the user forgot to request anything, we'll be safe and
  // calculate everything:
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
  if (!calculate_phi && !calculate_dphi && !calculate_d2phi && !calculate_curl_phi && !calculate_div_phi)
    {
      calculate_phi = calculate_dphi = calculate_d2phi = true;
      // Only compute curl, div for vector-valued elements
      if( TypesEqual<OutputType,RealGradient>::value )
        {
          calculate_curl_phi = true;
          calculate_div_phi  = true;
        }
    }
#else
  if (!calculate_phi && !calculate_dphi && !calculate_curl_phi && !calculate_div_phi)
    {
      calculate_phi = calculate_dphi = true;
      // Only compute curl for vector-valued elements
      if( TypesEqual<OutputType,RealGradient>::value )
        {
          calculate_curl_phi = true;
          calculate_div_phi  = true;
        }
    }
#endif // LIBMESH_ENABLE_SECOND_DERIVATIVES


  if( calculate_phi )
    this->_fe_trans->map_phi( this->dim, elem, qp, (*this), this->phi );

  if( calculate_dphi )
    this->_fe_trans->map_dphi( this->dim, elem, qp, (*this), this->dphi,
                               this->dphidx, this->dphidy, this->dphidz );

#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
  if( calculate_d2phi )
    this->_fe_trans->map_d2phi( this->dim, elem, qp, (*this), this->d2phi,
                                this->d2phidx2, this->d2phidxdy, this->d2phidxdz,
                                this->d2phidy2, this->d2phidydz, this->d2phidz2 );
#endif //LIBMESH_ENABLE_SECOND_DERIVATIVES

  // Only compute curl for vector-valued elements
  if( calculate_curl_phi && TypesEqual<OutputType,RealGradient>::value )
    this->_fe_trans->map_curl( this->dim, elem, qp, (*this), this->curl_phi );

  // Only compute div for vector-valued elements
  if( calculate_div_phi && TypesEqual<OutputType,RealGradient>::value )
    this->_fe_trans->map_div( this->dim, elem, qp, (*this), this->div_phi );

  // Stop logging the shape function computation
  STOP_LOG("compute_shape_functions()", "FE");
}
virtual void libMesh::FEAbstract::edge_reinit ( const Elem elem,
const unsigned int  edge,
const Real  tolerance = TOLERANCE,
const std::vector< Point > *  pts = NULL,
const std::vector< Real > *  weights = NULL 
) [pure virtual, inherited]

Reinitializes all the physical element-dependent data based on the edge of the element elem. The tolerance paremeter is passed to the involved call to inverse_map(). By default the element data are computed at the quadrature points specified by the quadrature rule qrule, but any set of points on the reference edge element may be specified in the optional argument pts.

Implemented in libMesh::FE< Dim, T >, libMesh::InfFE< Dim, T_radial, T_map >, libMesh::FE< Dim, T >, libMesh::FE< 2, SUBDIVISION >, libMesh::FE< Dim, HIERARCHIC >, libMesh::FE< Dim, SCALAR >, libMesh::FE< Dim, L2_LAGRANGE >, libMesh::FE< Dim, NEDELEC_ONE >, libMesh::FE< Dim, HERMITE >, libMesh::FE< Dim, CLOUGH >, libMesh::FE< Dim, MONOMIAL >, libMesh::FE< Dim, XYZ >, libMesh::FE< Dim, LAGRANGE >, libMesh::FE< Dim, L2_HIERARCHIC >, and libMesh::FE< Dim, LAGRANGE_VEC >.

Methods to enable/disable the reference counter output from print_info()

Definition at line 100 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter.

{
  _enable_print_counter = true;
  return;
}
virtual FEContinuity libMesh::FEAbstract::get_continuity ( ) const [pure virtual, inherited]
Returns:
the continuity level of the finite element.

Implemented in libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::InfFE< Dim, T_radial, T_map >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< 2, SUBDIVISION >, libMesh::FE< Dim, HIERARCHIC >, libMesh::FE< Dim, SCALAR >, libMesh::FE< Dim, L2_LAGRANGE >, libMesh::FE< Dim, NEDELEC_ONE >, libMesh::FE< Dim, HERMITE >, libMesh::FE< Dim, CLOUGH >, libMesh::FE< Dim, MONOMIAL >, libMesh::FE< Dim, XYZ >, libMesh::FE< Dim, LAGRANGE >, libMesh::FE< Dim, L2_HIERARCHIC >, libMesh::FE< Dim, LAGRANGE_VEC >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, and libMesh::FE< Dim, T >.

Referenced by libMesh::ProjectFEMSolution::operator()().

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_curl_phi ( ) const [inline]
Returns:
the curl of the shape function at the quadrature points.

Definition at line 226 of file fe_base.h.

Referenced by libMesh::ExactSolution::_compute_error(), and libMesh::FEMContext::interior_curl().

const std::vector<Real>& libMesh::FEAbstract::get_curvatures ( ) const [inline, inherited]
Returns:
the curvatures for use in face integration.

Definition at line 380 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_curvatures();}
template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phideta2 ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points, in reference coordinates

Definition at line 372 of file fe_base.h.

Referenced by libMesh::H1FETransformation< OutputShape >::map_d2phi().

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidetadzeta ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points, in reference coordinates

Definition at line 380 of file fe_base.h.

Referenced by libMesh::H1FETransformation< OutputShape >::map_d2phi().

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidx2 ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points.

Definition at line 300 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidxdy ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points.

Definition at line 308 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidxdz ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points.

Definition at line 316 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidxi2 ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points, in reference coordinates

Definition at line 348 of file fe_base.h.

Referenced by libMesh::H1FETransformation< OutputShape >::map_d2phi().

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidxideta ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points, in reference coordinates

Definition at line 356 of file fe_base.h.

Referenced by libMesh::H1FETransformation< OutputShape >::map_d2phi().

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidxidzeta ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points, in reference coordinates

Definition at line 364 of file fe_base.h.

Referenced by libMesh::H1FETransformation< OutputShape >::map_d2phi().

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidy2 ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points.

Definition at line 324 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidydz ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points.

Definition at line 332 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidz2 ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points.

Definition at line 340 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_d2phidzeta2 ( ) const [inline]
Returns:
the shape function second derivatives at the quadrature points, in reference coordinates

Definition at line 388 of file fe_base.h.

Referenced by libMesh::H1FETransformation< OutputShape >::map_d2phi().

const std::vector<RealGradient>& libMesh::FEAbstract::get_d2xyzdeta2 ( ) const [inline, inherited]
Returns:
the second partial derivatives in eta.

Definition at line 267 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_d2xyzdeta2(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_d2xyzdetadzeta ( ) const [inline, inherited]
Returns:
the second partial derivatives in eta-zeta.

Definition at line 297 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_d2xyzdetadzeta(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_d2xyzdxi2 ( ) const [inline, inherited]
Returns:
the second partial derivatives in xi.

Definition at line 261 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_d2xyzdxi2(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_d2xyzdxideta ( ) const [inline, inherited]
Returns:
the second partial derivatives in xi-eta.

Definition at line 283 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_d2xyzdxideta(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_d2xyzdxidzeta ( ) const [inline, inherited]
Returns:
the second partial derivatives in xi-zeta.

Definition at line 291 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_d2xyzdxidzeta(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_d2xyzdzeta2 ( ) const [inline, inherited]
Returns:
the second partial derivatives in zeta.

Definition at line 275 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_d2xyzdzeta2(); }
const std::vector<Real>& libMesh::FEAbstract::get_detadx ( ) const [inline, inherited]
Returns:
the deta/dx entry in the transformation matrix from physical to local coordinates.

Definition at line 327 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_detadx(); }
const std::vector<Real>& libMesh::FEAbstract::get_detady ( ) const [inline, inherited]
Returns:
the deta/dy entry in the transformation matrix from physical to local coordinates.

Definition at line 334 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_detady(); }
const std::vector<Real>& libMesh::FEAbstract::get_detadz ( ) const [inline, inherited]
Returns:
the deta/dz entry in the transformation matrix from physical to local coordinates.

Definition at line 341 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_detadz(); }
template<typename OutputType>
const std::vector<std::vector<OutputDivergence> >& libMesh::FEGenericBase< OutputType >::get_div_phi ( ) const [inline]
Returns:
the divergence of the shape function at the quadrature points.

Definition at line 234 of file fe_base.h.

Referenced by libMesh::ExactSolution::_compute_error(), and libMesh::FEMContext::interior_div().

template<typename OutputType>
const std::vector<OutputGradient>& libMesh::FEGenericBase< OutputType >::get_dphase ( ) const [inline]
Returns:
the global first derivative of the phase term which is used in infinite elements, evaluated at the quadrature points.

In case of the general finite element class FE this field is initialized to all zero, so that the variational formulation for an infinite element returns correct element matrices for a mesh using both finite and infinite elements.

Definition at line 406 of file fe_base.h.

  { return dphase; }
template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_dphideta ( ) const [inline]
template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_dphidx ( ) const [inline]
Returns:
the shape function x-derivative at the quadrature points.

Definition at line 242 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_dphidxi ( ) const [inline]
template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_dphidy ( ) const [inline]
Returns:
the shape function y-derivative at the quadrature points.

Definition at line 250 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_dphidz ( ) const [inline]
Returns:
the shape function z-derivative at the quadrature points.

Definition at line 258 of file fe_base.h.

template<typename OutputType>
const std::vector<std::vector<OutputShape> >& libMesh::FEGenericBase< OutputType >::get_dphidzeta ( ) const [inline]
const std::vector<Real>& libMesh::FEAbstract::get_dxidx ( ) const [inline, inherited]
Returns:
the dxi/dx entry in the transformation matrix from physical to local coordinates.

Definition at line 306 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dxidx(); }
const std::vector<Real>& libMesh::FEAbstract::get_dxidy ( ) const [inline, inherited]
Returns:
the dxi/dy entry in the transformation matrix from physical to local coordinates.

Definition at line 313 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dxidy(); }
const std::vector<Real>& libMesh::FEAbstract::get_dxidz ( ) const [inline, inherited]
Returns:
the dxi/dz entry in the transformation matrix from physical to local coordinates.

Definition at line 320 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dxidz(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_dxyzdeta ( ) const [inline, inherited]
Returns:
the element tangents in eta-direction at the quadrature points.

Definition at line 248 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dxyzdeta(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_dxyzdxi ( ) const [inline, inherited]
Returns:
the element tangents in xi-direction at the quadrature points.

Definition at line 241 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dxyzdxi(); }
const std::vector<RealGradient>& libMesh::FEAbstract::get_dxyzdzeta ( ) const [inline, inherited]
Returns:
the element tangents in zeta-direction at the quadrature points.

Definition at line 255 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return _fe_map->get_dxyzdzeta(); }
const std::vector<Real>& libMesh::FEAbstract::get_dzetadx ( ) const [inline, inherited]
Returns:
the dzeta/dx entry in the transformation matrix from physical to local coordinates.

Definition at line 348 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dzetadx(); }
const std::vector<Real>& libMesh::FEAbstract::get_dzetady ( ) const [inline, inherited]
Returns:
the dzeta/dy entry in the transformation matrix from physical to local coordinates.

Definition at line 355 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dzetady(); }
const std::vector<Real>& libMesh::FEAbstract::get_dzetadz ( ) const [inline, inherited]
Returns:
the dzeta/dz entry in the transformation matrix from physical to local coordinates.

Definition at line 362 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_dzetadz(); }
FEFamily libMesh::FEAbstract::get_family ( ) const [inline, inherited]
Returns:
the finite element family of this element.

Definition at line 439 of file fe_abstract.h.

References libMesh::FEType::family, and libMesh::FEAbstract::fe_type.

Referenced by libMesh::FE< Dim, T >::FE().

{ return fe_type.family; }
FEType libMesh::FEAbstract::get_fe_type ( ) const [inline, inherited]
std::string libMesh::ReferenceCounter::get_info ( ) [static, inherited]

Gets a string containing the reference information.

Definition at line 47 of file reference_counter.C.

References libMesh::ReferenceCounter::_counts, and libMesh::Quality::name().

Referenced by libMesh::ReferenceCounter::print_info().

{
#if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)

  std::ostringstream oss;

  oss << '\n'
      << " ---------------------------------------------------------------------------- \n"
      << "| Reference count information                                                |\n"
      << " ---------------------------------------------------------------------------- \n";

  for (Counts::iterator it = _counts.begin();
       it != _counts.end(); ++it)
    {
      const std::string name(it->first);
      const unsigned int creations    = it->second.first;
      const unsigned int destructions = it->second.second;

      oss << "| " << name << " reference count information:\n"
          << "|  Creations:    " << creations    << '\n'
          << "|  Destructions: " << destructions << '\n';
    }

  oss << " ---------------------------------------------------------------------------- \n";

  return oss.str();

#else

  return "";

#endif
}
const std::vector<Real>& libMesh::FEAbstract::get_JxW ( ) const [inline, inherited]
Returns:
the element Jacobian times the quadrature weight for each quadrature point.

Definition at line 234 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::ExactErrorEstimator::find_squared_element_error(), libMesh::FEMSystem::init_context(), and libMesh::ProjectFEMSolution::operator()().

  { return this->_fe_map->get_JxW(); }
const std::vector<Point>& libMesh::FEAbstract::get_normals ( ) const [inline, inherited]
Returns:
the normal vectors for face integration.

Definition at line 374 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_normals(); }
Order libMesh::FEAbstract::get_order ( ) const [inline, inherited]
Returns:
the approximation order of the finite element.

Definition at line 423 of file fe_abstract.h.

References libMesh::FEAbstract::_p_level, libMesh::FEAbstract::fe_type, and libMesh::FEType::order.

{ return static_cast<Order>(fe_type.order + _p_level); }
unsigned int libMesh::FEAbstract::get_p_level ( ) const [inline, inherited]
Returns:
the p refinement level that the current shape functions have been calculated for.

Definition at line 413 of file fe_abstract.h.

References libMesh::FEAbstract::_p_level.

{ return _p_level; }
void libMesh::FEAbstract::get_refspace_nodes ( const ElemType  t,
std::vector< Point > &  nodes 
) [static, inherited]

returns the reference space nodes coordinates given the element type

Definition at line 259 of file fe_abstract.C.

References libMesh::EDGE2, libMesh::EDGE3, libMesh::HEX20, libMesh::HEX27, libMesh::HEX8, libMesh::PRISM15, libMesh::PRISM18, libMesh::PRISM6, libMesh::PYRAMID13, libMesh::PYRAMID14, libMesh::PYRAMID5, libMesh::QUAD4, libMesh::QUAD8, libMesh::QUAD9, libMesh::TET10, libMesh::TET4, libMesh::TRI3, and libMesh::TRI6.

{
  switch(itemType)
    {
    case EDGE2:
      {
        nodes.resize(2);
        nodes[0] = Point (-1.,0.,0.);
        nodes[1] = Point (1.,0.,0.);
        return;
      }
    case EDGE3:
      {
        nodes.resize(3);
        nodes[0] = Point (-1.,0.,0.);
        nodes[1] = Point (1.,0.,0.);
        nodes[2] = Point (0.,0.,0.);
        return;
      }
    case TRI3:
      {
        nodes.resize(3);
        nodes[0] = Point (0.,0.,0.);
        nodes[1] = Point (1.,0.,0.);
        nodes[2] = Point (0.,1.,0.);
        return;
      }
    case TRI6:
      {
        nodes.resize(6);
        nodes[0] = Point (0.,0.,0.);
        nodes[1] = Point (1.,0.,0.);
        nodes[2] = Point (0.,1.,0.);
        nodes[3] = Point (.5,0.,0.);
        nodes[4] = Point (.5,.5,0.);
        nodes[5] = Point (0.,.5,0.);
        return;
      }
    case QUAD4:
      {
        nodes.resize(4);
        nodes[0] = Point (-1.,-1.,0.);
        nodes[1] = Point (1.,-1.,0.);
        nodes[2] = Point (1.,1.,0.);
        nodes[3] = Point (-1.,1.,0.);
        return;
      }
    case QUAD8:
      {
        nodes.resize(8);
        nodes[0] = Point (-1.,-1.,0.);
        nodes[1] = Point (1.,-1.,0.);
        nodes[2] = Point (1.,1.,0.);
        nodes[3] = Point (-1.,1.,0.);
        nodes[4] = Point (0.,-1.,0.);
        nodes[5] = Point (1.,0.,0.);
        nodes[6] = Point (0.,1.,0.);
        nodes[7] = Point (-1.,0.,0.);
        return;
      }
    case QUAD9:
      {
        nodes.resize(9);
        nodes[0] = Point (-1.,-1.,0.);
        nodes[1] = Point (1.,-1.,0.);
        nodes[2] = Point (1.,1.,0.);
        nodes[3] = Point (-1.,1.,0.);
        nodes[4] = Point (0.,-1.,0.);
        nodes[5] = Point (1.,0.,0.);
        nodes[6] = Point (0.,1.,0.);
        nodes[7] = Point (-1.,0.,0.);
        nodes[8] = Point (0.,0.,0.);
        return;
      }
    case TET4:
      {
        nodes.resize(4);
        nodes[0] = Point (0.,0.,0.);
        nodes[1] = Point (1.,0.,0.);
        nodes[2] = Point (0.,1.,0.);
        nodes[3] = Point (0.,0.,1.);
        return;
      }
    case TET10:
      {
        nodes.resize(10);
        nodes[0] = Point (0.,0.,0.);
        nodes[1] = Point (1.,0.,0.);
        nodes[2] = Point (0.,1.,0.);
        nodes[3] = Point (0.,0.,1.);
        nodes[4] = Point (.5,0.,0.);
        nodes[5] = Point (.5,.5,0.);
        nodes[6] = Point (0.,.5,0.);
        nodes[7] = Point (0.,0.,.5);
        nodes[8] = Point (.5,0.,.5);
        nodes[9] = Point (0.,.5,.5);
        return;
      }
    case HEX8:
      {
        nodes.resize(8);
        nodes[0] = Point (-1.,-1.,-1.);
        nodes[1] = Point (1.,-1.,-1.);
        nodes[2] = Point (1.,1.,-1.);
        nodes[3] = Point (-1.,1.,-1.);
        nodes[4] = Point (-1.,-1.,1.);
        nodes[5] = Point (1.,-1.,1.);
        nodes[6] = Point (1.,1.,1.);
        nodes[7] = Point (-1.,1.,1.);
        return;
      }
    case HEX20:
      {
        nodes.resize(20);
        nodes[0] = Point (-1.,-1.,-1.);
        nodes[1] = Point (1.,-1.,-1.);
        nodes[2] = Point (1.,1.,-1.);
        nodes[3] = Point (-1.,1.,-1.);
        nodes[4] = Point (-1.,-1.,1.);
        nodes[5] = Point (1.,-1.,1.);
        nodes[6] = Point (1.,1.,1.);
        nodes[7] = Point (-1.,1.,1.);
        nodes[8] = Point (0.,-1.,-1.);
        nodes[9] = Point (1.,0.,-1.);
        nodes[10] = Point (0.,1.,-1.);
        nodes[11] = Point (-1.,0.,-1.);
        nodes[12] = Point (-1.,-1.,0.);
        nodes[13] = Point (1.,-1.,0.);
        nodes[14] = Point (1.,1.,0.);
        nodes[15] = Point (-1.,1.,0.);
        nodes[16] = Point (0.,-1.,1.);
        nodes[17] = Point (1.,0.,1.);
        nodes[18] = Point (0.,1.,1.);
        nodes[19] = Point (-1.,0.,1.);
        return;
      }
    case HEX27:
      {
        nodes.resize(27);
        nodes[0] = Point (-1.,-1.,-1.);
        nodes[1] = Point (1.,-1.,-1.);
        nodes[2] = Point (1.,1.,-1.);
        nodes[3] = Point (-1.,1.,-1.);
        nodes[4] = Point (-1.,-1.,1.);
        nodes[5] = Point (1.,-1.,1.);
        nodes[6] = Point (1.,1.,1.);
        nodes[7] = Point (-1.,1.,1.);
        nodes[8] = Point (0.,-1.,-1.);
        nodes[9] = Point (1.,0.,-1.);
        nodes[10] = Point (0.,1.,-1.);
        nodes[11] = Point (-1.,0.,-1.);
        nodes[12] = Point (-1.,-1.,0.);
        nodes[13] = Point (1.,-1.,0.);
        nodes[14] = Point (1.,1.,0.);
        nodes[15] = Point (-1.,1.,0.);
        nodes[16] = Point (0.,-1.,1.);
        nodes[17] = Point (1.,0.,1.);
        nodes[18] = Point (0.,1.,1.);
        nodes[19] = Point (-1.,0.,1.);
        nodes[20] = Point (0.,0.,-1.);
        nodes[21] = Point (0.,-1.,0.);
        nodes[22] = Point (1.,0.,0.);
        nodes[23] = Point (0.,1.,0.);
        nodes[24] = Point (-1.,0.,0.);
        nodes[25] = Point (0.,0.,1.);
        nodes[26] = Point (0.,0.,0.);
        return;
      }
    case PRISM6:
      {
        nodes.resize(6);
        nodes[0] = Point (0.,0.,-1.);
        nodes[1] = Point (1.,0.,-1.);
        nodes[2] = Point (0.,1.,-1.);
        nodes[3] = Point (0.,0.,1.);
        nodes[4] = Point (1.,0.,1.);
        nodes[5] = Point (0.,1.,1.);
        return;
      }
    case PRISM15:
      {
        nodes.resize(15);
        nodes[0] = Point (0.,0.,-1.);
        nodes[1] = Point (1.,0.,-1.);
        nodes[2] = Point (0.,1.,-1.);
        nodes[3] = Point (0.,0.,1.);
        nodes[4] = Point (1.,0.,1.);
        nodes[5] = Point (0.,1.,1.);
        nodes[6] = Point (.5,0.,-1.);
        nodes[7] = Point (.5,.5,-1.);
        nodes[8] = Point (0.,.5,-1.);
        nodes[9] = Point (0.,0.,0.);
        nodes[10] = Point (1.,0.,0.);
        nodes[11] = Point (0.,1.,0.);
        nodes[12] = Point (.5,0.,1.);
        nodes[13] = Point (.5,.5,1.);
        nodes[14] = Point (0.,.5,1.);
        return;
      }
    case PRISM18:
      {
        nodes.resize(18);
        nodes[0] = Point (0.,0.,-1.);
        nodes[1] = Point (1.,0.,-1.);
        nodes[2] = Point (0.,1.,-1.);
        nodes[3] = Point (0.,0.,1.);
        nodes[4] = Point (1.,0.,1.);
        nodes[5] = Point (0.,1.,1.);
        nodes[6] = Point (.5,0.,-1.);
        nodes[7] = Point (.5,.5,-1.);
        nodes[8] = Point (0.,.5,-1.);
        nodes[9] = Point (0.,0.,0.);
        nodes[10] = Point (1.,0.,0.);
        nodes[11] = Point (0.,1.,0.);
        nodes[12] = Point (.5,0.,1.);
        nodes[13] = Point (.5,.5,1.);
        nodes[14] = Point (0.,.5,1.);
        nodes[15] = Point (.5,0.,0.);
        nodes[16] = Point (.5,.5,0.);
        nodes[17] = Point (0.,.5,0.);
        return;
      }
    case PYRAMID5:
      {
        nodes.resize(5);
        nodes[0] = Point (-1.,-1.,0.);
        nodes[1] = Point (1.,-1.,0.);
        nodes[2] = Point (1.,1.,0.);
        nodes[3] = Point (-1.,1.,0.);
        nodes[4] = Point (0.,0.,1.);
        return;
      }
    case PYRAMID13:
      {
        nodes.resize(13);

        // base corners
        nodes[0] = Point (-1.,-1.,0.);
        nodes[1] = Point (1.,-1.,0.);
        nodes[2] = Point (1.,1.,0.);
        nodes[3] = Point (-1.,1.,0.);

        // apex
        nodes[4] = Point (0.,0.,1.);

        // base midedge
        nodes[5] = Point (0.,-1.,0.);
        nodes[6] = Point (1.,0.,0.);
        nodes[7] = Point (0.,1.,0.);
        nodes[8] = Point (-1,0.,0.);

        // lateral midedge
        nodes[9] = Point (-.5,-.5,.5);
        nodes[10] = Point (.5,-.5,.5);
        nodes[11] = Point (.5,.5,.5);
        nodes[12] = Point (-.5,.5,.5);

        return;
      }
    case PYRAMID14:
      {
        nodes.resize(14);

        // base corners
        nodes[0] = Point (-1.,-1.,0.);
        nodes[1] = Point (1.,-1.,0.);
        nodes[2] = Point (1.,1.,0.);
        nodes[3] = Point (-1.,1.,0.);

        // apex
        nodes[4] = Point (0.,0.,1.);

        // base midedge
        nodes[5] = Point (0.,-1.,0.);
        nodes[6] = Point (1.,0.,0.);
        nodes[7] = Point (0.,1.,0.);
        nodes[8] = Point (-1,0.,0.);

        // lateral midedge
        nodes[9] = Point (-.5,-.5,.5);
        nodes[10] = Point (.5,-.5,.5);
        nodes[11] = Point (.5,.5,.5);
        nodes[12] = Point (-.5,.5,.5);

        // base center
        nodes[13] = Point (0.,0.,0.);

        return;
      }

    default:
      libmesh_error_msg("ERROR: Unknown element type " << itemType);
    }
}
template<typename OutputType>
const std::vector<RealGradient>& libMesh::FEGenericBase< OutputType >::get_Sobolev_dweight ( ) const [inline]
Returns:
the first global derivative of the multiplicative weight at each quadrature point. See get_Sobolev_weight() for details. In case of FE initialized to all zero.

Definition at line 430 of file fe_base.h.

  { return dweight; }
template<typename OutputType>
const std::vector<Real>& libMesh::FEGenericBase< OutputType >::get_Sobolev_weight ( ) const [inline]
Returns:
the multiplicative weight at each quadrature point. This weight is used for certain infinite element weak formulations, so that weighted Sobolev spaces are used for the trial function space. This renders the variational form easily computable.

In case of the general finite element class FE this field is initialized to all ones, so that the variational formulation for an infinite element returns correct element matrices for a mesh using both finite and infinite elements.

Definition at line 422 of file fe_base.h.

  { return weight; }
const std::vector<std::vector<Point> >& libMesh::FEAbstract::get_tangents ( ) const [inline, inherited]
Returns:
the tangent vectors for face integration.

Definition at line 368 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

  { return this->_fe_map->get_tangents(); }
ElemType libMesh::FEAbstract::get_type ( ) const [inline, inherited]
Returns:
the element type that the current shape functions have been calculated for. Useful in determining when shape functions must be recomputed.

Definition at line 407 of file fe_abstract.h.

References libMesh::FEAbstract::elem_type.

{ return elem_type; }
const std::vector<Point>& libMesh::FEAbstract::get_xyz ( ) const [inline, inherited]
Returns:
the xyz spatial locations of the quadrature points on the element.

Definition at line 227 of file fe_abstract.h.

References libMesh::FEAbstract::_fe_map.

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::ExactErrorEstimator::find_squared_element_error(), libMesh::DGFEMContext::neighbor_side_fe_reinit(), and libMesh::ProjectFEMSolution::operator()().

  { return this->_fe_map->get_xyz(); }
void libMesh::ReferenceCounter::increment_constructor_count ( const std::string &  name) [inline, protected, inherited]

Increments the construction counter. Should be called in the constructor of any derived class that will be reference counted.

Definition at line 163 of file reference_counter.h.

References libMesh::ReferenceCounter::_counts, libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

Referenced by libMesh::ReferenceCountedObject< RBParametrized >::ReferenceCountedObject().

{
  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
  std::pair<unsigned int, unsigned int>& p = _counts[name];

  p.first++;
}
void libMesh::ReferenceCounter::increment_destructor_count ( const std::string &  name) [inline, protected, inherited]

Increments the destruction counter. Should be called in the destructor of any derived class that will be reference counted.

Definition at line 176 of file reference_counter.h.

References libMesh::ReferenceCounter::_counts, libMesh::Quality::name(), and libMesh::Threads::spin_mtx.

Referenced by libMesh::ReferenceCountedObject< RBParametrized >::~ReferenceCountedObject().

{
  Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
  std::pair<unsigned int, unsigned int>& p = _counts[name];

  p.second++;
}
virtual bool libMesh::FEAbstract::is_hierarchic ( ) const [pure virtual, inherited]
Returns:
true if the finite element's higher order shape functions are hierarchic

Implemented in libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::InfFE< Dim, T_radial, T_map >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< 2, SUBDIVISION >, libMesh::FE< Dim, HIERARCHIC >, libMesh::FE< Dim, SCALAR >, libMesh::FE< Dim, L2_LAGRANGE >, libMesh::FE< Dim, NEDELEC_ONE >, libMesh::FE< Dim, HERMITE >, libMesh::FE< Dim, CLOUGH >, libMesh::FE< Dim, MONOMIAL >, libMesh::FE< Dim, XYZ >, libMesh::FE< Dim, LAGRANGE >, libMesh::FE< Dim, L2_HIERARCHIC >, libMesh::FE< Dim, LAGRANGE_VEC >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, and libMesh::FE< Dim, T >.

static unsigned int libMesh::ReferenceCounter::n_objects ( ) [inline, static, inherited]

Prints the number of outstanding (created, but not yet destroyed) objects.

Definition at line 79 of file reference_counter.h.

References libMesh::ReferenceCounter::_n_objects.

Referenced by libMesh::LibMeshInit::~LibMeshInit().

  { return _n_objects; }
bool libMesh::FEAbstract::on_reference_element ( const Point p,
const ElemType  t,
const Real  eps = TOLERANCE 
) [static, inherited]
Returns:
true if the point p is located on the reference element for element type t, false otherwise. Since we are doing floating point comparisons here the parameter eps can be specified to indicate a tolerance. For example, $ x \le 1 $ becomes $ x \le 1 + \epsilon $.

Definition at line 554 of file fe_abstract.C.

References libMesh::EDGE2, libMesh::EDGE3, libMesh::EDGE4, libMesh::HEX20, libMesh::HEX27, libMesh::HEX8, libMesh::INFHEX8, libMesh::INFPRISM6, libMesh::NODEELEM, libMesh::PRISM15, libMesh::PRISM18, libMesh::PRISM6, libMesh::PYRAMID13, libMesh::PYRAMID14, libMesh::PYRAMID5, libMesh::QUAD4, libMesh::QUAD8, libMesh::QUAD9, libMesh::Real, libMesh::TET10, libMesh::TET4, libMesh::TRI3, and libMesh::TRI6.

Referenced by libMesh::FE< Dim, T >::inverse_map().

{
  libmesh_assert_greater_equal (eps, 0.);

  const Real xi   = p(0);
#if LIBMESH_DIM > 1
  const Real eta  = p(1);
#else
  const Real eta  = 0.;
#endif
#if LIBMESH_DIM > 2
  const Real zeta = p(2);
#else
  const Real zeta  = 0.;
#endif

  switch (t)
    {
    case NODEELEM:
      {
        return (!xi && !eta && !zeta);
      }
    case EDGE2:
    case EDGE3:
    case EDGE4:
      {
        // The reference 1D element is [-1,1].
        if ((xi >= -1.-eps) &&
            (xi <=  1.+eps))
          return true;

        return false;
      }


    case TRI3:
    case TRI6:
      {
        // The reference triangle is isocoles
        // and is bound by xi=0, eta=0, and xi+eta=1.
        if ((xi  >= 0.-eps) &&
            (eta >= 0.-eps) &&
            ((xi + eta) <= 1.+eps))
          return true;

        return false;
      }


    case QUAD4:
    case QUAD8:
    case QUAD9:
      {
        // The reference quadrilateral element is [-1,1]^2.
        if ((xi  >= -1.-eps) &&
            (xi  <=  1.+eps) &&
            (eta >= -1.-eps) &&
            (eta <=  1.+eps))
          return true;

        return false;
      }


    case TET4:
    case TET10:
      {
        // The reference tetrahedral is isocoles
        // and is bound by xi=0, eta=0, zeta=0,
        // and xi+eta+zeta=1.
        if ((xi   >= 0.-eps) &&
            (eta  >= 0.-eps) &&
            (zeta >= 0.-eps) &&
            ((xi + eta + zeta) <= 1.+eps))
          return true;

        return false;
      }


    case HEX8:
    case HEX20:
    case HEX27:
      {
        /*
          if ((xi   >= -1.) &&
          (xi   <=  1.) &&
          (eta  >= -1.) &&
          (eta  <=  1.) &&
          (zeta >= -1.) &&
          (zeta <=  1.))
          return true;
        */

        // The reference hexahedral element is [-1,1]^3.
        if ((xi   >= -1.-eps) &&
            (xi   <=  1.+eps) &&
            (eta  >= -1.-eps) &&
            (eta  <=  1.+eps) &&
            (zeta >= -1.-eps) &&
            (zeta <=  1.+eps))
          {
            //    libMesh::out << "Strange Point:\n";
            //    p.print();
            return true;
          }

        return false;
      }

    case PRISM6:
    case PRISM15:
    case PRISM18:
      {
        // Figure this one out...
        // inside the reference triange with zeta in [-1,1]
        if ((xi   >=  0.-eps) &&
            (eta  >=  0.-eps) &&
            (zeta >= -1.-eps) &&
            (zeta <=  1.+eps) &&
            ((xi + eta) <= 1.+eps))
          return true;

        return false;
      }


    case PYRAMID5:
    case PYRAMID13:
    case PYRAMID14:
      {
        // Check that the point is on the same side of all the faces
        // by testing whether:
        //
        // n_i.(x - x_i) <= 0
        //
        // for each i, where:
        //   n_i is the outward normal of face i,
        //   x_i is a point on face i.
        if ((-eta - 1. + zeta <= 0.+eps) &&
            (  xi - 1. + zeta <= 0.+eps) &&
            ( eta - 1. + zeta <= 0.+eps) &&
            ( -xi - 1. + zeta <= 0.+eps) &&
            (            zeta >= 0.-eps))
          return true;

        return false;
      }

#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
    case INFHEX8:
      {
        // The reference infhex8 is a [-1,1]^3.
        if ((xi   >= -1.-eps) &&
            (xi   <=  1.+eps) &&
            (eta  >= -1.-eps) &&
            (eta  <=  1.+eps) &&
            (zeta >= -1.-eps) &&
            (zeta <=  1.+eps))
          {
            return true;
          }
        return false;
      }

    case INFPRISM6:
      {
        // inside the reference triange with zeta in [-1,1]
        if ((xi   >=  0.-eps) &&
            (eta  >=  0.-eps) &&
            (zeta >= -1.-eps) &&
            (zeta <=  1.+eps) &&
            ((xi + eta) <= 1.+eps))
          {
            return true;
          }

        return false;
      }
#endif

    default:
      libmesh_error_msg("ERROR: Unknown element type " << t);
    }

  // If we get here then the point is _not_ in the
  // reference element.   Better return false.

  return false;
}
template<typename OutputType >
void libMesh::FEGenericBase< OutputType >::print_d2phi ( std::ostream &  os) const [virtual]

Prints the value of each shape function's second derivatives at each quadrature point.

Implements libMesh::FEAbstract.

Definition at line 772 of file fe_base.C.

{
  for (unsigned int i=0; i<dphi.size(); ++i)
    for (unsigned int j=0; j<dphi[i].size(); ++j)
      os << " d2phi[" << i << "][" << j << "]=" << d2phi[i][j];
}
template<typename OutputType >
void libMesh::FEGenericBase< OutputType >::print_dphi ( std::ostream &  os) const [virtual]

Prints the value of each shape function's derivative at each quadrature point.

Implements libMesh::FEAbstract.

Definition at line 759 of file fe_base.C.

{
  for (unsigned int i=0; i<dphi.size(); ++i)
    for (unsigned int j=0; j<dphi[i].size(); ++j)
      os << " dphi[" << i << "][" << j << "]=" << dphi[i][j];
}
void libMesh::ReferenceCounter::print_info ( std::ostream &  out = libMesh::out) [static, inherited]

Prints the reference information, by default to libMesh::out.

Definition at line 88 of file reference_counter.C.

References libMesh::ReferenceCounter::_enable_print_counter, and libMesh::ReferenceCounter::get_info().

Referenced by libMesh::LibMeshInit::~LibMeshInit().

void libMesh::FEAbstract::print_info ( std::ostream &  os) const [inherited]

Prints all the relevant information about the current element.

Definition at line 761 of file fe_abstract.C.

References libMesh::FEAbstract::print_dphi(), libMesh::FEAbstract::print_JxW(), libMesh::FEAbstract::print_phi(), and libMesh::FEAbstract::print_xyz().

Referenced by libMesh::operator<<().

{
  os << "phi[i][j]: Shape function i at quadrature pt. j" << std::endl;
  this->print_phi(os);

  os << "dphi[i][j]: Shape function i's gradient at quadrature pt. j" << std::endl;
  this->print_dphi(os);

  os << "XYZ locations of the quadrature pts." << std::endl;
  this->print_xyz(os);

  os << "Values of JxW at the quadrature pts." << std::endl;
  this->print_JxW(os);
}
void libMesh::FEAbstract::print_JxW ( std::ostream &  os) const [inherited]

Prints the Jacobian times the weight for each quadrature point.

Definition at line 748 of file fe_abstract.C.

References libMesh::FEAbstract::_fe_map.

Referenced by libMesh::FEAbstract::print_info().

{
  this->_fe_map->print_JxW(os);
}
template<typename OutputType >
void libMesh::FEGenericBase< OutputType >::print_phi ( std::ostream &  os) const [virtual]

Prints the value of each shape function at each quadrature point.

Implements libMesh::FEAbstract.

Definition at line 748 of file fe_base.C.

{
  for (unsigned int i=0; i<phi.size(); ++i)
    for (unsigned int j=0; j<phi[i].size(); ++j)
      os << " phi[" << i << "][" << j << "]=" << phi[i][j] << std::endl;
}
void libMesh::FEAbstract::print_xyz ( std::ostream &  os) const [inherited]

Prints the spatial location of each quadrature point (on the physical element).

Definition at line 755 of file fe_abstract.C.

References libMesh::FEAbstract::_fe_map.

Referenced by libMesh::FEAbstract::print_info().

{
  this->_fe_map->print_xyz(os);
}
virtual void libMesh::FEAbstract::reinit ( const Elem elem,
const std::vector< Point > *const  pts = NULL,
const std::vector< Real > *const  weights = NULL 
) [pure virtual, inherited]

This is at the core of this class. Use this for each new element in the mesh. Reinitializes the requested physical element-dependent data based on the current element elem. By default the element data are computed at the quadrature points specified by the quadrature rule qrule, but any set of points on the reference element may be specified in the optional argument pts.

Note that the FE classes decide which data to initialize based on which accessor functions such as get_phi() or get_d2phi() have been called, so all such accessors should be called before the first reinit().

Implemented in libMesh::FEXYZ< Dim >, libMesh::FESubdivision, libMesh::InfFE< Dim, T_radial, T_map >, libMesh::FE< Dim, T >, libMesh::FE< 2, SUBDIVISION >, libMesh::FE< Dim, HIERARCHIC >, libMesh::FE< Dim, SCALAR >, libMesh::FE< Dim, L2_LAGRANGE >, libMesh::FE< Dim, NEDELEC_ONE >, libMesh::FE< Dim, HERMITE >, libMesh::FE< Dim, CLOUGH >, libMesh::FE< Dim, MONOMIAL >, libMesh::FE< Dim, XYZ >, libMesh::FE< Dim, LAGRANGE >, libMesh::FE< Dim, L2_HIERARCHIC >, and libMesh::FE< Dim, LAGRANGE_VEC >.

Referenced by libMesh::ExactSolution::_compute_error(), libMesh::FEMContext::build_new_fe(), and libMesh::ExactErrorEstimator::find_squared_element_error().

virtual void libMesh::FEAbstract::reinit ( const Elem elem,
const unsigned int  side,
const Real  tolerance = TOLERANCE,
const std::vector< Point > *const  pts = NULL,
const std::vector< Real > *const  weights = NULL 
) [pure virtual, inherited]

Reinitializes all the physical element-dependent data based on the side of the element elem. The tolerance paremeter is passed to the involved call to inverse_map(). By default the element data are computed at the quadrature points specified by the quadrature rule qrule, but any set of points on the reference side element may be specified in the optional argument pts.

Implemented in libMesh::FEXYZ< Dim >, libMesh::FESubdivision, libMesh::InfFE< Dim, T_radial, T_map >, libMesh::FE< Dim, T >, libMesh::FE< 2, SUBDIVISION >, libMesh::FE< Dim, HIERARCHIC >, libMesh::FE< Dim, SCALAR >, libMesh::FE< Dim, L2_LAGRANGE >, libMesh::FE< Dim, NEDELEC_ONE >, libMesh::FE< Dim, HERMITE >, libMesh::FE< Dim, CLOUGH >, libMesh::FE< Dim, MONOMIAL >, libMesh::FE< Dim, XYZ >, libMesh::FE< Dim, LAGRANGE >, libMesh::FE< Dim, L2_HIERARCHIC >, libMesh::FE< Dim, LAGRANGE_VEC >, libMesh::FEXYZ< Dim >, and libMesh::FEXYZ< Dim >.

virtual bool libMesh::FEAbstract::shapes_need_reinit ( ) const [protected, pure virtual, inherited]
Returns:
true when the shape functions (for this FEFamily) depend on the particular element, and therefore needs to be re-initialized for each new element. false otherwise.

Implemented in libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::InfFE< Dim, T_radial, T_map >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< 2, SUBDIVISION >, libMesh::FE< Dim, HIERARCHIC >, libMesh::FE< Dim, SCALAR >, libMesh::FE< Dim, L2_LAGRANGE >, libMesh::FE< Dim, NEDELEC_ONE >, libMesh::FE< Dim, HERMITE >, libMesh::FE< Dim, CLOUGH >, libMesh::FE< Dim, MONOMIAL >, libMesh::FE< Dim, XYZ >, libMesh::FE< Dim, LAGRANGE >, libMesh::FE< Dim, L2_HIERARCHIC >, libMesh::FE< Dim, LAGRANGE_VEC >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, libMesh::FE< Dim, T >, and libMesh::FE< Dim, T >.

virtual void libMesh::FEAbstract::side_map ( const Elem elem,
const Elem side,
const unsigned int  s,
const std::vector< Point > &  reference_side_points,
std::vector< Point > &  reference_points 
) [pure virtual, inherited]

Friends And Related Function Documentation

std::ostream& operator<< ( std::ostream &  os,
const FEAbstract fe 
) [friend, inherited]

Same as above, but allows you to print to a stream.

Definition at line 777 of file fe_abstract.C.

{
  fe.print_info(os);
  return os;
}

Member Data Documentation

bool libMesh::ReferenceCounter::_enable_print_counter = true [static, protected, inherited]

Flag to control whether reference count information is printed when print_info is called.

Definition at line 137 of file reference_counter.h.

Referenced by libMesh::ReferenceCounter::disable_print_counter_info(), libMesh::ReferenceCounter::enable_print_counter_info(), and libMesh::ReferenceCounter::print_info().

template<typename OutputType>
UniquePtr<FETransformationBase<OutputType> > libMesh::FEGenericBase< OutputType >::_fe_trans [protected]

Object that handles computing shape function values, gradients, etc in the physical domain.

Definition at line 490 of file fe_base.h.

Mutual exclusion object to enable thread-safe reference counting.

Definition at line 131 of file reference_counter.h.

Threads::atomic< unsigned int > libMesh::ReferenceCounter::_n_objects [static, protected, inherited]

The number of objects. Print the reference count information when the number returns to 0.

Definition at line 126 of file reference_counter.h.

Referenced by libMesh::ReferenceCounter::n_objects(), libMesh::ReferenceCounter::ReferenceCounter(), and libMesh::ReferenceCounter::~ReferenceCounter().

unsigned int libMesh::FEAbstract::_p_level [protected, inherited]

The p refinement level the current data structures are set up for.

Definition at line 570 of file fe_abstract.h.

Referenced by libMesh::FEAbstract::get_order(), and libMesh::FEAbstract::get_p_level().

bool libMesh::FEAbstract::calculate_curl_phi [mutable, protected, inherited]

Should we calculate shape function curls?

Definition at line 541 of file fe_abstract.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_curl_phi().

bool libMesh::FEAbstract::calculate_div_phi [mutable, protected, inherited]

Should we calculate shape function divergences?

Definition at line 546 of file fe_abstract.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_div_phi().

bool libMesh::FEAbstract::calculate_dphiref [mutable, protected, inherited]

Should we calculate reference shape function gradients?

Definition at line 551 of file fe_abstract.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_curl_phi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phideta2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidetadzeta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidx2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxdy(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxdz(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxi2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxideta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxidzeta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidy2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidydz(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidz2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidzeta2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_div_phi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphideta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidx(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidxi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidy(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidz(), and libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidzeta().

bool libMesh::FEAbstract::calculate_phi [mutable, protected, inherited]

Should we calculate shape functions?

Definition at line 526 of file fe_abstract.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_phi(), and libMesh::FESubdivision::init_shape_functions().

bool libMesh::FEAbstract::calculations_started [mutable, protected, inherited]

Have calculations with this object already been started? Then all get_* functions should already have been called.

Definition at line 521 of file fe_abstract.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_curl_phi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phideta2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidetadzeta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidx2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxdy(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxdz(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxi2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxideta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxidzeta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidy2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidydz(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidz2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidzeta2(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_div_phi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphideta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidx(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidxi(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidy(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidz(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidzeta(), libMesh::FEGenericBase< FEOutputType< T >::type >::get_phi(), and libMesh::FESubdivision::init_shape_functions().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::curl_phi [protected]

Shape function curl values. Only defined for vector types.

Definition at line 505 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_curl_phi().

template<typename OutputType>
std::vector<std::vector<OutputTensor> > libMesh::FEGenericBase< OutputType >::d2phi [protected]

Shape function second derivative values.

Definition at line 548 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phi().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phideta2 [protected]

Shape function second derivatives in the eta direction.

Definition at line 568 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phideta2().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidetadzeta [protected]

Shape function second derivatives in the eta-zeta direction.

Definition at line 573 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidetadzeta().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidx2 [protected]

Shape function second derivatives in the x direction.

Definition at line 583 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidx2().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidxdy [protected]

Shape function second derivatives in the x-y direction.

Definition at line 588 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxdy().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidxdz [protected]

Shape function second derivatives in the x-z direction.

Definition at line 593 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxdz().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidxi2 [protected]

Shape function second derivatives in the xi direction.

Definition at line 553 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxi2().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidxideta [protected]

Shape function second derivatives in the xi-eta direction.

Definition at line 558 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxideta().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidxidzeta [protected]

Shape function second derivatives in the xi-zeta direction.

Definition at line 563 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidxidzeta().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidy2 [protected]

Shape function second derivatives in the y direction.

Definition at line 598 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidy2().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidydz [protected]

Shape function second derivatives in the y-z direction.

Definition at line 603 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidydz().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidz2 [protected]

Shape function second derivatives in the z direction.

Definition at line 608 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidz2().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::d2phidzeta2 [protected]

Shape function second derivatives in the zeta direction.

Definition at line 578 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_d2phidzeta2().

const unsigned int libMesh::FEAbstract::dim [protected, inherited]

The dimensionality of the object

Definition at line 515 of file fe_abstract.h.

template<typename OutputType>
std::vector<std::vector<OutputDivergence> > libMesh::FEGenericBase< OutputType >::div_phi [protected]

Shape function divergence values. Only defined for vector types.

Definition at line 510 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_div_phi().

template<typename OutputType>
std::vector<OutputGradient> libMesh::FEGenericBase< OutputType >::dphase [protected]

Used for certain infinite element families: the first derivatives of the phase term in global coordinates, over all quadrature points.

Definition at line 626 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphase().

template<typename OutputType>
std::vector<std::vector<OutputGradient> > libMesh::FEGenericBase< OutputType >::dphi [protected]

Shape function derivative values.

Definition at line 500 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphi().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::dphideta [protected]

Shape function derivatives in the eta direction.

Definition at line 520 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphideta().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::dphidx [protected]

Shape function derivatives in the x direction.

Definition at line 530 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidx().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::dphidxi [protected]

Shape function derivatives in the xi direction.

Definition at line 515 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidxi().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::dphidy [protected]

Shape function derivatives in the y direction.

Definition at line 535 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidy().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::dphidz [protected]

Shape function derivatives in the z direction.

Definition at line 540 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidz().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::dphidzeta [protected]

Shape function derivatives in the zeta direction.

Definition at line 525 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_dphidzeta().

template<typename OutputType>
std::vector<RealGradient> libMesh::FEGenericBase< OutputType >::dweight [protected]

Used for certain infinite element families: the global derivative of the additional radial weight $ 1/{r^2} $, over all quadrature points.

Definition at line 633 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_Sobolev_dweight().

ElemType libMesh::FEAbstract::elem_type [protected, inherited]

The element type the current data structures are set up for.

Definition at line 564 of file fe_abstract.h.

Referenced by libMesh::FESubdivision::attach_quadrature_rule(), and libMesh::FEAbstract::get_type().

template<typename OutputType>
std::vector<std::vector<OutputShape> > libMesh::FEGenericBase< OutputType >::phi [protected]

Shape function values.

Definition at line 495 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_phi().

QBase* libMesh::FEAbstract::qrule [protected, inherited]

A pointer to the quadrature rule employed

Definition at line 575 of file fe_abstract.h.

Referenced by libMesh::FESubdivision::attach_quadrature_rule().

bool libMesh::FEAbstract::shapes_on_quadrature [protected, inherited]

A flag indicating if current data structures correspond to quadrature rule points

Definition at line 581 of file fe_abstract.h.

template<typename OutputType>
std::vector<Real> libMesh::FEGenericBase< OutputType >::weight [protected]

Used for certain infinite element families: the additional radial weight $ 1/{r^2} $ in local coordinates, over all quadrature points.

Definition at line 640 of file fe_base.h.

Referenced by libMesh::FEGenericBase< FEOutputType< T >::type >::get_Sobolev_weight().


The documentation for this class was generated from the following files: