#include <fe.h>
FE (const FEType &fet)
virtual unsigned int n_shape_functions () const
virtual FEContinuity get_continuity () const
virtual bool is_hierarchic () const
virtual void reinit (const Elem *elem, const std::vector< Point > *const pts=NULL)
virtual void reinit (const Elem *elem, const unsigned int side, const Real tolerance=TOLERANCE)
virtual void edge_reinit (const Elem *elem, const unsigned int edge, const Real tolerance=TOLERANCE)
virtual void attach_quadrature_rule (QBase *q)
virtual unsigned int n_quadrature_points () const
void init_base_shape_functions (const std::vector< Point > &qp, const Elem *e)
virtual bool shapes_need_reinit () const
virtual void init_shape_functions (const std::vector< Point > &qp, const Elem *e)
void init_face_shape_functions (const std::vector< Point > &qp, const Elem *side)
void init_edge_shape_functions (const std::vector< Point > &qp, const Elem *edge)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType type, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType type, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType type, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType type, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType type, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType type, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order order, const unsigned int i, const Point &p)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int i, const Point &)
template<> Real shape (const Elem *, const Order, const unsigned int i, const Point &)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape (const ElemType, const Order, const unsigned int, const Point &)
template<> Real shape (const Elem *elem, const Order order, const unsigned int i, const Point &p)
template<> Real shape_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
template<> Real shape_second_deriv (const ElemType, const Order, const unsigned int, const unsigned int, const Point &)
template<> Real shape_second_deriv (const Elem *elem, const Order order, const unsigned int i, const unsigned int j, const Point &p)
const std::vector< Point > & get_xyz () const
const std::vector< std::vector< Real > > & get_phi () const
const std::vector< Real > & get_JxW () const
const std::vector< std::vector< RealGradient > > & get_dphi () const
const std::vector< std::vector< Real > > & get_dphidx () const
const std::vector< std::vector< Real > > & get_dphidy () const
const std::vector< std::vector< Real > > & get_dphidz () const
const std::vector< std::vector< Real > > & get_dphidxi () const
const std::vector< std::vector< Real > > & get_dphideta () const
const std::vector< std::vector< Real > > & get_dphidzeta () const
const std::vector< std::vector< RealTensor > > & get_d2phi () const
const std::vector< std::vector< Real > > & get_d2phidx2 () const
const std::vector< std::vector< Real > > & get_d2phidxdy () const
const std::vector< std::vector< Real > > & get_d2phidxdz () const
const std::vector< std::vector< Real > > & get_d2phidy2 () const
const std::vector< std::vector< Real > > & get_d2phidydz () const
const std::vector< std::vector< Real > > & get_d2phidz2 () 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< RealGradient > & get_dphase () const
const std::vector< Real > & get_Sobolev_weight () const
const std::vector< RealGradient > & get_Sobolev_dweight () const
const std::vector< std::vector< Point > > & get_tangents () const
const std::vector< Point > & get_normals () const
const std::vector< Real > & get_curvatures () const
ElemType get_type () const
unsigned int get_p_level () const
FEType get_fe_type () const
Order get_order () const
FEFamily get_family () const
void print_JxW (std::ostream &os) const
void print_phi (std::ostream &os) const
void print_dphi (std::ostream &os) const
void print_d2phi (std::ostream &os) const
void print_xyz (std::ostream &os) const
void print_info (std::ostream &os) const
static Real shape (const ElemType t, const Order o, const unsigned int i, const Point &p)
static Real shape (const Elem *elem, const Order o, const unsigned int i, const Point &p)
static Real shape_deriv (const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
static Real shape_deriv (const Elem *elem, const Order o, const unsigned int i, const unsigned int j, const Point &p)
static Real shape_second_deriv (const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
static Real shape_second_deriv (const Elem *elem, const Order o, const unsigned int i, const unsigned int j, const Point &p)
static void nodal_soln (const Elem *elem, const Order o, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln)
static unsigned int n_shape_functions (const ElemType t, const Order o)
static unsigned int n_dofs (const ElemType t, const Order o)
static unsigned int n_dofs_at_node (const ElemType t, const Order o, const unsigned int n)
static unsigned int n_dofs_per_elem (const ElemType t, const Order o)
static void dofs_on_side (const Elem *const elem, const Order o, unsigned int s, std::vector< unsigned int > &di)
static void dofs_on_edge (const Elem *const elem, const Order o, unsigned int e, std::vector< unsigned int > &di)
static Point inverse_map (const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)
static void inverse_map (const Elem *elem, const std::vector< Point > &physical_points, std::vector< Point > &reference_points, const Real tolerance=TOLERANCE, const bool secure=true)
static void compute_constraints (DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
static Point map (const Elem *elem, const Point &reference_point)
static Point map_xi (const Elem *elem, const Point &reference_point)
static Point map_eta (const Elem *elem, const Point &reference_point)
static Point map_zeta (const Elem *elem, const Point &reference_point)
static AutoPtr< FEBase > build (const unsigned int dim, const FEType &type)
static AutoPtr< FEBase > build_InfFE (const unsigned int dim, const FEType &type)
static bool on_reference_element (const Point &p, const ElemType t, const Real eps=TOLERANCE)
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, PeriodicBoundaries &boundaries, const MeshBase &mesh, const unsigned int variable_number, const Elem *elem)
static void print_info ()
static std::string get_info ()
static unsigned int n_objects ()
typedef std::map< std::string, std::pair< unsigned int, unsigned int > > Counts
virtual void compute_map (const std::vector< Real > &qw, const Elem *e)
virtual void compute_affine_map (const std::vector< Real > &qw, const Elem *e)
void compute_single_point_map (const std::vector< Real > &qw, const Elem *e, unsigned int p)
void resize_map_vectors (unsigned int n_qp)
void compute_face_map (const std::vector< Real > &qw, const Elem *side)
void compute_edge_map (const std::vector< Real > &qw, const Elem *side)
virtual void compute_shape_functions (const Elem *)
Real dxdxi_map (const unsigned int p) const
Real dydxi_map (const unsigned int p) const
Real dzdxi_map (const unsigned int p) const
Real dxdeta_map (const unsigned int p) const
Real dydeta_map (const unsigned int p) const
Real dzdeta_map (const unsigned int p) const
Real dxdzeta_map (const unsigned int p) const
Real dydzeta_map (const unsigned int p) const
Real dzdzeta_map (const unsigned int p) const
void increment_constructor_count (const std::string &name)
void increment_destructor_count (const std::string &name)
std::vector< Point > cached_nodes
unsigned int last_side
unsigned int last_edge
const unsigned int dim
std::vector< Point > xyz
std::vector< RealGradient > dxyzdxi_map
std::vector< RealGradient > dxyzdeta_map
std::vector< RealGradient > dxyzdzeta_map
std::vector< RealGradient > d2xyzdxi2_map
std::vector< RealGradient > d2xyzdxideta_map
std::vector< RealGradient > d2xyzdeta2_map
std::vector< RealGradient > d2xyzdxidzeta_map
std::vector< RealGradient > d2xyzdetadzeta_map
std::vector< RealGradient > d2xyzdzeta2_map
std::vector< Real > dxidx_map
std::vector< Real > dxidy_map
std::vector< Real > dxidz_map
std::vector< Real > detadx_map
std::vector< Real > detady_map
std::vector< Real > detadz_map
std::vector< Real > dzetadx_map
std::vector< Real > dzetady_map
std::vector< Real > dzetadz_map
std::vector< std::vector< Real > > phi
bool calculations_started
bool calculate_phi
bool calculate_dphi
bool calculate_d2phi
std::vector< std::vector< RealGradient > > dphi
std::vector< std::vector< Real > > dphidxi
std::vector< std::vector< Real > > dphideta
std::vector< std::vector< Real > > dphidzeta
std::vector< std::vector< Real > > dphidx
std::vector< std::vector< Real > > dphidy
std::vector< std::vector< Real > > dphidz
std::vector< std::vector< RealTensor > > d2phi
std::vector< std::vector< Real > > d2phidxi2
std::vector< std::vector< Real > > d2phidxideta
std::vector< std::vector< Real > > d2phidxidzeta
std::vector< std::vector< Real > > d2phideta2
std::vector< std::vector< Real > > d2phidetadzeta
std::vector< std::vector< Real > > d2phidzeta2
std::vector< std::vector< Real > > d2phidx2
std::vector< std::vector< Real > > d2phidxdy
std::vector< std::vector< Real > > d2phidxdz
std::vector< std::vector< Real > > d2phidy2
std::vector< std::vector< Real > > d2phidydz
std::vector< std::vector< Real > > d2phidz2
std::vector< std::vector< Real > > phi_map
std::vector< std::vector< Real > > dphidxi_map
std::vector< std::vector< Real > > dphideta_map
std::vector< std::vector< Real > > dphidzeta_map
std::vector< std::vector< Real > > d2phidxi2_map
std::vector< std::vector< Real > > d2phidxideta_map
std::vector< std::vector< Real > > d2phidxidzeta_map
std::vector< std::vector< Real > > d2phideta2_map
std::vector< std::vector< Real > > d2phidetadzeta_map
std::vector< std::vector< Real > > d2phidzeta2_map
std::vector< std::vector< Real > > psi_map
std::vector< std::vector< Real > > dpsidxi_map
std::vector< std::vector< Real > > dpsideta_map
std::vector< std::vector< Real > > d2psidxi2_map
std::vector< std::vector< Real > > d2psidxideta_map
std::vector< std::vector< Real > > d2psideta2_map
std::vector< RealGradient > dphase
std::vector< RealGradient > dweight
std::vector< Real > weight
std::vector< std::vector< Point > > tangents
std::vector< Point > normals
std::vector< Real > curvatures
std::vector< Real > JxW
const FEType fe_type
ElemType elem_type
unsigned int _p_level
QBase * qrule
bool shapes_on_quadrature
static Counts _counts
static Threads::atomic< unsigned int > _n_objects
static Threads::spin_mutex _mutex
class InfFE
std::ostream & operator<< (std::ostream &os, const FEBase &fe)
Author:
Date:
Version:
Revision:
Definition at line 65 of file fe.h.
Definition at line 105 of file reference_counter.h.
Definition at line 745 of file fe.h.
References FEType::family, and FEBase::fe_type.
:
FEBase (Dim,fet),
last_side(libMesh::invalid_uint),
last_edge(libMesh::invalid_uint)
{
// Sanity check. Make sure the
// Family specified in the template instantiation
// matches the one in the FEType object
libmesh_assert (T == fe_type.family);
}
Implements FEBase.
Definition at line 42 of file fe.C.
References libMeshEnums::INVALID_ELEM.
{
libmesh_assert (q != NULL);
qrule = q;
// make sure we don't cache results from a previous quadrature rule
elem_type = INVALID_ELEM;
return;
}
Definition at line 43 of file fe_base.C.
References libMeshEnums::BERNSTEIN, libMeshEnums::CLOUGH, FEType::family, libMeshEnums::HERMITE, libMeshEnums::HIERARCHIC, libMeshEnums::LAGRANGE, libMeshEnums::MONOMIAL, libMeshEnums::SCALAR, libMeshEnums::SZABAB, and libMeshEnums::XYZ.
Referenced by ExactSolution::_compute_error(), UniformRefinementEstimator::_estimate_error(), System::calculate_norm(), FEBase::coarsened_dof_values(), FEBase::compute_periodic_constraints(), FEBase::compute_proj_constraints(), JumpErrorEstimator::estimate_error(), ExactErrorEstimator::estimate_error(), FEMContext::FEMContext(), MeshFunction::gradient(), MeshFunction::hessian(), InfFE< Dim, T_radial, T_map >::InfFE(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), System::ProjectVector::operator()(), PatchRecoveryErrorEstimator::EstimateError::operator()(), InfFE< Dim, T_radial, T_map >::reinit(), HPCoarsenTest::select_refinement(), DofMap::use_coupled_neighbor_dofs(), and Elem::volume().
{
// The stupid AutoPtr<FEBase> ap(); return ap;
// construct is required to satisfy IBM's xlC
switch (dim)
{
// 0D
case 0:
{
switch (fet.family)
{
case CLOUGH:
{
AutoPtr<FEBase> ap(new FE<0,CLOUGH>(fet));
return ap;
}
case HERMITE:
{
AutoPtr<FEBase> ap(new FE<0,HERMITE>(fet));
return ap;
}
case LAGRANGE:
{
AutoPtr<FEBase> ap(new FE<0,LAGRANGE>(fet));
return ap;
}
case HIERARCHIC:
{
AutoPtr<FEBase> ap(new FE<0,HIERARCHIC>(fet));
return ap;
}
case MONOMIAL:
{
AutoPtr<FEBase> ap(new FE<0,MONOMIAL>(fet));
return ap;
}
#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
case SZABAB:
{
AutoPtr<FEBase> ap(new FE<0,SZABAB>(fet));
return ap;
}
case BERNSTEIN:
{
AutoPtr<FEBase> ap(new FE<0,BERNSTEIN>(fet));
return ap;
}
#endif
case XYZ:
{
AutoPtr<FEBase> ap(new FEXYZ<0>(fet));
return ap;
}
case SCALAR:
{
AutoPtr<FEBase> ap(new FEScalar<0>(fet));
return ap;
}
default:
std::cout << 'ERROR: Bad FEType.family= ' << fet.family << std::endl;
libmesh_error();
}
}
// 1D
case 1:
{
switch (fet.family)
{
case CLOUGH:
{
AutoPtr<FEBase> ap(new FE<1,CLOUGH>(fet));
return ap;
}
case HERMITE:
{
AutoPtr<FEBase> ap(new FE<1,HERMITE>(fet));
return ap;
}
case LAGRANGE:
{
AutoPtr<FEBase> ap(new FE<1,LAGRANGE>(fet));
return ap;
}
case HIERARCHIC:
{
AutoPtr<FEBase> ap(new FE<1,HIERARCHIC>(fet));
return ap;
}
case MONOMIAL:
{
AutoPtr<FEBase> ap(new FE<1,MONOMIAL>(fet));
return ap;
}
#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
case SZABAB:
{
AutoPtr<FEBase> ap(new FE<1,SZABAB>(fet));
return ap;
}
case BERNSTEIN:
{
AutoPtr<FEBase> ap(new FE<1,BERNSTEIN>(fet));
return ap;
}
#endif
case XYZ:
{
AutoPtr<FEBase> ap(new FEXYZ<1>(fet));
return ap;
}
case SCALAR:
{
AutoPtr<FEBase> ap(new FEScalar<1>(fet));
return ap;
}
default:
std::cout << 'ERROR: Bad FEType.family= ' << fet.family << std::endl;
libmesh_error();
}
}
// 2D
case 2:
{
switch (fet.family)
{
case CLOUGH:
{
AutoPtr<FEBase> ap(new FE<2,CLOUGH>(fet));
return ap;
}
case HERMITE:
{
AutoPtr<FEBase> ap(new FE<2,HERMITE>(fet));
return ap;
}
case LAGRANGE:
{
AutoPtr<FEBase> ap(new FE<2,LAGRANGE>(fet));
return ap;
}
case HIERARCHIC:
{
AutoPtr<FEBase> ap(new FE<2,HIERARCHIC>(fet));
return ap;
}
case MONOMIAL:
{
AutoPtr<FEBase> ap(new FE<2,MONOMIAL>(fet));
return ap;
}
#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
case SZABAB:
{
AutoPtr<FEBase> ap(new FE<2,SZABAB>(fet));
return ap;
}
case BERNSTEIN:
{
AutoPtr<FEBase> ap(new FE<2,BERNSTEIN>(fet));
return ap;
}
#endif
case XYZ:
{
AutoPtr<FEBase> ap(new FEXYZ<2>(fet));
return ap;
}
case SCALAR:
{
AutoPtr<FEBase> ap(new FEScalar<2>(fet));
return ap;
}
default:
std::cout << 'ERROR: Bad FEType.family= ' << fet.family << std::endl;
libmesh_error();
}
}
// 3D
case 3:
{
switch (fet.family)
{
case CLOUGH:
{
std::cout << 'ERROR: Clough-Tocher elements currently only support 1D and 2D' <<
std::endl;
libmesh_error();
}
case HERMITE:
{
AutoPtr<FEBase> ap(new FE<3,HERMITE>(fet));
return ap;
}
case LAGRANGE:
{
AutoPtr<FEBase> ap(new FE<3,LAGRANGE>(fet));
return ap;
}
case HIERARCHIC:
{
AutoPtr<FEBase> ap(new FE<3,HIERARCHIC>(fet));
return ap;
}
case MONOMIAL:
{
AutoPtr<FEBase> ap(new FE<3,MONOMIAL>(fet));
return ap;
}
#ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES
case SZABAB:
{
AutoPtr<FEBase> ap(new FE<3,SZABAB>(fet));
return ap;
}
case BERNSTEIN:
{
AutoPtr<FEBase> ap(new FE<3,BERNSTEIN>(fet));
return ap;
}
#endif
case XYZ:
{
AutoPtr<FEBase> ap(new FEXYZ<3>(fet));
return ap;
}
case SCALAR:
{
AutoPtr<FEBase> ap(new FEScalar<3>(fet));
return ap;
}
default:
std::cout << 'ERROR: Bad FEType.family= ' << fet.family << std::endl;
libmesh_error();
}
}
default:
libmesh_error();
}
libmesh_error();
AutoPtr<FEBase> ap(NULL);
return ap;
}
Definition at line 339 of file fe_base.C.
References libMeshEnums::CARTESIAN, FEType::inf_map, libMeshEnums::INFINITE_MAP, libMeshEnums::JACOBI_20_00, libMeshEnums::JACOBI_30_00, libMeshEnums::LAGRANGE, libMeshEnums::LEGENDRE, and FEType::radial_family.
{
// The stupid AutoPtr<FEBase> ap(); return ap;
// construct is required to satisfy IBM's xlC
switch (dim)
{
// 1D
case 1:
{
switch (fet.radial_family)
{
case INFINITE_MAP:
{
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with FEFamily = ' << fet.radial_family << std::endl;
libmesh_error();
}
case JACOBI_20_00:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<1,JACOBI_20_00,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case JACOBI_30_00:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<1,JACOBI_30_00,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case LEGENDRE:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<1,LEGENDRE,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case LAGRANGE:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<1,LAGRANGE,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Bad FEType.radial_family= ' << fet.radial_family << std::endl;
libmesh_error();
}
}
// 2D
case 2:
{
switch (fet.radial_family)
{
case INFINITE_MAP:
{
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with FEFamily = ' << fet.radial_family << std::endl;
libmesh_error();
}
case JACOBI_20_00:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<2,JACOBI_20_00,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case JACOBI_30_00:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<2,JACOBI_30_00,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case LEGENDRE:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<2,LEGENDRE,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case LAGRANGE:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<2,LAGRANGE,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Bad FEType.radial_family= ' << fet.radial_family << std::endl;
libmesh_error();
}
}
// 3D
case 3:
{
switch (fet.radial_family)
{
case INFINITE_MAP:
{
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with FEFamily = ' << fet.radial_family << std::endl;
libmesh_error();
}
case JACOBI_20_00:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<3,JACOBI_20_00,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case JACOBI_30_00:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<3,JACOBI_30_00,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case LEGENDRE:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<3,LEGENDRE,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
case LAGRANGE:
{
switch (fet.inf_map)
{
case CARTESIAN:
{
AutoPtr<FEBase> ap(new InfFE<3,LAGRANGE,CARTESIAN>(fet));
return ap;
}
default:
std::cerr << 'ERROR: Don't build an infinite element ' << std::endl
<< ' with InfMapType = ' << fet.inf_map << std::endl;
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Bad FEType.radial_family= ' << fet.radial_family << std::endl;
libmesh_error();
}
}
default:
libmesh_error();
}
libmesh_error();
AutoPtr<FEBase> ap(NULL);
return ap;
}
Definition at line 1118 of file fe_base.C.
References TypeVector< T >::add_scaled(), FEBase::build(), libMeshEnums::C_ONE, Elem::child(), DenseMatrix< T >::cholesky_solve(), FEType::default_quadrature_rule(), Elem::dim(), FEBase::dim, libMeshEnums::DISCONTINUOUS, DofMap::dof_indices(), FEInterface::dofs_on_edge(), FEInterface::dofs_on_side(), FEBase::elem_type, FEBase::fe_type, FEInterface::inverse_map(), Elem::is_child_on_edge(), Elem::is_child_on_side(), Elem::is_vertex(), FEBase::JxW, Elem::max_descendant_p_level(), Elem::n_children(), FEInterface::n_dofs(), FEInterface::n_dofs_at_node(), Elem::n_edges(), Elem::n_nodes(), MeshTools::n_nodes(), QBase::n_points(), Elem::n_sides(), DofMap::old_dof_indices(), FEType::order, Elem::p_level(), FEBase::qrule, DenseMatrix< T >::resize(), DenseVector< T >::resize(), Elem::type(), DofMap::variable_type(), libMesh::zero, DenseMatrix< T >::zero(), and DenseVector< T >::zero().
Referenced by JumpErrorEstimator::estimate_error(), ExactErrorEstimator::estimate_error(), and System::ProjectVector::operator()().
{
// Side/edge 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);
AutoPtr<FEBase> fe (FEBase::build(dim, base_fe_type));
AutoPtr<FEBase> fe_coarse (FEBase::build(dim, base_fe_type));
AutoPtr<QBase> qrule (base_fe_type.default_quadrature_rule(dim));
AutoPtr<QBase> qedgerule (base_fe_type.default_quadrature_rule(1));
AutoPtr<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<Real> >& phi_values =
fe->get_phi();
const std::vector<std::vector<Real> >& 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<RealGradient> > *dphi_values =
NULL;
const std::vector<std::vector<RealGradient> > *dphi_coarse =
NULL;
const FEContinuity cont = fe->get_continuity();
if (cont == C_ONE)
{
const std::vector<std::vector<RealGradient> >&
ref_dphi_values = fe->get_dphi();
dphi_values = &ref_dphi_values;
const std::vector<std::vector<RealGradient> >&
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<unsigned int> 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<unsigned int> 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 = 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
Number fineval = libMesh::zero;
// solution grad at the quadrature point
Gradient 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.add_scaled((*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) -=
phi_coarse[i][qp] *
phi_coarse[j][qp] * JxW[qp] *
Ue(j);
else
Ke(freei,freej) +=
phi_coarse[i][qp] *
phi_coarse[j][qp] * JxW[qp];
if (cont == C_ONE)
{
if (dof_is_fixed[j])
Fe(freei) -=
((*dphi_coarse)[i][qp] *
(*dphi_coarse)[j][qp]) *
JxW[qp] *
Ue(j);
else
Ke(freei,freej) +=
((*dphi_coarse)[i][qp] *
(*dphi_coarse)[j][qp])
* JxW[qp];
}
if (!dof_is_fixed[j])
freej++;
}
Fe(freei) += phi_coarse[i][qp] *
fineval * JxW[qp];
if (cont == C_ONE)
Fe(freei) +=
(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<unsigned int> 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 = 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
Number fineval = libMesh::zero;
// solution grad at the quadrature point
Gradient 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.add_scaled((*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) -=
phi_coarse[i][qp] *
phi_coarse[j][qp] * JxW[qp] *
Ue(j);
else
Ke(freei,freej) +=
phi_coarse[i][qp] *
phi_coarse[j][qp] * JxW[qp];
if (cont == C_ONE)
{
if (dof_is_fixed[j])
Fe(freei) -=
((*dphi_coarse)[i][qp] *
(*dphi_coarse)[j][qp]) *
JxW[qp] *
Ue(j);
else
Ke(freei,freej) +=
((*dphi_coarse)[i][qp] *
(*dphi_coarse)[j][qp])
* JxW[qp];
}
if (!dof_is_fixed[j])
freej++;
}
Fe(freei) += (fineval * phi_coarse[i][qp]) * JxW[qp];
if (cont == C_ONE)
Fe(freei) +=
(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<unsigned int> 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 = 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
Number fineval = libMesh::zero;
// solution grad at the quadrature point
Gradient 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.add_scaled((*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) -=
phi_coarse[i][qp] *
phi_coarse[j][qp] * JxW[qp] *
Ue(j);
else
Ke(freei,freej) +=
phi_coarse[i][qp] *
phi_coarse[j][qp] * JxW[qp];
if (cont == C_ONE)
{
if (dof_is_fixed[j])
Fe(freei) -=
((*dphi_coarse)[i][qp] *
(*dphi_coarse)[j][qp]) *
JxW[qp] * Ue(j);
else
Ke(freei,freej) +=
((*dphi_coarse)[i][qp] *
(*dphi_coarse)[j][qp]) * JxW[qp];
}
if (!dof_is_fixed[j])
freej++;
}
Fe(freei) += phi_coarse[i][qp] * fineval *
JxW[qp];
if (cont == C_ONE)
Fe(freei) += (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);
dof_is_fixed[free_dof[i]] = true;
}
// Make sure every DoF got reached!
for (unsigned int i=0; i != new_n_dofs; ++i)
libmesh_assert(dof_is_fixed[i]);
}
Definition at line 410 of file fe_map.C.
References FEBase::compute_single_point_map(), FEBase::d2xyzdeta2_map, FEBase::d2xyzdetadzeta_map, FEBase::d2xyzdxi2_map, FEBase::d2xyzdxideta_map, FEBase::d2xyzdxidzeta_map, FEBase::d2xyzdzeta2_map, FEBase::detadx_map, FEBase::detady_map, FEBase::detadz_map, FEBase::dim, FEBase::dxidx_map, FEBase::dxidy_map, FEBase::dxidz_map, FEBase::dxyzdeta_map, FEBase::dxyzdxi_map, FEBase::dxyzdzeta_map, FEBase::dzetadx_map, FEBase::dzetady_map, FEBase::dzetadz_map, FEBase::JxW, FEBase::phi_map, Elem::point(), FEBase::resize_map_vectors(), and FEBase::xyz.
Referenced by FEBase::compute_map().
{
// Start logging the map computation.
START_LOG('compute_affine_map()', 'FE');
libmesh_assert (elem != NULL);
const unsigned int n_qp = qw.size();
// Resize the vectors to hold data at the quadrature points
this->resize_map_vectors(n_qp);
// Compute map at quadrature point 0
this->compute_single_point_map(qw, elem, 0);
// Compute xyz at all other quadrature points
for (unsigned int p=1; p<n_qp; p++)
{
xyz[p].zero();
for (unsigned int i=0; i<phi_map.size(); i++) // sum over the nodes
xyz[p].add_scaled (elem->point(i), phi_map[i][p] );
}
// Copy other map data from quadrature point 0
for (unsigned int p=1; p<n_qp; p++) // for each extra quadrature point
{
dxyzdxi_map[p] = dxyzdxi_map[0];
dxidx_map[p] = dxidx_map[0];
dxidy_map[p] = dxidy_map[0];
dxidz_map[p] = dxidz_map[0];
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
// The map should be affine, so second derivatives are zero
d2xyzdxi2_map[p] = 0.;
#endif
if (this->dim > 1)
{
dxyzdeta_map[p] = dxyzdeta_map[0];
detadx_map[p] = detadx_map[0];
detady_map[p] = detady_map[0];
detadz_map[p] = detadz_map[0];
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxideta_map[p] = 0.;
d2xyzdeta2_map[p] = 0.;
#endif
if (this->dim > 2)
{
dxyzdzeta_map[p] = dxyzdzeta_map[0];
dzetadx_map[p] = dzetadx_map[0];
dzetady_map[p] = dzetady_map[0];
dzetadz_map[p] = dzetadz_map[0];
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxidzeta_map[p] = 0.;
d2xyzdetadzeta_map[p] = 0.;
d2xyzdzeta2_map[p] = 0.;
#endif
}
}
JxW[p] = JxW[0] / qw[0] * qw[p];
}
STOP_LOG('compute_affine_map()', 'FE');
}
Definition at line 294 of file fe_clough.C.
References FEBase::compute_proj_constraints().
{
compute_proj_constraints(constraints, dof_map, variable_number, elem);
}
Definition at line 623 of file fe_boundary.C.
References FEBase::compute_face_map(), FEBase::curvatures, FEBase::d2psidxi2_map, FEBase::d2xyzdeta2_map, FEBase::d2xyzdxi2_map, FEBase::d2xyzdxideta_map, FEBase::dim, FEBase::dpsidxi_map, FEBase::dxdxi_map(), FEBase::dxyzdeta_map, FEBase::dxyzdxi_map, FEBase::dydxi_map(), FEBase::dzdxi_map(), FEBase::JxW, FEBase::normals, Elem::point(), FEBase::psi_map, FEBase::tangents, and FEBase::xyz.
Referenced by FE< Dim, T >::edge_reinit().
{
libmesh_assert (edge != NULL);
if (dim == 2)
{
// A 2D finite element living in either 2D or 3D space.
// The edges here are the sides of the element, so the
// (misnamed) compute_face_map function does what we want
FEBase::compute_face_map(qw, edge);
return;
}
libmesh_assert (dim == 3); // 1D is unnecessary and currently unsupported
START_LOG('compute_edge_map()', 'FE');
// The number of quadrature points.
const unsigned int n_qp = qw.size();
// Resize the vectors to hold data at the quadrature points
xyz.resize(n_qp);
dxyzdxi_map.resize(n_qp);
dxyzdeta_map.resize(n_qp);
d2xyzdxi2_map.resize(n_qp);
d2xyzdxideta_map.resize(n_qp);
d2xyzdeta2_map.resize(n_qp);
tangents.resize(n_qp);
normals.resize(n_qp);
curvatures.resize(n_qp);
JxW.resize(n_qp);
// Clear the entities that will be summed
for (unsigned int p=0; p<n_qp; p++)
{
tangents[p].resize(1);
xyz[p].zero();
dxyzdxi_map[p].zero();
dxyzdeta_map[p].zero();
d2xyzdxi2_map[p].zero();
d2xyzdxideta_map[p].zero();
d2xyzdeta2_map[p].zero();
}
// compute x, dxdxi at the quadrature points
for (unsigned int i=0; i<psi_map.size(); i++) // sum over the nodes
{
const Point& edge_point = edge->point(i);
for (unsigned int p=0; p<n_qp; p++) // for each quadrature point...
{
xyz[p].add_scaled (edge_point, psi_map[i][p]);
dxyzdxi_map[p].add_scaled (edge_point, dpsidxi_map[i][p]);
d2xyzdxi2_map[p].add_scaled (edge_point, d2psidxi2_map[i][p]);
}
}
// Compute the tangents at the quadrature point
// FIXME: normals (plural!) and curvatures are uncalculated
for (unsigned int p=0; p<n_qp; p++)
{
const Point n = dxyzdxi_map[p].cross(dxyzdeta_map[p]);
tangents[p][0] = dxyzdxi_map[p].unit();
// compute the jacobian at the quadrature points
const Real jac = std::sqrt(dxdxi_map(p)*dxdxi_map(p) +
dydxi_map(p)*dydxi_map(p) +
dzdxi_map(p)*dzdxi_map(p));
libmesh_assert (jac > 0.);
JxW[p] = jac*qw[p];
}
STOP_LOG('compute_edge_map()', 'FE');
}
Definition at line 345 of file fe_boundary.C.
References TypeVector< T >::cross(), FEBase::curvatures, FEBase::d2psideta2_map, FEBase::d2psidxi2_map, FEBase::d2psidxideta_map, FEBase::d2xyzdeta2_map, FEBase::d2xyzdxi2_map, FEBase::d2xyzdxideta_map, FEBase::dim, FEBase::dpsideta_map, FEBase::dpsidxi_map, FEBase::dxdeta_map(), FEBase::dxdxi_map(), FEBase::dxyzdeta_map, FEBase::dxyzdxi_map, FEBase::dydeta_map(), FEBase::dydxi_map(), FEBase::dzdeta_map(), FEBase::dzdxi_map(), InfFE< Dim, T_radial, T_map >::inverse_map(), FEBase::JxW, Elem::node(), FEBase::normals, Elem::parent(), Elem::point(), FEBase::psi_map, FEBase::tangents, TypeVector< T >::unit(), and FEBase::xyz.
Referenced by FEBase::compute_edge_map(), InfFE< Dim, T_radial, T_map >::reinit(), and REINIT_ERROR().
{
libmesh_assert (side != NULL);
START_LOG('compute_face_map()', 'FE');
// The number of quadrature points.
const unsigned int n_qp = qw.size();
switch (dim)
{
case 1:
{
// A 1D finite element, currently assumed to be in 1D space
// This means the boundary is a '0D finite element', a
// NODEELEM.
// Resize the vectors to hold data at the quadrature points
{
xyz.resize(n_qp);
normals.resize(n_qp);
JxW.resize(n_qp);
}
// If we have no quadrature points, there's nothing else to do
if (!n_qp)
break;
// We need to look back at the full edge to figure out the normal
// vector
const Elem *elem = side->parent();
libmesh_assert (elem);
if (side->node(0) == elem->node(0))
normals[0] = Point(-1.);
else
{
libmesh_assert (side->node(0) == elem->node(1));
normals[0] = Point(1.);
}
// Calculate x at the point
libmesh_assert (psi_map.size() == 1);
// In the unlikely event we have multiple quadrature
// points, they'll be in the same place
for (unsigned int p=0; p<n_qp; p++)
{
xyz[p].zero();
xyz[p].add_scaled (side->point(0), psi_map[0][p]);
normals[p] = normals[0];
JxW[p] = 1.0*qw[p];
}
// done computing the map
break;
}
case 2:
{
// A 2D finite element living in either 2D or 3D space.
// This means the boundary is a 1D finite element, i.e.
// and EDGE2 or EDGE3.
// Resize the vectors to hold data at the quadrature points
{
xyz.resize(n_qp);
dxyzdxi_map.resize(n_qp);
d2xyzdxi2_map.resize(n_qp);
tangents.resize(n_qp);
normals.resize(n_qp);
curvatures.resize(n_qp);
JxW.resize(n_qp);
}
// Clear the entities that will be summed
// Compute the tangent & normal at the quadrature point
for (unsigned int p=0; p<n_qp; p++)
{
tangents[p].resize(LIBMESH_DIM-1); // 1 Tangent in 2D, 2 in 3D
xyz[p].zero();
dxyzdxi_map[p].zero();
d2xyzdxi2_map[p].zero();
}
// compute x, dxdxi at the quadrature points
for (unsigned int i=0; i<psi_map.size(); i++) // sum over the nodes
{
const Point& side_point = side->point(i);
for (unsigned int p=0; p<n_qp; p++) // for each quadrature point...
{
xyz[p].add_scaled (side_point, psi_map[i][p]);
dxyzdxi_map[p].add_scaled (side_point, dpsidxi_map[i][p]);
d2xyzdxi2_map[p].add_scaled(side_point, d2psidxi2_map[i][p]);
}
}
// Compute the tangent & normal at the quadrature point
for (unsigned int p=0; p<n_qp; p++)
{
// The first tangent comes from just the edge's Jacobian
tangents[p][0] = dxyzdxi_map[p].unit();
#if LIBMESH_DIM == 2
// For a 2D element living in 2D, the normal is given directly
// from the entries in the edge Jacobian.
normals[p] = (Point(dxyzdxi_map[p](1), -dxyzdxi_map[p](0), 0.)).unit();
#elif LIBMESH_DIM == 3
// For a 2D element living in 3D, there is a second tangent.
// For the second tangent, we need to refer to the full
// element's (not just the edge's) Jacobian.
const Elem *elem = side->parent();
libmesh_assert (elem != NULL);
// Inverse map xyz[p] to a reference point on the parent...
Point reference_point = FE<2,LAGRANGE>::inverse_map(elem, xyz[p]);
// Get dxyz/dxi and dxyz/deta from the parent map.
Point dx_dxi = FE<2,LAGRANGE>::map_xi (elem, reference_point);
Point dx_deta = FE<2,LAGRANGE>::map_eta(elem, reference_point);
// The second tangent vector is formed by crossing these vectors.
tangents[p][1] = dx_dxi.cross(dx_deta).unit();
// Finally, the normal in this case is given by crossing these
// two tangents.
normals[p] = tangents[p][0].cross(tangents[p][1]).unit();
#endif
// The curvature is computed via the familiar Frenet formula:
// curvature = [d^2(x) / d (xi)^2] dot [normal]
// For a reference, see:
// F.S. Merritt, Mathematics Manual, 1962, McGraw-Hill, p. 310
//
// Note: The sign convention here is different from the
// 3D case. Concave-upward curves (smiles) have a positive
// curvature. Concave-downward curves (frowns) have a
// negative curvature. Be sure to take that into account!
const Real numerator = d2xyzdxi2_map[p] * normals[p];
const Real denominator = dxyzdxi_map[p].size_sq();
libmesh_assert (denominator != 0);
curvatures[p] = numerator / denominator;
}
// compute the jacobian at the quadrature points
for (unsigned int p=0; p<n_qp; p++)
{
const Real jac = dxyzdxi_map[p].size();
libmesh_assert (jac > 0.);
JxW[p] = jac*qw[p];
}
// done computing the map
break;
}
case 3:
{
// A 3D finite element living in 3D space.
// Resize the vectors to hold data at the quadrature points
{
xyz.resize(n_qp);
dxyzdxi_map.resize(n_qp);
dxyzdeta_map.resize(n_qp);
d2xyzdxi2_map.resize(n_qp);
d2xyzdxideta_map.resize(n_qp);
d2xyzdeta2_map.resize(n_qp);
tangents.resize(n_qp);
normals.resize(n_qp);
curvatures.resize(n_qp);
JxW.resize(n_qp);
}
// Clear the entities that will be summed
for (unsigned int p=0; p<n_qp; p++)
{
tangents[p].resize(LIBMESH_DIM-1); // 1 Tangent in 2D, 2 in 3D
xyz[p].zero();
dxyzdxi_map[p].zero();
dxyzdeta_map[p].zero();
d2xyzdxi2_map[p].zero();
d2xyzdxideta_map[p].zero();
d2xyzdeta2_map[p].zero();
}
// compute x, dxdxi at the quadrature points
for (unsigned int i=0; i<psi_map.size(); i++) // sum over the nodes
{
const Point& side_point = side->point(i);
for (unsigned int p=0; p<n_qp; p++) // for each quadrature point...
{
xyz[p].add_scaled (side_point, psi_map[i][p]);
dxyzdxi_map[p].add_scaled (side_point, dpsidxi_map[i][p]);
dxyzdeta_map[p].add_scaled(side_point, dpsideta_map[i][p]);
d2xyzdxi2_map[p].add_scaled (side_point, d2psidxi2_map[i][p]);
d2xyzdxideta_map[p].add_scaled(side_point, d2psidxideta_map[i][p]);
d2xyzdeta2_map[p].add_scaled (side_point, d2psideta2_map[i][p]);
}
}
// Compute the tangents, normal, and curvature at the quadrature point
for (unsigned int p=0; p<n_qp; p++)
{
const Point n = dxyzdxi_map[p].cross(dxyzdeta_map[p]);
normals[p] = n.unit();
tangents[p][0] = dxyzdxi_map[p].unit();
tangents[p][1] = n.cross(dxyzdxi_map[p]).unit();
// Compute curvature using the typical nomenclature
// of the first and second fundamental forms.
// For reference, see:
// 1) http://mathworld.wolfram.com/MeanCurvature.html
// (note -- they are using inward normal)
// 2) F.S. Merritt, Mathematics Manual, 1962, McGraw-Hill
const Real L = -d2xyzdxi2_map[p] * normals[p];
const Real M = -d2xyzdxideta_map[p] * normals[p];
const Real N = -d2xyzdeta2_map[p] * normals[p];
const Real E = dxyzdxi_map[p].size_sq();
const Real F = dxyzdxi_map[p] * dxyzdeta_map[p];
const Real G = dxyzdeta_map[p].size_sq();
const Real numerator = E*N -2.*F*M + G*L;
const Real denominator = E*G - F*F;
libmesh_assert (denominator != 0.);
curvatures[p] = 0.5*numerator/denominator;
}
// compute the jacobian at the quadrature points, see
// http://sp81.msi.umn.edu:999/fluent/fidap/help/theory/thtoc.htm
for (unsigned int p=0; p<n_qp; p++)
{
const Real g11 = (dxdxi_map(p)*dxdxi_map(p) +
dydxi_map(p)*dydxi_map(p) +
dzdxi_map(p)*dzdxi_map(p));
const Real g12 = (dxdxi_map(p)*dxdeta_map(p) +
dydxi_map(p)*dydeta_map(p) +
dzdxi_map(p)*dzdeta_map(p));
const Real g21 = g12;
const Real g22 = (dxdeta_map(p)*dxdeta_map(p) +
dydeta_map(p)*dydeta_map(p) +
dzdeta_map(p)*dzdeta_map(p));
const Real jac = std::sqrt(g11*g22 - g12*g21);
libmesh_assert (jac > 0.);
JxW[p] = jac*qw[p];
}
// done computing the map
break;
}
default:
libmesh_error();
}
STOP_LOG('compute_face_map()', 'FE');
}
Definition at line 476 of file fe_map.C.
References FEBase::calculate_d2phi, FEBase::compute_affine_map(), FEBase::compute_single_point_map(), Elem::has_affine_map(), and FEBase::resize_map_vectors().
{
if (elem->has_affine_map())
{
compute_affine_map(qw, elem);
return;
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
static bool curvy_second_derivative_warning = false;
if (calculate_d2phi && !curvy_second_derivative_warning)
{
std::cerr << 'WARNING: Second derivatives are not currently '
<< 'correctly calculated on non-affine elements!'
<< std::endl;
curvy_second_derivative_warning = true;
}
#endif
// Start logging the map computation.
START_LOG('compute_map()', 'FE');
libmesh_assert (elem != NULL);
const unsigned int n_qp = qw.size();
// Resize the vectors to hold data at the quadrature points
this->resize_map_vectors(n_qp);
// Compute map at all quadrature points
for (unsigned int p=0; p!=n_qp; p++)
this->compute_single_point_map(qw, elem, p);
// Stop logging the map computation.
STOP_LOG('compute_map()', 'FE');
}
Definition at line 1900 of file fe_base.C.
References Elem::active(), PeriodicBoundaries::boundary(), MeshBase::boundary_info, FEBase::build(), libMeshEnums::C_ONE, libMeshEnums::C_ZERO, DenseMatrix< T >::cholesky_solve(), DofMap::constrain_p_dofs(), FEType::default_quadrature_order(), Elem::dim(), libMeshEnums::DISCONTINUOUS, DofMap::dof_indices(), FEInterface::dofs_on_side(), FEBase::dphi, DofObject::invalid_id, libMesh::invalid_uint, FEInterface::inverse_map(), DofMap::is_constrained_dof(), FEBase::JxW, Elem::level(), std::min(), Elem::min_p_level_by_neighbor(), Elem::n_sides(), PeriodicBoundaries::neighbor(), Elem::neighbor(), Elem::p_level(), PeriodicBoundary::pairedboundary, FEBase::phi, DenseVector< T >::resize(), DenseMatrix< T >::resize(), Threads::spin_mtx, PeriodicBoundary::translation_vector, and DofMap::variable_type().
{
// Only bother if we truly have periodic boundaries
if (boundaries.empty())
return;
libmesh_assert (elem != NULL);
// Only constrain active elements with this method
if (!elem->active())
return;
const unsigned int Dim = elem->dim();
const FEType& base_fe_type = dof_map.variable_type(variable_number);
// Construct FE objects for this element and its pseudo-neighbors.
AutoPtr<FEBase> my_fe (FEBase::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);
AutoPtr<FEBase> neigh_fe (FEBase::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<Real> >& phi = my_fe->get_phi();
const std::vector<std::vector<Real> >& neigh_phi =
neigh_fe->get_phi();
const std::vector<Point> *face_normals = NULL;
const std::vector<std::vector<RealGradient> > *dphi = NULL;
const std::vector<std::vector<RealGradient> > *neigh_dphi = NULL;
std::vector<unsigned int> 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<RealGradient> >& ref_dphi =
my_fe->get_dphi();
dphi = &ref_dphi;
const std::vector<std::vector<RealGradient> >& 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))
continue;
unsigned int boundary_id = mesh.boundary_info->boundary_id(elem, s);
PeriodicBoundary *periodic = boundaries.boundary(boundary_id);
if (periodic)
{
// Get pointers to the element's neighbor.
const Elem* neigh = boundaries.neighbor(boundary_id, mesh, 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.boundary_info->side_with_boundary_id (neigh, periodic->pairedboundary);
libmesh_assert(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
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;
for (unsigned int i=0; i != neigh_point.size(); ++i)
neigh_point[i] += periodic->translation_vector;
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 = my_side_dofs.size();
libmesh_assert(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] * (phi[i][qp] * phi[j][qp]);
if (cont != C_ZERO)
Ke(is,js) += JxW[qp] * (((*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] * (neigh_phi[i][qp] *
phi[j][qp]);
if (cont != C_ZERO)
Fe(js) += JxW[qp] * (((*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
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 unsigned int their_dof_g = neigh_dof_indices[i];
libmesh_assert(their_dof_g != DofObject::invalid_id);
if (!dof_map.is_constrained_dof(their_dof_g))
continue;
DofConstraintRow& their_constraint_row =
constraints[their_dof_g];
for (unsigned int js = 0; js != n_side_dofs; ++js)
{
const unsigned int j = my_side_dofs[js];
const unsigned int my_dof_g = my_dof_indices[j];
libmesh_assert(my_dof_g != DofObject::invalid_id);
if (their_constraint_row.count(my_dof_g))
recursive_constraint[js] = true;
}
}
for (unsigned int is = 0; is != n_side_dofs; ++is)
{
const unsigned int i = neigh_side_dofs[is];
const unsigned int their_dof_g = neigh_dof_indices[i];
libmesh_assert(their_dof_g != DofObject::invalid_id);
for (unsigned int js = 0; js != n_side_dofs; ++js)
{
if (recursive_constraint[js])
continue;
const unsigned int j = my_side_dofs[js];
const unsigned int my_dof_g = my_dof_indices[j];
libmesh_assert(my_dof_g != DofObject::invalid_id);
if (dof_map.is_constrained_dof(my_dof_g))
continue;
const Real their_dof_value = Ue[is](js);
if (their_dof_g == my_dof_g)
{
libmesh_assert(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) < 1.e-5)
continue;
// since we may be running this method concurretly
// 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);
DofConstraintRow& constraint_row =
constraints[my_dof_g];
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
}
}
}
Definition at line 1659 of file fe_base.C.
References Elem::active(), FEBase::build(), libMeshEnums::C_ONE, libMeshEnums::C_ZERO, DenseMatrix< T >::cholesky_solve(), DofMap::constrain_p_dofs(), FEType::default_quadrature_order(), Elem::dim(), libMeshEnums::DISCONTINUOUS, DofMap::dof_indices(), FEInterface::dofs_on_side(), FEBase::dphi, DofObject::invalid_id, FEInterface::inverse_map(), FEBase::JxW, Elem::level(), std::min(), Elem::min_p_level_by_neighbor(), Elem::n_nodes(), Elem::n_sides(), Elem::neighbor(), Elem::p_level(), FEBase::phi, DenseVector< T >::resize(), DenseMatrix< T >::resize(), Threads::spin_mtx, DofMap::variable_type(), and Elem::which_neighbor_am_i().
Referenced by FE< Dim, T >::compute_constraints().
{
libmesh_assert (elem != NULL);
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.
AutoPtr<FEBase> my_fe (FEBase::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);
AutoPtr<FEBase> neigh_fe (FEBase::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<Real> >& phi = my_fe->get_phi();
const std::vector<std::vector<Real> >& neigh_phi =
neigh_fe->get_phi();
const std::vector<Point> *face_normals = NULL;
const std::vector<std::vector<RealGradient> > *dphi = NULL;
const std::vector<std::vector<RealGradient> > *neigh_dphi = NULL;
std::vector<unsigned int> 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<RealGradient> >& ref_dphi =
my_fe->get_dphi();
dphi = &ref_dphi;
const std::vector<std::vector<RealGradient> >& 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 (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 = my_side_dofs.size();
libmesh_assert(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] * (phi[i][qp] * phi[j][qp]);
if (cont != C_ZERO)
Ke(is,js) += JxW[qp] * (((*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] * (neigh_phi[i][qp] *
phi[j][qp]);
if (cont != C_ZERO)
Fe(js) += JxW[qp] * (((*neigh_dphi)[i][qp] *
(*face_normals)[qp]) *
((*dphi)[j][qp] *
(*face_normals)[qp]));
}
}
Ke.cholesky_solve(Fe, Ue[is]);
}
for (unsigned int is = 0; is != n_side_dofs; ++is)
{
const unsigned int i = neigh_side_dofs[is];
const unsigned int their_dof_g = neigh_dof_indices[i];
libmesh_assert(their_dof_g != DofObject::invalid_id);
for (unsigned int js = 0; js != n_side_dofs; ++js)
{
const unsigned int j = my_side_dofs[js];
const unsigned int my_dof_g = my_dof_indices[j];
libmesh_assert(my_dof_g != DofObject::invalid_id);
const Real their_dof_value = Ue[is](js);
if (their_dof_g == my_dof_g)
{
libmesh_assert(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) < 1.e-5)
continue;
// since we may be running this method concurretly
// 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);
DofConstraintRow& constraint_row =
constraints[my_dof_g];
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);
}
}
}
Reimplemented in FEXYZ< Dim >, and InfFE< Dim, T_radial, T_map >.
Definition at line 632 of file fe_base.C.
References FEBase::calculate_d2phi, FEBase::calculate_dphi, FEBase::calculate_phi, FEBase::calculations_started, FEBase::d2phi, FEBase::d2phideta2, FEBase::d2phidetadzeta, FEBase::d2phidx2, FEBase::d2phidxdy, FEBase::d2phidxdz, FEBase::d2phidxi2, FEBase::d2phidxideta, FEBase::d2phidxidzeta, FEBase::d2phidy2, FEBase::d2phidydz, FEBase::d2phidz2, FEBase::d2phidzeta2, FEBase::detadx_map, FEBase::detady_map, FEBase::detadz_map, FEBase::dim, FEBase::dphi, FEBase::dphideta, FEBase::dphidx, FEBase::dphidxi, FEBase::dphidy, FEBase::dphidz, FEBase::dphidzeta, FEBase::dxidx_map, FEBase::dxidy_map, FEBase::dxidz_map, FEBase::dzetadx_map, FEBase::dzetady_map, and FEBase::dzetadz_map.
{
//-------------------------------------------------------------------------
// 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_phi = calculate_dphi = calculate_d2phi = true;
#else
if (!calculate_phi && !calculate_dphi)
calculate_phi = calculate_dphi = true;
#endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
// Compute the value of the derivative shape function i at quadrature point p
switch (dim)
{
case 1:
{
if (calculate_dphi)
for (unsigned int i=0; i<dphi.size(); i++)
for (unsigned int p=0; p<dphi[i].size(); p++)
{
// dphi/dx = (dphi/dxi)*(dxi/dx)
dphi[i][p](0) =
dphidx[i][p] = dphidxi[i][p]*dxidx_map[p];
dphi[i][p](1) = dphidy[i][p] = 0.;
dphi[i][p](2) = dphidz[i][p] = 0.;
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
for (unsigned int i=0; i<d2phi.size(); i++)
for (unsigned int p=0; p<d2phi[i].size(); p++)
{
d2phi[i][p](0,0) = d2phidx2[i][p] =
d2phidxi2[i][p]*dxidx_map[p]*dxidx_map[p];
#if LIBMESH_DIM>1
d2phi[i][p](0,1) = d2phidxdy[i][p] =
d2phi[i][p](1,0) = 0.;
d2phi[i][p](1,1) = d2phidy2[i][p] = 0.;
#if LIBMESH_DIM>2
d2phi[i][p](0,2) = d2phidxdz[i][p] =
d2phi[i][p](2,0) = 0.;
d2phi[i][p](1,2) = d2phidydz[i][p] =
d2phi[i][p](2,1) = 0.;
d2phi[i][p](2,2) = d2phidz2[i][p] = 0.;
#endif
#endif
}
#endif
// All done
break;
}
case 2:
{
if (calculate_dphi)
for (unsigned int i=0; i<dphi.size(); i++)
for (unsigned int p=0; p<dphi[i].size(); p++)
{
// dphi/dx = (dphi/dxi)*(dxi/dx) + (dphi/deta)*(deta/dx)
dphi[i][p](0) =
dphidx[i][p] = (dphidxi[i][p]*dxidx_map[p] +
dphideta[i][p]*detadx_map[p]);
// dphi/dy = (dphi/dxi)*(dxi/dy) + (dphi/deta)*(deta/dy)
dphi[i][p](1) =
dphidy[i][p] = (dphidxi[i][p]*dxidy_map[p] +
dphideta[i][p]*detady_map[p]);
// dphi/dz = (dphi/dxi)*(dxi/dz) + (dphi/deta)*(deta/dz)
#if LIBMESH_DIM == 3
dphi[i][p](2) = // can only assign to the Z component if LIBMESH_DIM==3
#endif
dphidz[i][p] = (dphidxi[i][p]*dxidz_map[p] +
dphideta[i][p]*detadz_map[p]);
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
for (unsigned int i=0; i<d2phi.size(); i++)
for (unsigned int p=0; p<d2phi[i].size(); p++)
{
d2phi[i][p](0,0) = d2phidx2[i][p] =
d2phidxi2[i][p]*dxidx_map[p]*dxidx_map[p] +
2*d2phidxideta[i][p]*dxidx_map[p]*detadx_map[p] +
d2phideta2[i][p]*detadx_map[p]*detadx_map[p];
d2phi[i][p](0,1) = d2phidxdy[i][p] =
d2phi[i][p](1,0) =
d2phidxi2[i][p]*dxidx_map[p]*dxidy_map[p] +
d2phidxideta[i][p]*dxidx_map[p]*detady_map[p] +
d2phideta2[i][p]*detadx_map[p]*detady_map[p] +
d2phidxideta[i][p]*detadx_map[p]*dxidy_map[p];
d2phi[i][p](1,1) = d2phidy2[i][p] =
d2phidxi2[i][p]*dxidy_map[p]*dxidy_map[p] +
2*d2phidxideta[i][p]*dxidy_map[p]*detady_map[p] +
d2phideta2[i][p]*detady_map[p]*detady_map[p];
#if LIBMESH_DIM == 3
d2phi[i][p](0,2) = d2phidxdz[i][p] =
d2phi[i][p](2,0) =
d2phidxi2[i][p]*dxidx_map[p]*dxidz_map[p] +
d2phidxideta[i][p]*dxidx_map[p]*detadz_map[p] +
d2phideta2[i][p]*detadx_map[p]*detadz_map[p] +
d2phidxideta[i][p]*detadx_map[p]*dxidz_map[p];
d2phi[i][p](1,2) = d2phidydz[i][p] =
d2phi[i][p](2,1) =
d2phidxi2[i][p]*dxidy_map[p]*dxidz_map[p] +
d2phidxideta[i][p]*dxidy_map[p]*detadz_map[p] +
d2phideta2[i][p]*detady_map[p]*detadz_map[p] +
d2phidxideta[i][p]*detady_map[p]*dxidz_map[p];
d2phi[i][p](2,2) = d2phidz2[i][p] =
d2phidxi2[i][p]*dxidz_map[p]*dxidz_map[p] +
2*d2phidxideta[i][p]*dxidz_map[p]*detadz_map[p] +
d2phideta2[i][p]*detadz_map[p]*detadz_map[p];
#endif
}
#endif
// All done
break;
}
case 3:
{
if (calculate_dphi)
for (unsigned int i=0; i<dphi.size(); i++)
for (unsigned int p=0; p<dphi[i].size(); p++)
{
// dphi/dx = (dphi/dxi)*(dxi/dx) + (dphi/deta)*(deta/dx) + (dphi/dzeta)*(dzeta/dx);
dphi[i][p](0) =
dphidx[i][p] = (dphidxi[i][p]*dxidx_map[p] +
dphideta[i][p]*detadx_map[p] +
dphidzeta[i][p]*dzetadx_map[p]);
// dphi/dy = (dphi/dxi)*(dxi/dy) + (dphi/deta)*(deta/dy) + (dphi/dzeta)*(dzeta/dy);
dphi[i][p](1) =
dphidy[i][p] = (dphidxi[i][p]*dxidy_map[p] +
dphideta[i][p]*detady_map[p] +
dphidzeta[i][p]*dzetady_map[p]);
// dphi/dz = (dphi/dxi)*(dxi/dz) + (dphi/deta)*(deta/dz) + (dphi/dzeta)*(dzeta/dz);
dphi[i][p](2) =
dphidz[i][p] = (dphidxi[i][p]*dxidz_map[p] +
dphideta[i][p]*detadz_map[p] +
dphidzeta[i][p]*dzetadz_map[p]);
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
for (unsigned int i=0; i<d2phi.size(); i++)
for (unsigned int p=0; p<d2phi[i].size(); p++)
{
d2phi[i][p](0,0) = d2phidx2[i][p] =
d2phidxi2[i][p]*dxidx_map[p]*dxidx_map[p] +
2*d2phidxideta[i][p]*dxidx_map[p]*detadx_map[p] +
2*d2phidxidzeta[i][p]*dxidx_map[p]*dzetadx_map[p] +
2*d2phidetadzeta[i][p]*detadx_map[p]*dzetadx_map[p] +
d2phideta2[i][p]*detadx_map[p]*detadx_map[p] +
d2phidzeta2[i][p]*dzetadx_map[p]*dzetadx_map[p];
d2phi[i][p](0,1) = d2phidxdy[i][p] =
d2phi[i][p](1,0) =
d2phidxi2[i][p]*dxidx_map[p]*dxidy_map[p] +
d2phidxideta[i][p]*dxidx_map[p]*detady_map[p] +
d2phidxidzeta[i][p]*dxidx_map[p]*dzetady_map[p] +
d2phideta2[i][p]*detadx_map[p]*detady_map[p] +
d2phidxideta[i][p]*detadx_map[p]*dxidy_map[p] +
d2phidetadzeta[i][p]*detadx_map[p]*dzetady_map[p] +
d2phidzeta2[i][p]*dzetadx_map[p]*dzetady_map[p] +
d2phidxidzeta[i][p]*dzetadx_map[p]*dxidy_map[p] +
d2phidetadzeta[i][p]*dzetadx_map[p]*detady_map[p];
d2phi[i][p](0,2) = d2phidxdz[i][p] =
d2phi[i][p](2,0) =
d2phidxi2[i][p]*dxidx_map[p]*dxidz_map[p] +
d2phidxideta[i][p]*dxidx_map[p]*detadz_map[p] +
d2phidxidzeta[i][p]*dxidx_map[p]*dzetadz_map[p] +
d2phideta2[i][p]*detadx_map[p]*detadz_map[p] +
d2phidxideta[i][p]*detadx_map[p]*dxidz_map[p] +
d2phidetadzeta[i][p]*detadx_map[p]*dzetadz_map[p] +
d2phidzeta2[i][p]*dzetadx_map[p]*dzetadz_map[p] +
d2phidxidzeta[i][p]*dzetadx_map[p]*dxidz_map[p] +
d2phidetadzeta[i][p]*dzetadx_map[p]*detadz_map[p];
d2phi[i][p](1,1) = d2phidy2[i][p] =
d2phidxi2[i][p]*dxidy_map[p]*dxidy_map[p] +
2*d2phidxideta[i][p]*dxidy_map[p]*detady_map[p] +
2*d2phidxidzeta[i][p]*dxidy_map[p]*dzetady_map[p] +
2*d2phidetadzeta[i][p]*detady_map[p]*dzetady_map[p] +
d2phideta2[i][p]*detady_map[p]*detady_map[p] +
d2phidzeta2[i][p]*dzetady_map[p]*dzetady_map[p];
d2phi[i][p](1,2) = d2phidydz[i][p] =
d2phi[i][p](2,1) =
d2phidxi2[i][p]*dxidy_map[p]*dxidz_map[p] +
d2phidxideta[i][p]*dxidy_map[p]*detadz_map[p] +
d2phidxidzeta[i][p]*dxidy_map[p]*dzetadz_map[p] +
d2phideta2[i][p]*detady_map[p]*detadz_map[p] +
d2phidxideta[i][p]*detady_map[p]*dxidz_map[p] +
d2phidetadzeta[i][p]*detady_map[p]*dzetadz_map[p] +
d2phidzeta2[i][p]*dzetady_map[p]*dzetadz_map[p] +
d2phidxidzeta[i][p]*dzetady_map[p]*dxidz_map[p] +
d2phidetadzeta[i][p]*dzetady_map[p]*detadz_map[p];
d2phi[i][p](2,2) = d2phidz2[i][p] =
d2phidxi2[i][p]*dxidz_map[p]*dxidz_map[p] +
2*d2phidxideta[i][p]*dxidz_map[p]*detadz_map[p] +
2*d2phidxidzeta[i][p]*dxidz_map[p]*dzetadz_map[p] +
2*d2phidetadzeta[i][p]*detadz_map[p]*dzetadz_map[p] +
d2phideta2[i][p]*detadz_map[p]*detadz_map[p] +
d2phidzeta2[i][p]*dzetadz_map[p]*dzetadz_map[p];
}
#endif
// All done
break;
}
default:
{
libmesh_error();
}
}
// Stop logging the shape function computation
STOP_LOG('compute_shape_functions()', 'FE');
}
Definition at line 35 of file fe_map.C.
References FEBase::d2phideta2_map, FEBase::d2phidetadzeta_map, FEBase::d2phidxi2_map, FEBase::d2phidxideta_map, FEBase::d2phidxidzeta_map, FEBase::d2phidzeta2_map, FEBase::d2xyzdeta2_map, FEBase::d2xyzdetadzeta_map, FEBase::d2xyzdxi2_map, FEBase::d2xyzdxideta_map, FEBase::d2xyzdxidzeta_map, FEBase::d2xyzdzeta2_map, FEBase::detadx_map, FEBase::detady_map, FEBase::detadz_map, FEBase::dim, FEBase::dphideta_map, FEBase::dphidxi_map, FEBase::dphidzeta_map, FEBase::dxdeta_map(), FEBase::dxdxi_map(), FEBase::dxdzeta_map(), FEBase::dxidx_map, FEBase::dxidy_map, FEBase::dxidz_map, FEBase::dxyzdeta_map, FEBase::dxyzdxi_map, FEBase::dxyzdzeta_map, FEBase::dydeta_map(), FEBase::dydxi_map(), FEBase::dydzeta_map(), FEBase::dzdeta_map(), FEBase::dzdxi_map(), FEBase::dzdzeta_map(), FEBase::dzetadx_map, FEBase::dzetady_map, FEBase::dzetadz_map, DofObject::id(), FEBase::JxW, FEBase::phi_map, Elem::point(), and FEBase::xyz.
Referenced by FEBase::compute_affine_map(), and FEBase::compute_map().
{
libmesh_assert (elem != NULL);
switch (this->dim)
{
//--------------------------------------------------------------------
// 1D
case 1:
{
// Clear the entities that will be summed
xyz[p].zero();
dxyzdxi_map[p].zero();
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxi2_map[p].zero();
#endif
// compute x, dx, d2x at the quadrature point
for (unsigned int i=0; i<phi_map.size(); i++) // sum over the nodes
{
// Reference to the point, helps eliminate
// exessive temporaries in the inner loop
const Point& elem_point = elem->point(i);
xyz[p].add_scaled (elem_point, phi_map[i][p] );
dxyzdxi_map[p].add_scaled (elem_point, dphidxi_map[i][p]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxi2_map[p].add_scaled(elem_point, d2phidxi2_map[i][p]);
#endif
}
// Compute the jacobian
//
// 1D elements can live in 2D or 3D space.
// The transformation matrix from local->global
// coordinates is
//
// T = | dx/dxi |
// | dy/dxi |
// | dz/dxi |
//
// The generalized determinant of T (from the
// so-called 'normal' eqns.) is
// jac = 'det(T)' = sqrt(det(T'T))
//
// where T'= transpose of T, so
//
// jac = sqrt( (dx/dxi)^2 + (dy/dxi)^2 + (dz/dxi)^2 )
const Real jac = dxyzdxi_map[p].size();
if (jac <= 0.)
{
std::cerr << 'ERROR: negative Jacobian: '
<< jac
<< ' in element '
<< elem->id()
<< std::endl;
libmesh_error();
}
// The inverse Jacobian entries also come from the
// generalized inverse of T (see also the 2D element
// living in 3D code).
const Real jacm2 = 1./jac/jac;
dxidx_map[p] = jacm2*dxdxi_map(p);
dxidy_map[p] = jacm2*dydxi_map(p);
dxidz_map[p] = jacm2*dzdxi_map(p);
JxW[p] = jac*qw[p];
// done computing the map
break;
}
//--------------------------------------------------------------------
// 2D
case 2:
{
//------------------------------------------------------------------
// Compute the (x,y) values at the quadrature points,
// the Jacobian at the quadrature points
xyz[p].zero();
dxyzdxi_map[p].zero();
dxyzdeta_map[p].zero();
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxi2_map[p].zero();
d2xyzdxideta_map[p].zero();
d2xyzdeta2_map[p].zero();
#endif
// compute (x,y) at the quadrature points, derivatives once
for (unsigned int i=0; i<phi_map.size(); i++) // sum over the nodes
{
// Reference to the point, helps eliminate
// exessive temporaries in the inner loop
const Point& elem_point = elem->point(i);
xyz[p].add_scaled (elem_point, phi_map[i][p] );
dxyzdxi_map[p].add_scaled (elem_point, dphidxi_map[i][p] );
dxyzdeta_map[p].add_scaled (elem_point, dphideta_map[i][p]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxi2_map[p].add_scaled (elem_point, d2phidxi2_map[i][p]);
d2xyzdxideta_map[p].add_scaled (elem_point, d2phidxideta_map[i][p]);
d2xyzdeta2_map[p].add_scaled (elem_point, d2phideta2_map[i][p]);
#endif
}
// compute the jacobian once
const Real dx_dxi = dxdxi_map(p), dx_deta = dxdeta_map(p),
dy_dxi = dydxi_map(p), dy_deta = dydeta_map(p),
dz_dxi = dzdxi_map(p), dz_deta = dzdeta_map(p);
#if LIBMESH_DIM == 2
// Compute the Jacobian. This assumes the 2D face
// lives in 2D space
//
// Symbolically, the matrix determinant is
//
// | dx/dxi dx/deta |
// jac = | dy/dxi dy/deta |
//
// jac = dx/dxi*dy/deta - dx/deta*dy/dxi
const Real jac = (dx_dxi*dy_deta - dx_deta*dy_dxi);
if (jac <= 0.)
{
std::cerr << 'ERROR: negative Jacobian: '
<< jac
<< ' in element '
<< elem->id()
<< std::endl;
libmesh_error();
}
JxW[p] = jac*qw[p];
// Compute the shape function derivatives wrt x,y at the
// quadrature points
const Real inv_jac = 1./jac;
dxidx_map[p] = dy_deta*inv_jac; //dxi/dx = (1/J)*dy/deta
dxidy_map[p] = -dx_deta*inv_jac; //dxi/dy = -(1/J)*dx/deta
detadx_map[p] = -dy_dxi* inv_jac; //deta/dx = -(1/J)*dy/dxi
detady_map[p] = dx_dxi* inv_jac; //deta/dy = (1/J)*dx/dxi
dxidz_map[p] = detadz_map[p] = 0.;
#else
// Compute the Jacobian. This assumes a 2D face in
// 3D space.
//
// The transformation matrix T from local to global
// coordinates is
//
// | dx/dxi dx/deta |
// T = | dy/dxi dy/deta |
// | dz/dxi dz/deta |
// note det(T' T) = det(T')det(T) = det(T)det(T)
// so det(T) = std::sqrt(det(T' T))
//
//----------------------------------------------
// Notes:
//
// dX = R dXi -> R'dX = R'R dXi
// (R^-1)dX = dXi [(R'R)^-1 R']dX = dXi
//
// so R^-1 = (R'R)^-1 R'
//
// and R^-1 R = (R'R)^-1 R'R = I.
//
const Real g11 = (dx_dxi*dx_dxi +
dy_dxi*dy_dxi +
dz_dxi*dz_dxi);
const Real g12 = (dx_dxi*dx_deta +
dy_dxi*dy_deta +
dz_dxi*dz_deta);
const Real g21 = g12;
const Real g22 = (dx_deta*dx_deta +
dy_deta*dy_deta +
dz_deta*dz_deta);
const Real det = (g11*g22 - g12*g21);
if (det <= 0.)
{
std::cerr << 'ERROR: negative Jacobian! '
<< ' in element '
<< elem->id()
<< std::endl;
libmesh_error();
}
const Real inv_det = 1./det;
const Real jac = std::sqrt(det);
JxW[p] = jac*qw[p];
const Real g11inv = g22*inv_det;
const Real g12inv = -g12*inv_det;
const Real g21inv = -g21*inv_det;
const Real g22inv = g11*inv_det;
dxidx_map[p] = g11inv*dx_dxi + g12inv*dx_deta;
dxidy_map[p] = g11inv*dy_dxi + g12inv*dy_deta;
dxidz_map[p] = g11inv*dz_dxi + g12inv*dz_deta;
detadx_map[p] = g21inv*dx_dxi + g22inv*dx_deta;
detady_map[p] = g21inv*dy_dxi + g22inv*dy_deta;
detadz_map[p] = g21inv*dz_dxi + g22inv*dz_deta;
#endif
// done computing the map
break;
}
//--------------------------------------------------------------------
// 3D
case 3:
{
//------------------------------------------------------------------
// Compute the (x,y,z) values at the quadrature points,
// the Jacobian at the quadrature point
// Clear the entities that will be summed
xyz[p].zero ();
dxyzdxi_map[p].zero ();
dxyzdeta_map[p].zero ();
dxyzdzeta_map[p].zero ();
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxi2_map[p].zero();
d2xyzdxideta_map[p].zero();
d2xyzdxidzeta_map[p].zero();
d2xyzdeta2_map[p].zero();
d2xyzdetadzeta_map[p].zero();
d2xyzdzeta2_map[p].zero();
#endif
// compute (x,y,z) at the quadrature points,
// dxdxi, dydxi, dzdxi,
// dxdeta, dydeta, dzdeta,
// dxdzeta, dydzeta, dzdzeta all once
for (unsigned int i=0; i<phi_map.size(); i++) // sum over the nodes
{
// Reference to the point, helps eliminate
// exessive temporaries in the inner loop
const Point& elem_point = elem->point(i);
xyz[p].add_scaled (elem_point, phi_map[i][p] );
dxyzdxi_map[p].add_scaled (elem_point, dphidxi_map[i][p] );
dxyzdeta_map[p].add_scaled (elem_point, dphideta_map[i][p] );
dxyzdzeta_map[p].add_scaled (elem_point, dphidzeta_map[i][p]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxi2_map[p].add_scaled (elem_point,
d2phidxi2_map[i][p]);
d2xyzdxideta_map[p].add_scaled (elem_point,
d2phidxideta_map[i][p]);
d2xyzdxidzeta_map[p].add_scaled (elem_point,
d2phidxidzeta_map[i][p]);
d2xyzdeta2_map[p].add_scaled (elem_point,
d2phideta2_map[i][p]);
d2xyzdetadzeta_map[p].add_scaled (elem_point,
d2phidetadzeta_map[i][p]);
d2xyzdzeta2_map[p].add_scaled (elem_point,
d2phidzeta2_map[i][p]);
#endif
}
// compute the jacobian
const Real
dx_dxi = dxdxi_map(p), dy_dxi = dydxi_map(p), dz_dxi = dzdxi_map(p),
dx_deta = dxdeta_map(p), dy_deta = dydeta_map(p), dz_deta = dzdeta_map(p),
dx_dzeta = dxdzeta_map(p), dy_dzeta = dydzeta_map(p), dz_dzeta = dzdzeta_map(p);
// Symbolically, the matrix determinant is
//
// | dx/dxi dy/dxi dz/dxi |
// jac = | dx/deta dy/deta dz/deta |
// | dx/dzeta dy/dzeta dz/dzeta |
//
// jac = dx/dxi*(dy/deta*dz/dzeta - dz/deta*dy/dzeta) +
// dy/dxi*(dz/deta*dx/dzeta - dx/deta*dz/dzeta) +
// dz/dxi*(dx/deta*dy/dzeta - dy/deta*dx/dzeta)
const Real jac = (dx_dxi*(dy_deta*dz_dzeta - dz_deta*dy_dzeta) +
dy_dxi*(dz_deta*dx_dzeta - dx_deta*dz_dzeta) +
dz_dxi*(dx_deta*dy_dzeta - dy_deta*dx_dzeta));
if (jac <= 0.)
{
std::cerr << 'ERROR: negative Jacobian: '
<< jac
<< ' in element '
<< elem->id()
<< std::endl;
libmesh_error();
}
JxW[p] = jac*qw[p];
// Compute the shape function derivatives wrt x,y at the
// quadrature points
const Real inv_jac = 1./jac;
dxidx_map[p] = (dy_deta*dz_dzeta - dz_deta*dy_dzeta)*inv_jac;
dxidy_map[p] = (dz_deta*dx_dzeta - dx_deta*dz_dzeta)*inv_jac;
dxidz_map[p] = (dx_deta*dy_dzeta - dy_deta*dx_dzeta)*inv_jac;
detadx_map[p] = (dz_dxi*dy_dzeta - dy_dxi*dz_dzeta )*inv_jac;
detady_map[p] = (dx_dxi*dz_dzeta - dz_dxi*dx_dzeta )*inv_jac;
detadz_map[p] = (dy_dxi*dx_dzeta - dx_dxi*dy_dzeta )*inv_jac;
dzetadx_map[p] = (dy_dxi*dz_deta - dz_dxi*dy_deta )*inv_jac;
dzetady_map[p] = (dz_dxi*dx_deta - dx_dxi*dz_deta )*inv_jac;
dzetadz_map[p] = (dx_dxi*dy_deta - dy_dxi*dx_deta )*inv_jac;
// done computing the map
break;
}
default:
libmesh_error();
}
}
On a p-refined element, o should be the base order of the element.
Definition at line 87 of file fe.C.
References Elem::is_node_on_edge(), Elem::n_nodes(), MeshTools::n_nodes(), Elem::p_level(), and Elem::type().
{
libmesh_assert(elem != NULL);
libmesh_assert(e < elem->n_edges());
di.clear();
unsigned int nodenum = 0;
const unsigned int n_nodes = elem->n_nodes();
for (unsigned int n = 0; n != n_nodes; ++n)
{
const unsigned int n_dofs = n_dofs_at_node(elem->type(),
static_cast<Order>(o + elem->p_level()), n);
if (elem->is_node_on_edge(n, e))
for (unsigned int i = 0; i != n_dofs; ++i)
di.push_back(nodenum++);
else
nodenum += n_dofs;
}
}
On a p-refined element, o should be the base order of the element.
Definition at line 61 of file fe.C.
References Elem::is_node_on_side(), Elem::n_nodes(), MeshTools::n_nodes(), Elem::p_level(), and Elem::type().
{
libmesh_assert(elem != NULL);
libmesh_assert(s < elem->n_sides());
di.clear();
unsigned int nodenum = 0;
const unsigned int n_nodes = elem->n_nodes();
for (unsigned int n = 0; n != n_nodes; ++n)
{
const unsigned int n_dofs = n_dofs_at_node(elem->type(),
static_cast<Order>(o + elem->p_level()), n);
if (elem->is_node_on_side(n, s))
for (unsigned int i = 0; i != n_dofs; ++i)
di.push_back(nodenum++);
else
nodenum += n_dofs;
}
}
Definition at line 740 of file fe_base.h.
References FEBase::dxyzdeta_map.
Referenced by FEBase::compute_face_map(), and FEBase::compute_single_point_map().
{ return dxyzdeta_map[p](0); }
Definition at line 719 of file fe_base.h.
References FEBase::dxyzdxi_map.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), and FEBase::compute_single_point_map().
{ return dxyzdxi_map[p](0); }
Definition at line 761 of file fe_base.h.
References FEBase::dxyzdzeta_map.
Referenced by FEBase::compute_single_point_map().
{ return dxyzdzeta_map[p](0); }
Definition at line 747 of file fe_base.h.
References FEBase::dxyzdeta_map.
Referenced by FEBase::compute_face_map(), and FEBase::compute_single_point_map().
{ return dxyzdeta_map[p](1); }
Definition at line 726 of file fe_base.h.
References FEBase::dxyzdxi_map.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), and FEBase::compute_single_point_map().
{ return dxyzdxi_map[p](1); }
Definition at line 768 of file fe_base.h.
References FEBase::dxyzdzeta_map.
Referenced by FEBase::compute_single_point_map().
{ return dxyzdzeta_map[p](1); }
Definition at line 754 of file fe_base.h.
References FEBase::dxyzdeta_map.
Referenced by FEBase::compute_face_map(), and FEBase::compute_single_point_map().
{ return dxyzdeta_map[p](2); }
Definition at line 733 of file fe_base.h.
References FEBase::dxyzdxi_map.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), and FEBase::compute_single_point_map().
{ return dxyzdxi_map[p](2); }
Definition at line 775 of file fe_base.h.
References FEBase::dxyzdzeta_map.
Referenced by FEBase::compute_single_point_map().
{ return dxyzdzeta_map[p](2); }
Implements FEBase.
Definition at line 148 of file fe_boundary.C.
References Elem::build_edge(), FEBase::compute_edge_map(), FEBase::elem_type, QBase::get_points(), FEBase::get_type(), QBase::get_weights(), QBase::init(), InfFE< Dim, T_radial, T_map >::inverse_map(), FEBase::JxW, Elem::p_level(), FEBase::qrule, InfFE< Dim, T_radial, T_map >::reinit(), InfFE< Dim, T_radial, T_map >::shapes_need_reinit(), Elem::type(), and FEBase::xyz.
{
libmesh_assert (elem != NULL);
libmesh_assert (qrule != NULL);
// We don't do this for 1D elements!
libmesh_assert (Dim != 1);
// Build the side of interest
const AutoPtr<Elem> edge(elem->build_edge(e));
// initialize quadrature rule
qrule->init(edge->type(), elem->p_level());
// We might not need to reinitialize the shape functions
if ((this->get_type() != elem->type()) ||
(e != last_edge) ||
this->shapes_need_reinit())
{
// Set the element type
elem_type = elem->type();
// Set the last_edge
last_edge = e;
// Initialize the edge shape functions
this->init_edge_shape_functions (qrule->get_points(), edge.get());
}
// Compute the Jacobian*Weight on the face for integration
this->compute_edge_map (qrule->get_weights(), edge.get());
// make a copy of the Jacobian for integration
const std::vector<Real> JxW_int(JxW);
// Find where the integration points are located on the
// full element.
std::vector<Point> qp; this->inverse_map (elem, xyz, qp, tolerance);
// compute the shape function and derivative values
// at the points qp
this->reinit (elem, &qp);
// copy back old data
JxW = JxW_int;
}
Implements FEBase.
Definition at line 1613 of file fe_bernstein.C.
References libMeshEnums::C_ZERO.
{
return C_ZERO;
}
Definition at line 539 of file fe_base.h.
References FEBase::curvatures.
{ return curvatures;}
Definition at line 300 of file fe_base.h.
References FEBase::calculate_d2phi, FEBase::calculations_started, and FEBase::d2phi.
Referenced by ExactErrorEstimator::find_squared_element_error().
{ libmesh_assert(!calculations_started || calculate_d2phi);
calculate_d2phi = true; return d2phi; }
Definition at line 308 of file fe_base.h.
References FEBase::calculate_d2phi, FEBase::calculations_started, and FEBase::d2phidx2.
{ libmesh_assert(!calculations_started || calculate_d2phi);
calculate_d2phi = true; return d2phidx2; }
Definition at line 316 of file fe_base.h.
References FEBase::calculate_d2phi, FEBase::calculations_started, and FEBase::d2phidxdy.
{ libmesh_assert(!calculations_started || calculate_d2phi);
calculate_d2phi = true; return d2phidxdy; }
Definition at line 324 of file fe_base.h.
References FEBase::calculate_d2phi, FEBase::calculations_started, and FEBase::d2phidxdz.
{ libmesh_assert(!calculations_started || calculate_d2phi);
calculate_d2phi = true; return d2phidxdz; }
Definition at line 332 of file fe_base.h.
References FEBase::calculate_d2phi, FEBase::calculations_started, and FEBase::d2phidy2.
{ libmesh_assert(!calculations_started || calculate_d2phi);
calculate_d2phi = true; return d2phidy2; }
Definition at line 340 of file fe_base.h.
References FEBase::calculate_d2phi, FEBase::calculations_started, and FEBase::d2phidydz.
{ libmesh_assert(!calculations_started || calculate_d2phi);
calculate_d2phi = true; return d2phidydz; }
Definition at line 348 of file fe_base.h.
References FEBase::calculate_d2phi, FEBase::calculations_started, and FEBase::d2phidz2.
{ libmesh_assert(!calculations_started || calculate_d2phi);
calculate_d2phi = true; return d2phidz2; }
Definition at line 384 of file fe_base.h.
References FEBase::d2xyzdeta2_map.
{ return d2xyzdeta2_map; }
Definition at line 414 of file fe_base.h.
References FEBase::d2xyzdetadzeta_map.
{ return d2xyzdetadzeta_map; }
Definition at line 378 of file fe_base.h.
References FEBase::d2xyzdxi2_map.
{ return d2xyzdxi2_map; }
Definition at line 400 of file fe_base.h.
References FEBase::d2xyzdxideta_map.
{ return d2xyzdxideta_map; }
Definition at line 408 of file fe_base.h.
References FEBase::d2xyzdxidzeta_map.
{ return d2xyzdxidzeta_map; }
Definition at line 392 of file fe_base.h.
References FEBase::d2xyzdzeta2_map.
{ return d2xyzdzeta2_map; }
Definition at line 444 of file fe_base.h.
References FEBase::detadx_map.
{ return detadx_map; }
Definition at line 451 of file fe_base.h.
References FEBase::detady_map.
{ return detady_map; }
Definition at line 458 of file fe_base.h.
References FEBase::detadz_map.
{ return detadz_map; }
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 494 of file fe_base.h.
References FEBase::dphase.
{ return dphase; }
Definition at line 242 of file fe_base.h.
References FEBase::calculate_dphi, FEBase::calculations_started, and FEBase::dphi.
Referenced by ExactErrorEstimator::find_squared_element_error().
{ libmesh_assert(!calculations_started || calculate_dphi);
calculate_dphi = true; return dphi; }
Definition at line 282 of file fe_base.h.
References FEBase::calculate_dphi, FEBase::calculations_started, and FEBase::dphideta.
{ libmesh_assert(!calculations_started || calculate_dphi);
calculate_dphi = true; return dphideta; }
Definition at line 250 of file fe_base.h.
References FEBase::calculate_dphi, FEBase::calculations_started, and FEBase::dphidx.
{ libmesh_assert(!calculations_started || calculate_dphi);
calculate_dphi = true; return dphidx; }
Definition at line 274 of file fe_base.h.
References FEBase::calculate_dphi, FEBase::calculations_started, and FEBase::dphidxi.
{ libmesh_assert(!calculations_started || calculate_dphi);
calculate_dphi = true; return dphidxi; }
Definition at line 258 of file fe_base.h.
References FEBase::calculate_dphi, FEBase::calculations_started, and FEBase::dphidy.
{ libmesh_assert(!calculations_started || calculate_dphi);
calculate_dphi = true; return dphidy; }
Definition at line 266 of file fe_base.h.
References FEBase::calculate_dphi, FEBase::calculations_started, and FEBase::dphidz.
{ libmesh_assert(!calculations_started || calculate_dphi);
calculate_dphi = true; return dphidz; }
Definition at line 290 of file fe_base.h.
References FEBase::calculate_dphi, FEBase::calculations_started, and FEBase::dphidzeta.
{ libmesh_assert(!calculations_started || calculate_dphi);
calculate_dphi = true; return dphidzeta; }
Definition at line 423 of file fe_base.h.
References FEBase::dxidx_map.
{ return dxidx_map; }
Definition at line 430 of file fe_base.h.
References FEBase::dxidy_map.
{ return dxidy_map; }
Definition at line 437 of file fe_base.h.
References FEBase::dxidz_map.
{ return dxidz_map; }
Definition at line 365 of file fe_base.h.
References FEBase::dxyzdeta_map.
{ return dxyzdeta_map; }
Definition at line 358 of file fe_base.h.
References FEBase::dxyzdxi_map.
{ return dxyzdxi_map; }
Definition at line 372 of file fe_base.h.
References FEBase::dxyzdzeta_map.
{ return dxyzdzeta_map; }
Definition at line 465 of file fe_base.h.
References FEBase::dzetadx_map.
{ return dzetadx_map; }
Definition at line 472 of file fe_base.h.
References FEBase::dzetady_map.
{ return dzetady_map; }
Definition at line 479 of file fe_base.h.
References FEBase::dzetadz_map.
{ return dzetadz_map; }
Definition at line 598 of file fe_base.h.
References FEType::family, and FEBase::fe_type.
{ return fe_type.family; }
Definition at line 577 of file fe_base.h.
References FEBase::fe_type.
{ return fe_type; }
Definition at line 45 of file reference_counter.C.
References ReferenceCounter::_counts, and Quality::name().
Referenced by ReferenceCounter::print_info().
{
#if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
std::ostringstream out;
out << '
<< ' ----------------------------------------------------------------------------
<< '| Reference count information |
<< ' ---------------------------------------------------------------------------- ;
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;
out << '| ' << name << ' reference count information:
<< '| Creations: ' << creations << '
<< '| Destructions: ' << destructions << ';
}
out << ' ---------------------------------------------------------------------------- ;
return out.str();
#else
return '';
#endif
}
Definition at line 235 of file fe_base.h.
References FEBase::JxW.
Referenced by ExactErrorEstimator::find_squared_element_error().
{ return JxW; }
Definition at line 533 of file fe_base.h.
References FEBase::normals.
{ return normals; }
Definition at line 582 of file fe_base.h.
References FEBase::_p_level, FEBase::fe_type, and FEType::order.
{ return static_cast<Order>(fe_type.order + _p_level); }
Definition at line 572 of file fe_base.h.
References FEBase::_p_level.
Referenced by REINIT_ERROR().
{ return _p_level; }
Definition at line 227 of file fe_base.h.
References FEBase::calculate_phi, FEBase::calculations_started, and FEBase::phi.
Referenced by ExactErrorEstimator::find_squared_element_error().
{ libmesh_assert(!calculations_started || calculate_phi);
calculate_phi = true; return phi; }
Definition at line 518 of file fe_base.h.
References FEBase::dweight.
{ return dweight; }
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 510 of file fe_base.h.
References FEBase::weight.
{ return weight; }
Definition at line 527 of file fe_base.h.
References FEBase::tangents.
{ return tangents; }
Definition at line 566 of file fe_base.h.
References FEBase::elem_type.
Referenced by FE< Dim, T >::edge_reinit(), InfFE< Dim, T_radial, T_map >::reinit(), and REINIT_ERROR().
{ return elem_type; }
Definition at line 220 of file fe_base.h.
References FEBase::xyz.
Referenced by ExactErrorEstimator::find_squared_element_error().
{ return xyz; }
Definition at line 149 of file reference_counter.h.
References ReferenceCounter::_counts, Quality::name(), and Threads::spin_mtx.
Referenced by ReferenceCountedObject< Value >::ReferenceCountedObject().
{
Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
std::pair<unsigned int, unsigned int>& p = _counts[name];
p.first++;
}
Definition at line 167 of file reference_counter.h.
References ReferenceCounter::_counts, Quality::name(), and Threads::spin_mtx.
Referenced by ReferenceCountedObject< Value >::~ReferenceCountedObject().
{
Threads::spin_mutex::scoped_lock lock(Threads::spin_mtx);
std::pair<unsigned int, unsigned int>& p = _counts[name];
p.second++;
}
Implements FEBase.
Definition at line 664 of file fe.C.
References Elem::type().
{
// I don't understand infinite elements well enough to risk
// calculating too little. :-( RHS
calculate_phi = calculate_dphi = calculate_d2phi = true;
elem_type = e->type();
init_shape_functions(qp, e);
}
Start logging the shape function initialization
Stop logging the shape function initialization
Definition at line 290 of file fe_boundary.C.
References FEBase::d2psidxi2_map, Elem::default_order(), FEBase::dpsidxi_map, FE< Dim, T >::n_shape_functions(), FEBase::psi_map, FE< Dim, T >::shape(), FE< Dim, T >::shape_deriv(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (edge != NULL);
START_LOG('init_edge_shape_functions()', 'FE');
// The element type and order to use in
// the map
const Order mapping_order (edge->default_order());
const ElemType mapping_elem_type (edge->type());
// The number of quadrature points.
const unsigned int n_qp = qp.size();
const unsigned int n_mapping_shape_functions =
FE<Dim,LAGRANGE>::n_shape_functions (mapping_elem_type,
mapping_order);
// resize the vectors to hold current data
// Psi are the shape functions used for the FE mapping
psi_map.resize (n_mapping_shape_functions);
dpsidxi_map.resize (n_mapping_shape_functions);
d2psidxi2_map.resize (n_mapping_shape_functions);
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
{
// Allocate space to store the values of the shape functions
// and their first and second derivatives at the quadrature points.
psi_map[i].resize (n_qp);
dpsidxi_map[i].resize (n_qp);
d2psidxi2_map[i].resize (n_qp);
// Compute the value of shape function i, and its first and
// second derivatives at quadrature point p
// (Lagrange shape functions are used for the mapping)
for (unsigned int p=0; p<n_qp; p++)
{
psi_map[i][p] = FE<1,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
dpsidxi_map[i][p] = FE<1,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
d2psidxi2_map[i][p] = FE<1,LAGRANGE>::shape_second_deriv(mapping_elem_type, mapping_order, i, 0, qp[p]);
}
}
STOP_LOG('init_edge_shape_functions()', 'FE');
}
Start logging the shape function initialization
Stop logging the shape function initialization
Definition at line 199 of file fe_boundary.C.
References FEBase::d2psideta2_map, FEBase::d2psidxi2_map, FEBase::d2psidxideta_map, Elem::default_order(), FEBase::dpsideta_map, FEBase::dpsidxi_map, FE< Dim, T >::n_shape_functions(), FEBase::psi_map, FE< Dim, T >::shape(), FE< Dim, T >::shape_deriv(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (side != NULL);
START_LOG('init_face_shape_functions()', 'FE');
// The element type and order to use in
// the map
const Order mapping_order (side->default_order());
const ElemType mapping_elem_type (side->type());
// The number of quadrature points.
const unsigned int n_qp = qp.size();
const unsigned int n_mapping_shape_functions =
FE<Dim,LAGRANGE>::n_shape_functions (mapping_elem_type,
mapping_order);
// resize the vectors to hold current data
// Psi are the shape functions used for the FE mapping
psi_map.resize (n_mapping_shape_functions);
if (Dim > 1)
{
dpsidxi_map.resize (n_mapping_shape_functions);
d2psidxi2_map.resize (n_mapping_shape_functions);
}
if (Dim == 3)
{
dpsideta_map.resize (n_mapping_shape_functions);
d2psidxideta_map.resize (n_mapping_shape_functions);
d2psideta2_map.resize (n_mapping_shape_functions);
}
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
{
// Allocate space to store the values of the shape functions
// and their first and second derivatives at the quadrature points.
psi_map[i].resize (n_qp);
if (Dim > 1)
{
dpsidxi_map[i].resize (n_qp);
d2psidxi2_map[i].resize (n_qp);
}
if (Dim == 3)
{
dpsideta_map[i].resize (n_qp);
d2psidxideta_map[i].resize (n_qp);
d2psideta2_map[i].resize (n_qp);
}
// Compute the value of shape function i, and its first and
// second derivatives at quadrature point p
// (Lagrange shape functions are used for the mapping)
for (unsigned int p=0; p<n_qp; p++)
{
psi_map[i][p] = FE<Dim-1,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
if (Dim > 1)
{
dpsidxi_map[i][p] = FE<Dim-1,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
d2psidxi2_map[i][p] = FE<Dim-1,LAGRANGE>::shape_second_deriv(mapping_elem_type, mapping_order, i, 0, qp[p]);
}
// std::cout << 'd2psidxi2_map['<<i<<'][p]=' << d2psidxi2_map[i][p] << std::endl;
// If we are in 3D, then our sides are 2D faces.
// For the second derivatives, we must also compute the cross
// derivative d^2() / dxi deta
if (Dim == 3)
{
dpsideta_map[i][p] = FE<Dim-1,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
d2psidxideta_map[i][p] = FE<Dim-1,LAGRANGE>::shape_second_deriv(mapping_elem_type, mapping_order, i, 1, qp[p]);
d2psideta2_map[i][p] = FE<Dim-1,LAGRANGE>::shape_second_deriv(mapping_elem_type, mapping_order, i, 2, qp[p]);
}
}
}
STOP_LOG('init_face_shape_functions()', 'FE');
}
Reimplemented in FEXYZ< Dim >.
Definition at line 221 of file fe.C.
References Elem::default_order(), Elem::has_affine_map(), FE< Dim, T >::n_shape_functions(), FE< Dim, T >::shape(), FE< Dim, T >::shape_deriv(), FE< Dim, T >::shape_second_deriv(), Elem::type(), and MeshTools::weight().
{
libmesh_assert (elem != NULL);
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_phi = calculate_dphi = calculate_d2phi = true;
#else
if (!calculate_phi && !calculate_dphi)
calculate_phi = calculate_dphi = true;
#endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
// Start logging the shape function initialization
START_LOG('init_shape_functions()', 'FE');
// The number of quadrature points.
const unsigned int n_qp = qp.size();
// The element type and order to use in
// the map
const Order mapping_order (elem->default_order());
const ElemType mapping_elem_type (elem->type());
// Number of shape functions in the finite element approximation
// space.
const unsigned int n_approx_shape_functions =
this->n_shape_functions(this->get_type(),
this->get_order());
// Number of shape functions used to construt the map
// (Lagrange shape functions are used for mapping)
const unsigned int n_mapping_shape_functions =
FE<Dim,LAGRANGE>::n_shape_functions (mapping_elem_type,
mapping_order);
// resize the vectors to hold current data
// Phi are the shape functions used for the FE approximation
// Phi_map are the shape functions used for the FE mapping
{
if (calculate_phi)
phi.resize (n_approx_shape_functions);
if (calculate_dphi)
{
dphi.resize (n_approx_shape_functions);
dphidx.resize (n_approx_shape_functions);
dphidy.resize (n_approx_shape_functions);
dphidz.resize (n_approx_shape_functions);
dphidxi.resize (n_approx_shape_functions);
if (Dim > 1)
dphideta.resize (n_approx_shape_functions);
if (Dim == 3)
dphidzeta.resize (n_approx_shape_functions);
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
{
d2phi.resize (n_approx_shape_functions);
d2phidx2.resize (n_approx_shape_functions);
d2phidxdy.resize (n_approx_shape_functions);
d2phidxdz.resize (n_approx_shape_functions);
d2phidy2.resize (n_approx_shape_functions);
d2phidydz.resize (n_approx_shape_functions);
d2phidz2.resize (n_approx_shape_functions);
d2phidxi2.resize (n_approx_shape_functions);
if (Dim > 1)
{
d2phidxideta.resize (n_approx_shape_functions);
d2phideta2.resize (n_approx_shape_functions);
}
if (Dim > 2)
{
d2phidxidzeta.resize (n_approx_shape_functions);
d2phidetadzeta.resize (n_approx_shape_functions);
d2phidzeta2.resize (n_approx_shape_functions);
}
}
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
phi_map.resize (n_mapping_shape_functions);
dphidxi_map.resize (n_mapping_shape_functions);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map.resize (n_mapping_shape_functions);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (Dim > 1)
{
dphideta_map.resize (n_mapping_shape_functions);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxideta_map.resize (n_mapping_shape_functions);
d2phideta2_map.resize (n_mapping_shape_functions);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
if (Dim == 3)
{
dphidzeta_map.resize (n_mapping_shape_functions);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxidzeta_map.resize (n_mapping_shape_functions);
d2phidetadzeta_map.resize (n_mapping_shape_functions);
d2phidzeta2_map.resize (n_mapping_shape_functions);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
for (unsigned int i=0; i<n_approx_shape_functions; i++)
{
if (calculate_phi)
phi[i].resize (n_qp);
if (calculate_dphi)
{
dphi[i].resize (n_qp);
dphidx[i].resize (n_qp);
dphidy[i].resize (n_qp);
dphidz[i].resize (n_qp);
dphidxi[i].resize (n_qp);
if (Dim > 1)
dphideta[i].resize (n_qp);
if (Dim == 3)
dphidzeta[i].resize (n_qp);
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
{
d2phi[i].resize (n_qp);
d2phidx2[i].resize (n_qp);
d2phidxdy[i].resize (n_qp);
d2phidxdz[i].resize (n_qp);
d2phidy2[i].resize (n_qp);
d2phidydz[i].resize (n_qp);
d2phidz2[i].resize (n_qp);
d2phidxi2[i].resize (n_qp);
if (Dim > 1)
{
d2phidxideta[i].resize (n_qp);
d2phideta2[i].resize (n_qp);
}
if (Dim > 2)
{
d2phidxidzeta[i].resize (n_qp);
d2phidetadzeta[i].resize (n_qp);
d2phidzeta2[i].resize (n_qp);
}
}
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
{
phi_map[i].resize (n_qp);
dphidxi_map[i].resize (n_qp);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i].resize (n_qp);
if (Dim > 1)
{
d2phidxideta_map[i].resize (n_qp);
d2phideta2_map[i].resize (n_qp);
}
if (Dim > 2)
{
d2phidxidzeta_map[i].resize (n_qp);
d2phidetadzeta_map[i].resize (n_qp);
d2phidzeta2_map[i].resize (n_qp);
}
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (Dim > 1)
dphideta_map[i].resize (n_qp);
if (Dim == 3)
dphidzeta_map[i].resize (n_qp);
}
}
#ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
//------------------------------------------------------------
// Initialize the data fields, which should only be used for infinite
// elements, to some sensible values, so that using a FE with the
// variational formulation of an InfFE, correct element matrices are
// returned
{
weight.resize (n_qp);
dweight.resize (n_qp);
dphase.resize (n_qp);
for (unsigned int p=0; p<n_qp; p++)
{
weight[p] = 1.;
dweight[p].zero();
dphase[p].zero();
}
}
#endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
// Optimize for the affine elements case:
bool has_affine_map = elem->has_affine_map();
switch (Dim)
{
//------------------------------------------------------------
// 1D
case 1:
{
// Compute the value of the approximation shape function i at quadrature point p
if (calculate_phi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
phi[i][p] = FE<Dim,T>::shape (elem, fe_type.order, i, qp[p]);
if (calculate_dphi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
dphidxi[i][p] = FE<Dim,T>::shape_deriv (elem, fe_type.order, i, 0, qp[p]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
d2phidxi2[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 0, qp[p]);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
// Compute the value of the mapping shape function i at quadrature point p
// (Lagrange shape functions are used for mapping)
if (has_affine_map)
{
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
{
phi_map[i][0] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[0]);
dphidxi_map[i][0] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[0]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 0, qp[0]);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
for (unsigned int p=1; p<n_qp; p++)
{
phi_map[i][p] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
dphidxi_map[i][p] = dphidxi_map[i][0];
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][p] = d2phidxi2_map[i][0];
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
}
}
else
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
{
phi_map[i][p] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
dphidxi_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
break;
}
//------------------------------------------------------------
// 2D
case 2:
{
// Compute the value of the approximation shape function i at quadrature point p
if (calculate_phi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
phi[i][p] = FE<Dim,T>::shape (elem, fe_type.order, i, qp[p]);
if (calculate_dphi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
{
dphidxi[i][p] = FE<Dim,T>::shape_deriv (elem, fe_type.order, i, 0, qp[p]);
dphideta[i][p] = FE<Dim,T>::shape_deriv (elem, fe_type.order, i, 1, qp[p]);
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
{
d2phidxi2[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 0, qp[p]);
d2phidxideta[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 1, qp[p]);
d2phideta2[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 2, qp[p]);
}
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
// Compute the value of the mapping shape function i at quadrature point p
// (Lagrange shape functions are used for mapping)
if (has_affine_map)
{
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
{
phi_map[i][0] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[0]);
dphidxi_map[i][0] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[0]);
dphideta_map[i][0] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[0]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 0, qp[0]);
d2phidxideta_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 1, qp[0]);
d2phideta2_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 2, qp[0]);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
for (unsigned int p=1; p<n_qp; p++)
{
phi_map[i][p] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
dphidxi_map[i][p] = dphidxi_map[i][0];
dphideta_map[i][p] = dphideta_map[i][0];
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][p] = d2phidxi2_map[i][0];
d2phidxideta_map[i][p] = d2phidxideta_map[i][0];
d2phideta2_map[i][p] = d2phideta2_map[i][0];
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
}
}
else
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
{
phi_map[i][p] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
dphidxi_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
dphideta_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
d2phidxideta_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
d2phideta2_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 2, qp[p]);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
break;
}
//------------------------------------------------------------
// 3D
case 3:
{
// Compute the value of the approximation shape function i at quadrature point p
if (calculate_phi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
phi[i][p] = FE<Dim,T>::shape (elem, fe_type.order, i, qp[p]);
if (calculate_dphi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
{
dphidxi[i][p] = FE<Dim,T>::shape_deriv (elem, fe_type.order, i, 0, qp[p]);
dphideta[i][p] = FE<Dim,T>::shape_deriv (elem, fe_type.order, i, 1, qp[p]);
dphidzeta[i][p] = FE<Dim,T>::shape_deriv (elem, fe_type.order, i, 2, qp[p]);
}
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
if (calculate_d2phi)
for (unsigned int i=0; i<n_approx_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
{
d2phidxi2[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 0, qp[p]);
d2phidxideta[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 1, qp[p]);
d2phideta2[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 2, qp[p]);
d2phidxidzeta[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 3, qp[p]);
d2phidetadzeta[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 4, qp[p]);
d2phidzeta2[i][p] = FE<Dim,T>::shape_second_deriv (elem, fe_type.order, i, 5, qp[p]);
}
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
// Compute the value of the mapping shape function i at quadrature point p
// (Lagrange shape functions are used for mapping)
if (has_affine_map)
{
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
{
phi_map[i][0] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[0]);
dphidxi_map[i][0] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[0]);
dphideta_map[i][0] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[0]);
dphidzeta_map[i][0] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 2, qp[0]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 0, qp[0]);
d2phidxideta_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 1, qp[0]);
d2phideta2_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 2, qp[0]);
d2phidxideta_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 3, qp[0]);
d2phidetadzeta_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 4, qp[0]);
d2phidzeta2_map[i][0] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 5, qp[0]);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
for (unsigned int p=1; p<n_qp; p++)
{
phi_map[i][p] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
dphidxi_map[i][p] = dphidxi_map[i][0];
dphideta_map[i][p] = dphideta_map[i][0];
dphidzeta_map[i][p] = dphidzeta_map[i][0];
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][p] = d2phidxi2_map[i][0];
d2phidxideta_map[i][p] = d2phidxideta_map[i][0];
d2phideta2_map[i][p] = d2phideta2_map[i][0];
d2phidxideta_map[i][p] = d2phidxideta_map[i][0];
d2phidetadzeta_map[i][p] = d2phidetadzeta_map[i][0];
d2phidzeta2_map[i][p] = d2phidzeta2_map[i][0];
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
}
}
else
for (unsigned int i=0; i<n_mapping_shape_functions; i++)
for (unsigned int p=0; p<n_qp; p++)
{
phi_map[i][p] = FE<Dim,LAGRANGE>::shape (mapping_elem_type, mapping_order, i, qp[p]);
dphidxi_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
dphideta_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
dphidzeta_map[i][p] = FE<Dim,LAGRANGE>::shape_deriv (mapping_elem_type, mapping_order, i, 2, qp[p]);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2phidxi2_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 0, qp[p]);
d2phidxideta_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 1, qp[p]);
d2phideta2_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 2, qp[p]);
d2phidxideta_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 3, qp[p]);
d2phidetadzeta_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 4, qp[p]);
d2phidzeta2_map[i][p] = FE<Dim,LAGRANGE>::shape_second_deriv (mapping_elem_type, mapping_order, i, 5, qp[p]);
#endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
}
break;
}
default:
libmesh_error();
}
// Stop logging the shape function initialization
STOP_LOG('init_shape_functions()', 'FE');
}
Definition at line 625 of file fe_map.C.
References TypeVector< T >::add(), DofObject::id(), FE< Dim, T >::map(), FE< Dim, T >::map_eta(), FE< Dim, T >::map_xi(), FE< Dim, T >::map_zeta(), and TypeVector< T >::size().
Referenced by FE< Dim, T >::nodal_soln().
{
libmesh_assert (elem != NULL);
libmesh_assert (tolerance >= 0.);
// Start logging the map inversion.
START_LOG('inverse_map()', 'FE');
// How much did the point on the reference
// element change by in this Newton step?
Real inverse_map_error = 0.;
// The point on the reference element. This is
// the 'initial guess' for Newton's method. The
// centroid seems like a good idea, but computing
// it is a little more intensive than, say taking
// the zero point.
//
// Convergence should be insensitive of this choice
// for 'good' elements.
Point p; // the zero point. No computation required
// The number of iterations in the map inversion process.
unsigned int cnt = 0;
// Newton iteration loop.
do
{
// Where our current iterate
p maps to.
const Point physical_guess = FE<Dim,T>::map (elem, p);
// How far our current iterate is from the actual point.
const Point delta = physical_point - physical_guess;
// Increment in current iterate
p, will be computed.
Point dp;
// The form of the map and how we invert it depends
// on the dimension that we are in.
switch (Dim)
{
// ------------------------------------------------------------------
// 1D map inversion
//
// Here we find the point on a 1D reference element that maps to
// the point
physical_point in the domain. This is a bit tricky
// since we do not want to assume that the point
physical_point
// is also in a 1D domain. In particular, this method might get
// called on the edge of a 3D element, in which case
//
physical_point actually lives in 3D.
case 1:
{
const Point dxi = FE<Dim,T>::map_xi (elem, p);
// Newton's method in this case looks like
//
// {X} - {X_n} = [J]*dp
//
// Where {X}, {X_n} are 3x1 vectors, [J] is a 3x1 matrix
// d(x,y,z)/dxi, and we seek dp, a scalar. Since the above
// system is either overdetermined or rank-deficient, we will
// solve the normal equations for this system
//
// [J]^T ({X} - {X_n}) = [J]^T [J] {dp}
//
// which involves the trivial inversion of the scalar
// G = [J]^T [J]
const Real G = dxi*dxi;
if (secure)
libmesh_assert (G > 0.);
const Real Ginv = 1./G;
const Real dxidelta = dxi*delta;
dp(0) = Ginv*dxidelta;
// Assume that no master elements have radius > 4
if (secure)
libmesh_assert (dp.size() < 4);
break;
}
// ------------------------------------------------------------------
// 2D map inversion
//
// Here we find the point on a 2D reference element that maps to
// the point
physical_point in the domain. This is a bit tricky
// since we do not want to assume that the point
physical_point
// is also in a 2D domain. In particular, this method might get
// called on the face of a 3D element, in which case
//
physical_point actually lives in 3D.
case 2:
{
const Point dxi = FE<Dim,T>::map_xi (elem, p);
const Point deta = FE<Dim,T>::map_eta (elem, p);
// Newton's method in this case looks like
//
// {X} - {X_n} = [J]*{dp}
//
// Where {X}, {X_n} are 3x1 vectors, [J] is a 3x2 matrix
// d(x,y,z)/d(xi,eta), and we seek {dp}, a 2x1 vector. Since
// the above system is either overdermined or rank-deficient,
// we will solve the normal equations for this system
//
// [J]^T ({X} - {X_n}) = [J]^T [J] {dp}
//
// which involves the inversion of the 2x2 matrix
// [G] = [J]^T [J]
const Real
G11 = dxi*dxi, G12 = dxi*deta,
G21 = dxi*deta, G22 = deta*deta;
const Real det = (G11*G22 - G12*G21);
if (secure)
libmesh_assert (det != 0.);
const Real inv_det = 1./det;
const Real
Ginv11 = G22*inv_det,
Ginv12 = -G12*inv_det,
Ginv21 = -G21*inv_det,
Ginv22 = G11*inv_det;
const Real dxidelta = dxi*delta;
const Real detadelta = deta*delta;
dp(0) = (Ginv11*dxidelta + Ginv12*detadelta);
dp(1) = (Ginv21*dxidelta + Ginv22*detadelta);
// Assume that no master elements have radius > 4
if (secure)
libmesh_assert (dp.size() < 4);
break;
}
// ------------------------------------------------------------------
// 3D map inversion
//
// Here we find the point in a 3D reference element that maps to
// the point
physical_point in a 3D domain. Nothing special
// has to happen here, since (unless the map is singular because
// you have a BAD element) the map will be invertable and we can
// apply Newton's method directly.
case 3:
{
const Point dxi = FE<Dim,T>::map_xi (elem, p);
const Point deta = FE<Dim,T>::map_eta (elem, p);
const Point dzeta = FE<Dim,T>::map_zeta (elem, p);
// Newton's method in this case looks like
//
// {X} = {X_n} + [J]*{dp}
//
// Where {X}, {X_n} are 3x1 vectors, [J] is a 3x3 matrix
// d(x,y,z)/d(xi,eta,zeta), and we seek {dp}, a 3x1 vector.
// Since the above system is nonsingular for invertable maps
// we will solve
//
// {dp} = [J]^-1 ({X} - {X_n})
//
// which involves the inversion of the 3x3 matrix [J]
const Real
J11 = dxi(0), J12 = deta(0), J13 = dzeta(0),
J21 = dxi(1), J22 = deta(1), J23 = dzeta(1),
J31 = dxi(2), J32 = deta(2), J33 = dzeta(2);
const Real det = (J11*(J22*J33 - J23*J32) +
J12*(J23*J31 - J21*J33) +
J13*(J21*J32 - J22*J31));
if (secure)
libmesh_assert (det != 0.);
const Real inv_det = 1./det;
const Real
Jinv11 = (J22*J33 - J23*J32)*inv_det,
Jinv12 = -(J12*J33 - J13*J32)*inv_det,
Jinv13 = (J12*J23 - J13*J22)*inv_det,
Jinv21 = -(J21*J33 - J23*J31)*inv_det,
Jinv22 = (J11*J33 - J13*J31)*inv_det,
Jinv23 = -(J11*J23 - J13*J21)*inv_det,
Jinv31 = (J21*J32 - J22*J31)*inv_det,
Jinv32 = -(J11*J32 - J12*J31)*inv_det,
Jinv33 = (J11*J22 - J12*J21)*inv_det;
dp(0) = (Jinv11*delta(0) +
Jinv12*delta(1) +
Jinv13*delta(2));
dp(1) = (Jinv21*delta(0) +
Jinv22*delta(1) +
Jinv23*delta(2));
dp(2) = (Jinv31*delta(0) +
Jinv32*delta(1) +
Jinv33*delta(2));
// Assume that no master elements have radius > 4
if (secure)
libmesh_assert (dp.size() < 4);
break;
}
// Some other dimension?
default:
libmesh_error();
} // end switch(Dim), dp now computed
// ||P_n+1 - P_n||
inverse_map_error = dp.size();
// P_n+1 = P_n + dp
p.add (dp);
// Increment the iteration count.
cnt++;
// Watch for divergence of Newton's
// method. Here's how it goes:
// (1) For good elements, we expect convergence in 10 iterations.
// - If called with (secure == true) and we have not yet converged
// print out a warning message.
// - If called with (secure == true) and we have not converged in
// 20 iterations abort
// (2) This method may be called in cases when the target point is not
// inside the element and we have no business expecting convergence.
// For these cases if we have not converged in 10 iterations forget
// about it.
if (cnt > 10)
{
// Warn about divergence when secure is true - this
// shouldn't happen
if (secure)
{
libmesh_here();
std::cerr << 'WARNING: Newton scheme has not converged in '
<< cnt << ' iterations:' << std::endl
<< ' physical_point='
<< physical_point
<< ' physical_guess='
<< physical_guess
<< ' dp='
<< dp
<< ' p='
<< p
<< ' error=' << inverse_map_error
<< ' in element ' << elem->id()
<< std::endl;
if (cnt > 20)
{
std::cerr << 'ERROR: Newton scheme FAILED to converge in '
<< cnt
<< ' iterations!'
<< ' in element ' << elem->id()
<< std::endl;
libmesh_error();
}
}
// Return a far off point when secure is false - this
// should only happen when we're trying to map a point
// that's outside the element
else
{
for (unsigned int i=0; i != Dim; ++i)
p(i) = 1e6;
STOP_LOG('inverse_map()', 'FE');
return p;
}
}
}
while (inverse_map_error > tolerance);
// If we are in debug mode do a sanity check. Make sure
// the point
p on the reference element actually does
// map to the point
physical_point within a tolerance.
#ifdef DEBUG
if (secure)
{
const Point check = FE<Dim,T>::map (elem, p);
const Point diff = physical_point - check;
if (diff.size() > tolerance)
{
libmesh_here();
std::cerr << 'WARNING: diff is '
<< diff.size()
<< std::endl
<< ' point='
<< physical_point;
std::cerr << ' local=' << check;
std::cerr << ' lref= ' << p;
}
}
#endif
// Stop logging the map inversion.
STOP_LOG('inverse_map()', 'FE');
return p;
}
Definition at line 968 of file fe_map.C.
References TypeVector< T >::size().
{
// The number of points to find the
// inverse map of
const unsigned int n_points = physical_points.size();
// Resize the vector to hold the points
// on the reference element
reference_points.resize(n_points);
// Find the coordinates on the reference
// element of each point in physical space
for (unsigned int p=0; p<n_points; p++)
reference_points[p] =
FE<Dim,T>::inverse_map (elem, physical_points[p], tolerance, secure);
}
Implements FEBase.
Definition at line 1620 of file fe_bernstein.C.
{
return false;
}
Definition at line 518 of file fe_map.C.
References TypeVector< T >::add_scaled(), Elem::default_order(), FE< Dim, T >::n_shape_functions(), Elem::point(), FE< Dim, T >::shape(), and Elem::type().
Referenced by InfFE< Dim, T_radial, T_map >::inverse_map(), FE< Dim, T >::inverse_map(), and InfFE< Dim, T_radial, T_map >::map().
{
libmesh_assert (elem != NULL);
Point p;
const ElemType type = elem->type();
const Order order = elem->default_order();
const unsigned int n_sf = FE<Dim,LAGRANGE>::n_shape_functions(type, order);
// Lagrange basis functions are used for mapping
for (unsigned int i=0; i<n_sf; i++)
p.add_scaled (elem->point(i),
FE<Dim,LAGRANGE>::shape(type,
order,
i,
reference_point)
);
return p;
}
Definition at line 571 of file fe_map.C.
References TypeVector< T >::add_scaled(), Elem::default_order(), FE< Dim, T >::n_shape_functions(), Elem::point(), FE< Dim, T >::shape_deriv(), and Elem::type().
Referenced by InfFE< Dim, T_radial, T_map >::inverse_map(), and FE< Dim, T >::inverse_map().
{
libmesh_assert (elem != NULL);
Point p;
const ElemType type = elem->type();
const Order order = elem->default_order();
const unsigned int n_sf = FE<Dim,LAGRANGE>::n_shape_functions(type, order);
// Lagrange basis functions are used for mapping
for (unsigned int i=0; i<n_sf; i++)
p.add_scaled (elem->point(i),
FE<Dim,LAGRANGE>::shape_deriv(type,
order,
i,
1,
reference_point)
);
return p;
}
Definition at line 544 of file fe_map.C.
References TypeVector< T >::add_scaled(), Elem::default_order(), FE< Dim, T >::n_shape_functions(), Elem::point(), FE< Dim, T >::shape_deriv(), and Elem::type().
Referenced by InfFE< Dim, T_radial, T_map >::inverse_map(), and FE< Dim, T >::inverse_map().
{
libmesh_assert (elem != NULL);
Point p;
const ElemType type = elem->type();
const Order order = elem->default_order();
const unsigned int n_sf = FE<Dim,LAGRANGE>::n_shape_functions(type, order);
// Lagrange basis functions are used for mapping
for (unsigned int i=0; i<n_sf; i++)
p.add_scaled (elem->point(i),
FE<Dim,LAGRANGE>::shape_deriv(type,
order,
i,
0,
reference_point)
);
return p;
}
Definition at line 598 of file fe_map.C.
References TypeVector< T >::add_scaled(), Elem::default_order(), FE< Dim, T >::n_shape_functions(), Elem::point(), FE< Dim, T >::shape_deriv(), and Elem::type().
Referenced by FE< Dim, T >::inverse_map().
{
libmesh_assert (elem != NULL);
Point p;
const ElemType type = elem->type();
const Order order = elem->default_order();
const unsigned int n_sf = FE<Dim,LAGRANGE>::n_shape_functions(type, order);
// Lagrange basis functions are used for mapping
for (unsigned int i=0; i<n_sf; i++)
p.add_scaled (elem->point(i),
FE<Dim,LAGRANGE>::shape_deriv(type,
order,
i,
2,
reference_point)
);
return p;
}
On a p-refined element, o should be the total order of the element.
Definition at line 117 of file fe_bernstein.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, libMeshEnums::NODEELEM, libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::TET10, libMeshEnums::TET4, libMeshEnums::TRI3, and libMeshEnums::TRI6.
Referenced by FE< Dim, LAGRANGE >::n_shape_functions(), and FE< Dim, T >::n_shape_functions().
{
switch (t)
{
case NODEELEM:
return 1;
case EDGE2:
case EDGE3:
return (o+1);
case QUAD4:
libmesh_assert(o < 2);
case QUAD8:
{
if (o == 1)
return 4;
else if (o == 2)
return 8;
else
libmesh_error();
}
case QUAD9:
return ((o+1)*(o+1));
case HEX8:
libmesh_assert(o < 2);
case HEX20:
{
if (o == 1)
return 8;
else if (o == 2)
return 20;
else
libmesh_error();
}
case HEX27:
return ((o+1)*(o+1)*(o+1));
case TRI3:
libmesh_assert (o<2);
case TRI6:
return ((o+1)*(o+2)/2);
case TET4:
libmesh_assert (o<2);
case TET10:
{
libmesh_assert (o<3);
return ((o+1)*(o+2)*(o+3)/6);
}
default:
libmesh_error();
}
libmesh_error();
return 0;
// old code
// switch (o)
// {
// // Bernstein 1st-order polynomials.
// case FIRST:
// {
// switch (t)
// {
// case EDGE2:
// case EDGE3:
// return 2;
// case TRI6:
// return 3;
// case QUAD8:
// case QUAD9:
// return 4;
// case TET4:
// case TET10:
// return 4;
// case HEX20:
// case HEX27:
// return 8;
// default:
// libmesh_error();
// }
// }
// // Bernstein 2nd-order polynomials.
// case SECOND:
// {
// switch (t)
// {
// case EDGE2:
// case EDGE3:
// return 3;
// case TRI6:
// return 6;
// case QUAD8:
// return 8;
// case QUAD9:
// return 9;
// case TET10:
// return 10;
// case HEX20:
// return 20;
// case HEX27:
// return 27;
// default:
// libmesh_error();
// }
// }
// // Bernstein 3rd-order polynomials.
// case THIRD:
// {
// switch (t)
// {
// case EDGE2:
// case EDGE3:
// return 4;
// case TRI6:
// return 10;
// case QUAD8:
// case QUAD9:
// return 16;
// case TET10:
// return 20;
// case HEX27:
// return 64;
// default:
// libmesh_error();
// }
// }
// // Bernstein 4th-order polynomials.
// case FOURTH:
// {
// switch (t)
// {
// case EDGE2:
// case EDGE3:
// return 5;
// case TRI6:
// return 15;
// case QUAD8:
// case QUAD9:
// return 25;
// case TET10:
// return 35;
// case HEX27:
// return 125;
// default:
// libmesh_error();
// }
// }
// // Bernstein 5th-order polynomials.
// case FIFTH:
// {
// switch (t)
// {
// case EDGE2:
// case EDGE3:
// return 6;
// case TRI6:
// return 21;
// case QUAD8:
// case QUAD9:
// return 36;
// case HEX27:
// return 216;
// default:
// libmesh_error();
// }
// }
// // Bernstein 6th-order polynomials.
// case SIXTH:
// {
// switch (t)
// {
// case EDGE2:
// case EDGE3:
// return 7;
// case TRI6:
// return 28;
// case QUAD8:
// case QUAD9:
// return 49;
// case HEX27:
// return 343;
// default:
// libmesh_error();
// }
// }
// default:
// {
// libmesh_error();
// }
// }
// libmesh_error();
// return 0;
}
On a p-refined element, o should be the total order of the element.
Definition at line 355 of file fe_bernstein.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, libMeshEnums::NODEELEM, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::TET10, libMeshEnums::TET4, and libMeshEnums::TRI6.
{
switch (t)
{
case NODEELEM:
return 1;
case EDGE2:
case EDGE3:
switch (n)
{
case 0:
case 1:
return 1;
case 2:
libmesh_assert (o>1);
return (o-1);
default:
libmesh_error();
}
case TRI6:
switch (n)
{
case 0:
case 1:
case 2:
return 1;
case 3:
case 4:
case 5:
return (o-1);
// Internal DoFs are associated with the elem, not its nodes
default:
libmesh_error();
}
case QUAD8:
libmesh_assert (n<8);
libmesh_assert (o<3);
case QUAD9:
{
switch (n)
{
case 0:
case 1:
case 2:
case 3:
return 1;
case 4:
case 5:
case 6:
case 7:
return (o-1);
// Internal DoFs are associated with the elem, not its nodes
case 8:
return 0;
default:
libmesh_error();
}
}
case HEX8:
libmesh_assert (n < 8);
libmesh_assert (o < 2);
case HEX20:
libmesh_assert (n < 20);
libmesh_assert (o < 3);
case HEX27:
switch (n)
{
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
return 1;
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
case 17:
case 18:
case 19:
return (o-1);
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
return ((o-1)*(o-1));
// Internal DoFs are associated with the elem, not its nodes
case 26:
return 0;
default:
libmesh_error();
}
case TET4:
libmesh_assert(n<4);
libmesh_assert(o<2);
case TET10:
libmesh_assert (o<3);
libmesh_assert (n<10);
switch (n)
{
case 0:
case 1:
case 2:
case 3:
return 1;
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
return (o-1);
default:
libmesh_error();
}
default:
libmesh_error();
}
libmesh_error();
return 0;
// switch (o)
// {
// // The first-order Bernstein shape functions
// case FIRST:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a three-noded edge
// case EDGE2:
// case EDGE3:
// {
// switch (n)
// {
// case 0:
// case 1:
// return 1;
// case 2:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// return 1;
// case 3:
// case 4:
// case 5:
// case 6:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// return 0;
// case 8:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The 3D Bernsteins defined on a ten-noded tetrahedral.
// case TET4:
// case TET10:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// case 8:
// case 9:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The 3D Bernsteins defined on a hexahedral.
// case HEX20:
// case HEX27:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// case 4:
// case 5:
// case 6:
// case 7:
// return 1;
// case 8:
// case 9:
// case 10:
// case 11:
// case 12:
// case 13:
// case 14:
// case 15:
// case 16:
// case 17:
// case 18:
// case 19:
// return 0;
// case 20:
// case 21:
// case 22:
// case 23:
// case 24:
// case 25:
// return 0;
// case 26:
// return 0;
// }
// }
// default:
// libmesh_error();
// }
// }
// // The second-order Bernstein shape functions
// case SECOND:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a three-noded edge
// case EDGE2:
// case EDGE3:
// {
// libmesh_assert (n<3);
// return 1;
// }
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// {
// libmesh_assert (n<6);
// return 1;
// }
// // The 8-noded quadrilateral
// case QUAD8:
// {
// libmesh_assert (n<8);
// return 1;
// }
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD9:
// {
// libmesh_assert (n<9);
// return 1;
// }
// // The 3D Bernsteins defined on a ten-noded tetrahedral.
// case TET10:
// {
// libmesh_assert(n<10);
// return 1;
// }
// // The 3D Bernsteins defined on a
// // 20-noded hexahedral.
// case HEX20:
// {
// libmesh_assert(n<20);
// return 1;
// }
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// {
// libmesh_assert(n<27);
// return 1;
// }
// default:
// libmesh_error();
// }
// }
// // The third-order Bernstein shape functions
// case THIRD:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a three-noded edge
// case EDGE2:
// case EDGE3:
// {
// switch (n)
// {
// case 0:
// case 1:
// return 1;
// case 2:
// return 2;
// default:
// libmesh_error();
// }
// }
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// return 1;
// case 3:
// case 4:
// case 5:
// return 2;
// case 6:
// return 1;
// default:
// libmesh_error();
// }
// }
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// return 2;
// case 8:
// return 4;
// default:
// libmesh_error();
// }
// }
// // The 3D Bernsteins defined on a ten-noded tetrahedral.
// case TET10:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// case 8:
// case 9:
// return 2;
// default:
// libmesh_error();
// }
// }
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// case 4:
// case 5:
// case 6:
// case 7:
// return 1;
// case 8:
// case 9:
// case 10:
// case 11:
// case 12:
// case 13:
// case 14:
// case 15:
// case 16:
// case 17:
// case 18:
// case 19:
// return 2;
// case 20:
// case 21:
// case 22:
// case 23:
// case 24:
// case 25:
// return 4;
// case 26:
// return 8;
// }
// }
// default:
// libmesh_error();
// }
// }
// // The fourth-order Bernstein shape functions
// case FOURTH:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a three-noded edge
// case EDGE2:
// case EDGE3:
// {
// switch (n)
// {
// case 0:
// case 1:
// return 1;
// case 2:
// return 3;
// default:
// libmesh_error();
// }
// }
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// return 1;
// case 3:
// case 4:
// case 5:
// return 3;
// case 6:
// return 3;
// default:
// libmesh_error();
// }
// }
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// return 3;
// case 8:
// return 9;
// default:
// libmesh_error();
// }
// }
// // The 3D Bernsteins defined on a ten-noded tetrahedral.
// case TET10:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// case 8:
// case 9:
// return 3;
// default:
// libmesh_error();
// }
// }
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// case 4:
// case 5:
// case 6:
// case 7:
// return 1;
// case 8:
// case 9:
// case 10:
// case 11:
// case 12:
// case 13:
// case 14:
// case 15:
// case 16:
// case 17:
// case 18:
// case 19:
// return 3;
// case 20:
// case 21:
// case 22:
// case 23:
// case 24:
// case 25:
// return 9;
// case 26:
// return 27;
// }
// }
// default:
// libmesh_error();
// }
// }
// // The fifth-order Bernstein shape functions
// case FIFTH:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a three-noded edge
// case EDGE2:
// case EDGE3:
// {
// switch (n)
// {
// case 0:
// case 1:
// return 1;
// case 2:
// return 4;
// default:
// libmesh_error();
// }
// }
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// return 1;
// case 3:
// case 4:
// case 5:
// return 4;
// case 6:
// return 6;
// default:
// libmesh_error();
// }
// }
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// return 4;
// case 8:
// return 16;
// default:
// libmesh_error();
// }
// }
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// case 4:
// case 5:
// case 6:
// case 7:
// return 1;
// case 8:
// case 9:
// case 10:
// case 11:
// case 12:
// case 13:
// case 14:
// case 15:
// case 16:
// case 17:
// case 18:
// case 19:
// return 4;
// case 20:
// case 21:
// case 22:
// case 23:
// case 24:
// case 25:
// return 16;
// case 26:
// return 64;
// }
// }
// default:
// libmesh_error();
// } // switch ElemType
// } // case FIFTH
// // The sixth-order Bernstein shape functions
// case SIXTH:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a three-noded edge
// case EDGE2:
// case EDGE3:
// {
// switch (n)
// {
// case 0:
// case 1:
// return 1;
// case 2:
// return 5;
// default:
// libmesh_error();
// }
// }
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// return 1;
// case 3:
// case 4:
// case 5:
// return 5;
// case 6:
// return 10;
// default:
// libmesh_error();
// }
// }
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// return 1;
// case 4:
// case 5:
// case 6:
// case 7:
// return 5;
// case 8:
// return 25;
// default:
// libmesh_error();
// }
// }
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// {
// switch (n)
// {
// case 0:
// case 1:
// case 2:
// case 3:
// case 4:
// case 5:
// case 6:
// case 7:
// return 1;
// case 8:
// case 9:
// case 10:
// case 11:
// case 12:
// case 13:
// case 14:
// case 15:
// case 16:
// case 17:
// case 18:
// case 19:
// return 5;
// case 20:
// case 21:
// case 22:
// case 23:
// case 24:
// case 25:
// return 25;
// case 26:
// return 125;
// }
// }
// default:
// libmesh_error();
// } // switch ElemType
// } // case SIXTH
// default:
// libmesh_error();
//
// }
// libmesh_error();
// return 0;
}
On a p-refined element, o should be the total order of the element.
Definition at line 1286 of file fe_bernstein.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, libMeshEnums::NODEELEM, libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::TET10, libMeshEnums::TET4, libMeshEnums::TRI3, and libMeshEnums::TRI6.
{
switch (t)
{
case NODEELEM:
case EDGE2:
case EDGE3:
return 0;
case TRI3:
case QUAD4:
return 0;
case TRI6:
return ((o-1)*(o-2)/2);
case QUAD8:
if (o <= 2)
return 0;
case QUAD9:
return ((o-1)*(o-1));
case HEX8:
libmesh_assert(o < 2);
case HEX20:
libmesh_assert(o < 3);
return 0;
case HEX27:
return ((o-1)*(o-1)*(o-1));
case TET4:
libmesh_assert (o<2);
case TET10:
libmesh_assert (o<3);
return 0;
default:
libmesh_error();
}
libmesh_error();
return 0;
// switch (o)
// {
// // The first-order Bernstein shape functions
// case FIRST:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a two-noded edge
// case EDGE2:
// return 0;
// // The 1D Bernstein defined on a three-noded edge
// case EDGE3:
// return 0;
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// return 0;
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD8:
// return 0;
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD9:
// return 0;
// // The 3D Bernsteins defined on a four-noded hexahedral.
// case TET4:
// return 0;
// // The 3D Bernsteins defined on a ten-noded hexahedral.
// case TET10:
// return 0;
// // The 3D Bernsteins defined on a 20-noded hexahedral.
// case HEX20:
// return 0;
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The second-order Bernstein shape functions
// case SECOND:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a two-noded edge
// case EDGE2:
// return 1;
// // The 1D Bernstein defined on a three-noded edge
// case EDGE3:
// return 0;
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// return 0;
// // The 2D tensor-product Bernsteins defined on a
// // eight-noded quadrilateral.
// case QUAD8:
// return 0;
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD9:
// return 0;
// // The 3D Bernsteins defined on a ten-noded hexahedral.
// case TET10:
// return 0;
// // The 3D Bernsteins defined on a 20-noded hexahedral.
// case HEX20:
// return 0;
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The third-order Bernstein shape functions
// case THIRD:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a two-noded edge
// case EDGE2:
// return 2;
// // The 1D Bernstein defined on a three-noded edge
// case EDGE3:
// return 0;
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// return 1;
// // The 2D tensor-product Bernsteins defined on a
// // eight-noded quadrilateral.
// case QUAD8:
// return 4;
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD9:
// return 0;
// // The 3D Bernsteins defined on a ten-noded hexahedral.
// case TET10:
// return 4;
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The fourth-order Bernstein shape functions
// case FOURTH:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a two-noded edge
// case EDGE2:
// return 3;
// // The 1D Bernstein defined on a three-noded edge
// case EDGE3:
// return 0;
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// return 3;
// // The 2D tensor-product Bernsteins defined on a
// // eight-noded quadrilateral.
// case QUAD8:
// return 9;
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD9:
// return 0;
// // The 3D Bernsteins defined on a ten-noded hexahedral.
// case TET10:
// return 13;
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The fifth-order Bernstein shape functions
// case FIFTH:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a two-noded edge
// case EDGE2:
// return 4;
// // The 1D Bernstein defined on a three-noded edge
// case EDGE3:
// return 0;
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// return 6;
// // The 2D tensor-product Bernsteins defined on a
// // eight-noded quadrilateral.
// case QUAD8:
// return 16;
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD9:
// return 0;
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// return 0;
// default:
// libmesh_error();
// }
// }
// // The sixth-order Bernstein shape functions
// case SIXTH:
// {
// switch (t)
// {
// // The 1D Bernstein defined on a two-noded edge
// case EDGE2:
// return 5;
// // The 1D Bernstein defined on a three-noded edge
// case EDGE3:
// return 0;
// // The 2D Bernstein defined on a 6-noded triangle
// case TRI6:
// return 10;
// // The 2D tensor-product Bernsteins defined on a
// // eight-noded quadrilateral.
// case QUAD8:
// return 25;
// // The 2D tensor-product Bernsteins defined on a
// // nine-noded quadrilateral.
// case QUAD9:
// return 0;
// // The 3D tensor-product Bernsteins defined on a
// // twenty-seven noded hexahedral.
// case HEX27:
// return 0;
// default:
// libmesh_error();
// }
// }
// // Otherwise no DOFS per element
// default:
// return 0;
// }
}
Definition at line 76 of file reference_counter.h.
References ReferenceCounter::_n_objects.
Referenced by System::read_serialized_blocked_dof_objects(), and System::write_serialized_blocked_dof_objects().
{ return _n_objects; }
Implements FEBase.
Definition at line 53 of file fe.C.
{
libmesh_assert (qrule != NULL);
return qrule->n_points();
}
Implements FEBase.
Definition at line 34 of file fe.C.
References FE< Dim, T >::n_dofs().
Referenced by FE< Dim, T >::init_edge_shape_functions(), FE< Dim, T >::init_face_shape_functions(), FEXYZ< Dim >::init_shape_functions(), FE< Dim, T >::init_shape_functions(), FE< Dim, T >::map(), FE< Dim, T >::map_eta(), FE< Dim, T >::map_xi(), FE< Dim, T >::map_zeta(), and FE< Dim, T >::nodal_soln().
{
return FE<Dim,T>::n_dofs (elem_type,
static_cast<Order>(fe_type.order + _p_level));
}
On a p-refined element, o should be the total order of the element.
Definition at line 195 of file fe.h.
{ return FE<Dim,T>::n_dofs (t,o); }
On a p-refined element, o should be the base order of the element.
Definition at line 37 of file fe_bernstein.C.
References libMeshEnums::CONSTANT, libMeshEnums::FIFTH, libMeshEnums::FIRST, libMeshEnums::FOURTH, FE< Dim, T >::inverse_map(), Elem::n_nodes(), MeshTools::n_nodes(), FE< Dim, T >::n_shape_functions(), Elem::p_level(), Elem::point(), libMeshEnums::SECOND, libMeshEnums::SIXTH, libMeshEnums::THIRD, and Elem::type().
{
const unsigned int n_nodes = elem->n_nodes();
const ElemType type = elem->type();
nodal_soln.resize(n_nodes);
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// Constant shape functions
case CONSTANT:
{
libmesh_assert (elem_soln.size() == 1);
const Number val = elem_soln[0];
for (unsigned int n=0; n<n_nodes; n++)
nodal_soln[n] = val;
return;
}
// For other bases do interpolation at the nodes
// explicitly.
case FIRST:
case SECOND:
case THIRD:
case FOURTH:
case FIFTH:
case SIXTH:
{
const unsigned int n_sf =
FE<Dim,T>::n_shape_functions(type, totalorder);
for (unsigned int n=0; n<n_nodes; n++)
{
const Point mapped_point = FE<Dim,T>::inverse_map(elem,
elem->point(n));
libmesh_assert (elem_soln.size() == n_sf);
// Zero before summation
nodal_soln[n] = 0;
// u_i = Sum (alpha_i phi_i)
for (unsigned int i=0; i<n_sf; i++)
nodal_soln[n] += elem_soln[i]*FE<Dim,T>::shape(elem,
order,
i,
mapped_point);
}
return;
}
default:
{
libmesh_error();
return;
}
}
// How did we get here?
libmesh_error();
return;
}
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::EDGE4, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, libMeshEnums::INFHEX8, libMeshEnums::INFPRISM6, libMeshEnums::PRISM15, libMeshEnums::PRISM18, libMeshEnums::PRISM6, libMeshEnums::PYRAMID5, libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::TET10, libMeshEnums::TET4, libMeshEnums::TRI3, and libMeshEnums::TRI6.
{
libmesh_assert (eps >= 0.);
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
switch (t)
{
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))
{
// std::cout << 'Strange Point:;
// 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:
{
std::cerr << 'BEN: Implement this you lazy bastard!'
<< std::endl;
libmesh_error();
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:
std::cerr << 'ERROR: Unknown element type ' << t << std::endl;
libmesh_error();
}
// If we get here then the point is _not_ in the
// reference element. Better return false.
return false;
}
Definition at line 1069 of file fe_base.C.
References FEBase::d2phi, and FEBase::dphi.
{
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];
}
Definition at line 1057 of file fe_base.C.
References FEBase::dphi.
Referenced by FEBase::print_info().
{
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];
}
Definition at line 1090 of file fe_base.C.
References FEBase::print_dphi(), FEBase::print_JxW(), FEBase::print_phi(), and FEBase::print_xyz().
Referenced by operator<<().
{
os << 'Shape functions at the Gauss pts.' << std::endl;
this->print_phi(os);
os << 'Shape function gradients at the Gauss pts.' << std::endl;
this->print_dphi(os);
os << 'XYZ locations of the Gauss pts.' << std::endl;
this->print_xyz(os);
os << 'Values of JxW at the Gauss pts.' << std::endl;
this->print_JxW(os);
}
Definition at line 83 of file reference_counter.C.
References ReferenceCounter::get_info().
{
#if defined(LIBMESH_ENABLE_REFERENCE_COUNTING) && defined(DEBUG)
std::cout << ReferenceCounter::get_info();
#endif
}
Definition at line 1038 of file fe_base.C.
References FEBase::JxW.
Referenced by FEBase::print_info().
{
for (unsigned int i=0; i<JxW.size(); ++i)
os << JxW[i] << std::endl;
}
Definition at line 1047 of file fe_base.C.
References FEBase::phi.
Referenced by FEBase::print_info().
{
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;
}
Definition at line 1081 of file fe_base.C.
References FEBase::xyz.
Referenced by FEBase::print_info().
{
for (unsigned int i=0; i<xyz.size(); ++i)
os << xyz[i];
}
Implements FEBase.
Reimplemented in FEXYZ< Dim >.
Definition at line 113 of file fe.C.
References Elem::n_nodes(), Elem::p_level(), Elem::point(), and Elem::type().
{
libmesh_assert (elem != NULL);
// Try to avoid calling init_shape_functions
// even when shapes_need_reinit
bool cached_nodes_still_fit = false;
// Initialize the shape functions at the user-specified
// points
if (pts != NULL)
{
// Set the type and p level for this element
elem_type = elem->type();
_p_level = elem->p_level();
// Initialize the shape functions
this->init_shape_functions (*pts, elem);
// The shape functions do not correspond to the qrule
shapes_on_quadrature = false;
}
// If there are no user specified points, we use the
// quadrature rule
// update the type in accordance to the current cell
// and reinit if the cell type has changed or (as in
// the case of the hierarchics) the shape functions need
// reinit, since they depend on the particular element shape
else
{
libmesh_assert (qrule != NULL);
qrule->init(elem->type(), elem->p_level());
if (elem_type != elem->type() ||
_p_level != elem->p_level() ||
!shapes_on_quadrature)
{
// Set the type and p level for this element
elem_type = elem->type();
_p_level = elem->p_level();
// Initialize the shape functions
this->init_shape_functions (qrule->get_points(), elem);
if (this->shapes_need_reinit())
{
cached_nodes.resize(elem->n_nodes());
for (unsigned int n = 0; n != elem->n_nodes(); ++n)
{
cached_nodes[n] = elem->point(n);
}
}
}
else
{
libmesh_assert(elem->n_nodes() > 1);
cached_nodes_still_fit = true;
if (cached_nodes.size() != elem->n_nodes())
cached_nodes_still_fit = false;
else
for (unsigned int n = 1; n < elem->n_nodes(); ++n)
{
if ((elem->point(n) - elem->point(0)) !=
(cached_nodes[n] - cached_nodes[0]))
{
cached_nodes_still_fit = false;
break;
}
}
if (this->shapes_need_reinit() && !cached_nodes_still_fit)
{
this->init_shape_functions (qrule->get_points(), elem);
cached_nodes.resize(elem->n_nodes());
for (unsigned int n = 0; n != elem->n_nodes(); ++n)
cached_nodes[n] = elem->point(n);
}
}
// The shape functions correspond to the qrule
shapes_on_quadrature = true;
}
// Compute the map for this element. In the future we can specify
// different types of maps
if (pts != NULL)
{
std::vector<Real> dummy_weights (pts->size(), 1.);
this->compute_map (dummy_weights, elem);
}
else
{
this->compute_map (qrule->get_weights(), elem);
}
// Compute the shape functions and the derivatives at all of the
// quadrature points.
if (!cached_nodes_still_fit)
this->compute_shape_functions (elem);
}
Implements FEBase.
Reimplemented in FEXYZ< Dim >, FEXYZ< Dim >, and FEXYZ< Dim >.
Definition at line 372 of file fe_map.C.
References FEBase::d2xyzdeta2_map, FEBase::d2xyzdetadzeta_map, FEBase::d2xyzdxi2_map, FEBase::d2xyzdxideta_map, FEBase::d2xyzdxidzeta_map, FEBase::d2xyzdzeta2_map, FEBase::detadx_map, FEBase::detady_map, FEBase::detadz_map, FEBase::dim, FEBase::dxidx_map, FEBase::dxidy_map, FEBase::dxidz_map, FEBase::dxyzdeta_map, FEBase::dxyzdxi_map, FEBase::dxyzdzeta_map, FEBase::dzetadx_map, FEBase::dzetady_map, FEBase::dzetadz_map, FEBase::JxW, and FEBase::xyz.
Referenced by FEBase::compute_affine_map(), and FEBase::compute_map().
{
// Resize the vectors to hold data at the quadrature points
xyz.resize(n_qp);
dxyzdxi_map.resize(n_qp);
dxidx_map.resize(n_qp);
dxidy_map.resize(n_qp); // 1D element may live in 2D ...
dxidz_map.resize(n_qp); // ... or 3D
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxi2_map.resize(n_qp);
#endif
if (this->dim > 1)
{
dxyzdeta_map.resize(n_qp);
detadx_map.resize(n_qp);
detady_map.resize(n_qp);
detadz_map.resize(n_qp);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxideta_map.resize(n_qp);
d2xyzdeta2_map.resize(n_qp);
#endif
if (this->dim > 2)
{
dxyzdzeta_map.resize (n_qp);
dzetadx_map.resize (n_qp);
dzetady_map.resize (n_qp);
dzetadz_map.resize (n_qp);
#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
d2xyzdxidzeta_map.resize(n_qp);
d2xyzdetadzeta_map.resize(n_qp);
d2xyzdzeta2_map.resize(n_qp);
#endif
}
}
JxW.resize(n_qp);
}
Definition at line 42 of file fe_xyz_shape_3D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 174 of file fe_clough_shape_1D.C.
{
std::cerr << 'Clough-Tocher elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 1452 of file fe_clough_shape_2D.C.
References Elem::p_level(), libMeshEnums::SECOND, libMeshEnums::THIRD, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
clough_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 2nd-order restricted Clough-Tocher element
case SECOND:
{
switch (type)
{
// C1 functions on the Clough-Tocher triangle.
case TRI6:
{
libmesh_assert (i<9);
// FIXME: it would be nice to calculate (and cache)
// clough_raw_shape(j,p) only once per triangle, not 1-7
// times
switch (i)
{
// Note: these DoF numbers are 'scrambled' because my
// initial numbering conventions didn't match libMesh
case 0:
return clough_raw_shape(0, p)
+ d1d2n * clough_raw_shape(10, p)
+ d1d3n * clough_raw_shape(11, p);
case 3:
return clough_raw_shape(1, p)
+ d2d3n * clough_raw_shape(11, p)
+ d2d1n * clough_raw_shape(9, p);
case 6:
return clough_raw_shape(2, p)
+ d3d1n * clough_raw_shape(9, p)
+ d3d2n * clough_raw_shape(10, p);
case 1:
return d1xd1x * clough_raw_shape(3, p)
+ d1xd1y * clough_raw_shape(4, p)
+ d1xd2n * clough_raw_shape(10, p)
+ d1xd3n * clough_raw_shape(11, p)
+ 0.5 * N01x * d3nd3n * clough_raw_shape(11, p)
+ 0.5 * N02x * d2nd2n * clough_raw_shape(10, p);
case 2:
return d1yd1y * clough_raw_shape(4, p)
+ d1yd1x * clough_raw_shape(3, p)
+ d1yd2n * clough_raw_shape(10, p)
+ d1yd3n * clough_raw_shape(11, p)
+ 0.5 * N01y * d3nd3n * clough_raw_shape(11, p)
+ 0.5 * N02y * d2nd2n * clough_raw_shape(10, p);
case 4:
return d2xd2x * clough_raw_shape(5, p)
+ d2xd2y * clough_raw_shape(6, p)
+ d2xd3n * clough_raw_shape(11, p)
+ d2xd1n * clough_raw_shape(9, p)
+ 0.5 * N10x * d3nd3n * clough_raw_shape(11, p)
+ 0.5 * N12x * d1nd1n * clough_raw_shape(9, p);
case 5:
return d2yd2y * clough_raw_shape(6, p)
+ d2yd2x * clough_raw_shape(5, p)
+ d2yd3n * clough_raw_shape(11, p)
+ d2yd1n * clough_raw_shape(9, p)
+ 0.5 * N10y * d3nd3n * clough_raw_shape(11, p)
+ 0.5 * N12y * d1nd1n * clough_raw_shape(9, p);
case 7:
return d3xd3x * clough_raw_shape(7, p)
+ d3xd3y * clough_raw_shape(8, p)
+ d3xd1n * clough_raw_shape(9, p)
+ d3xd2n * clough_raw_shape(10, p)
+ 0.5 * N20x * d2nd2n * clough_raw_shape(10, p)
+ 0.5 * N21x * d1nd1n * clough_raw_shape(9, p);
case 8:
return d3yd3y * clough_raw_shape(8, p)
+ d3yd3x * clough_raw_shape(7, p)
+ d3yd1n * clough_raw_shape(9, p)
+ d3yd2n * clough_raw_shape(10, p)
+ 0.5 * N20y * d2nd2n * clough_raw_shape(10, p)
+ 0.5 * N21y * d1nd1n * clough_raw_shape(9, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// 3rd-order Clough-Tocher element
case THIRD:
{
switch (type)
{
// C1 functions on the Clough-Tocher triangle.
case TRI6:
{
libmesh_assert (i<12);
// FIXME: it would be nice to calculate (and cache)
// clough_raw_shape(j,p) only once per triangle, not 1-7
// times
switch (i)
{
// Note: these DoF numbers are 'scrambled' because my
// initial numbering conventions didn't match libMesh
case 0:
return clough_raw_shape(0, p)
+ d1d2n * clough_raw_shape(10, p)
+ d1d3n * clough_raw_shape(11, p);
case 3:
return clough_raw_shape(1, p)
+ d2d3n * clough_raw_shape(11, p)
+ d2d1n * clough_raw_shape(9, p);
case 6:
return clough_raw_shape(2, p)
+ d3d1n * clough_raw_shape(9, p)
+ d3d2n * clough_raw_shape(10, p);
case 1:
return d1xd1x * clough_raw_shape(3, p)
+ d1xd1y * clough_raw_shape(4, p)
+ d1xd2n * clough_raw_shape(10, p)
+ d1xd3n * clough_raw_shape(11, p);
case 2:
return d1yd1y * clough_raw_shape(4, p)
+ d1yd1x * clough_raw_shape(3, p)
+ d1yd2n * clough_raw_shape(10, p)
+ d1yd3n * clough_raw_shape(11, p);
case 4:
return d2xd2x * clough_raw_shape(5, p)
+ d2xd2y * clough_raw_shape(6, p)
+ d2xd3n * clough_raw_shape(11, p)
+ d2xd1n * clough_raw_shape(9, p);
case 5:
return d2yd2y * clough_raw_shape(6, p)
+ d2yd2x * clough_raw_shape(5, p)
+ d2yd3n * clough_raw_shape(11, p)
+ d2yd1n * clough_raw_shape(9, p);
case 7:
return d3xd3x * clough_raw_shape(7, p)
+ d3xd3y * clough_raw_shape(8, p)
+ d3xd1n * clough_raw_shape(9, p)
+ d3xd2n * clough_raw_shape(10, p);
case 8:
return d3yd3y * clough_raw_shape(8, p)
+ d3yd3x * clough_raw_shape(7, p)
+ d3yd1n * clough_raw_shape(9, p)
+ d3yd2n * clough_raw_shape(10, p);
case 10:
return d1nd1n * clough_raw_shape(9, p);
case 11:
return d2nd2n * clough_raw_shape(10, p);
case 9:
return d3nd3n * clough_raw_shape(11, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 44 of file fe_szabab_shape_3D.C.
{
std::cerr << 'Szabo-Babuska polynomials are not defined in 3D << std::endl;
libmesh_error();
return 0.;
}
Definition at line 31 of file fe_szabab_shape_3D.C.
{
std::cerr << 'Szabo-Babuska polynomials are not defined in 3D << std::endl;
libmesh_error();
return 0.;
}
Definition at line 31 of file fe_lagrange_shape_1D.C.
References libMeshEnums::FIRST, libMeshEnums::SECOND, and libMeshEnums::THIRD.
{
const Real xi = p(0);
switch (order)
{
// Lagrange linears
case FIRST:
{
libmesh_assert (i<2);
switch (i)
{
case 0:
return .5*(1. - xi);
case 1:
return .5*(1. + xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
}
// Lagrange quadratics
case SECOND:
{
libmesh_assert (i<3);
switch (i)
{
case 0:
return .5*xi*(xi - 1.);
case 1:
return .5*xi*(xi + 1);
case 2:
return (1. - xi*xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
}
// Lagrange cubics
case THIRD:
{
libmesh_assert (i<4);
switch (i)
{
case 0:
return 9./16.*(1./9.-xi*xi)*(xi-1.);
case 1:
return -9./16.*(1./9.-xi*xi)*(xi+1.);
case 2:
return 27./16.*(1.-xi*xi)*(1./3.-xi);
case 3:
return 27./16.*(1.-xi*xi)*(1./3.+xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
}
libmesh_error();
return 0.;
}
Definition at line 126 of file fe_lagrange_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,LAGRANGE>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 31 of file fe_bernstein_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 221 of file fe_lagrange_shape_2D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape functions
return FE<2,LAGRANGE>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 31 of file fe_lagrange_shape_2D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::SECOND, libMeshEnums::TRI3, and libMeshEnums::TRI6.
{
#if LIBMESH_DIM > 1
switch (order)
{
// linear Lagrange shape functions
case FIRST:
{
switch (type)
{
case QUAD4:
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<4);
// 0 1 2 3
static const unsigned int i0[] = {0, 1, 1, 0};
static const unsigned int i1[] = {0, 0, 1, 1};
return (FE<1,LAGRANGE>::shape(EDGE2, FIRST, i0[i], xi)*
FE<1,LAGRANGE>::shape(EDGE2, FIRST, i1[i], eta));
}
case TRI3:
case TRI6:
{
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta0 = 1. - zeta1 - zeta2;
libmesh_assert (i<3);
switch(i)
{
case 0:
return zeta0;
case 1:
return zeta1;
case 2:
return zeta2;
default:
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported 2D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// quadratic Lagrange shape functions
case SECOND:
{
switch (type)
{
case QUAD8:
{
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<8);
switch (i)
{
case 0:
return .25*(1. - xi)*(1. - eta)*(-1. - xi - eta);
case 1:
return .25*(1. + xi)*(1. - eta)*(-1. + xi - eta);
case 2:
return .25*(1. + xi)*(1. + eta)*(-1. + xi + eta);
case 3:
return .25*(1. - xi)*(1. + eta)*(-1. - xi + eta);
case 4:
return .5*(1. - xi*xi)*(1. - eta);
case 5:
return .5*(1. + xi)*(1. - eta*eta);
case 6:
return .5*(1. - xi*xi)*(1. + eta);
case 7:
return .5*(1. - xi)*(1. - eta*eta);
default:
libmesh_error();
}
}
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<9);
// 0 1 2 3 4 5 6 7 8
static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
return (FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i1[i], eta));
}
case TRI6:
{
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta0 = 1. - zeta1 - zeta2;
libmesh_assert (i<6);
switch(i)
{
case 0:
return 2.*zeta0*(zeta0-0.5);
case 1:
return 2.*zeta1*(zeta1-0.5);
case 2:
return 2.*zeta2*(zeta2-0.5);
case 3:
return 4.*zeta0*zeta1;
case 4:
return 4.*zeta1*zeta2;
case 5:
return 4.*zeta2*zeta0;
default:
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported 2D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// unsupported order
default:
{
std::cerr << 'ERROR: Unsupported 2D FE order!: ' << order
<< std::endl;
libmesh_error();
}
}
libmesh_error();
return 0.;
#endif
}
Definition at line 43 of file fe_bernstein_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 370 of file fe_lagrange_shape_3D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape functions
return FE<3,LAGRANGE>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 31 of file fe_lagrange_shape_3D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, libMeshEnums::PRISM15, libMeshEnums::PRISM18, libMeshEnums::PRISM6, libMeshEnums::PYRAMID5, libMeshEnums::SECOND, libMeshEnums::TET10, libMeshEnums::TET4, libMeshEnums::TRI3, and libMeshEnums::TRI6.
{
#if LIBMESH_DIM == 3
switch (order)
{
// linear Lagrange shape functions
case FIRST:
{
switch (type)
{
// trilinear hexahedral shape functions
case HEX8:
case HEX20:
case HEX27:
{
libmesh_assert (i<8);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// 0 1 2 3 4 5 6 7
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
return (FE<1,LAGRANGE>::shape(EDGE2, FIRST, i0[i], xi)*
FE<1,LAGRANGE>::shape(EDGE2, FIRST, i1[i], eta)*
FE<1,LAGRANGE>::shape(EDGE2, FIRST, i2[i], zeta));
}
// linear tetrahedral shape functions
case TET4:
case TET10:
{
libmesh_assert(i<4);
// Area coordinates, pg. 205, Vol. I, Carey, Oden, Becker FEM
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta3 = p(2);
const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
switch(i)
{
case 0:
return zeta0;
case 1:
return zeta1;
case 2:
return zeta2;
case 3:
return zeta3;
default:
libmesh_error();
}
}
// linear prism shape functions
case PRISM6:
case PRISM15:
case PRISM18:
{
libmesh_assert (i<6);
// Compute prism shape functions as a tensor-product
// of a triangle and an edge
Point p2d(p(0),p(1));
Point p1d(p(2));
// 0 1 2 3 4 5
static const unsigned int i0[] = {0, 0, 0, 1, 1, 1};
static const unsigned int i1[] = {0, 1, 2, 0, 1, 2};
return (FE<2,LAGRANGE>::shape(TRI3, FIRST, i1[i], p2d)*
FE<1,LAGRANGE>::shape(EDGE2, FIRST, i0[i], p1d));
}
// linear pyramid shape functions
case PYRAMID5:
{
libmesh_assert (i<5);
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
const Real eps = 1.e-35;
switch(i)
{
case 0:
return .25*(zeta + xi - 1.)*(zeta + eta - 1.)/((1. - zeta) + eps);
case 1:
return .25*(zeta - xi - 1.)*(zeta + eta - 1.)/((1. - zeta) + eps);
case 2:
return .25*(zeta - xi - 1.)*(zeta - eta - 1.)/((1. - zeta) + eps);
case 3:
return .25*(zeta + xi - 1.)*(zeta - eta - 1.)/((1. - zeta) + eps);
case 4:
return zeta;
default:
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported 3D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// quadratic Lagrange shape functions
case SECOND:
{
switch (type)
{
// serendipity hexahedral quadratic shape functions
case HEX20:
{
libmesh_assert (i<20);
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// these functions are defined for (x,y,z) in [0,1]^3
// so transform the locations
const Real x = .5*(xi + 1.);
const Real y = .5*(eta + 1.);
const Real z = .5*(zeta + 1.);
switch (i)
{
case 0:
return (1. - x)*(1. - y)*(1. - z)*(1. - 2.*x - 2.*y - 2.*z);
case 1:
return x*(1. - y)*(1. - z)*(2.*x - 2.*y - 2.*z - 1.);
case 2:
return x*y*(1. - z)*(2.*x + 2.*y - 2.*z - 3.);
case 3:
return (1. - x)*y*(1. - z)*(2.*y - 2.*x - 2.*z - 1.);
case 4:
return (1. - x)*(1. - y)*z*(2.*z - 2.*x - 2.*y - 1.);
case 5:
return x*(1. - y)*z*(2.*x - 2.*y + 2.*z - 3.);
case 6:
return x*y*z*(2.*x + 2.*y + 2.*z - 5.);
case 7:
return (1. - x)*y*z*(2.*y - 2.*x + 2.*z - 3.);
case 8:
return 4.*x*(1. - x)*(1. - y)*(1. - z);
case 9:
return 4.*x*y*(1. - y)*(1. - z);
case 10:
return 4.*x*(1. - x)*y*(1. - z);
case 11:
return 4.*(1. - x)*y*(1. - y)*(1. - z);
case 12:
return 4.*(1. - x)*(1. - y)*z*(1. - z);
case 13:
return 4.*x*(1. - y)*z*(1. - z);
case 14:
return 4.*x*y*z*(1. - z);
case 15:
return 4.*(1. - x)*y*z*(1. - z);
case 16:
return 4.*x*(1. - x)*(1. - y)*z;
case 17:
return 4.*x*y*(1. - y)*z;
case 18:
return 4.*x*(1. - x)*y*z;
case 19:
return 4.*(1. - x)*y*(1. - y)*z;
default:
libmesh_error();
}
}
// triquadraic hexahedral shape funcions
case HEX27:
{
libmesh_assert (i<27);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
return (FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i1[i], eta)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i2[i], zeta));
}
// quadratic tetrahedral shape functions
case TET10:
{
libmesh_assert (i<10);
// Area coordinates, pg. 205, Vol. I, Carey, Oden, Becker FEM
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta3 = p(2);
const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
switch(i)
{
case 0:
return zeta0*(2.*zeta0 - 1.);
case 1:
return zeta1*(2.*zeta1 - 1.);
case 2:
return zeta2*(2.*zeta2 - 1.);
case 3:
return zeta3*(2.*zeta3 - 1.);
case 4:
return 4.*zeta0*zeta1;
case 5:
return 4.*zeta1*zeta2;
case 6:
return 4.*zeta2*zeta0;
case 7:
return 4.*zeta0*zeta3;
case 8:
return 4.*zeta1*zeta3;
case 9:
return 4.*zeta2*zeta3;
default:
libmesh_error();
}
}
// quadradic prism shape functions
case PRISM18:
{
libmesh_assert (i<18);
// Compute prism shape functions as a tensor-product
// of a triangle and an edge
Point p2d(p(0),p(1));
Point p1d(p(2));
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
static const unsigned int i0[] = {0, 0, 0, 1, 1, 1, 0, 0, 0, 2, 2, 2, 1, 1, 1, 2, 2, 2};
static const unsigned int i1[] = {0, 1, 2, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 3, 4, 5};
return (FE<2,LAGRANGE>::shape(TRI6, SECOND, i1[i], p2d)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], p1d));
}
default:
{
std::cerr << 'ERROR: Unsupported 3D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// unsupported order
default:
{
std::cerr << 'ERROR: Unsupported 3D FE order!: ' << order
<< std::endl;
libmesh_error();
}
}
#endif
libmesh_error();
return 0.;
}
Definition at line 190 of file fe_clough_shape_1D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
clough_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 3rd-order C1 cubic element
case THIRD:
{
switch (type)
{
// C1 functions on the C1 cubic edge
case EDGE2:
case EDGE3:
{
libmesh_assert (i<4);
switch (i)
{
case 0:
return clough_raw_shape(0, p);
case 1:
return clough_raw_shape(1, p);
case 2:
return d1xd1x * clough_raw_shape(2, p);
case 3:
return d2xd2x * clough_raw_shape(3, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 31 of file fe_monomial_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 89 of file fe_szabab_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,SZABAB>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 158 of file fe_clough_shape_3D.C.
{
std::cerr << 'Clough-Tocher elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 31 of file fe_lagrange_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 174 of file fe_clough_shape_3D.C.
References Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
std::cerr << '3D Clough elements not yet implemented.'
<< std::endl;
libmesh_error();
clough_compute_coefs(elem);
const ElemType type = elem->type();
switch (order+elem->p_level())
{
// 3rd-order Clough-Tocher element
case THIRD:
{
switch (type)
{
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 31 of file fe_monomial_shape_1D.C.
{
const Real xi = p(0);
libmesh_assert (i <= static_cast<unsigned int>(order));
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
case 0:
return 1.;
case 1:
return xi;
case 2:
return xi*xi;
case 3:
return xi*xi*xi;
case 4:
return xi*xi*xi*xi;
default:
Real val = 1.;
for (unsigned int index = 0; index != i; ++index)
val *= xi;
return val;
}
libmesh_error();
return 0.;
}
Definition at line 72 of file fe_monomial_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,MONOMIAL>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 31 of file fe_hermite_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 43 of file fe_hermite_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 33 of file fe_bernstein_shape_1D.C.
References Utility::factorial(), libMeshEnums::FIFTH, libMeshEnums::FIRST, libMeshEnums::FOURTH, Utility::pow(), Utility::pow< 2 >(), Utility::pow< 3 >(), Utility::pow< 4 >(), Utility::pow< 6 >(), libMeshEnums::SECOND, libMeshEnums::SIXTH, and libMeshEnums::THIRD.
{
const Real xi = p(0);
using Utility::pow;
switch (order)
{
case FIRST:
switch(i)
{
case 0:
return (1.-xi)/2.;
case 1:
return (1.+xi)/2.;
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case SECOND:
switch(i)
{
case 0:
return (1./4.)*pow<2>(1.-xi);
case 1:
return (1./4.)*pow<2>(1.+xi);
case 2:
return (1./2.)*(1.-xi)*(1.+xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case THIRD:
switch(i)
{
case 0:
return (1./8.)*pow<3>(1.-xi);
case 1:
return (1./8.)*pow<3>(1.+xi);
case 2:
return (3./8.)*(1.+xi)*pow<2>(1.-xi);
case 3:
return (3./8.)*pow<2>(1.+xi)*(1.-xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case FOURTH:
switch(i)
{
case 0:
return (1./16.)*pow<4>(1.-xi);
case 1:
return (1./16.)*pow<4>(1.+xi);
case 2:
return (1./ 4.)*(1.+xi)*pow<3>(1.-xi);
case 3:
return (3./ 8.)*pow<2>(1.+xi)*pow<2>(1.-xi);
case 4:
return (1./ 4.)*pow<3>(1.+xi)*(1.-xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case FIFTH:
switch(i)
{
case 0:
return (1./32.)*pow<5>(1.-xi);
case 1:
return (1./32.)*pow<5>(1.+xi);
case 2:
return (5./32.)*(1.+xi)*pow<4>(1.-xi);
case 3:
return (5./16.)*pow<2>(1.+xi)*pow<3>(1.-xi);
case 4:
return (5./16.)*pow<3>(1.+xi)*pow<2>(1.-xi);
case 5:
return (5./32.)*pow<4>(1.+xi)*(1.-xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case SIXTH:
switch (i)
{
case 0:
return ( 1./64.)*pow<6>(1.-xi);
case 1:
return ( 1./64.)*pow<6>(1.+xi);
case 2:
return ( 3./32.)*(1.+xi)*pow<5>(1.-xi);
case 3:
return (15./64.)*pow<2>(1.+xi)*pow<4>(1.-xi);
case 4:
return ( 5./16.)*pow<3>(1.+xi)*pow<3>(1.-xi);
case 5:
return (15./64.)*pow<4>(1.+xi)*pow<2>(1.-xi);
case 6:
return ( 3./32.)*pow<5>(1.+xi)*(1.-xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
default:
{
libmesh_assert (order>6);
// Use this for arbitrary orders.
// Note that this implementation is less efficient.
const int p_order = static_cast<unsigned int>(order);
const int m = p_order-i+1;
const int n = (i-1);
unsigned int binomial_p_i = 1;
// the binomial coefficient (p choose n)
if (i>1)
binomial_p_i = Utility::factorial(p_order)
/ (Utility::factorial(n)*Utility::factorial(p_order-n));
switch(i)
{
case 0:
return binomial_p_i * std::pow((1.-xi)/2.,static_cast<Real>(p_order));
case 1:
return binomial_p_i * std::pow((1.+xi)/2.,static_cast<Real>(p_order));
default:
{
return binomial_p_i * std::pow((1.+xi)/2.,static_cast<Real>(n))
* std::pow((1.-xi)/2.,static_cast<Real>(m));
}
}
// we should never get here
libmesh_error();
}
}
libmesh_error();
return 0.;
}
Definition at line 196 of file fe_bernstein_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,BERNSTEIN>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 31 of file fe_monomial_shape_3D.C.
{
#if LIBMESH_DIM == 3
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
libmesh_assert (i < (static_cast<unsigned int>(order)+1)*
(static_cast<unsigned int>(order)+2)*
(static_cast<unsigned int>(order)+3)/6);
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
// constant
case 0:
return 1.;
// linears
case 1:
return xi;
case 2:
return eta;
case 3:
return zeta;
// quadratics
case 4:
return xi*xi;
case 5:
return xi*eta;
case 6:
return eta*eta;
case 7:
return xi*zeta;
case 8:
return zeta*eta;
case 9:
return zeta*zeta;
// cubics
case 10:
return xi*xi*xi;
case 11:
return xi*xi*eta;
case 12:
return xi*eta*eta;
case 13:
return eta*eta*eta;
case 14:
return xi*xi*zeta;
case 15:
return xi*eta*zeta;
case 16:
return eta*eta*zeta;
case 17:
return xi*zeta*zeta;
case 18:
return eta*zeta*zeta;
case 19:
return zeta*zeta*zeta;
// quartics
case 20:
return xi*xi*xi*xi;
case 21:
return xi*xi*xi*eta;
case 22:
return xi*xi*eta*eta;
case 23:
return xi*eta*eta*eta;
case 24:
return eta*eta*eta*eta;
case 25:
return xi*xi*xi*zeta;
case 26:
return xi*xi*eta*zeta;
case 27:
return xi*eta*eta*zeta;
case 28:
return eta*eta*eta*zeta;
case 29:
return xi*xi*zeta*zeta;
case 30:
return xi*eta*zeta*zeta;
case 31:
return eta*eta*zeta*zeta;
case 32:
return xi*zeta*zeta*zeta;
case 33:
return eta*zeta*zeta*zeta;
case 34:
return zeta*zeta*zeta*zeta;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = 1.;
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
for (unsigned int index=0; index != nz; index++)
val *= zeta;
return val;
}
#endif
libmesh_error();
return 0.;
}
Definition at line 186 of file fe_monomial_shape_3D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape functions
return FE<3,MONOMIAL>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 37 of file fe_scalar_shape_3D.C.
{
return 1.;
}
Definition at line 28 of file fe_scalar_shape_3D.C.
{
return 1.;
}
Definition at line 200 of file fe_hermite_shape_1D.C.
{
std::cerr << 'Hermite elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 216 of file fe_hermite_shape_1D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, FEHermite< Dim >::hermite_raw_shape(), Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// Hermite cubic shape functions
case THIRD:
{
switch (type)
{
// C1 functions on the C1 cubic edge
case EDGE2:
case EDGE3:
{
libmesh_assert (i<4);
switch (i)
{
case 0:
return FEHermite<1>::hermite_raw_shape(0, p(0));
case 1:
return d1xd1x * FEHermite<1>::hermite_raw_shape(2, p(0));
case 2:
return FEHermite<1>::hermite_raw_shape(1, p(0));
case 3:
return d2xd2x * FEHermite<1>::hermite_raw_shape(3, p(0));
default:
return FEHermite<1>::hermite_raw_shape(i, p(0));
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 28 of file fe_scalar_shape_0D.C.
{
return 1.;
}
Definition at line 37 of file fe_scalar_shape_0D.C.
{
return 1.;
}
Definition at line 28 of file fe_scalar_shape_1D.C.
{
return 1.;
}
Definition at line 37 of file fe_scalar_shape_1D.C.
{
return 1.;
}
Definition at line 200 of file fe_hermite_shape_2D.C.
{
std::cerr << 'Hermite elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 216 of file fe_hermite_shape_2D.C.
References FEHermite< Dim >::hermite_raw_shape(), Elem::p_level(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, and Elem::type().
{
libmesh_assert (elem != NULL);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (type)
{
case QUAD4:
libmesh_assert (totalorder < 4);
case QUAD8:
case QUAD9:
{
libmesh_assert (i<(totalorder+1u)*(totalorder+1u));
std::vector<unsigned int> bases1D;
Real coef = hermite_bases_2D(bases1D, dxdxi, totalorder, i);
return coef * FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1));
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 33 of file fe_bernstein_shape_2D.C.
{
std::cerr << 'Bernstein polynomials require the element type
<< 'because edge orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 28 of file fe_scalar_shape_2D.C.
{
return 1.;
}
Definition at line 37 of file fe_scalar_shape_2D.C.
{
return 1.;
}
Definition at line 49 of file fe_bernstein_shape_2D.C.
References libMeshEnums::EDGE3, libMeshEnums::FIFTH, libMeshEnums::FIRST, libMeshEnums::FOURTH, Elem::p_level(), Elem::point(), Utility::pow(), Utility::pow< 2 >(), Utility::pow< 3 >(), Utility::pow< 4 >(), Utility::pow< 6 >(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::SECOND, InfFE< Dim, T_radial, T_map >::shape(), FE< Dim, T >::shape(), libMeshEnums::SIXTH, square_number_column, square_number_row, libMeshEnums::THIRD, libMeshEnums::TRI3, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
// Declare that we are using our own special power function
// from the Utility namespace. This saves typing later.
using Utility::pow;
switch (type)
{
// Hierarchic shape functions on the quadrilateral.
case QUAD4:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < (totalorder+1u)*(totalorder+1u));
// Example i, i0, i1 values for totalorder = 5:
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 3, 2, 4, 4, 4, 3, 2, 5, 5, 5, 5, 4, 3, 2};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 3, 3, 2, 3, 4, 4, 4, 2, 3, 4, 5, 5, 5, 5};
unsigned int i0, i1;
// Vertex DoFs
if (i == 0)
{ i0 = 0; i1 = 0; }
else if (i == 1)
{ i0 = 1; i1 = 0; }
else if (i == 2)
{ i0 = 1; i1 = 1; }
else if (i == 3)
{ i0 = 0; i1 = 1; }
// Edge DoFs
else if (i < totalorder + 3u)
{ i0 = i - 2; i1 = 0; }
else if (i < 2u*totalorder + 2)
{ i0 = 1; i1 = i - totalorder - 1; }
else if (i < 3u*totalorder + 1)
{ i0 = i - 2u*totalorder; i1 = 1; }
else if (i < 4u*totalorder)
{ i0 = 0; i1 = i - 3u*totalorder + 1; }
// Interior DoFs. Use Roy's number look up
else
{
unsigned int basisnum = i - 4*totalorder;
i0 = square_number_column[basisnum] + 2;
i1 = square_number_row[basisnum] + 2;
}
// Flip odd degree of freedom values if necessary
// to keep continuity on sides.
if ((i>= 4 && i<= 4+ totalorder-2u) && elem->point(0) > elem->point(1)) i0=totalorder+2-i0; //
else if((i>= 4+ totalorder-1u && i<= 4+2*totalorder-3u) && elem->point(1) > elem->point(2)) i1=totalorder+2-i1;
else if((i>= 4+2*totalorder-2u && i<= 4+3*totalorder-4u) && elem->point(3) > elem->point(2)) i0=totalorder+2-i0;
else if((i>= 4+3*totalorder-3u && i<= 4+4*totalorder-5u) && elem->point(0) > elem->point(3)) i1=totalorder+2-i1;
return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0, xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1, eta));
}
// handle serendipity QUAD8 element separately
case QUAD8:
{
libmesh_assert (totalorder < 3);
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 8);
// 0 1 2 3 4 5 6 7 8
static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
static const Real scal[] = {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5};
//B_t,i0(i)|xi * B_s,i1(i)|eta + scal(i) * B_t,2|xi * B_t,2|eta
return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)
+scal[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[8], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[8], eta));
}
case TRI3:
libmesh_assert (totalorder<2);
case TRI6:
switch (totalorder)
{
case FIRST:
{
const Real x=p(0);
const Real y=p(1);
const Real r=1.-x-y;
libmesh_assert(i<3);
switch(i)
{
case 0: return r; //f0,0,1
case 1: return x; //f0,1,1
case 2: return y; //f1,0,1
default: libmesh_error(); return 0;
}
}
case SECOND:
{
const Real x=p(0);
const Real y=p(1);
const Real r=1.-x-y;
libmesh_assert(i<6);
switch(i)
{
case 0: return r*r;
case 1: return x*x;
case 2: return y*y;
case 3: return 2.*x*r;
case 4: return 2.*x*y;
case 5: return 2.*r*y;
default: libmesh_error(); return 0;
}
}
case THIRD:
{
const Real x=p(0);
const Real y=p(1);
const Real r=1.-x-y;
libmesh_assert(i<10);
unsigned int shape=i;
if((i==3||i==4) && elem->point(0) > elem->point(1)) shape=7-i;
if((i==5||i==6) && elem->point(1) > elem->point(2)) shape=11-i;
if((i==7||i==8) && elem->point(0) > elem->point(2)) shape=15-i;
switch(shape)
{
case 0: return r*r*r;
case 1: return x*x*x;
case 2: return y*y*y;
case 3: return 3.*x*r*r;
case 4: return 3.*x*x*r;
case 5: return 3.*y*x*x;
case 6: return 3.*y*y*x;
case 7: return 3.*y*r*r;
case 8: return 3.*y*y*r;
case 9: return 6.*x*y*r;
default: libmesh_error(); return 0;
}
}
case FOURTH:
{
const Real x=p(0);
const Real y=p(1);
const Real r=1-x-y;
unsigned int shape=i;
libmesh_assert(i<15);
if((i==3||i== 5) && elem->point(0) > elem->point(1))shape=8-i;
if((i==6||i== 8) && elem->point(1) > elem->point(2))shape=14-i;
if((i==9||i==11) && elem->point(0) > elem->point(2))shape=20-i;
switch(shape)
{
// point functions
case 0: return r*r*r*r;
case 1: return x*x*x*x;
case 2: return y*y*y*y;
// edge functions
case 3: return 4.*x*r*r*r;
case 4: return 6.*x*x*r*r;
case 5: return 4.*x*x*x*r;
case 6: return 4.*y*x*x*x;
case 7: return 6.*y*y*x*x;
case 8: return 4.*y*y*y*x;
case 9: return 4.*y*r*r*r;
case 10: return 6.*y*y*r*r;
case 11: return 4.*y*y*y*r;
// inner functions
case 12: return 12.*x*y*r*r;
case 13: return 12.*x*x*y*r;
case 14: return 12.*x*y*y*r;
default: libmesh_error(); return 0;
}
}
case FIFTH:
{
const Real x=p(0);
const Real y=p(1);
const Real r=1-x-y;
unsigned int shape=i;
libmesh_assert(i<21);
if((i>= 3&&i<= 6) && elem->point(0) > elem->point(1))shape=9-i;
if((i>= 7&&i<=10) && elem->point(1) > elem->point(2))shape=17-i;
if((i>=11&&i<=14) && elem->point(0) > elem->point(2))shape=25-i;
switch(shape)
{
//point functions
case 0: return pow<5>(r);
case 1: return pow<5>(x);
case 2: return pow<5>(y);
//edge functions
case 3: return 5.*x *pow<4>(r);
case 4: return 10.*pow<2>(x)*pow<3>(r);
case 5: return 10.*pow<3>(x)*pow<2>(r);
case 6: return 5.*pow<4>(x)*r;
case 7: return 5.*y *pow<4>(x);
case 8: return 10.*pow<2>(y)*pow<3>(x);
case 9: return 10.*pow<3>(y)*pow<2>(x);
case 10: return 5.*pow<4>(y)*x;
case 11: return 5.*y *pow<4>(r);
case 12: return 10.*pow<2>(y)*pow<3>(r);
case 13: return 10.*pow<3>(y)*pow<2>(r);
case 14: return 5.*pow<4>(y)*r;
//inner functions
case 15: return 20.*x*y*pow<3>(r);
case 16: return 30.*x*pow<2>(y)*pow<2>(r);
case 17: return 30.*pow<2>(x)*y*pow<2>(r);
case 18: return 20.*x*pow<3>(y)*r;
case 19: return 20.*pow<3>(x)*y*r;
case 20: return 30.*pow<2>(x)*pow<2>(y)*r;
default: libmesh_error(); return 0;
}
}
case SIXTH:
{
const Real x=p(0);
const Real y=p(1);
const Real r=1-x-y;
unsigned int shape=i;
libmesh_assert(i<28);
if((i>= 3&&i<= 7) && elem->point(0) > elem->point(1))shape=10-i;
if((i>= 8&&i<=12) && elem->point(1) > elem->point(2))shape=20-i;
if((i>=13&&i<=17) && elem->point(0) > elem->point(2))shape=30-i;
switch(shape)
{
//point functions
case 0: return pow<6>(r);
case 1: return pow<6>(x);
case 2: return pow<6>(y);
//edge functions
case 3: return 6.*x *pow<5>(r);
case 4: return 15.*pow<2>(x)*pow<4>(r);
case 5: return 20.*pow<3>(x)*pow<3>(r);
case 6: return 15.*pow<4>(x)*pow<2>(r);
case 7: return 6.*pow<5>(x)*r;
case 8: return 6.*y *pow<5>(x);
case 9: return 15.*pow<2>(y)*pow<4>(x);
case 10: return 20.*pow<3>(y)*pow<3>(x);
case 11: return 15.*pow<4>(y)*pow<2>(x);
case 12: return 6.*pow<5>(y)*x;
case 13: return 6.*y *pow<5>(r);
case 14: return 15.*pow<2>(y)*pow<4>(r);
case 15: return 20.*pow<3>(y)*pow<3>(r);
case 16: return 15.*pow<4>(y)*pow<2>(r);
case 17: return 6.*pow<5>(y)*r;
//inner functions
case 18: return 30.*x*y*pow<4>(r);
case 19: return 60.*x*pow<2>(y)*pow<3>(r);
case 20: return 60.* pow<2>(x)*y*pow<3>(r);
case 21: return 60.*x*pow<3>(y)*pow<2>(r);
case 22: return 60.*pow<3>(x)*y*pow<2>(r);
case 23: return 90.*pow<2>(x)*pow<2>(y)*pow<2>(r);
case 24: return 30.*x*pow<4>(y)*r;
case 25: return 60.*pow<2>(x)*pow<3>(y)*r;
case 26: return 60.*pow<3>(x)*pow<2>(y)*r;
case 27: return 30.*pow<4>(x)*y*r;
default: libmesh_error(); return 0;
} // switch shape
} // case TRI6
default:
{
std::cerr << 'ERROR: element order!' << std::endl;
libmesh_error();
}
} // switch order
default:
{
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
} // switch type
// old code
// switch (totalorder)
// {
// case FIRST:
// switch(type)
// {
// case TRI6:
// {
// const Real x=p(0);
// const Real y=p(1);
// const Real r=1.-x-y;
// libmesh_assert(i<3);
// switch(i)
// {
// case 0: return r; //f0,0,1
// case 1: return x; //f0,1,1
// case 2: return y; //f1,0,1
// }
// }
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 4);
// // 0 1 2 3
// static const unsigned int i0[] = {0, 1, 1, 0};
// static const unsigned int i1[] = {0, 0, 1, 1};
// return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta));
// }
// default:
// libmesh_error();
// }
// case SECOND:
// switch(type)
// {
// case TRI6:
// {
// const Real x=p(0);
// const Real y=p(1);
// const Real r=1.-x-y;
// libmesh_assert(i<6);
// switch(i)
// {
// case 0: return r*r;
// case 1: return x*x;
// case 2: return y*y;
// case 3: return 2.*x*r;
// case 4: return 2.*x*y;
// case 5: return 2.*r*y;
// }
// }
// // Bernstein shape functions on the 8-noded quadrilateral.
// case QUAD8:
// {
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 8);
// // 0 1 2 3 4 5 6 7 8
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
// static const Real scal[] = {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5};
// return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)
// +scal[i]*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[8], xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[8], eta));
// //B_t,i0(i)|xi * B_s,i1(i)|eta + scal(i) * B_t,2|xi * B_t,2|eta
// }
// // Bernstein shape functions on the 9-noded quadrilateral.
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 9);
// // 0 1 2 3 4 5 6 7 8
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
// return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta));
// }
// default:
// libmesh_error();
// }
// case THIRD:
// switch(type)
// {
// case TRI6:
// {
// const Real x=p(0);
// const Real y=p(1);
// const Real r=1.-x-y;
// libmesh_assert(i<10);
// unsigned int shape=i;
// if((i==3||i==4) && elem->node(0) > elem->node(1))shape=7-i;
// if((i==5||i==6) && elem->node(1) > elem->node(2))shape=11-i;
// if((i==7||i==8) && elem->node(0) > elem->node(2))shape=15-i;
// switch(shape)
// {
// case 0: return r*r*r;
// case 1: return x*x*x;
// case 2: return y*y*y;
// case 3: return 3.*x*r*r;
// case 4: return 3.*x*x*r;
// case 5: return 3.*y*x*x;
// case 6: return 3.*y*y*x;
// case 7: return 3.*y*r*r;
// case 8: return 3.*y*y*r;
// case 9: return 6.*x*y*r;
// }
// }
// // Bernstein shape functions on the quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// Real xi = p(0);
// Real eta = p(1);
// libmesh_assert (i < 16);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i== 4||i== 5) && elem->node(0) > elem->node(1)) i0=5-i0; // 2->3 3->2
// if((i== 6||i== 7) && elem->node(1) > elem->node(2)) i1=5-i1;
// if((i== 8||i== 9) && elem->node(3) > elem->node(2)) i0=5-i0;
// if((i==10||i==11) && elem->node(0) > elem->node(3)) i1=5-i1;
// // element dof orientation is needed when used with ifems
// // if(i > 11)
// // {
// // const unsigned int min_node = std::min(elem->node(1),
// // std::min(elem->node(2),
// // std::min(elem->node(0),
// // elem->node(3))));
// // if (elem->node(0) == min_node)
// // if (elem->node(1) == std::min(elem->node(1), elem->node(3)))
// // {
// // // Case 1
// // xi = xi;
// // eta = eta;
// // }
// // else
// // {
// // // Case 2
// // xi = eta;
// // eta = xi;
// // }
// // else if (elem->node(3) == min_node)
// // if (elem->node(0) == std::min(elem->node(0), elem->node(2)))
// // {
// // // Case 3
// // xi = -eta;
// // eta = xi;
// // }
// // else
// // {
// // // Case 4
// // xi = xi;
// // eta = -eta;
// // }
// // else if (elem->node(2) == min_node)
// // if (elem->node(3) == std::min(elem->node(3), elem->node(1)))
// // {
// // // Case 5
// // xi = -xi;
// // eta = -eta;
// // }
// // else
// // {
// // // Case 6
// // xi = -eta;
// // eta = -xi;
// // }
// // else if (elem->node(1) == min_node)
// // if (elem->node(2) == std::min(elem->node(2), elem->node(0)))
// // {
// // // Case 7
// // xi = eta;
// // eta = -xi;
// // }
// // else
// // {
// // // Case 8
// // xi = -xi;
// // eta = eta;
// // }
// // }
// return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1, eta));
// }
// default:
// libmesh_error();
// }
// case FOURTH:
// switch(type)
// {
// case TRI6:
// {
// const Real x=p(0);
// const Real y=p(1);
// const Real r=1-x-y;
// unsigned int shape=i;
// libmesh_assert(i<15);
// if((i==3||i== 5) && elem->node(0) > elem->node(1))shape=8-i;
// if((i==6||i== 8) && elem->node(1) > elem->node(2))shape=14-i;
// if((i==9||i==11) && elem->node(0) > elem->node(2))shape=20-i;
// switch(shape)
// {
// // point functions
// case 0: return r*r*r*r;
// case 1: return x*x*x*x;
// case 2: return y*y*y*y;
// // edge functions
// case 3: return 4.*x*r*r*r;
// case 4: return 6.*x*x*r*r;
// case 5: return 4.*x*x*x*r;
// case 6: return 4.*y*x*x*x;
// case 7: return 6.*y*y*x*x;
// case 8: return 4.*y*y*y*x;
// case 9: return 4.*y*r*r*r;
// case 10: return 6.*y*y*r*r;
// case 11: return 4.*y*y*y*r;
// // inner functions
// case 12: return 12.*x*y*r*r;
// case 13: return 12.*x*x*y*r;
// case 14: return 12.*x*y*y*r;
// }
// }
// // Bernstein shape functions on the quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 25);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i>= 4&&i<= 6) && elem->node(0) > elem->node(1)) i0=6-i0; // 2->4, 4->2
// if((i>= 7&&i<= 9) && elem->node(1) > elem->node(2)) i1=6-i1;
// if((i>=10&&i<=12) && elem->node(3) > elem->node(2)) i0=6-i0;
// if((i>=13&&i<=15) && elem->node(0) > elem->node(3)) i1=6-i1;
// return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1, eta));
// }
// default:
// libmesh_error();
// }
// case FIFTH:
// switch(type)
// {
// case TRI6:
// {
// const Real x=p(0);
// const Real y=p(1);
// const Real r=1-x-y;
// unsigned int shape=i;
// libmesh_assert(i<21);
// if((i>= 3&&i<= 6) && elem->node(0) > elem->node(1))shape=9-i;
// if((i>= 7&&i<=10) && elem->node(1) > elem->node(2))shape=17-i;
// if((i>=11&&i<=14) && elem->node(0) > elem->node(2))shape=25-i;
// switch(shape)
// {
// //point functions
// case 0: return pow<5>(r);
// case 1: return pow<5>(x);
// case 2: return pow<5>(y);
// //edge functions
// case 3: return 5.*x *pow<4>(r);
// case 4: return 10.*pow<2>(x)*pow<3>(r);
// case 5: return 10.*pow<3>(x)*pow<2>(r);
// case 6: return 5.*pow<4>(x)*r;
// case 7: return 5.*y *pow<4>(x);
// case 8: return 10.*pow<2>(y)*pow<3>(x);
// case 9: return 10.*pow<3>(y)*pow<2>(x);
// case 10: return 5.*pow<4>(y)*x;
// case 11: return 5.*y *pow<4>(r);
// case 12: return 10.*pow<2>(y)*pow<3>(r);
// case 13: return 10.*pow<3>(y)*pow<2>(r);
// case 14: return 5.*pow<4>(y)*r;
// //inner functions
// case 15: return 20.*x*y*pow<3>(r);
// case 16: return 30.*x*pow<2>(y)*pow<2>(r);
// case 17: return 30.*pow<2>(x)*y*pow<2>(r);
// case 18: return 20.*x*pow<3>(y)*r;
// case 19: return 20.*pow<3>(x)*y*r;
// case 20: return 30.*pow<2>(x)*pow<2>(y)*r;
// }
// }
// // Bernstein shape functions on the quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 36);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i>= 4&&i<= 7) && elem->node(0) > elem->node(1)) i0=7-i0;
// if((i>= 8&&i<=11) && elem->node(1) > elem->node(2)) i1=7-i1;
// if((i>=12&&i<=15) && elem->node(3) > elem->node(2)) i0=7-i0;
// if((i>=16&&i<=19) && elem->node(0) > elem->node(3)) i1=7-i1;
// return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1, eta));
// }
// default:
// libmesh_error();
// }
// case SIXTH:
// switch(type)
// {
// case TRI6:
// {
// const Real x=p(0);
// const Real y=p(1);
// const Real r=1-x-y;
// unsigned int shape=i;
// libmesh_assert(i<28);
// if((i>= 3&&i<= 7) && elem->node(0) > elem->node(1))shape=10-i;
// if((i>= 8&&i<=12) && elem->node(1) > elem->node(2))shape=20-i;
// if((i>=13&&i<=17) && elem->node(0) > elem->node(2))shape=30-i;
// switch(shape)
// {
// //point functions
// case 0: return pow<6>(r);
// case 1: return pow<6>(x);
// case 2: return pow<6>(y);
// //edge functions
// case 3: return 6.*x *pow<5>(r);
// case 4: return 15.*pow<2>(x)*pow<4>(r);
// case 5: return 20.*pow<3>(x)*pow<3>(r);
// case 6: return 15.*pow<4>(x)*pow<2>(r);
// case 7: return 6.*pow<5>(x)*r;
// case 8: return 6.*y *pow<5>(x);
// case 9: return 15.*pow<2>(y)*pow<4>(x);
// case 10: return 20.*pow<3>(y)*pow<3>(x);
// case 11: return 15.*pow<4>(y)*pow<2>(x);
// case 12: return 6.*pow<5>(y)*x;
// case 13: return 6.*y *pow<5>(r);
// case 14: return 15.*pow<2>(y)*pow<4>(r);
// case 15: return 20.*pow<3>(y)*pow<3>(r);
// case 16: return 15.*pow<4>(y)*pow<2>(r);
// case 17: return 6.*pow<5>(y)*r;
// //inner functions
// case 18: return 30.*x*y*pow<4>(r);
// case 19: return 60.*x*pow<2>(y)*pow<3>(r);
// case 20: return 60.* pow<2>(x)*y*pow<3>(r);
// case 21: return 60.*x*pow<3>(y)*pow<2>(r);
// case 22: return 60.*pow<3>(x)*y*pow<2>(r);
// case 23: return 90.*pow<2>(x)*pow<2>(y)*pow<2>(r);
// case 24: return 30.*x*pow<4>(y)*r;
// case 25: return 60.*pow<2>(x)*pow<3>(y)*r;
// case 26: return 60.*pow<3>(x)*pow<2>(y)*r;
// case 27: return 30.*pow<4>(x)*y*r;
// } // switch shape
// } // case TRI6
// // Bernstein shape functions on the quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 49);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i>= 4&&i<= 8) && elem->node(0) > elem->node(1)) i0=8-i0;
// if((i>= 9&&i<=13) && elem->node(1) > elem->node(2)) i1=8-i1;
// if((i>=14&&i<=18) && elem->node(3) > elem->node(2)) i0=8-i0;
// if((i>=19&&i<=23) && elem->node(0) > elem->node(3)) i1=8-i1;
// return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1, eta));
// } // case QUAD8/9
// default:
// libmesh_error();
// }
// // 7th-order Bernstein.
// case SEVENTH:
// {
// switch (type)
// {
// // Szabo-Babuska shape functions on the quadrilateral.
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 64);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7};
// Real f=1.;
// switch(i)
// {
// case 5: // edge 0 nodes
// case 7:
// case 9:
// if (elem->node(0) > elem->node(1))f = -1.;
// break;
// case 11: // edge 1 nodes
// case 13:
// case 15:
// if (elem->node(1) > elem->node(2))f = -1.;
// break;
// case 17: // edge 2 nodes
// case 19:
// case 21:
// if (elem->node(3) > elem->node(2))f = -1.;
// break;
// case 23: // edge 3 nodes
// case 25:
// case 27:
// if (elem->node(0) > elem->node(3))f = -1.;
// break;
// }
// return f*(FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta));
// } // case QUAD8/QUAD9
// default:
// libmesh_error();
// } // switch type
// } // case SEVENTH
// // by default throw an error
// default:
// std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
// libmesh_error();
// }
libmesh_error();
return 0.;
}
Definition at line 379 of file fe_hermite_shape_3D.C.
{
std::cerr << 'Hermite elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 395 of file fe_hermite_shape_3D.C.
References FEHermite< Dim >::hermite_raw_shape(), libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 3rd-order tricubic Hermite functions
case THIRD:
{
switch (type)
{
case HEX8:
case HEX20:
case HEX27:
{
libmesh_assert (i<64);
std::vector<unsigned int> bases1D;
Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 31 of file fe_szabab_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 43 of file fe_szabab_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 31 of file fe_hierarchic_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 43 of file fe_hierarchic_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 34 of file fe_szabab_shape_1D.C.
References libMeshEnums::SEVENTH.
{
const Real xi = p(0);
const Real xi2 = xi*xi;
// Use this libmesh_assert rather than a switch with a single entry...
// It will go away in optimized mode, essentially has the same effect.
libmesh_assert (order <= SEVENTH);
// switch (order)
// {
// case FIRST:
// case SECOND:
// case THIRD:
// case FOURTH:
// case FIFTH:
// case SIXTH:
// case SEVENTH:
switch(i)
{
//nodal shape functions
case 0: return 1./2.-1./2.*xi;
case 1: return 1./2.+1./2.*xi;
case 2: return 1./4. *2.4494897427831780982*(xi2-1.);
case 3: return 1./4. *3.1622776601683793320*(xi2-1.)*xi;
case 4: return 1./16. *3.7416573867739413856*((5.*xi2-6.)*xi2+1.);
case 5: return 3./16. *1.4142135623730950488*(3.+(-10.+7.*xi2)*xi2)*xi;
case 6: return 1./32. *4.6904157598234295546*(-1.+(15.+(-35.+21.*xi2)*xi2)*xi2);
case 7: return 1./32. *5.0990195135927848300*(-5.+(35.+(-63.+33.*xi2)*xi2)*xi2)*xi;
case 8: return 1./256.*5.4772255750516611346*(5.+(-140.+(630.+(-924.+429.*xi2)*xi2)*xi2)*xi2);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
// default:
// {
// std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
// libmesh_error();
// }
// }
libmesh_error();
return 0.;
}
Definition at line 118 of file fe_monomial_shape_2D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
// by default call the orientation-independent shape functions
return FE<2,MONOMIAL>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
Definition at line 35 of file fe_bernstein_shape_3D.C.
{
std::cerr << 'Bernstein polynomials require the element type
<< 'because edge and face orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 49 of file fe_szabab_shape_2D.C.
{
std::cerr << 'Szabo-Babuska polynomials require the element type
<< 'because edge orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 65 of file fe_szabab_shape_2D.C.
References libMeshEnums::EDGE3, libMeshEnums::FIFTH, libMeshEnums::FIRST, libMeshEnums::FOURTH, Elem::p_level(), Elem::point(), Utility::pow(), Utility::pow< 2 >(), libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::SECOND, libMeshEnums::SEVENTH, FE< Dim, T >::shape(), libMeshEnums::SIXTH, libMeshEnums::THIRD, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
// Declare that we are using our own special power function
// from the Utility namespace. This saves typing later.
using Utility::pow;
switch (totalorder)
{
// 1st & 2nd-order Szabo-Babuska.
case FIRST:
case SECOND:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
const Real l1 = 1-p(0)-p(1);
const Real l2 = p(0);
const Real l3 = p(1);
libmesh_assert (i<6);
switch (i)
{
case 0: return l1;
case 1: return l2;
case 2: return l3;
case 3: return l1*l2*(-4.*sqrt6);
case 4: return l2*l3*(-4.*sqrt6);
case 5: return l3*l1*(-4.*sqrt6);
default:
libmesh_error();
}
}
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 9);
// 0 1 2 3 4 5 6 7 8
static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
return (FE<1,SZABAB>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape(EDGE3, totalorder, i1[i], eta));
}
default:
libmesh_error();
}
}
// 3rd-order Szabo-Babuska.
case THIRD:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
Real l1 = 1-p(0)-p(1);
Real l2 = p(0);
Real l3 = p(1);
Real f=1;
libmesh_assert (i<10);
if (i==4 && (elem->point(0) > elem->point(1)))f=-1;
if (i==6 && (elem->point(1) > elem->point(2)))f=-1;
if (i==8 && (elem->point(2) > elem->point(0)))f=-1;
switch (i)
{
//nodal modes
case 0: return l1;
case 1: return l2;
case 2: return l3;
//side modes
case 3: return l1*l2*(-4.*sqrt6);
case 4: return f*l1*l2*(-4.*sqrt10)*(l2-l1);
case 5: return l2*l3*(-4.*sqrt6);
case 6: return f*l2*l3*(-4.*sqrt10)*(l3-l2);
case 7: return l3*l1*(-4.*sqrt6);
case 8: return f*l3*l1*(-4.*sqrt10)*(l1-l3);
//internal modes
case 9: return l1*l2*l3;
default:
libmesh_error();
}
}
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 16);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3};
Real f=1.;
// take care of edge orientation, this is needed at
// edge shapes with (y=0)-asymmetric 1D shapes, these have
// one 1D shape index being 0 or 1, the other one being odd and >=3
switch(i)
{
case 5: // edge 0 points
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 7: // edge 1 points
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 9: // edge 2 points
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 11: // edge 3 points
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
return f*(FE<1,SZABAB>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape(EDGE3, totalorder, i1[i], eta));
}
default:
libmesh_error();
}
}
// 4th-order Szabo-Babuska.
case FOURTH:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
Real l1 = 1-p(0)-p(1);
Real l2 = p(0);
Real l3 = p(1);
Real f=1;
libmesh_assert (i<15);
if (i== 4 && (elem->point(0) > elem->point(1)))f=-1;
if (i== 7 && (elem->point(1) > elem->point(2)))f=-1;
if (i==10 && (elem->point(2) > elem->point(0)))f=-1;
switch (i)
{
//nodal modes
case 0: return l1;
case 1: return l2;
case 2: return l3;
//side modes
case 3: return l1*l2*(-4.*sqrt6);
case 4: return f*l1*l2*(-4.*sqrt10)*(l2-l1);
case 5: return l1*l2*(-sqrt14)*(5.*pow<2>(l2-l1)-1);
case 6: return l2*l3*(-4.*sqrt6);
case 7: return f*l2*l3*(-4.*sqrt10)*(l3-l2);
case 8: return l2*l3*(-sqrt14)*(5.*pow<2>(l3-l2)-1);
case 9: return l3*l1*(-4.*sqrt6);
case 10: return f*l3*l1*(-4.*sqrt10)*(l1-l3);
case 11: return l3*l1*(-sqrt14)*(5.*pow<2>(l1-l3)-1);
//internal modes
case 12: return l1*l2*l3;
case 13: return l1*l2*l3*(l2-l1);
case 14: return l1*l2*l3*(2*l3-1);
default:
libmesh_error();
}
}
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 25);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 8: // edge 1 points
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 11: // edge 2 points
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 14: // edge 3 points
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
return f*(FE<1,SZABAB>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape(EDGE3, totalorder, i1[i], eta));
}
default:
libmesh_error();
}
}
// 5th-order Szabo-Babuska.
case FIFTH:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
Real l1 = 1-p(0)-p(1);
Real l2 = p(0);
Real l3 = p(1);
const Real x=l2-l1;
const Real y=2.*l3-1;
Real f=1;
libmesh_assert (i<21);
if ((i== 4||i== 6) && (elem->point(0) > elem->point(1)))f=-1;
if ((i== 8||i==10) && (elem->point(1) > elem->point(2)))f=-1;
if ((i==12||i==14) && (elem->point(2) > elem->point(0)))f=-1;
switch (i)
{
//nodal modes
case 0: return l1;
case 1: return l2;
case 2: return l3;
//side modes
case 3: return l1*l2*(-4.*sqrt6);
case 4: return f*l1*l2*(-4.*sqrt10)*(l2-l1);
case 5: return -sqrt14*l1*l2*(5.0*l1*l1-1.0+(-10.0*l1+5.0*l2)*l2);
case 6: return f*(-sqrt2)*l1*l2*((9.-21.*l1*l1)*l1+(-9.+63.*l1*l1+(-63.*l1+21.*l2)*l2)*l2);
case 7: return l2*l3*(-4.*sqrt6);
case 8: return f*l2*l3*(-4.*sqrt10)*(l3-l2);
case 9: return -sqrt14*l2*l3*(5.0*l3*l3-1.0+(-10.0*l3+5.0*l2)*l2);
case 10: return -f*sqrt2*l2*l3*((-9.0+21.0*l3*l3)*l3+(-63.0*l3*l3+9.0+(63.0*l3-21.0*l2)*l2)*l2);
case 11: return l3*l1*(-4.*sqrt6);
case 12: return f*l3*l1*(-4.*sqrt10)*(l1-l3);
case 13: return -sqrt14*l3*l1*(5.0*l3*l3-1.0+(-10.0*l3+5.0*l1)*l1);
case 14: return f*(-sqrt2)*l3*l1*((9.0-21.0*l3*l3)*l3+(-9.0+63.0*l3*l3+(-63.0*l3+21.0*l1)*l1)*l1);
//internal modes
case 15: return l1*l2*l3;
case 16: return l1*l2*l3*x;
case 17: return l1*l2*l3*y;
case 18: return l1*l2*l3*(1.5*l1*l1-.5+(-3.0*l1+1.5*l2)*l2);
case 19: return l1*l2*l3*x*y;
case 20: return l1*l2*l3*(1.0+(-6.0+6.0*l3)*l3);
default:
libmesh_error();
}
} // case TRI6
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 36);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
case 7:
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 9: // edge 1 points
case 11:
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 13: // edge 2 points
case 15:
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 14: // edge 3 points
case 19:
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
return f*(FE<1,SZABAB>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape(EDGE3, totalorder, i1[i], eta));
} // case QUAD8/QUAD9
default:
libmesh_error();
} // switch type
} // case FIFTH
// 6th-order Szabo-Babuska.
case SIXTH:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
Real l1 = 1-p(0)-p(1);
Real l2 = p(0);
Real l3 = p(1);
const Real x=l2-l1;
const Real y=2.*l3-1;
Real f=1;
libmesh_assert (i<28);
if ((i== 4||i== 6) && (elem->point(0) > elem->point(1)))f=-1;
if ((i== 9||i==11) && (elem->point(1) > elem->point(2)))f=-1;
if ((i==14||i==16) && (elem->point(2) > elem->point(0)))f=-1;
switch (i)
{
//nodal modes
case 0: return l1;
case 1: return l2;
case 2: return l3;
//side modes
case 3: return l1*l2*(-4.*sqrt6);
case 4: return f*l1*l2*(-4.*sqrt10)*(l2-l1);
case 5: return -sqrt14*l1*l2*(5.0*l1*l1-1.0+(-10.0*l1+5.0*l2)*l2);
case 6: return f*(-sqrt2)*l1*l2*((9.0-21.0*l1*l1)*l1+(-9.0+63.0*l1*l1+(-63.0*l1+21.0*l2)*l2)*l2);
case 7: return -sqrt22*l1*l2*(0.5+(-7.0+0.105E2*l1*l1)*l1*l1+((14.0-0.42E2*l1*l1)*l1+(-7.0+0.63E2*l1*l1+(-0.42E2*l1+0.105E2*l2)*l2)*l2)*l2);
case 8: return l2*l3*(-4.*sqrt6);
case 9: return f*l2*l3*(-4.*sqrt10)*(l3-l2);
case 10: return -sqrt14*l2*l3*(5.0*l3*l3-1.0+(-10.0*l3+5.0*l2)*l2);
case 11: return f*(-sqrt2)*l2*l3*((-9.0+21.0*l3*l3)*l3+(-63.0*l3*l3+9.0+(63.0*l3-21.0*l2)*l2)*l2);
case 12: return -sqrt22*l2*l3*(0.5+(-7.0+0.105E2*l3*l3)*l3*l3+((14.0-0.42E2*l3*l3)*l3+(-7.0+0.63E2*l3*l3+(-0.42E2*l3+0.105E2*l2)*l2)*l2)*l2);
case 13: return l3*l1*(-4.*sqrt6);
case 14: return f*l3*l1*(-4.*sqrt10)*(l1-l3);
case 15: return -sqrt14*l3*l1*(5.0*l3*l3-1.0+(-10.0*l3+5.0*l1)*l1);
case 16: return f*(-sqrt2)*l3*l1*((9.0-21.0*l3*l3)*l3+(-9.0+63.0*l3*l3+(-63.0*l3+21.0*l1)*l1)*l1);
case 17: return -sqrt22*l3*l1*(0.5+(-7.0+0.105E2*l3*l3)*l3*l3+((14.0-0.42E2*l3*l3)*l3+(-7.0+0.63E2*l3*l3+(-0.42E2*l3+0.105E2*l1)*l1)*l1)*l1);
//internal modes
case 18: return l1*l2*l3;
case 19: return l1*l2*l3*x;
case 20: return l1*l2*l3*y;
case 21: return 0.5*l1*l2*l3*(3.0*l1*l1-1.0+(-6.0*l1+3.0*l2)*l2);
case 22: return l1*l2*l3*(l2-l1)*(2.0*l3-1.0);
case 23: return 0.5*l1*l2*l3*(2.0+(-12.0+12.0*l3)*l3);
case 24: return 0.5*l1*l2*l3*((3.0-5.0*l1*l1)*l1+(-3.0+15.0*l1*l1+(-15.0*l1+5.0*l2)*l2)*l2);
case 25: return 0.5*l1*l2*l3*(3.0*l1*l1-1.0+(-6.0*l1+3.0*l2)*l2)*(2.0*l3-1.0);
case 26: return 0.5*l1*l2*l3*(2.0+(-12.0+12.0*l3)*l3)*(l2-l1);
case 27: return 0.5*l1*l2*l3*(-2.0+(24.0+(-60.0+40.0*l3)*l3)*l3);
default:
libmesh_error();
}
} // case TRI6
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 49);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
case 7:
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 10: // edge 1 points
case 12:
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 15: // edge 2 points
case 17:
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 20: // edge 3 points
case 22:
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
return f*(FE<1,SZABAB>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape(EDGE3, totalorder, i1[i], eta));
} // case QUAD8/QUAD9
default:
libmesh_error();
} // switch type
} // case SIXTH
// 7th-order Szabo-Babuska.
case SEVENTH:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
Real l1 = 1-p(0)-p(1);
Real l2 = p(0);
Real l3 = p(1);
const Real x=l2-l1;
const Real y=2.*l3-1.;
Real f=1;
libmesh_assert (i<36);
if ((i>= 4&&i<= 8) && (elem->point(0) > elem->point(1)))f=-1;
if ((i>=10&&i<=14) && (elem->point(1) > elem->point(2)))f=-1;
if ((i>=16&&i<=20) && (elem->point(2) > elem->point(0)))f=-1;
switch (i)
{
//nodal modes
case 0: return l1;
case 1: return l2;
case 2: return l3;
//side modes
case 3: return l1*l2*(-4.*sqrt6);
case 4: return f*l1*l2*(-4.*sqrt10)*(l2-l1);
case 5: return -sqrt14*l1*l2*(5.0*l1*l1-1.0+(-10.0*l1+5.0*l2)*l2);
case 6: return f*-sqrt2*l1*l2*((9.0-21.0*l1*l1)*l1+(-9.0+63.0*l1*l1+(-63.0*l1+21.0*l2)*l2)*l2);
case 7: return -sqrt22*l1*l2*(0.5+(-7.0+0.105E2*l1*l1)*l1*l1+((14.0-0.42E2*l1*l1)*l1+(-7.0+0.63E2*l1*l1+(-0.42E2*l1+0.105E2*l2)*l2)*l2)*l2);
case 8: return f*-sqrt26*l1*l2*((-0.25E1+(15.0-0.165E2*l1*l1)*l1*l1)*l1+(0.25E1+(-45.0+0.825E2*l1*l1)*l1*l1+((45.0-0.165E3*l1*l1)*l1+(-15.0+0.165E3*l1*l1+(-0.825E2*l1+0.165E2*l2)*l2)*l2)*l2)*l2);
case 9: return l2*l3*(-4.*sqrt6);
case 10: return f*l2*l3*(-4.*sqrt10)*(l3-l2);
case 11: return -sqrt14*l2*l3*(5.0*l3*l3-1.0+(-10.0*l3+5.0*l2)*l2);
case 12: return f*-sqrt2*l2*l3*((-9.0+21.0*l3*l3)*l3+(-63.0*l3*l3+9.0+(63.0*l3-21.0*l2)*l2)*l2);
case 13: return -sqrt22*l2*l3*(0.5+(-7.0+0.105E2*l3*l3)*l3*l3+((14.0-0.42E2*l3*l3)*l3+(-7.0+0.63E2*l3*l3+(-0.42E2*l3+0.105E2*l2)*l2)*l2)*l2);
case 14: return f*-sqrt26*l2*l3*((0.25E1+(-15.0+0.165E2*l3*l3)*l3*l3)*l3+(-0.25E1+(45.0-0.825E2*l3*l3)*l3*l3+((-45.0+0.165E3*l3*l3)*l3+(15.0-0.165E3*l3*l3+(0.825E2*l3-0.165E2*l2)*l2)*l2)*l2)*l2);
case 15: return l3*l1*(-4.*sqrt6);
case 16: return f*l3*l1*(-4.*sqrt10)*(l1-l3);
case 17: return -sqrt14*l3*l1*(5.0*l3*l3-1.0+(-10.0*l3+5.0*l1)*l1);
case 18: return -f*sqrt2*l3*l1*((9.-21.*l3*l3)*l3+(-9.+63.*l3*l3+(-63.*l3+21.*l1)*l1)*l1);
case 19: return -sqrt22*l3*l1*(0.5+(-7.0+0.105E2*l3*l3)*l3*l3+((14.0-0.42E2*l3*l3)*l3+(-7.0+0.63E2*l3*l3+(-0.42E2*l3+0.105E2*l1)*l1)*l1)*l1);
case 20: return f*-sqrt26*l3*l1*((-0.25E1+(15.0-0.165E2*l3*l3)*l3*l3)*l3+(0.25E1+(-45.0+0.825E2*l3*l3)*l3*l3+((45.0-0.165E3*l3*l3)*l3+(-15.0+0.165E3*l3*l3+(-0.825E2*l3+0.165E2*l1)*l1)*l1)*l1)*l1);
//internal modes
case 21: return l1*l2*l3;
case 22: return l1*l2*l3*x;
case 23: return l1*l2*l3*y;
case 24: return l1*l2*l3*0.5*(3.*pow<2>(x)-1.);
case 25: return l1*l2*l3*x*y;
case 26: return l1*l2*l3*0.5*(3.*pow<2>(y)-1.);
case 27: return 0.5*l1*l2*l3*((3.0-5.0*l1*l1)*l1+(-3.0+15.0*l1*l1+(-15.0*l1+5.0*l2)*l2)*l2);
case 28: return 0.5*l1*l2*l3*(3.0*l1*l1-1.0+(-6.0*l1+3.0*l2)*l2)*(2.0*l3-1.0);
case 29: return 0.5*l1*l2*l3*(2.0+(-12.0+12.0*l3)*l3)*(l2-l1);
case 30: return 0.5*l1*l2*l3*(-2.0+(24.0+(-60.0+40.0*l3)*l3)*l3);
case 31: return 0.125*l1*l2*l3*((-15.0+(70.0-63.0*l1*l1)*l1*l1)*l1+(15.0+(-210.0+315.0*l1*l1)*l1*l1+((210.0-630.0*l1*l1)*l1+(-70.0+630.0*l1*l1+(-315.0*l1+63.0*l2)*l2)*l2)*l2)*l2);
case 32: return 0.5*l1*l2*l3*((3.0-5.0*l1*l1)*l1+(-3.0+15.0*l1*l1+(-15.0*l1+5.0*l2)*l2)*l2)*(2.0*l3-1.0);
case 33: return 0.25*l1*l2*l3*(3.0*l1*l1-1.0+(-6.0*l1+3.0*l2)*l2)*(2.0+(-12.0+12.0*l3)*l3);
case 34: return 0.5*l1*l2*l3*(-2.0+(24.0+(-60.0+40.0*l3)*l3)*l3)*(l2-l1);
case 35: return 0.125*l1*l2*l3*(-8.0+(240.0+(-1680.0+(4480.0+(-5040.0+2016.0*l3)*l3)*l3)*l3)*l3);
default:
libmesh_error();
}
} // case TRI6
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 64);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
case 7:
case 9:
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 11: // edge 1 points
case 13:
case 15:
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 17: // edge 2 points
case 19:
case 21:
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 23: // edge 3 points
case 25:
case 27:
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
return f*(FE<1,SZABAB>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape(EDGE3, totalorder, i1[i], eta));
} // case QUAD8/QUAD9
default:
libmesh_error();
} // switch type
} // case SEVENTH
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
} // switch order
libmesh_error();
return 0.;
}
Definition at line 51 of file fe_bernstein_shape_3D.C.
References libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::FOURTH, libMeshEnums::HEX20, libMeshEnums::HEX27, std::min(), Elem::p_level(), Elem::point(), libMeshEnums::SECOND, FE< Dim, T >::shape(), libMeshEnums::TET10, libMeshEnums::TET4, libMeshEnums::THIRD, and Elem::type().
{
#if LIBMESH_DIM == 3
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 1st order Bernstein.
case FIRST:
{
switch (type)
{
// Bernstein shape functions on the tetrahedron.
case TET4:
case TET10:
{
libmesh_assert(i<4);
// Area coordinates
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta3 = p(2);
const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
switch(i)
{
case 0: return zeta0;
case 1: return zeta1;
case 2: return zeta2;
case 3: return zeta3;
default:
libmesh_error();
}
}
// Bernstein shape functions on the hexahedral.
case HEX20:
case HEX27:
{
libmesh_assert (i<8);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta));
}
default:
libmesh_error();
}
}
case SECOND:
{
switch (type)
{
// Bernstein shape functions on the tetrahedron.
case TET10:
{
libmesh_assert(i<10);
// Area coordinates
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta3 = p(2);
const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
switch(i)
{
case 0: return zeta0*zeta0;
case 1: return zeta1*zeta1;
case 2: return zeta2*zeta2;
case 3: return zeta3*zeta3;
case 4: return 2.*zeta0*zeta1;
case 5: return 2.*zeta1*zeta2;
case 6: return 2.*zeta0*zeta2;
case 7: return 2.*zeta3*zeta0;
case 8: return 2.*zeta1*zeta3;
case 9: return 2.*zeta2*zeta3;
default:
libmesh_error();
}
}
// Bernstein shape functions on the 20-noded hexahedral.
case HEX20:
{
libmesh_assert (i<20);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
//To compute the hex20 shape functions the original shape functions for hex27 are used.
//scalx[i] tells how often the original x-th shape function has to be added to the original i-th shape function
//to compute the new i-th shape function for hex20
//example: B_0^HEX20 = B_0^HEX27 - 0.25*B_20^HEX27 - 0.25*B_21^HEX27 + 0*B_22^HEX27 + 0*B_23^HEX27 - 0.25*B_24^HEX27 + 0*B_25^HEX27 - 0.25*B_26^HEX27
// B_0^HEX20 = B_0^HEX27 + scal20[0]*B_20^HEX27 + scal21[0]*B_21^HEX27 + ...
static const Real scal20[] = {-0.25, -0.25, -0.25, -0.25, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0};
static const Real scal21[] = {-0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0, 0};
static const Real scal22[] = {0, -0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0};
static const Real scal23[] = {0, 0, -0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0};
static const Real scal24[] = {-0.25, 0, 0, -0.25, -0.25, 0, 0, -0.25, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0, 0, 0.5};
static const Real scal25[] = {0, 0, 0, 0, -0.25, -0.25, -0.25, -0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5};
static const Real scal26[] = {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25};
return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta)
+scal20[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[20], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[20], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[20], zeta)
+scal21[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[21], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[21], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[21], zeta)
+scal22[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[22], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[22], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[22], zeta)
+scal23[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[23], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[23], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[23], zeta)
+scal24[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[24], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[24], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[24], zeta)
+scal25[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[25], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[25], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[25], zeta)
+scal26[i]*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[26], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[26], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[26], zeta));
}
// Bernstein shape functions on the hexahedral.
case HEX27:
{
libmesh_assert (i<27);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta));
}
default:
libmesh_error();
}
}
// 3rd-order Bernstein.
case THIRD:
{
switch (type)
{
// // Bernstein shape functions on the tetrahedron.
// case TET10:
// {
// libmesh_assert(i<20);
// // Area coordinates
// const Real zeta1 = p(0);
// const Real zeta2 = p(1);
// const Real zeta3 = p(2);
// const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
// unsigned int shape=i;
// // handle the edge orientation
// if ((i== 4||i== 5) && elem->node(0) > elem->node(1))shape= 9-i; //Edge 0
// if ((i== 6||i== 7) && elem->node(1) > elem->node(2))shape=13-i; //Edge 1
// if ((i== 8||i== 9) && elem->node(0) > elem->node(2))shape=17-i; //Edge 2
// if ((i==10||i==11) && elem->node(0) > elem->node(3))shape=21-i; //Edge 3
// if ((i==12||i==13) && elem->node(1) > elem->node(3))shape=25-i; //Edge 4
// if ((i==14||i==15) && elem->node(2) > elem->node(3))shape=29-i; //Edge 5
// // No need to handle face orientation in 3rd order.
// switch(shape)
// {
// //point function
// case 0: return zeta0*zeta0*zeta0;
// case 1: return zeta1*zeta1*zeta1;
// case 2: return zeta2*zeta2*zeta2;
// case 3: return zeta3*zeta3*zeta3;
// //edge functions
// case 4: return 3.*zeta0*zeta0*zeta1;
// case 5: return 3.*zeta1*zeta1*zeta0;
// case 6: return 3.*zeta1*zeta1*zeta2;
// case 7: return 3.*zeta2*zeta2*zeta1;
// case 8: return 3.*zeta0*zeta0*zeta2;
// case 9: return 3.*zeta2*zeta2*zeta0;
// case 10: return 3.*zeta0*zeta0*zeta3;
// case 11: return 3.*zeta3*zeta3*zeta0;
// case 12: return 3.*zeta1*zeta1*zeta3;
// case 13: return 3.*zeta3*zeta3*zeta1;
// case 14: return 3.*zeta2*zeta2*zeta3;
// case 15: return 3.*zeta3*zeta3*zeta2;
// //face functions
// case 16: return 6.*zeta0*zeta1*zeta2;
// case 17: return 6.*zeta0*zeta1*zeta3;
// case 18: return 6.*zeta1*zeta2*zeta3;
// case 19: return 6.*zeta2*zeta0*zeta3;
// default:
// libmesh_error();
// }
// }
// Bernstein shape functions on the hexahedral.
case HEX27:
{
libmesh_assert (i<64);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
Real xi_mapped = p(0);
Real eta_mapped = p(1);
Real zeta_mapped = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// Nodes 0 1 2 3 4 5 6 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
// DOFS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3, 0, 0, 0, 0, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
// handle the edge orientation
{
// Edge 0
if ( (i0[i] >= 2) && (i1[i] == 0) && (i2[i] == 0))
{
if (elem->point(0) != std::min(elem->point(0), elem->point(1)))
xi_mapped = -xi;
}
// Edge 1
else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] == 0))
{
if (elem->point(1) != std::min(elem->point(1), elem->point(2)))
eta_mapped = -eta;
}
// Edge 2
else if ((i0[i] >= 2) && (i1[i] == 1) && (i2[i] == 0))
{
if (elem->point(3) != std::min(elem->point(3), elem->point(2)))
xi_mapped = -xi;
}
// Edge 3
else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] == 0))
{
if (elem->point(0) != std::min(elem->point(0), elem->point(3)))
eta_mapped = -eta;
}
// Edge 4
else if ((i0[i] == 0) && (i1[i] == 0) && (i2[i] >=2 ))
{
if (elem->point(0) != std::min(elem->point(0), elem->point(4)))
zeta_mapped = -zeta;
}
// Edge 5
else if ((i0[i] == 1) && (i1[i] == 0) && (i2[i] >=2 ))
{
if (elem->point(1) != std::min(elem->point(1), elem->point(5)))
zeta_mapped = -zeta;
}
// Edge 6
else if ((i0[i] == 1) && (i1[i] == 1) && (i2[i] >=2 ))
{
if (elem->point(2) != std::min(elem->point(2), elem->point(6)))
zeta_mapped = -zeta;
}
// Edge 7
else if ((i0[i] == 0) && (i1[i] == 1) && (i2[i] >=2 ))
{
if (elem->point(3) != std::min(elem->point(3), elem->point(7)))
zeta_mapped = -zeta;
}
// Edge 8
else if ((i0[i] >=2 ) && (i1[i] == 0) && (i2[i] == 1))
{
if (elem->point(4) != std::min(elem->point(4), elem->point(5)))
xi_mapped = -xi;
}
// Edge 9
else if ((i0[i] == 1) && (i1[i] >=2 ) && (i2[i] == 1))
{
if (elem->point(5) != std::min(elem->point(5), elem->point(6)))
eta_mapped = -eta;
}
// Edge 10
else if ((i0[i] >=2 ) && (i1[i] == 1) && (i2[i] == 1))
{
if (elem->point(7) != std::min(elem->point(7), elem->point(6)))
xi_mapped = -xi;
}
// Edge 11
else if ((i0[i] == 0) && (i1[i] >=2 ) && (i2[i] == 1))
{
if (elem->point(4) != std::min(elem->point(4), elem->point(7)))
eta_mapped = -eta;
}
}
// handle the face orientation
{
// Face 0
if ( (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
{
const Point min_point = std::min(elem->point(1),
std::min(elem->point(2),
std::min(elem->point(0),
elem->point(3))));
if (elem->point(0) == min_point)
if (elem->point(1) == std::min(elem->point(1), elem->point(3)))
{
// Case 1
xi_mapped = xi;
eta_mapped = eta;
}
else
{
// Case 2
xi_mapped = eta;
eta_mapped = xi;
}
else if (elem->point(3) == min_point)
if (elem->point(0) == std::min(elem->point(0), elem->point(2)))
{
// Case 3
xi_mapped = -eta;
eta_mapped = xi;
}
else
{
// Case 4
xi_mapped = xi;
eta_mapped = -eta;
}
else if (elem->point(2) == min_point)
if (elem->point(3) == std::min(elem->point(3), elem->point(1)))
{
// Case 5
xi_mapped = -xi;
eta_mapped = -eta;
}
else
{
// Case 6
xi_mapped = -eta;
eta_mapped = -xi;
}
else if (elem->point(1) == min_point)
{
if (elem->point(2) == std::min(elem->point(2), elem->point(0)))
{
// Case 7
xi_mapped = eta;
eta_mapped = -xi;
}
else
{
// Case 8
xi_mapped = -xi;
eta_mapped = eta;
}
}
}
// Face 1
else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(0),
std::min(elem->point(1),
std::min(elem->point(5),
elem->point(4))));
if (elem->point(0) == min_point)
if (elem->point(1) == std::min(elem->point(1), elem->point(4)))
{
// Case 1
xi_mapped = xi;
zeta_mapped = zeta;
}
else
{
// Case 2
xi_mapped = zeta;
zeta_mapped = xi;
}
else if (elem->point(1) == min_point)
if (elem->point(5) == std::min(elem->point(5), elem->point(0)))
{
// Case 3
xi_mapped = zeta;
zeta_mapped = -xi;
}
else
{
// Case 4
xi_mapped = -xi;
zeta_mapped = zeta;
}
else if (elem->point(5) == min_point)
if (elem->point(4) == std::min(elem->point(4), elem->point(1)))
{
// Case 5
xi_mapped = -xi;
zeta_mapped = -zeta;
}
else
{
// Case 6
xi_mapped = -zeta;
zeta_mapped = -xi;
}
else if (elem->point(4) == min_point)
{
if (elem->point(0) == std::min(elem->point(0), elem->point(5)))
{
// Case 7
xi_mapped = -xi;
zeta_mapped = zeta;
}
else
{
// Case 8
xi_mapped = xi;
zeta_mapped = -zeta;
}
}
}
// Face 2
else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(1),
std::min(elem->point(2),
std::min(elem->point(6),
elem->point(5))));
if (elem->point(1) == min_point)
if (elem->point(2) == std::min(elem->point(2), elem->point(5)))
{
// Case 1
eta_mapped = eta;
zeta_mapped = zeta;
}
else
{
// Case 2
eta_mapped = zeta;
zeta_mapped = eta;
}
else if (elem->point(2) == min_point)
if (elem->point(6) == std::min(elem->point(6), elem->point(1)))
{
// Case 3
eta_mapped = zeta;
zeta_mapped = -eta;
}
else
{
// Case 4
eta_mapped = -eta;
zeta_mapped = zeta;
}
else if (elem->point(6) == min_point)
if (elem->point(5) == std::min(elem->point(5), elem->point(2)))
{
// Case 5
eta_mapped = -eta;
zeta_mapped = -zeta;
}
else
{
// Case 6
eta_mapped = -zeta;
zeta_mapped = -eta;
}
else if (elem->point(5) == min_point)
{
if (elem->point(1) == std::min(elem->point(1), elem->point(6)))
{
// Case 7
eta_mapped = -zeta;
zeta_mapped = eta;
}
else
{
// Case 8
eta_mapped = eta;
zeta_mapped = -zeta;
}
}
}
// Face 3
else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(2),
std::min(elem->point(3),
std::min(elem->point(7),
elem->point(6))));
if (elem->point(3) == min_point)
if (elem->point(2) == std::min(elem->point(2), elem->point(7)))
{
// Case 1
xi_mapped = xi;
zeta_mapped = zeta;
}
else
{
// Case 2
xi_mapped = zeta;
zeta_mapped = xi;
}
else if (elem->point(7) == min_point)
if (elem->point(3) == std::min(elem->point(3), elem->point(6)))
{
// Case 3
xi_mapped = -zeta;
zeta_mapped = xi;
}
else
{
// Case 4
xi_mapped = xi;
zeta_mapped = -zeta;
}
else if (elem->point(6) == min_point)
if (elem->point(7) == std::min(elem->point(7), elem->point(2)))
{
// Case 5
xi_mapped = -xi;
zeta_mapped = -zeta;
}
else
{
// Case 6
xi_mapped = -zeta;
zeta_mapped = -xi;
}
else if (elem->point(2) == min_point)
{
if (elem->point(6) == std::min(elem->point(3), elem->point(6)))
{
// Case 7
xi_mapped = zeta;
zeta_mapped = -xi;
}
else
{
// Case 8
xi_mapped = -xi;
zeta_mapped = zeta;
}
}
}
// Face 4
else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(3),
std::min(elem->point(0),
std::min(elem->point(4),
elem->point(7))));
if (elem->point(0) == min_point)
if (elem->point(3) == std::min(elem->point(3), elem->point(4)))
{
// Case 1
eta_mapped = eta;
zeta_mapped = zeta;
}
else
{
// Case 2
eta_mapped = zeta;
zeta_mapped = eta;
}
else if (elem->point(4) == min_point)
if (elem->point(0) == std::min(elem->point(0), elem->point(7)))
{
// Case 3
eta_mapped = -zeta;
zeta_mapped = eta;
}
else
{
// Case 4
eta_mapped = eta;
zeta_mapped = -zeta;
}
else if (elem->point(7) == min_point)
if (elem->point(4) == std::min(elem->point(4), elem->point(3)))
{
// Case 5
eta_mapped = -eta;
zeta_mapped = -zeta;
}
else
{
// Case 6
eta_mapped = -zeta;
zeta_mapped = -eta;
}
else if (elem->point(3) == min_point)
{
if (elem->point(7) == std::min(elem->point(7), elem->point(0)))
{
// Case 7
eta_mapped = zeta;
zeta_mapped = -eta;
}
else
{
// Case 8
eta_mapped = -eta;
zeta_mapped = zeta;
}
}
}
// Face 5
else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
{
const Point min_point = std::min(elem->point(4),
std::min(elem->point(5),
std::min(elem->point(6),
elem->point(7))));
if (elem->point(4) == min_point)
if (elem->point(5) == std::min(elem->point(5), elem->point(7)))
{
// Case 1
xi_mapped = xi;
eta_mapped = eta;
}
else
{
// Case 2
xi_mapped = eta;
eta_mapped = xi;
}
else if (elem->point(5) == min_point)
if (elem->point(6) == std::min(elem->point(6), elem->point(4)))
{
// Case 3
xi_mapped = eta;
eta_mapped = -xi;
}
else
{
// Case 4
xi_mapped = -xi;
eta_mapped = eta;
}
else if (elem->point(6) == min_point)
if (elem->point(7) == std::min(elem->point(7), elem->point(5)))
{
// Case 5
xi_mapped = -xi;
eta_mapped = -eta;
}
else
{
// Case 6
xi_mapped = -eta;
eta_mapped = -xi;
}
else if (elem->point(7) == min_point)
{
if (elem->point(4) == std::min(elem->point(4), elem->point(6)))
{
// Case 7
xi_mapped = -eta;
eta_mapped = xi;
}
else
{
// Case 8
xi_mapped = xi;
eta_mapped = eta;
}
}
}
}
return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi_mapped)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta_mapped)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta_mapped));
}
default:
libmesh_error();
} //case HEX27
} //case THIRD
// 4th-order Bernstein.
case FOURTH:
{
switch (type)
{
// Bernstein shape functions on the hexahedral.
case HEX27:
{
libmesh_assert (i<125);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
Real xi_mapped = p(0);
Real eta_mapped = p(1);
Real zeta_mapped = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// Nodes 0 1 2 3 4 5 6 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
// DOFS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4};
// handle the edge orientation
{
// Edge 0
if ( (i0[i] >= 2) && (i1[i] == 0) && (i2[i] == 0))
{
if (elem->point(0) != std::min(elem->point(0), elem->point(1)))
xi_mapped = -xi;
}
// Edge 1
else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] == 0))
{
if (elem->point(1) != std::min(elem->point(1), elem->point(2)))
eta_mapped = -eta;
}
// Edge 2
else if ((i0[i] >= 2) && (i1[i] == 1) && (i2[i] == 0))
{
if (elem->point(3) != std::min(elem->point(3), elem->point(2)))
xi_mapped = -xi;
}
// Edge 3
else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] == 0))
{
if (elem->point(0) != std::min(elem->point(0), elem->point(3)))
eta_mapped = -eta;
}
// Edge 4
else if ((i0[i] == 0) && (i1[i] == 0) && (i2[i] >=2 ))
{
if (elem->point(0) != std::min(elem->point(0), elem->point(4)))
zeta_mapped = -zeta;
}
// Edge 5
else if ((i0[i] == 1) && (i1[i] == 0) && (i2[i] >=2 ))
{
if (elem->point(1) != std::min(elem->point(1), elem->point(5)))
zeta_mapped = -zeta;
}
// Edge 6
else if ((i0[i] == 1) && (i1[i] == 1) && (i2[i] >=2 ))
{
if (elem->point(2) != std::min(elem->point(2), elem->point(6)))
zeta_mapped = -zeta;
}
// Edge 7
else if ((i0[i] == 0) && (i1[i] == 1) && (i2[i] >=2 ))
{
if (elem->point(3) != std::min(elem->point(3), elem->point(7)))
zeta_mapped = -zeta;
}
// Edge 8
else if ((i0[i] >=2 ) && (i1[i] == 0) && (i2[i] == 1))
{
if (elem->point(4) != std::min(elem->point(4), elem->point(5)))
xi_mapped = -xi;
}
// Edge 9
else if ((i0[i] == 1) && (i1[i] >=2 ) && (i2[i] == 1))
{
if (elem->point(5) != std::min(elem->point(5), elem->point(6)))
eta_mapped = -eta;
}
// Edge 10
else if ((i0[i] >=2 ) && (i1[i] == 1) && (i2[i] == 1))
{
if (elem->point(7) != std::min(elem->point(7), elem->point(6)))
xi_mapped = -xi;
}
// Edge 11
else if ((i0[i] == 0) && (i1[i] >=2 ) && (i2[i] == 1))
{
if (elem->point(4) != std::min(elem->point(4), elem->point(7)))
eta_mapped = -eta;
}
}
// handle the face orientation
{
// Face 0
if ( (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
{
const Point min_point = std::min(elem->point(1),
std::min(elem->point(2),
std::min(elem->point(0),
elem->point(3))));
if (elem->point(0) == min_point)
if (elem->point(1) == std::min(elem->point(1), elem->point(3)))
{
// Case 1
xi_mapped = xi;
eta_mapped = eta;
}
else
{
// Case 2
xi_mapped = eta;
eta_mapped = xi;
}
else if (elem->point(3) == min_point)
if (elem->point(0) == std::min(elem->point(0), elem->point(2)))
{
// Case 3
xi_mapped = -eta;
eta_mapped = xi;
}
else
{
// Case 4
xi_mapped = xi;
eta_mapped = -eta;
}
else if (elem->point(2) == min_point)
if (elem->point(3) == std::min(elem->point(3), elem->point(1)))
{
// Case 5
xi_mapped = -xi;
eta_mapped = -eta;
}
else
{
// Case 6
xi_mapped = -eta;
eta_mapped = -xi;
}
else if (elem->point(1) == min_point)
{
if (elem->point(2) == std::min(elem->point(2), elem->point(0)))
{
// Case 7
xi_mapped = eta;
eta_mapped = -xi;
}
else
{
// Case 8
xi_mapped = -xi;
eta_mapped = eta;
}
}
}
// Face 1
else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(0),
std::min(elem->point(1),
std::min(elem->point(5),
elem->point(4))));
if (elem->point(0) == min_point)
if (elem->point(1) == std::min(elem->point(1), elem->point(4)))
{
// Case 1
xi_mapped = xi;
zeta_mapped = zeta;
}
else
{
// Case 2
xi_mapped = zeta;
zeta_mapped = xi;
}
else if (elem->point(1) == min_point)
if (elem->point(5) == std::min(elem->point(5), elem->point(0)))
{
// Case 3
xi_mapped = zeta;
zeta_mapped = -xi;
}
else
{
// Case 4
xi_mapped = -xi;
zeta_mapped = zeta;
}
else if (elem->point(5) == min_point)
if (elem->point(4) == std::min(elem->point(4), elem->point(1)))
{
// Case 5
xi_mapped = -xi;
zeta_mapped = -zeta;
}
else
{
// Case 6
xi_mapped = -zeta;
zeta_mapped = -xi;
}
else if (elem->point(4) == min_point)
{
if (elem->point(0) == std::min(elem->point(0), elem->point(5)))
{
// Case 7
xi_mapped = -xi;
zeta_mapped = zeta;
}
else
{
// Case 8
xi_mapped = xi;
zeta_mapped = -zeta;
}
}
}
// Face 2
else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(1),
std::min(elem->point(2),
std::min(elem->point(6),
elem->point(5))));
if (elem->point(1) == min_point)
if (elem->point(2) == std::min(elem->point(2), elem->point(5)))
{
// Case 1
eta_mapped = eta;
zeta_mapped = zeta;
}
else
{
// Case 2
eta_mapped = zeta;
zeta_mapped = eta;
}
else if (elem->point(2) == min_point)
if (elem->point(6) == std::min(elem->point(6), elem->point(1)))
{
// Case 3
eta_mapped = zeta;
zeta_mapped = -eta;
}
else
{
// Case 4
eta_mapped = -eta;
zeta_mapped = zeta;
}
else if (elem->point(6) == min_point)
if (elem->point(5) == std::min(elem->point(5), elem->point(2)))
{
// Case 5
eta_mapped = -eta;
zeta_mapped = -zeta;
}
else
{
// Case 6
eta_mapped = -zeta;
zeta_mapped = -eta;
}
else if (elem->point(5) == min_point)
{
if (elem->point(1) == std::min(elem->point(1), elem->point(6)))
{
// Case 7
eta_mapped = -zeta;
zeta_mapped = eta;
}
else
{
// Case 8
eta_mapped = eta;
zeta_mapped = -zeta;
}
}
}
// Face 3
else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(2),
std::min(elem->point(3),
std::min(elem->point(7),
elem->point(6))));
if (elem->point(3) == min_point)
if (elem->point(2) == std::min(elem->point(2), elem->point(7)))
{
// Case 1
xi_mapped = xi;
zeta_mapped = zeta;
}
else
{
// Case 2
xi_mapped = zeta;
zeta_mapped = xi;
}
else if (elem->point(7) == min_point)
if (elem->point(3) == std::min(elem->point(3), elem->point(6)))
{
// Case 3
xi_mapped = -zeta;
zeta_mapped = xi;
}
else
{
// Case 4
xi_mapped = xi;
zeta_mapped = -zeta;
}
else if (elem->point(6) == min_point)
if (elem->point(7) == std::min(elem->point(7), elem->point(2)))
{
// Case 5
xi_mapped = -xi;
zeta_mapped = -zeta;
}
else
{
// Case 6
xi_mapped = -zeta;
zeta_mapped = -xi;
}
else if (elem->point(2) == min_point)
{
if (elem->point(6) == std::min(elem->point(3), elem->point(6)))
{
// Case 7
xi_mapped = zeta;
zeta_mapped = -xi;
}
else
{
// Case 8
xi_mapped = -xi;
zeta_mapped = zeta;
}
}
}
// Face 4
else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
{
const Point min_point = std::min(elem->point(3),
std::min(elem->point(0),
std::min(elem->point(4),
elem->point(7))));
if (elem->point(0) == min_point)
if (elem->point(3) == std::min(elem->point(3), elem->point(4)))
{
// Case 1
eta_mapped = eta;
zeta_mapped = zeta;
}
else
{
// Case 2
eta_mapped = zeta;
zeta_mapped = eta;
}
else if (elem->point(4) == min_point)
if (elem->point(0) == std::min(elem->point(0), elem->point(7)))
{
// Case 3
eta_mapped = -zeta;
zeta_mapped = eta;
}
else
{
// Case 4
eta_mapped = eta;
zeta_mapped = -zeta;
}
else if (elem->point(7) == min_point)
if (elem->point(4) == std::min(elem->point(4), elem->point(3)))
{
// Case 5
eta_mapped = -eta;
zeta_mapped = -zeta;
}
else
{
// Case 6
eta_mapped = -zeta;
zeta_mapped = -eta;
}
else if (elem->point(3) == min_point)
{
if (elem->point(7) == std::min(elem->point(7), elem->point(0)))
{
// Case 7
eta_mapped = zeta;
zeta_mapped = -eta;
}
else
{
// Case 8
eta_mapped = -eta;
zeta_mapped = zeta;
}
}
}
// Face 5
else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
{
const Point min_point = std::min(elem->point(4),
std::min(elem->point(5),
std::min(elem->point(6),
elem->point(7))));
if (elem->point(4) == min_point)
if (elem->point(5) == std::min(elem->point(5), elem->point(7)))
{
// Case 1
xi_mapped = xi;
eta_mapped = eta;
}
else
{
// Case 2
xi_mapped = eta;
eta_mapped = xi;
}
else if (elem->point(5) == min_point)
if (elem->point(6) == std::min(elem->point(6), elem->point(4)))
{
// Case 3
xi_mapped = eta;
eta_mapped = -xi;
}
else
{
// Case 4
xi_mapped = -xi;
eta_mapped = eta;
}
else if (elem->point(6) == min_point)
if (elem->point(7) == std::min(elem->point(7), elem->point(5)))
{
// Case 5
xi_mapped = -xi;
eta_mapped = -eta;
}
else
{
// Case 6
xi_mapped = -eta;
eta_mapped = -xi;
}
else if (elem->point(7) == min_point)
{
if (elem->point(4) == std::min(elem->point(4), elem->point(6)))
{
// Case 7
xi_mapped = -eta;
eta_mapped = xi;
}
else
{
// Case 8
xi_mapped = xi;
eta_mapped = eta;
}
}
}
}
return (FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i0[i], xi_mapped)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i1[i], eta_mapped)*
FE<1,BERNSTEIN>::shape(EDGE3, totalorder, i2[i], zeta_mapped));
}
default:
libmesh_error();
}
}
default:
libmesh_error();
}
#endif
libmesh_error();
return 0.;
}
Definition at line 32 of file fe_hierarchic_shape_1D.C.
References Utility::pow(), Utility::pow< 4 >(), and Utility::pow< 6 >().
{
libmesh_assert(i < order+1u);
// Declare that we are using our own special power function
// from the Utility namespace. This saves typing later.
using Utility::pow;
const Real xi = p(0);
Real returnval = 1.;
switch (i)
{
case 0:
returnval = .5*(1. - xi);
break;
case 1:
returnval = .5*(1. + xi);
break;
// All even-terms have the same form.
// (xi^p - 1.)/p!
case 2:
returnval = (xi*xi - 1.)/2.;
break;
case 4:
returnval = (pow<4>(xi) - 1.)/24.;
break;
case 6:
returnval = (pow<6>(xi) - 1.)/720.;
break;
// All odd-terms have the same form.
// (xi^p - xi)/p!
case 3:
returnval = (xi*xi*xi - xi)/6.;
break;
case 5:
returnval = (pow<5>(xi) - xi)/120.;
break;
case 7:
returnval = (pow<7>(xi) - xi)/5040.;
break;
default:
Real denominator = 1.;
for (unsigned int n=1; n <= i; ++n)
{
returnval *= xi;
denominator *= n;
}
// Odd:
if (i % 2)
returnval = (returnval - xi)/denominator;
// Even:
else
returnval = (returnval - 1.)/denominator;
break;
}
return returnval;
}
Definition at line 100 of file fe_hierarchic_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,HIERARCHIC>::shape(elem->type(), static_cast<Order>(order + elem->p_level()), i, p);
}
On a p-refined element, o should be the total order of the element.
Referenced by InfFE< Dim, T_radial, T_map >::compute_data(), FEXYZ< Dim >::compute_face_values(), FE< Dim, T >::init_edge_shape_functions(), FE< Dim, T >::init_face_shape_functions(), FEXYZ< Dim >::init_shape_functions(), FE< Dim, T >::init_shape_functions(), InfFE< Dim, T_radial, T_map >::inverse_map(), FE< Dim, T >::map(), FE< Dim, T >::shape(), and FE< Dim, T >::shape_deriv().
Definition at line 31 of file fe_xyz_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 43 of file fe_xyz_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 31 of file fe_hierarchic_shape_2D.C.
{
std::cerr << 'Hierarchic polynomials require the element type
<< 'because edge orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 47 of file fe_hierarchic_shape_2D.C.
References libMeshEnums::EDGE3, Elem::p_level(), Elem::point(), Utility::pow(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, FE< Dim, T >::shape(), square_number_column, square_number_row, libMeshEnums::TRI3, libMeshEnums::TRI6, triangular_number_column, triangular_number_row, and Elem::type().
{
libmesh_assert (elem != NULL);
// Declare that we are using our own special power function
// from the Utility namespace. This saves typing later.
using Utility::pow;
const Order totalorder = static_cast<Order>(order+elem->p_level());
libmesh_assert(totalorder > 0);
switch (elem->type())
{
case TRI3:
case TRI6:
{
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta0 = 1. - zeta1 - zeta2;
libmesh_assert (i<(totalorder+1u)*(totalorder+2u)/2);
libmesh_assert (elem->type() == TRI6 || totalorder < 2);
// Vertex DoFs
if (i == 0)
return zeta0;
else if (i == 1)
return zeta1;
else if (i == 2)
return zeta2;
// Edge DoFs
else if (i < totalorder + 2u)
{
// Avoid returning NaN on vertices!
if (zeta0 + zeta1 == 0.)
return 0.;
const unsigned int basisorder = i - 1;
// Get factors to account for edge-flipping
Real f0 = 1;
if (basisorder%2 && (elem->point(0) > elem->point(1)))
f0 = -1.;
Real edgeval = (zeta1 - zeta0) / (zeta1 + zeta0);
Real crossfunc = zeta0 + zeta1;
for (unsigned int n=1; n != basisorder; ++n)
crossfunc *= (zeta0 + zeta1);
return f0 * crossfunc *
FE<1,HIERARCHIC>::shape(EDGE3, totalorder,
basisorder, edgeval);
}
else if (i < 2u*totalorder + 1)
{
// Avoid returning NaN on vertices!
if (zeta1 + zeta2 == 0.)
return 0.;
const unsigned int basisorder = i - totalorder;
// Get factors to account for edge-flipping
Real f1 = 1;
if (basisorder%2 && (elem->point(1) > elem->point(2)))
f1 = -1.;
Real edgeval = (zeta2 - zeta1) / (zeta2 + zeta1);
Real crossfunc = zeta2 + zeta1;
for (unsigned int n=1; n != basisorder; ++n)
crossfunc *= (zeta2 + zeta1);
return f1 * crossfunc *
FE<1,HIERARCHIC>::shape(EDGE3, totalorder,
basisorder, edgeval);
}
else if (i < 3u*totalorder)
{
// Avoid returning NaN on vertices!
if (zeta0 + zeta2 == 0.)
return 0.;
const unsigned int basisorder = i - (2u*totalorder) + 1;
// Get factors to account for edge-flipping
Real f2 = 1;
if (basisorder%2 && (elem->point(2) > elem->point(0)))
f2 = -1.;
Real edgeval = (zeta0 - zeta2) / (zeta0 + zeta2);
Real crossfunc = zeta0 + zeta2;
for (unsigned int n=1; n != basisorder; ++n)
crossfunc *= (zeta0 + zeta2);
return f2 * crossfunc *
FE<1,HIERARCHIC>::shape(EDGE3, totalorder,
basisorder, edgeval);
}
// Interior DoFs
else
{
const unsigned int basisnum = i - (3u*totalorder);
unsigned int exp0 = triangular_number_column[basisnum] + 1;
unsigned int exp1 = triangular_number_row[basisnum] + 1 -
triangular_number_column[basisnum];
Real returnval = 1;
for (unsigned int n = 0; n != exp0; ++n)
returnval *= zeta0;
for (unsigned int n = 0; n != exp1; ++n)
returnval *= zeta1;
returnval *= zeta2;
return returnval;
}
}
// Hierarchic shape functions on the quadrilateral.
case QUAD4:
libmesh_assert (totalorder < 2);
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < (totalorder+1u)*(totalorder+1u));
// Example i, i0, i1 values for totalorder = 5:
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 3, 2, 4, 4, 4, 3, 2, 5, 5, 5, 5, 4, 3, 2};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 3, 3, 2, 3, 4, 4, 4, 2, 3, 4, 5, 5, 5, 5};
unsigned int i0, i1;
// Vertex DoFs
if (i == 0)
{ i0 = 0; i1 = 0; }
else if (i == 1)
{ i0 = 1; i1 = 0; }
else if (i == 2)
{ i0 = 1; i1 = 1; }
else if (i == 3)
{ i0 = 0; i1 = 1; }
// Edge DoFs
else if (i < totalorder + 3u)
{ i0 = i - 2; i1 = 0; }
else if (i < 2u*totalorder + 2)
{ i0 = 1; i1 = i - totalorder - 1; }
else if (i < 3u*totalorder + 1)
{ i0 = i - 2u*totalorder; i1 = 1; }
else if (i < 4u*totalorder)
{ i0 = 0; i1 = i - 3u*totalorder + 1; }
// Interior DoFs
else
{
unsigned int basisnum = i - 4*totalorder;
i0 = square_number_column[basisnum] + 2;
i1 = square_number_row[basisnum] + 2;
}
// Flip odd degree of freedom values if necessary
// to keep continuity on sides
Real f = 1.;
if ((i0%2) && (i0 > 2) && (i1 == 0))
f = (elem->point(0) > elem->point(1))?-1.:1.;
else if ((i0%2) && (i0>2) && (i1 == 1))
f = (elem->point(3) > elem->point(2))?-1.:1.;
else if ((i0 == 0) && (i1%2) && (i1>2))
f = (elem->point(0) > elem->point(3))?-1.:1.;
else if ((i0 == 1) && (i1%2) && (i1>2))
f = (elem->point(1) > elem->point(2))?-1.:1.;
return f*(FE<1,HIERARCHIC>::shape(EDGE3, totalorder, i0, xi)*
FE<1,HIERARCHIC>::shape(EDGE3, totalorder, i1, eta));
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
return 0.;
}
Definition at line 42 of file fe_xyz_shape_1D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 58 of file fe_xyz_shape_1D.C.
References Elem::centroid(), and DofObject::id().
{
libmesh_assert (elem != NULL);
libmesh_assert (i <= order + elem->p_level());
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real xc = centroid(0);
const Real dx = x - xc;
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
case 0:
return 1.;
case 1:
return dx;
case 2:
return dx*dx;
case 3:
return dx*dx*dx;
case 4:
return dx*dx*dx*dx;
default:
Real val = 1.;
for (unsigned int index = 0; index != i; ++index)
val *= dx;
return val;
}
libmesh_error();
return 0.;
}
Definition at line 31 of file fe_clough_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 42 of file fe_xyz_shape_2D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 58 of file fe_xyz_shape_2D.C.
References Elem::centroid(), DofObject::id(), and Elem::p_level().
{
#if LIBMESH_DIM > 1
libmesh_assert (elem != NULL);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real y = p(1);
const Real xc = centroid(0);
const Real yc = centroid(1);
const Real dx = x - xc;
const Real dy = y - yc;
#ifndef NDEBUG
// totalorder is only used in the assertion below, so
// we avoid declaring it when asserts are not active.
const unsigned int totalorder = order + elem->p_level();
#endif
libmesh_assert (i < (totalorder+1)*(totalorder+2)/2);
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
// constant
case 0:
return 1.;
// linear
case 1:
return dx;
case 2:
return dy;
// quadratics
case 3:
return dx*dx;
case 4:
return dx*dy;
case 5:
return dy*dy;
// cubics
case 6:
return dx*dx*dx;
case 7:
return dx*dx*dy;
case 8:
return dx*dy*dy;
case 9:
return dy*dy*dy;
// quartics
case 10:
return dx*dx*dx*dx;
case 11:
return dx*dx*dx*dy;
case 12:
return dx*dx*dy*dy;
case 13:
return dx*dy*dy*dy;
case 14:
return dy*dy*dy*dy;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int i2 = i - (o*(o+1)/2);
Real val = 1.;
for (unsigned int index=i2; index != o; index++)
val *= dx;
for (unsigned int index=0; index != i2; index++)
val *= dy;
return val;
}
libmesh_error();
return 0.;
#endif
}
Definition at line 43 of file fe_clough_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 644 of file fe_hierarchic_shape_3D.C.
{
std::cerr << 'Hierarchic polynomials require the element type
<< 'because edge and face orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 660 of file fe_hierarchic_shape_3D.C.
References libMeshEnums::EDGE3, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, Elem::p_level(), and Elem::type().
{
#if LIBMESH_DIM == 3
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order+elem->p_level());
switch (type)
{
case HEX8:
case HEX20:
libmesh_assert(totalorder < 2);
case HEX27:
{
libmesh_assert (i<(totalorder+1u)*(totalorder+1u)*(totalorder+1u));
// Compute hex shape functions as a tensor-product
Real xi = p(0);
Real eta = p(1);
Real zeta = p(2);
unsigned int i0, i1, i2;
cube_indices(elem, totalorder, i, xi, eta, zeta, i0, i1, i2);
return (FE<1,HIERARCHIC>::shape(EDGE3, totalorder, i0, xi)*
FE<1,HIERARCHIC>::shape(EDGE3, totalorder, i1, eta)*
FE<1,HIERARCHIC>::shape(EDGE3, totalorder, i2, zeta));
}
default:
libmesh_error();
}
#endif
libmesh_error();
return 0.;
}
Definition at line 58 of file fe_xyz_shape_3D.C.
References Elem::centroid(), DofObject::id(), and Elem::p_level().
{
#if LIBMESH_DIM == 3
libmesh_assert (elem != NULL);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real y = p(1);
const Real z = p(2);
const Real xc = centroid(0);
const Real yc = centroid(1);
const Real zc = centroid(2);
const Real dx = x - xc;
const Real dy = y - yc;
const Real dz = z - zc;
#ifndef NDEBUG
// totalorder is only used in the assertion below, so
// we avoid declaring it when asserts are not active.
const unsigned int totalorder = order + elem->p_level();
#endif
libmesh_assert (i < (static_cast<unsigned int>(totalorder)+1)*
(static_cast<unsigned int>(totalorder)+2)*
(static_cast<unsigned int>(totalorder)+2)/6);
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
// constant
case 0:
return 1.;
// linears
case 1:
return dx;
case 2:
return dy;
case 3:
return dz;
// quadratics
case 4:
return dx*dx;
case 5:
return dx*dy;
case 6:
return dy*dy;
case 7:
return dx*dz;
case 8:
return dz*dy;
case 9:
return dz*dz;
// cubics
case 10:
return dx*dx*dx;
case 11:
return dx*dx*dy;
case 12:
return dx*dy*dy;
case 13:
return dy*dy*dy;
case 14:
return dx*dx*dz;
case 15:
return dx*dy*dz;
case 16:
return dy*dy*dz;
case 17:
return dx*dz*dz;
case 18:
return dy*dz*dz;
case 19:
return dz*dz*dz;
// quartics
case 20:
return dx*dx*dx*dx;
case 21:
return dx*dx*dx*dy;
case 22:
return dx*dx*dy*dy;
case 23:
return dx*dy*dy*dy;
case 24:
return dy*dy*dy*dy;
case 25:
return dx*dx*dx*dz;
case 26:
return dx*dx*dy*dz;
case 27:
return dx*dy*dy*dz;
case 28:
return dy*dy*dy*dz;
case 29:
return dx*dx*dz*dz;
case 30:
return dx*dy*dz*dz;
case 31:
return dy*dy*dz*dz;
case 32:
return dx*dz*dz*dz;
case 33:
return dy*dz*dz*dz;
case 34:
return dz*dz*dz*dz;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = 1.;
for (unsigned int index=0; index != nx; index++)
val *= dx;
for (unsigned int index=0; index != ny; index++)
val *= dy;
for (unsigned int index=0; index != nz; index++)
val *= dz;
return val;
}
#endif
libmesh_error();
return 0.;
}
On a p-refined element, o should be the base order of the element.
Definition at line 1436 of file fe_clough_shape_2D.C.
{
std::cerr << 'Clough-Tocher elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 43 of file fe_lagrange_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 43 of file fe_monomial_shape_0D.C.
{
libmesh_assert (i < 1);
return 1.;
}
Definition at line 31 of file fe_monomial_shape_2D.C.
{
#if LIBMESH_DIM > 1
libmesh_assert (i < (static_cast<unsigned int>(order)+1)*
(static_cast<unsigned int>(order)+2)/2);
const Real xi = p(0);
const Real eta = p(1);
switch (i)
{
// constant
case 0:
return 1.;
// linear
case 1:
return xi;
case 2:
return eta;
// quadratics
case 3:
return xi*xi;
case 4:
return xi*eta;
case 5:
return eta*eta;
// cubics
case 6:
return xi*xi*xi;
case 7:
return xi*xi*eta;
case 8:
return xi*eta*eta;
case 9:
return eta*eta*eta;
// quartics
case 10:
return xi*xi*xi*xi;
case 11:
return xi*xi*xi*eta;
case 12:
return xi*xi*eta*eta;
case 13:
return xi*eta*eta*eta;
case 14:
return eta*eta*eta*eta;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int ny = i - (o*(o+1)/2);
unsigned int nx = o - ny;
Real val = 1.;
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
return val;
}
libmesh_error();
return 0.;
#endif
}
Definition at line 70 of file fe_szabab_shape_3D.C.
{
std::cerr << 'Szabo-Babuska polynomials are not defined in 3D << std::endl;
libmesh_error();
return 0.;
}
Definition at line 55 of file fe_lagrange_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
On a p-refined element, o should be the base order of the element.
Definition at line 577 of file fe_lagrange_shape_2D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape functions
return FE<2,LAGRANGE>::shape_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 237 of file fe_lagrange_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,LAGRANGE>::shape_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 265 of file fe_clough_shape_1D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
clough_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 3rd-order C1 cubic element
case THIRD:
{
switch (type)
{
// C1 functions on the C1 cubic edge
case EDGE2:
case EDGE3:
{
switch (i)
{
case 0:
return clough_raw_shape_deriv(0, j, p);
case 1:
return clough_raw_shape_deriv(1, j, p);
case 2:
return d1xd1x * clough_raw_shape_deriv(2, j, p);
case 3:
return d2xd2x * clough_raw_shape_deriv(3, j, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 56 of file fe_szabab_shape_3D.C.
{
std::cerr << 'Szabo-Babuska polynomials are not defined in 3D << std::endl;
libmesh_error();
return 0.;
}
Definition at line 236 of file fe_xyz_shape_3D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 1651 of file fe_clough_shape_2D.C.
References Elem::p_level(), libMeshEnums::SECOND, libMeshEnums::THIRD, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
clough_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 2nd-order restricted Clough-Tocher element
case SECOND:
{
switch (type)
{
// C1 functions on the Clough-Tocher triangle.
case TRI6:
{
libmesh_assert (i<9);
// FIXME: it would be nice to calculate (and cache)
// clough_raw_shape(j,p) only once per triangle, not 1-7
// times
switch (i)
{
// Note: these DoF numbers are 'scrambled' because my
// initial numbering conventions didn't match libMesh
case 0:
return clough_raw_shape_deriv(0, j, p)
+ d1d2n * clough_raw_shape_deriv(10, j, p)
+ d1d3n * clough_raw_shape_deriv(11, j, p);
case 3:
return clough_raw_shape_deriv(1, j, p)
+ d2d3n * clough_raw_shape_deriv(11, j, p)
+ d2d1n * clough_raw_shape_deriv(9, j, p);
case 6:
return clough_raw_shape_deriv(2, j, p)
+ d3d1n * clough_raw_shape_deriv(9, j, p)
+ d3d2n * clough_raw_shape_deriv(10, j, p);
case 1:
return d1xd1x * clough_raw_shape_deriv(3, j, p)
+ d1xd1y * clough_raw_shape_deriv(4, j, p)
+ d1xd2n * clough_raw_shape_deriv(10, j, p)
+ d1xd3n * clough_raw_shape_deriv(11, j, p)
+ 0.5 * N01x * d3nd3n * clough_raw_shape_deriv(11, j, p)
+ 0.5 * N02x * d2nd2n * clough_raw_shape_deriv(10, j, p);
case 2:
return d1yd1y * clough_raw_shape_deriv(4, j, p)
+ d1yd1x * clough_raw_shape_deriv(3, j, p)
+ d1yd2n * clough_raw_shape_deriv(10, j, p)
+ d1yd3n * clough_raw_shape_deriv(11, j, p)
+ 0.5 * N01y * d3nd3n * clough_raw_shape_deriv(11, j, p)
+ 0.5 * N02y * d2nd2n * clough_raw_shape_deriv(10, j, p);
case 4:
return d2xd2x * clough_raw_shape_deriv(5, j, p)
+ d2xd2y * clough_raw_shape_deriv(6, j, p)
+ d2xd3n * clough_raw_shape_deriv(11, j, p)
+ d2xd1n * clough_raw_shape_deriv(9, j, p)
+ 0.5 * N10x * d3nd3n * clough_raw_shape_deriv(11, j, p)
+ 0.5 * N12x * d1nd1n * clough_raw_shape_deriv(9, j, p);
case 5:
return d2yd2y * clough_raw_shape_deriv(6, j, p)
+ d2yd2x * clough_raw_shape_deriv(5, j, p)
+ d2yd3n * clough_raw_shape_deriv(11, j, p)
+ d2yd1n * clough_raw_shape_deriv(9, j, p)
+ 0.5 * N10y * d3nd3n * clough_raw_shape_deriv(11, j, p)
+ 0.5 * N12y * d1nd1n * clough_raw_shape_deriv(9, j, p);
case 7:
return d3xd3x * clough_raw_shape_deriv(7, j, p)
+ d3xd3y * clough_raw_shape_deriv(8, j, p)
+ d3xd1n * clough_raw_shape_deriv(9, j, p)
+ d3xd2n * clough_raw_shape_deriv(10, j, p)
+ 0.5 * N20x * d2nd2n * clough_raw_shape_deriv(10, j, p)
+ 0.5 * N21x * d1nd1n * clough_raw_shape_deriv(9, j, p);
case 8:
return d3yd3y * clough_raw_shape_deriv(8, j, p)
+ d3yd3x * clough_raw_shape_deriv(7, j, p)
+ d3yd1n * clough_raw_shape_deriv(9, j, p)
+ d3yd2n * clough_raw_shape_deriv(10, j, p)
+ 0.5 * N20y * d2nd2n * clough_raw_shape_deriv(10, j, p)
+ 0.5 * N21y * d1nd1n * clough_raw_shape_deriv(9, j, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// 3rd-order Clough-Tocher element
case THIRD:
{
switch (type)
{
// C1 functions on the Clough-Tocher triangle.
case TRI6:
{
libmesh_assert (i<12);
// FIXME: it would be nice to calculate (and cache)
// clough_raw_shape(j,p) only once per triangle, not 1-7
// times
switch (i)
{
// Note: these DoF numbers are 'scrambled' because my
// initial numbering conventions didn't match libMesh
case 0:
return clough_raw_shape_deriv(0, j, p)
+ d1d2n * clough_raw_shape_deriv(10, j, p)
+ d1d3n * clough_raw_shape_deriv(11, j, p);
case 3:
return clough_raw_shape_deriv(1, j, p)
+ d2d3n * clough_raw_shape_deriv(11, j, p)
+ d2d1n * clough_raw_shape_deriv(9, j, p);
case 6:
return clough_raw_shape_deriv(2, j, p)
+ d3d1n * clough_raw_shape_deriv(9, j, p)
+ d3d2n * clough_raw_shape_deriv(10, j, p);
case 1:
return d1xd1x * clough_raw_shape_deriv(3, j, p)
+ d1xd1y * clough_raw_shape_deriv(4, j, p)
+ d1xd2n * clough_raw_shape_deriv(10, j, p)
+ d1xd3n * clough_raw_shape_deriv(11, j, p);
case 2:
return d1yd1y * clough_raw_shape_deriv(4, j, p)
+ d1yd1x * clough_raw_shape_deriv(3, j, p)
+ d1yd2n * clough_raw_shape_deriv(10, j, p)
+ d1yd3n * clough_raw_shape_deriv(11, j, p);
case 4:
return d2xd2x * clough_raw_shape_deriv(5, j, p)
+ d2xd2y * clough_raw_shape_deriv(6, j, p)
+ d2xd3n * clough_raw_shape_deriv(11, j, p)
+ d2xd1n * clough_raw_shape_deriv(9, j, p);
case 5:
return d2yd2y * clough_raw_shape_deriv(6, j, p)
+ d2yd2x * clough_raw_shape_deriv(5, j, p)
+ d2yd3n * clough_raw_shape_deriv(11, j, p)
+ d2yd1n * clough_raw_shape_deriv(9, j, p);
case 7:
return d3xd3x * clough_raw_shape_deriv(7, j, p)
+ d3xd3y * clough_raw_shape_deriv(8, j, p)
+ d3xd1n * clough_raw_shape_deriv(9, j, p)
+ d3xd2n * clough_raw_shape_deriv(10, j, p);
case 8:
return d3yd3y * clough_raw_shape_deriv(8, j, p)
+ d3yd3x * clough_raw_shape_deriv(7, j, p)
+ d3yd1n * clough_raw_shape_deriv(9, j, p)
+ d3yd2n * clough_raw_shape_deriv(10, j, p);
case 10:
return d1nd1n * clough_raw_shape_deriv(9, j, p);
case 11:
return d2nd2n * clough_raw_shape_deriv(10, j, p);
case 9:
return d3nd3n * clough_raw_shape_deriv(11, j, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 235 of file fe_lagrange_shape_2D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::SECOND, libMeshEnums::TRI3, and libMeshEnums::TRI6.
{
#if LIBMESH_DIM > 1
libmesh_assert (j<2);
switch (order)
{
// linear Lagrange shape functions
case FIRST:
{
switch (type)
{
case QUAD4:
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<4);
// 0 1 2 3
static const unsigned int i0[] = {0, 1, 1, 0};
static const unsigned int i1[] = {0, 0, 1, 1};
switch (j)
{
// d()/dxi
case 0:
return (FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape (EDGE2, FIRST, i1[i], eta));
// d()/deta
case 1:
return (FE<1,LAGRANGE>::shape (EDGE2, FIRST, i0[i], xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i1[i], 0, eta));
default:
libmesh_error();
}
}
case TRI3:
case TRI6:
{
libmesh_assert (i<3);
const Real dzeta0dxi = -1.;
const Real dzeta1dxi = 1.;
const Real dzeta2dxi = 0.;
const Real dzeta0deta = -1.;
const Real dzeta1deta = 0.;
const Real dzeta2deta = 1.;
switch (j)
{
// d()/dxi
case 0:
{
switch(i)
{
case 0:
return dzeta0dxi;
case 1:
return dzeta1dxi;
case 2:
return dzeta2dxi;
default:
libmesh_error();
}
}
// d()/deta
case 1:
{
switch(i)
{
case 0:
return dzeta0deta;
case 1:
return dzeta1deta;
case 2:
return dzeta2deta;
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported 2D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// quadratic Lagrange shape functions
case SECOND:
{
switch (type)
{
case QUAD8:
{
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<8);
switch (j)
{
// d/dxi
case 0:
switch (i)
{
case 0:
return .25*(1. - eta)*((1. - xi)*(-1.) +
(-1.)*(-1. - xi - eta));
case 1:
return .25*(1. - eta)*((1. + xi)*(1.) +
(1.)*(-1. + xi - eta));
case 2:
return .25*(1. + eta)*((1. + xi)*(1.) +
(1.)*(-1. + xi + eta));
case 3:
return .25*(1. + eta)*((1. - xi)*(-1.) +
(-1.)*(-1. - xi + eta));
case 4:
return .5*(-2.*xi)*(1. - eta);
case 5:
return .5*(1.)*(1. - eta*eta);
case 6:
return .5*(-2.*xi)*(1. + eta);
case 7:
return .5*(-1.)*(1. - eta*eta);
default:
libmesh_error();
}
// d/deta
case 1:
switch (i)
{
case 0:
return .25*(1. - xi)*((1. - eta)*(-1.) +
(-1.)*(-1. - xi - eta));
case 1:
return .25*(1. + xi)*((1. - eta)*(-1.) +
(-1.)*(-1. + xi - eta));
case 2:
return .25*(1. + xi)*((1. + eta)*(1.) +
(1.)*(-1. + xi + eta));
case 3:
return .25*(1. - xi)*((1. + eta)*(1.) +
(1.)*(-1. - xi + eta));
case 4:
return .5*(1. - xi*xi)*(-1.);
case 5:
return .5*(1. + xi)*(-2.*eta);
case 6:
return .5*(1. - xi*xi)*(1.);
case 7:
return .5*(1. - xi)*(-2.*eta);
default:
libmesh_error();
}
default:
libmesh_error();
}
}
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<9);
// 0 1 2 3 4 5 6 7 8
static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
switch (j)
{
// d()/dxi
case 0:
return (FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i1[i], eta));
// d()/deta
case 1:
return (FE<1,LAGRANGE>::shape (EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i1[i], 0, eta));
default:
libmesh_error();
}
}
case TRI6:
{
libmesh_assert (i<6);
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta0 = 1. - zeta1 - zeta2;
const Real dzeta0dxi = -1.;
const Real dzeta1dxi = 1.;
const Real dzeta2dxi = 0.;
const Real dzeta0deta = -1.;
const Real dzeta1deta = 0.;
const Real dzeta2deta = 1.;
switch(j)
{
case 0:
{
switch(i)
{
case 0:
return (4.*zeta0-1.)*dzeta0dxi;
case 1:
return (4.*zeta1-1.)*dzeta1dxi;
case 2:
return (4.*zeta2-1.)*dzeta2dxi;
case 3:
return 4.*zeta1*dzeta0dxi + 4.*zeta0*dzeta1dxi;
case 4:
return 4.*zeta2*dzeta1dxi + 4.*zeta1*dzeta2dxi;
case 5:
return 4.*zeta2*dzeta0dxi + 4*zeta0*dzeta2dxi;
default:
libmesh_error();
}
}
case 1:
{
switch(i)
{
case 0:
return (4.*zeta0-1.)*dzeta0deta;
case 1:
return (4.*zeta1-1.)*dzeta1deta;
case 2:
return (4.*zeta2-1.)*dzeta2deta;
case 3:
return 4.*zeta1*dzeta0deta + 4.*zeta0*dzeta1deta;
case 4:
return 4.*zeta2*dzeta1deta + 4.*zeta1*dzeta2deta;
case 5:
return 4.*zeta2*dzeta0deta + 4*zeta0*dzeta2deta;
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported 2D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// unsupported order
default:
{
std::cerr << 'ERROR: Unsupported 2D FE order!: ' << order
<< std::endl;
libmesh_error();
}
}
libmesh_error();
return 0.;
#endif
}
Definition at line 1634 of file fe_clough_shape_2D.C.
{
std::cerr << 'Clough-Tocher elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 69 of file fe_bernstein_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 738 of file fe_szabab_shape_2D.C.
References libMeshEnums::EDGE3, libMeshEnums::FIFTH, libMeshEnums::FIRST, libMeshEnums::FOURTH, Elem::p_level(), Elem::point(), libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::SECOND, libMeshEnums::SEVENTH, FE< Dim, T >::shape(), FE< Dim, T >::shape_deriv(), libMeshEnums::SIXTH, libMeshEnums::THIRD, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 1st & 2nd-order Szabo-Babuska.
case FIRST:
case SECOND:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
// Here we use finite differences to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 6);
libmesh_assert (j < 2);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 9);
// 0 1 2 3 4 5 6 7 8
static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
switch (j)
{
// d()/dxi
case 0:
return (FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,SZABAB>::shape (EDGE3, totalorder, i1[i], eta));
// d()/deta
case 1:
return (FE<1,SZABAB>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// 3rd-order Szabo-Babuska.
case THIRD:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
// Here we use finite differences to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 10);
libmesh_assert (j < 2);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 16);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 7: // edge 1 points
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 9: // edge 2 points
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 11: // edge 3 points
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
switch (j)
{
// d()/dxi
case 0:
return f*(FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,SZABAB>::shape (EDGE3, totalorder, i1[i], eta));
// d()/deta
case 1:
return f*(FE<1,SZABAB>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// 4th-order Szabo-Babuska.
case FOURTH:
{
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
// Here we use finite differences to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 15);
libmesh_assert (j < 2);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
// Szabo-Babuska shape functions on the quadrilateral.
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 25);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 8: // edge 1 points
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 11: // edge 2 points
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 14: // edge 3 points
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
switch (j)
{
// d()/dxi
case 0:
return f*(FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,SZABAB>::shape (EDGE3, totalorder, i1[i], eta));
// d()/deta
case 1:
return f*(FE<1,SZABAB>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// 5th-order Szabo-Babuska.
case FIFTH:
{
// Szabo-Babuska shape functions on the quadrilateral.
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
// Here we use finite differences to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 21);
libmesh_assert (j < 2);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 36);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
case 7:
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 9: // edge 1 points
case 11:
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 13: // edge 2 points
case 15:
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 14: // edge 3 points
case 19:
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
switch (j)
{
// d()/dxi
case 0:
return f*(FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,SZABAB>::shape (EDGE3, totalorder, i1[i], eta));
// d()/deta
case 1:
return f*(FE<1,SZABAB>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// 6th-order Szabo-Babuska.
case SIXTH:
{
// Szabo-Babuska shape functions on the quadrilateral.
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
// Here we use finite differences to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 28);
libmesh_assert (j < 2);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 49);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
case 7:
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 10: // edge 1 points
case 12:
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 15: // edge 2 points
case 17:
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 20: // edge 3 points
case 22:
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
switch (j)
{
// d()/dxi
case 0:
return f*(FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,SZABAB>::shape (EDGE3, totalorder, i1[i], eta));
// d()/deta
case 1:
return f*(FE<1,SZABAB>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// 7th-order Szabo-Babuska.
case SEVENTH:
{
// Szabo-Babuska shape functions on the quadrilateral.
switch (type)
{
// Szabo-Babuska shape functions on the triangle.
case TRI6:
{
// Here we use finite differences to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 36);
libmesh_assert (j < 2);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,SZABAB>::shape(elem, order, i, pp) -
FE<2,SZABAB>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 64);
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7};
Real f=1.;
switch(i)
{
case 5: // edge 0 points
case 7:
case 9:
if (elem->point(0) > elem->point(1))f = -1.;
break;
case 11: // edge 1 points
case 13:
case 15:
if (elem->point(1) > elem->point(2))f = -1.;
break;
case 17: // edge 2 points
case 19:
case 21:
if (elem->point(3) > elem->point(2))f = -1.;
break;
case 23: // edge 3 points
case 25:
case 27:
if (elem->point(0) > elem->point(3))f = -1.;
break;
}
switch (j)
{
// d()/dxi
case 0:
return f*(FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,SZABAB>::shape (EDGE3, totalorder, i1[i], eta));
// d()/deta
case 1:
return f*(FE<1,SZABAB>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,SZABAB>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// by default throw an error;call the orientation-independent shape functions
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 69 of file fe_szabab_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 55 of file fe_bernstein_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
On a p-refined element, o should be the total order of the element.
Referenced by FE< Dim, T >::init_edge_shape_functions(), FE< Dim, T >::init_face_shape_functions(), FEXYZ< Dim >::init_shape_functions(), FE< Dim, T >::init_shape_functions(), FE< Dim, T >::map_eta(), FE< Dim, T >::map_xi(), FE< Dim, T >::map_zeta(), and FE< Dim, T >::shape_deriv().
Definition at line 1218 of file fe_lagrange_shape_3D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape function derivatives
return FE<3,LAGRANGE>::shape_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 159 of file fe_szabab_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,SZABAB>::shape_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 69 of file fe_lagrange_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 85 of file fe_monomial_shape_1D.C.
{
// only d()/dxi in 1D!
libmesh_assert (j == 0);
const Real xi = p(0);
libmesh_assert (i <= static_cast<unsigned int>(order));
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
case 0:
return 0.;
case 1:
return 1.;
case 2:
return 2.*xi;
case 3:
return 3.*xi*xi;
case 4:
return 4.*xi*xi*xi;
default:
Real val = i;
for (unsigned int index = 1; index != i; ++index)
val *= xi;
return val;
}
libmesh_error();
return 0.;
}
Definition at line 139 of file fe_lagrange_shape_1D.C.
References libMeshEnums::FIRST, libMeshEnums::SECOND, and libMeshEnums::THIRD.
{
// only d()/dxi in 1D!
libmesh_assert (j == 0);
const Real xi = p(0);
switch (order)
{
// Lagrange linear shape function derivatives
case FIRST:
{
libmesh_assert (i<2);
switch (i)
{
case 0:
return -.5;
case 1:
return .5;
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
}
// Lagrange quadratic shape function derivatives
case SECOND:
{
libmesh_assert (i<3);
switch (i)
{
case 0:
return xi-.5;
case 1:
return xi+.5;
case 2:
return -2.*xi;
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
}
// Lagrange cubic shape function derivatives
case THIRD:
{
libmesh_assert (i<4);
switch (i)
{
case 0:
return -9./16.*(3.*xi*xi-2.*xi-1./9.);
case 1:
return -9./16.*(-3.*xi*xi-2.*xi+1./9.);
case 2:
return 27./16.*(3.*xi*xi-2./3.*xi-1.);
case 3:
return 27./16.*(-3.*xi*xi-2./3.*xi+1.);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
}
libmesh_error();
return 0.;
}
Definition at line 69 of file fe_xyz_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 232 of file fe_clough_shape_3D.C.
References Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
std::cerr << '3D Clough elements not yet implemented.'
<< std::endl;
libmesh_error();
clough_compute_coefs(elem);
const ElemType type = elem->type();
switch (order+elem->p_level())
{
// 3rd-order Clough-Tocher element
case THIRD:
{
switch (type)
{
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 726 of file fe_hierarchic_shape_3D.C.
{
#if LIBMESH_DIM == 3
libmesh_assert (elem != NULL);
libmesh_assert (j < 3);
// cheat by using finite difference approximations:
const Real eps = 1.e-6;
Point pp, pm;
switch (j)
{
// d()/dxi
case 0:
{
pp = Point(p(0)+eps, p(1), p(2));
pm = Point(p(0)-eps, p(1), p(2));
break;
}
// d()/deta
case 1:
{
pp = Point(p(0), p(1)+eps, p(2));
pm = Point(p(0), p(1)-eps, p(2));
break;
}
// d()/dzeta
case 2:
{
pp = Point(p(0), p(1), p(2)+eps);
pm = Point(p(0), p(1), p(2)-eps);
break;
}
default:
libmesh_error();
}
return (FE<3,HIERARCHIC>::shape(elem, order, i, pp) -
FE<3,HIERARCHIC>::shape(elem, order, i, pm))/2./eps;
#endif
libmesh_error();
return 0.;
}
Definition at line 709 of file fe_hierarchic_shape_3D.C.
{
std::cerr << 'Hierarchic polynomials require the element type
<< 'because edge and face orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 385 of file fe_lagrange_shape_3D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, libMeshEnums::PRISM15, libMeshEnums::PRISM18, libMeshEnums::PRISM6, libMeshEnums::PYRAMID5, libMeshEnums::SECOND, libMeshEnums::TET10, libMeshEnums::TET4, libMeshEnums::TRI3, and libMeshEnums::TRI6.
{
#if LIBMESH_DIM == 3
libmesh_assert (j<3);
switch (order)
{
// linear Lagrange shape functions
case FIRST:
{
switch (type)
{
// trilinear hexahedral shape functions
case HEX8:
case HEX20:
case HEX27:
{
libmesh_assert (i<8);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
switch(j)
{
case 0:
return (FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape (EDGE2, FIRST, i1[i], eta)*
FE<1,LAGRANGE>::shape (EDGE2, FIRST, i2[i], zeta));
case 1:
return (FE<1,LAGRANGE>::shape (EDGE2, FIRST, i0[i], xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i1[i], 0, eta)*
FE<1,LAGRANGE>::shape (EDGE2, FIRST, i2[i], zeta));
case 2:
return (FE<1,LAGRANGE>::shape (EDGE2, FIRST, i0[i], xi)*
FE<1,LAGRANGE>::shape (EDGE2, FIRST, i1[i], eta)*
FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i2[i], 0, zeta));
default:
{
libmesh_error();
}
}
}
// linear tetrahedral shape functions
case TET4:
case TET10:
{
libmesh_assert (i<4);
// Area coordinates, pg. 205, Vol. I, Carey, Oden, Becker FEM
const Real dzeta0dxi = -1.;
const Real dzeta1dxi = 1.;
const Real dzeta2dxi = 0.;
const Real dzeta3dxi = 0.;
const Real dzeta0deta = -1.;
const Real dzeta1deta = 0.;
const Real dzeta2deta = 1.;
const Real dzeta3deta = 0.;
const Real dzeta0dzeta = -1.;
const Real dzeta1dzeta = 0.;
const Real dzeta2dzeta = 0.;
const Real dzeta3dzeta = 1.;
switch (j)
{
// d()/dxi
case 0:
{
switch(i)
{
case 0:
return dzeta0dxi;
case 1:
return dzeta1dxi;
case 2:
return dzeta2dxi;
case 3:
return dzeta3dxi;
default:
libmesh_error();
}
}
// d()/deta
case 1:
{
switch(i)
{
case 0:
return dzeta0deta;
case 1:
return dzeta1deta;
case 2:
return dzeta2deta;
case 3:
return dzeta3deta;
default:
libmesh_error();
}
}
// d()/dzeta
case 2:
{
switch(i)
{
case 0:
return dzeta0dzeta;
case 1:
return dzeta1dzeta;
case 2:
return dzeta2dzeta;
case 3:
return dzeta3dzeta;
default:
libmesh_error();
}
}
}
}
// linear prism shape functions
case PRISM6:
case PRISM15:
case PRISM18:
{
libmesh_assert (i<6);
// Compute prism shape functions as a tensor-product
// of a triangle and an edge
Point p2d(p(0),p(1));
Point p1d(p(2));
// 0 1 2 3 4 5
static const unsigned int i0[] = {0, 0, 0, 1, 1, 1};
static const unsigned int i1[] = {0, 1, 2, 0, 1, 2};
switch (j)
{
// d()/dxi
case 0:
return (FE<2,LAGRANGE>::shape_deriv(TRI3, FIRST, i1[i], 0, p2d)*
FE<1,LAGRANGE>::shape(EDGE2, FIRST, i0[i], p1d));
// d()/deta
case 1:
return (FE<2,LAGRANGE>::shape_deriv(TRI3, FIRST, i1[i], 1, p2d)*
FE<1,LAGRANGE>::shape(EDGE2, FIRST, i0[i], p1d));
// d()/dzeta
case 2:
return (FE<2,LAGRANGE>::shape(TRI3, FIRST, i1[i], p2d)*
FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i0[i], 0, p1d));
}
}
// linear pyramid shape functions
case PYRAMID5:
{
libmesh_assert (i<5);
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
const Real eps = 1.e-35;
switch (j)
{
// d/dxi
case 0:
switch(i)
{
case 0:
return .25*(zeta + eta - 1.)/((1. - zeta) + eps);
case 1:
return -.25*(zeta + eta - 1.)/((1. - zeta) + eps);
case 2:
return -.25*(zeta - eta - 1.)/((1. - zeta) + eps);
case 3:
return .25*(zeta - eta - 1.)/((1. - zeta) + eps);
case 4:
return 0;
default:
libmesh_error();
}
// d/deta
case 1:
switch(i)
{
case 0:
return .25*(zeta + xi - 1.)/((1. - zeta) + eps);
case 1:
return .25*(zeta - xi - 1.)/((1. - zeta) + eps);
case 2:
return -.25*(zeta - xi - 1.)/((1. - zeta) + eps);
case 3:
return -.25*(zeta + xi - 1.)/((1. - zeta) + eps);
case 4:
return 0;
default:
libmesh_error();
}
// d/dzeta
case 2:
switch(i)
{
case 0:
{
const Real a=1.;
const Real b=1.;
return .25*(((zeta + a*xi - 1.)*(zeta + b*eta - 1.) +
(1. - zeta)*((zeta + a*xi -1.) + (zeta + b*eta - 1.)))/
((1. - zeta)*(1. - zeta) + eps));
}
case 1:
{
const Real a=-1.;
const Real b=1.;
return .25*(((zeta + a*xi - 1.)*(zeta + b*eta - 1.) +
(1. - zeta)*((zeta + a*xi -1.) + (zeta + b*eta - 1.)))/
((1. - zeta)*(1. - zeta) + eps));
}
case 2:
{
const Real a=-1.;
const Real b=-1.;
return .25*(((zeta + a*xi - 1.)*(zeta + b*eta - 1.) +
(1. - zeta)*((zeta + a*xi -1.) + (zeta + b*eta - 1.)))/
((1. - zeta)*(1. - zeta) + eps));
}
case 3:
{
const Real a=1.;
const Real b=-1.;
return .25*(((zeta + a*xi - 1.)*(zeta + b*eta - 1.) +
(1. - zeta)*((zeta + a*xi -1.) + (zeta + b*eta - 1.)))/
((1. - zeta)*(1. - zeta) + eps));
}
case 4:
return 1.;
default:
libmesh_error();
}
default:
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported 3D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// quadratic Lagrange shape functions
case SECOND:
{
switch (type)
{
// serendipity hexahedral quadratic shape functions
case HEX20:
{
libmesh_assert (i<20);
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// these functions are defined for (x,y,z) in [0,1]^3
// so transform the locations
const Real x = .5*(xi + 1.);
const Real y = .5*(eta + 1.);
const Real z = .5*(zeta + 1.);
// and don't forget the chain rule!
switch (j)
{
// d/dx*dx/dxi
case 0:
switch (i)
{
case 0:
return .5*(1. - y)*(1. - z)*((1. - x)*(-2.) +
(-1.)*(1. - 2.*x - 2.*y - 2.*z));
libmesh_error(); // done to here
case 1:
return .5*(1. - y)*(1. - z)*(x*(2.) +
(1.)*(2.*x - 2.*y - 2.*z - 1.));
case 2:
return .5*y*(1. - z)*(x*(2.) +
(1.)*(2.*x + 2.*y - 2.*z - 3.));
case 3:
return .5*y*(1. - z)*((1. - x)*(-2.) +
(-1.)*(2.*y - 2.*x - 2.*z - 1.));
case 4:
return .5*(1. - y)*z*((1. - x)*(-2.) +
(-1.)*(2.*z - 2.*x - 2.*y - 1.));
case 5:
return .5*(1. - y)*z*(x*(2.) +
(1.)*(2.*x - 2.*y + 2.*z - 3.));
case 6:
return .5*y*z*(x*(2.) +
(1.)*(2.*x + 2.*y + 2.*z - 5.));
case 7:
return .5*y*z*((1. - x)*(-2.) +
(-1.)*(2.*y - 2.*x + 2.*z - 3.));
case 8:
return 2.*(1. - y)*(1. - z)*(1. - 2.*x);
case 9:
return 2.*y*(1. - y)*(1. - z);
case 10:
return 2.*y*(1. - z)*(1. - 2.*x);
case 11:
return 2.*y*(1. - y)*(1. - z)*(-1.);
case 12:
return 2.*(1. - y)*z*(1. - z)*(-1.);
case 13:
return 2.*(1. - y)*z*(1. - z);
case 14:
return 2.*y*z*(1. - z);
case 15:
return 2.*y*z*(1. - z)*(-1.);
case 16:
return 2.*(1. - y)*z*(1. - 2.*x);
case 17:
return 2.*y*(1. - y)*z;
case 18:
return 2.*y*z*(1. - 2.*x);
case 19:
return 2.*y*(1. - y)*z*(-1.);
default:
libmesh_error();
}
// d/dy*dy/deta
case 1:
switch (i)
{
case 0:
return .5*(1. - x)*(1. - z)*((1. - y)*(-2.) +
(-1.)*(1. - 2.*x - 2.*y - 2.*z));
case 1:
return .5*x*(1. - z)*((1. - y)*(-2.) +
(-1.)*(2.*x - 2.*y - 2.*z - 1.));
case 2:
return .5*x*(1. - z)*(y*(2.) +
(1.)*(2.*x + 2.*y - 2.*z - 3.));
case 3:
return .5*(1. - x)*(1. - z)*(y*(2.) +
(1.)*(2.*y - 2.*x - 2.*z - 1.));
case 4:
return .5*(1. - x)*z*((1. - y)*(-2.) +
(-1.)*(2.*z - 2.*x - 2.*y - 1.));
case 5:
return .5*x*z*((1. - y)*(-2.) +
(-1.)*(2.*x - 2.*y + 2.*z - 3.));
case 6:
return .5*x*z*(y*(2.) +
(1.)*(2.*x + 2.*y + 2.*z - 5.));
case 7:
return .5*(1. - x)*z*(y*(2.) +
(1.)*(2.*y - 2.*x + 2.*z - 3.));
case 8:
return 2.*x*(1. - x)*(1. - z)*(-1.);
case 9:
return 2.*x*(1. - z)*(1. - 2.*y);
case 10:
return 2.*x*(1. - x)*(1. - z);
case 11:
return 2.*(1. - x)*(1. - z)*(1. - 2.*y);
case 12:
return 2.*(1. - x)*z*(1. - z)*(-1.);
case 13:
return 2.*x*z*(1. - z)*(-1.);
case 14:
return 2.*x*z*(1. - z);
case 15:
return 2.*(1. - x)*z*(1. - z);
case 16:
return 2.*x*(1. - x)*z*(-1.);
case 17:
return 2.*x*z*(1. - 2.*y);
case 18:
return 2.*x*(1. - x)*z;
case 19:
return 2.*(1. - x)*z*(1. - 2.*y);
default:
libmesh_error();
}
// d/dz*dz/dzeta
case 2:
switch (i)
{
case 0:
return .5*(1. - x)*(1. - y)*((1. - z)*(-2.) +
(-1.)*(1. - 2.*x - 2.*y - 2.*z));
case 1:
return .5*x*(1. - y)*((1. - z)*(-2.) +
(-1.)*(2.*x - 2.*y - 2.*z - 1.));
case 2:
return .5*x*y*((1. - z)*(-2.) +
(-1.)*(2.*x + 2.*y - 2.*z - 3.));
case 3:
return .5*(1. - x)*y*((1. - z)*(-2.) +
(-1.)*(2.*y - 2.*x - 2.*z - 1.));
case 4:
return .5*(1. - x)*(1. - y)*(z*(2.) +
(1.)*(2.*z - 2.*x - 2.*y - 1.));
case 5:
return .5*x*(1. - y)*(z*(2.) +
(1.)*(2.*x - 2.*y + 2.*z - 3.));
case 6:
return .5*x*y*(z*(2.) +
(1.)*(2.*x + 2.*y + 2.*z - 5.));
case 7:
return .5*(1. - x)*y*(z*(2.) +
(1.)*(2.*y - 2.*x + 2.*z - 3.));
case 8:
return 2.*x*(1. - x)*(1. - y)*(-1.);
case 9:
return 2.*x*y*(1. - y)*(-1.);
case 10:
return 2.*x*(1. - x)*y*(-1.);
case 11:
return 2.*(1. - x)*y*(1. - y)*(-1.);
case 12:
return 2.*(1. - x)*(1. - y)*(1. - 2.*z);
case 13:
return 2.*x*(1. - y)*(1. - 2.*z);
case 14:
return 2.*x*y*(1. - 2.*z);
case 15:
return 2.*(1. - x)*y*(1. - 2.*z);
case 16:
return 2.*x*(1. - x)*(1. - y);
case 17:
return 2.*x*y*(1. - y);
case 18:
return 2.*x*(1. - x)*y;
case 19:
return 2.*(1. - x)*y*(1. - y);
default:
libmesh_error();
}
}
}
// triquadraic hexahedral shape funcions
case HEX27:
{
libmesh_assert (i<27);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
switch(j)
{
case 0:
return (FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i1[i], eta)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i2[i], zeta));
case 1:
return (FE<1,LAGRANGE>::shape (EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i1[i], 0, eta)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i2[i], zeta));
case 2:
return (FE<1,LAGRANGE>::shape (EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i1[i], eta)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i2[i], 0, zeta));
default:
{
libmesh_error();
}
}
}
// quadratic tetrahedral shape functions
case TET10:
{
libmesh_assert (i<10);
// Area coordinates, pg. 205, Vol. I, Carey, Oden, Becker FEM
const Real zeta1 = p(0);
const Real zeta2 = p(1);
const Real zeta3 = p(2);
const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
const Real dzeta0dxi = -1.;
const Real dzeta1dxi = 1.;
const Real dzeta2dxi = 0.;
const Real dzeta3dxi = 0.;
const Real dzeta0deta = -1.;
const Real dzeta1deta = 0.;
const Real dzeta2deta = 1.;
const Real dzeta3deta = 0.;
const Real dzeta0dzeta = -1.;
const Real dzeta1dzeta = 0.;
const Real dzeta2dzeta = 0.;
const Real dzeta3dzeta = 1.;
switch (j)
{
// d()/dxi
case 0:
{
switch(i)
{
case 0:
return (4.*zeta0 - 1.)*dzeta0dxi;
case 1:
return (4.*zeta1 - 1.)*dzeta1dxi;
case 2:
return (4.*zeta2 - 1.)*dzeta2dxi;
case 3:
return (4.*zeta3 - 1.)*dzeta3dxi;
case 4:
return 4.*(zeta0*dzeta1dxi + dzeta0dxi*zeta1);
case 5:
return 4.*(zeta1*dzeta2dxi + dzeta1dxi*zeta2);
case 6:
return 4.*(zeta0*dzeta2dxi + dzeta0dxi*zeta2);
case 7:
return 4.*(zeta0*dzeta3dxi + dzeta0dxi*zeta3);
case 8:
return 4.*(zeta1*dzeta3dxi + dzeta1dxi*zeta3);
case 9:
return 4.*(zeta2*dzeta3dxi + dzeta2dxi*zeta3);
default:
libmesh_error();
}
}
// d()/deta
case 1:
{
switch(i)
{
case 0:
return (4.*zeta0 - 1.)*dzeta0deta;
case 1:
return (4.*zeta1 - 1.)*dzeta1deta;
case 2:
return (4.*zeta2 - 1.)*dzeta2deta;
case 3:
return (4.*zeta3 - 1.)*dzeta3deta;
case 4:
return 4.*(zeta0*dzeta1deta + dzeta0deta*zeta1);
case 5:
return 4.*(zeta1*dzeta2deta + dzeta1deta*zeta2);
case 6:
return 4.*(zeta0*dzeta2deta + dzeta0deta*zeta2);
case 7:
return 4.*(zeta0*dzeta3deta + dzeta0deta*zeta3);
case 8:
return 4.*(zeta1*dzeta3deta + dzeta1deta*zeta3);
case 9:
return 4.*(zeta2*dzeta3deta + dzeta2deta*zeta3);
default:
libmesh_error();
}
}
// d()/dzeta
case 2:
{
switch(i)
{
case 0:
return (4.*zeta0 - 1.)*dzeta0dzeta;
case 1:
return (4.*zeta1 - 1.)*dzeta1dzeta;
case 2:
return (4.*zeta2 - 1.)*dzeta2dzeta;
case 3:
return (4.*zeta3 - 1.)*dzeta3dzeta;
case 4:
return 4.*(zeta0*dzeta1dzeta + dzeta0dzeta*zeta1);
case 5:
return 4.*(zeta1*dzeta2dzeta + dzeta1dzeta*zeta2);
case 6:
return 4.*(zeta0*dzeta2dzeta + dzeta0dzeta*zeta2);
case 7:
return 4.*(zeta0*dzeta3dzeta + dzeta0dzeta*zeta3);
case 8:
return 4.*(zeta1*dzeta3dzeta + dzeta1dzeta*zeta3);
case 9:
return 4.*(zeta2*dzeta3dzeta + dzeta2dzeta*zeta3);
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// quadradic prism shape functions
case PRISM18:
{
libmesh_assert (i<18);
// Compute prism shape functions as a tensor-product
// of a triangle and an edge
Point p2d(p(0),p(1));
Point p1d(p(2));
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
static const unsigned int i0[] = {0, 0, 0, 1, 1, 1, 0, 0, 0, 2, 2, 2, 1, 1, 1, 2, 2, 2};
static const unsigned int i1[] = {0, 1, 2, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 3, 4, 5};
switch (j)
{
// d()/dxi
case 0:
return (FE<2,LAGRANGE>::shape_deriv(TRI6, SECOND, i1[i], 0, p2d)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], p1d));
// d()/deta
case 1:
return (FE<2,LAGRANGE>::shape_deriv(TRI6, SECOND, i1[i], 1, p2d)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], p1d));
// d()/dzeta
case 2:
return (FE<2,LAGRANGE>::shape(TRI6, SECOND, i1[i], p2d)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, p1d));
}
}
default:
{
std::cerr << 'ERROR: Unsupported 3D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// unsupported order
default:
{
std::cerr << 'ERROR: Unsupported 3D FE order!: ' << order
<< std::endl;
libmesh_error();
}
}
#endif
libmesh_error();
return 0.;
}
Definition at line 55 of file fe_monomial_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 55 of file fe_hermite_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 132 of file fe_monomial_shape_2D.C.
{
#if LIBMESH_DIM > 1
libmesh_assert (j<2);
libmesh_assert (i < (static_cast<unsigned int>(order)+1)*
(static_cast<unsigned int>(order)+2)/2);
const Real xi = p(0);
const Real eta = p(1);
// monomials. since they are hierarchic we only need one case block.
switch (j)
{
// d()/dxi
case 0:
{
switch (i)
{
// constants
case 0:
return 0.;
// linears
case 1:
return 1.;
case 2:
return 0.;
// quadratics
case 3:
return 2.*xi;
case 4:
return eta;
case 5:
return 0.;
// cubics
case 6:
return 3.*xi*xi;
case 7:
return 2.*xi*eta;
case 8:
return eta*eta;
case 9:
return 0.;
// quartics
case 10:
return 4.*xi*xi*xi;
case 11:
return 3.*xi*xi*eta;
case 12:
return 2.*xi*eta*eta;
case 13:
return eta*eta*eta;
case 14:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int ny = i - (o*(o+1)/2);
unsigned int nx = o - ny;
Real val = nx;
for (unsigned int index=1; index < nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
return val;
}
}
// d()/deta
case 1:
{
switch (i)
{
// constants
case 0:
return 0.;
// linears
case 1:
return 0.;
case 2:
return 1.;
// quadratics
case 3:
return 0.;
case 4:
return xi;
case 5:
return 2.*eta;
// cubics
case 6:
return 0.;
case 7:
return xi*xi;
case 8:
return 2.*xi*eta;
case 9:
return 3.*eta*eta;
// quartics
case 10:
return 0.;
case 11:
return xi*xi*xi;
case 12:
return 2.*xi*xi*eta;
case 13:
return 3.*xi*eta*eta;
case 14:
return 4.*eta*eta*eta;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int ny = i - (o*(o+1)/2);
unsigned int nx = o - ny;
Real val = ny;
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=1; index < ny; index++)
val *= eta;
return val;
}
}
}
libmesh_error();
return 0.;
#endif
}
Definition at line 302 of file fe_monomial_shape_2D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// by default call the orientation-independent shape functions
return FE<2,MONOMIAL>::shape_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 69 of file fe_hermite_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 1406 of file fe_bernstein_shape_3D.C.
References libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::FOURTH, libMeshEnums::HEX20, libMeshEnums::HEX27, Elem::p_level(), libMeshEnums::SECOND, libMeshEnums::TET10, libMeshEnums::TET4, libMeshEnums::THIRD, and Elem::type().
{
#if LIBMESH_DIM == 3
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
libmesh_assert (j < 3);
switch (totalorder)
{
// 1st order Bernstein.
case FIRST:
{
switch (type)
{
// Bernstein shape functions on the tetrahedron.
case TET4:
case TET10:
{
// I have been lazy here and am using finite differences
// to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 4);
libmesh_assert (j < 3);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1), p(2));
const Point pm(p(0)-eps, p(1), p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps, p(2));
const Point pm(p(0), p(1)-eps, p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/dzeta
case 2:
{
const Point pp(p(0), p(1), p(2)+eps);
const Point pm(p(0), p(1), p(2)-eps);
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
// Bernstein shape functions on the hexahedral.
case HEX20:
case HEX27:
{
libmesh_assert (i<8);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
switch (j)
{
// d()/dxi
case 0:
return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta));
// d()/deta
case 1:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta));
// d()/dzeta
case 2:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
case SECOND:
{
switch (type)
{
// Bernstein shape functions on the tetrahedron.
case TET10:
{
// I have been lazy here and am using finite differences
// to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i <10);
libmesh_assert (j < 3);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1), p(2));
const Point pm(p(0)-eps, p(1), p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps, p(2));
const Point pm(p(0), p(1)-eps, p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/dzeta
case 2:
{
const Point pp(p(0), p(1), p(2)+eps);
const Point pm(p(0), p(1), p(2)-eps);
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
// Bernstein shape functions on the hexahedral.
case HEX20:
{
libmesh_assert (i<20);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
static const Real scal20[] = {-0.25, -0.25, -0.25, -0.25, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0};
static const Real scal21[] = {-0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0, 0};
static const Real scal22[] = {0, -0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0};
static const Real scal23[] = {0, 0, -0.25, -0.25, 0, 0, -0.25, -0.25, 0, 0, 0.5, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0};
static const Real scal24[] = {-0.25, 0, 0, -0.25, -0.25, 0, 0, -0.25, 0, 0, 0, 0.5, 0.5, 0, 0, 0.5, 0, 0, 0, 0.5};
static const Real scal25[] = {0, 0, 0, 0, -0.25, -0.25, -0.25, -0.25, 0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0.5};
static const Real scal26[] = {-0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, -0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25};
switch (j)
{
// d()/dxi
case 0:
return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta)
+scal20[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[20], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[20], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[20], zeta)
+scal21[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[21], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[21], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[21], zeta)
+scal22[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[22], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[22], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[22], zeta)
+scal23[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[23], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[23], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[23], zeta)
+scal24[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[24], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[24], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[24], zeta)
+scal25[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[25], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[25], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[25], zeta)
+scal26[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[26], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[26], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[26], zeta));
// d()/deta
case 1:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta)
+scal20[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[20], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[20], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[20], zeta)
+scal21[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[21], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[21], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[21], zeta)
+scal22[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[22], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[22], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[22], zeta)
+scal23[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[23], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[23], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[23], zeta)
+scal24[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[24], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[24], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[24], zeta)
+scal25[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[25], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[25], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[25], zeta)
+scal26[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[26], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[26], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[26], zeta));
// d()/dzeta
case 2:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta)
+scal20[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[20], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[20], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[20], 0, zeta)
+scal21[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[21], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[21], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[21], 0, zeta)
+scal22[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[22], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[22], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[22], 0, zeta)
+scal23[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[23], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[23], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[23], 0, zeta)
+scal24[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[24], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[24], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[24], 0, zeta)
+scal25[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[25], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[25], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[25], 0, zeta)
+scal26[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[26], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[26], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[26], 0, zeta));
default:
libmesh_error();
}
}
// Bernstein shape functions on the hexahedral.
case HEX27:
{
libmesh_assert (i<27);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
switch (j)
{
// d()/dxi
case 0:
return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta));
// d()/deta
case 1:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta));
// d()/dzeta
case 2:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta));
default:
libmesh_error();
}
}
default:
libmesh_error();
}
}
// 3rd-order Bernstein.
case THIRD:
{
switch (type)
{
// // Bernstein shape functions derivatives.
// case TET10:
// {
// // I have been lazy here and am using finite differences
// // to compute the derivatives!
// const Real eps = 1.e-6;
// libmesh_assert (i < 20);
// libmesh_assert (j < 3);
// switch (j)
// {
// // d()/dxi
// case 0:
// {
// const Point pp(p(0)+eps, p(1), p(2));
// const Point pm(p(0)-eps, p(1), p(2));
// return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
// FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
// }
// // d()/deta
// case 1:
// {
// const Point pp(p(0), p(1)+eps, p(2));
// const Point pm(p(0), p(1)-eps, p(2));
// return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
// FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
// }
// // d()/dzeta
// case 2:
// {
// const Point pp(p(0), p(1), p(2)+eps);
// const Point pm(p(0), p(1), p(2)-eps);
// return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
// FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
// }
// default:
// libmesh_error();
// }
// }
// Bernstein shape functions on the hexahedral.
case HEX27:
{
// I have been lazy here and am using finite differences
// to compute the derivatives!
const Real eps = 1.e-6;
libmesh_assert (i < 64);
libmesh_assert (j < 3);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1), p(2));
const Point pm(p(0)-eps, p(1), p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps, p(2));
const Point pm(p(0), p(1)-eps, p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/dzeta
case 2:
{
const Point pp(p(0), p(1), p(2)+eps);
const Point pm(p(0), p(1), p(2)-eps);
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
// // Compute hex shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// const Real zeta = p(2);
// Real xi_mapped = p(0);
// Real eta_mapped = p(1);
// Real zeta_mapped = p(2);
// // The only way to make any sense of this
// // is to look at the mgflo/mg2/mgf documentation
// // and make the cut-out cube!
// // Nodes 0 1 2 3 4 5 6 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
// // DOFS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63
// static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3, 0, 0, 0, 0, 2, 3, 2, 3, 1, 1, 1, 1, 2, 3, 2, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3};
// static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 2, 3, 2, 3, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3};
// // handle the edge orientation
// {
// // Edge 0
// if ((i1[i] == 0) && (i2[i] == 0))
// {
// if (elem->node(0) != std::min(elem->node(0), elem->node(1)))
// xi_mapped = -xi;
// }
// // Edge 1
// else if ((i0[i] == 1) && (i2[i] == 0))
// {
// if (elem->node(1) != std::min(elem->node(1), elem->node(2)))
// eta_mapped = -eta;
// }
// // Edge 2
// else if ((i1[i] == 1) && (i2[i] == 0))
// {
// if (elem->node(3) != std::min(elem->node(3), elem->node(2)))
// xi_mapped = -xi;
// }
// // Edge 3
// else if ((i0[i] == 0) && (i2[i] == 0))
// {
// if (elem->node(0) != std::min(elem->node(0), elem->node(3)))
// eta_mapped = -eta;
// }
// // Edge 4
// else if ((i0[i] == 0) && (i1[i] == 0))
// {
// if (elem->node(0) != std::min(elem->node(0), elem->node(4)))
// zeta_mapped = -zeta;
// }
// // Edge 5
// else if ((i0[i] == 1) && (i1[i] == 0))
// {
// if (elem->node(1) != std::min(elem->node(1), elem->node(5)))
// zeta_mapped = -zeta;
// }
// // Edge 6
// else if ((i0[i] == 1) && (i1[i] == 1))
// {
// if (elem->node(2) != std::min(elem->node(2), elem->node(6)))
// zeta_mapped = -zeta;
// }
// // Edge 7
// else if ((i0[i] == 0) && (i1[i] == 1))
// {
// if (elem->node(3) != std::min(elem->node(3), elem->node(7)))
// zeta_mapped = -zeta;
// }
// // Edge 8
// else if ((i1[i] == 0) && (i2[i] == 1))
// {
// if (elem->node(4) != std::min(elem->node(4), elem->node(5)))
// xi_mapped = -xi;
// }
// // Edge 9
// else if ((i0[i] == 1) && (i2[i] == 1))
// {
// if (elem->node(5) != std::min(elem->node(5), elem->node(6)))
// eta_mapped = -eta;
// }
// // Edge 10
// else if ((i1[i] == 1) && (i2[i] == 1))
// {
// if (elem->node(7) != std::min(elem->node(7), elem->node(6)))
// xi_mapped = -xi;
// }
// // Edge 11
// else if ((i0[i] == 0) && (i2[i] == 1))
// {
// if (elem->node(4) != std::min(elem->node(4), elem->node(7)))
// eta_mapped = -eta;
// }
// }
// // handle the face orientation
// {
// // Face 0
// if ( (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(1),
// std::min(elem->node(2),
// std::min(elem->node(0),
// elem->node(3))));
// if (elem->node(0) == min_node)
// if (elem->node(1) == std::min(elem->node(1), elem->node(3)))
// {
// // Case 1
// xi_mapped = xi;
// eta_mapped = eta;
// }
// else
// {
// // Case 2
// xi_mapped = eta;
// eta_mapped = xi;
// }
// else if (elem->node(3) == min_node)
// if (elem->node(0) == std::min(elem->node(0), elem->node(2)))
// {
// // Case 3
// xi_mapped = -eta;
// eta_mapped = xi;
// }
// else
// {
// // Case 4
// xi_mapped = xi;
// eta_mapped = -eta;
// }
// else if (elem->node(2) == min_node)
// if (elem->node(3) == std::min(elem->node(3), elem->node(1)))
// {
// // Case 5
// xi_mapped = -xi;
// eta_mapped = -eta;
// }
// else
// {
// // Case 6
// xi_mapped = -eta;
// eta_mapped = -xi;
// }
// else if (elem->node(1) == min_node)
// if (elem->node(2) == std::min(elem->node(2), elem->node(0)))
// {
// // Case 7
// xi_mapped = eta;
// eta_mapped = -xi;
// }
// else
// {
// // Case 8
// xi_mapped = -xi;
// eta_mapped = eta;
// }
// }
// // Face 1
// else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(0),
// std::min(elem->node(1),
// std::min(elem->node(5),
// elem->node(4))));
// if (elem->node(0) == min_node)
// if (elem->node(1) == std::min(elem->node(1), elem->node(4)))
// {
// // Case 1
// xi_mapped = xi;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// xi_mapped = zeta;
// zeta_mapped = xi;
// }
// else if (elem->node(1) == min_node)
// if (elem->node(5) == std::min(elem->node(5), elem->node(0)))
// {
// // Case 3
// xi_mapped = zeta;
// zeta_mapped = -xi;
// }
// else
// {
// // Case 4
// xi_mapped = -xi;
// zeta_mapped = zeta;
// }
// else if (elem->node(5) == min_node)
// if (elem->node(4) == std::min(elem->node(4), elem->node(1)))
// {
// // Case 5
// xi_mapped = -xi;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// xi_mapped = -zeta;
// zeta_mapped = -xi;
// }
// else if (elem->node(4) == min_node)
// if (elem->node(0) == std::min(elem->node(0), elem->node(5)))
// {
// // Case 7
// xi_mapped = -xi;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 8
// xi_mapped = xi;
// zeta_mapped = -zeta;
// }
// }
// // Face 2
// else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(1),
// std::min(elem->node(2),
// std::min(elem->node(6),
// elem->node(5))));
// if (elem->node(1) == min_node)
// if (elem->node(2) == std::min(elem->node(2), elem->node(5)))
// {
// // Case 1
// eta_mapped = eta;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// eta_mapped = zeta;
// zeta_mapped = eta;
// }
// else if (elem->node(2) == min_node)
// if (elem->node(6) == std::min(elem->node(6), elem->node(1)))
// {
// // Case 3
// eta_mapped = zeta;
// zeta_mapped = -eta;
// }
// else
// {
// // Case 4
// eta_mapped = -eta;
// zeta_mapped = zeta;
// }
// else if (elem->node(6) == min_node)
// if (elem->node(5) == std::min(elem->node(5), elem->node(2)))
// {
// // Case 5
// eta_mapped = -eta;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// eta_mapped = -zeta;
// zeta_mapped = -eta;
// }
// else if (elem->node(5) == min_node)
// if (elem->node(1) == std::min(elem->node(1), elem->node(6)))
// {
// // Case 7
// eta_mapped = -zeta;
// zeta_mapped = eta;
// }
// else
// {
// // Case 8
// eta_mapped = eta;
// zeta_mapped = -zeta;
// }
// }
// // Face 3
// else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(2),
// std::min(elem->node(3),
// std::min(elem->node(7),
// elem->node(6))));
// if (elem->node(3) == min_node)
// if (elem->node(2) == std::min(elem->node(2), elem->node(7)))
// {
// // Case 1
// xi_mapped = xi;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// xi_mapped = zeta;
// zeta_mapped = xi;
// }
// else if (elem->node(7) == min_node)
// if (elem->node(3) == std::min(elem->node(3), elem->node(6)))
// {
// // Case 3
// xi_mapped = -zeta;
// zeta_mapped = xi;
// }
// else
// {
// // Case 4
// xi_mapped = xi;
// zeta_mapped = -zeta;
// }
// else if (elem->node(6) == min_node)
// if (elem->node(7) == std::min(elem->node(7), elem->node(2)))
// {
// // Case 5
// xi_mapped = -xi;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// xi_mapped = -zeta;
// zeta_mapped = -xi;
// }
// else if (elem->node(2) == min_node)
// if (elem->node(6) == std::min(elem->node(3), elem->node(6)))
// {
// // Case 7
// xi_mapped = zeta;
// zeta_mapped = -xi;
// }
// else
// {
// // Case 8
// xi_mapped = -xi;
// zeta_mapped = zeta;
// }
// }
// // Face 4
// else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(3),
// std::min(elem->node(0),
// std::min(elem->node(4),
// elem->node(7))));
// if (elem->node(0) == min_node)
// if (elem->node(3) == std::min(elem->node(3), elem->node(4)))
// {
// // Case 1
// eta_mapped = eta;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// eta_mapped = zeta;
// zeta_mapped = eta;
// }
// else if (elem->node(4) == min_node)
// if (elem->node(0) == std::min(elem->node(0), elem->node(7)))
// {
// // Case 3
// eta_mapped = -zeta;
// zeta_mapped = eta;
// }
// else
// {
// // Case 4
// eta_mapped = eta;
// zeta_mapped = -zeta;
// }
// else if (elem->node(7) == min_node)
// if (elem->node(4) == std::min(elem->node(4), elem->node(3)))
// {
// // Case 5
// eta_mapped = -eta;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// eta_mapped = -zeta;
// zeta_mapped = -eta;
// }
// else if (elem->node(3) == min_node)
// if (elem->node(7) == std::min(elem->node(7), elem->node(0)))
// {
// // Case 7
// eta_mapped = zeta;
// zeta_mapped = -eta;
// }
// else
// {
// // Case 8
// eta_mapped = -eta;
// zeta_mapped = zeta;
// }
// }
// // Face 5
// else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(4),
// std::min(elem->node(5),
// std::min(elem->node(6),
// elem->node(7))));
// if (elem->node(4) == min_node)
// if (elem->node(5) == std::min(elem->node(5), elem->node(7)))
// {
// // Case 1
// xi_mapped = xi;
// eta_mapped = eta;
// }
// else
// {
// // Case 2
// xi_mapped = eta;
// eta_mapped = xi;
// }
// else if (elem->node(5) == min_node)
// if (elem->node(6) == std::min(elem->node(6), elem->node(4)))
// {
// // Case 3
// xi_mapped = eta;
// eta_mapped = -xi;
// }
// else
// {
// // Case 4
// xi_mapped = -xi;
// eta_mapped = eta;
// }
// else if (elem->node(6) == min_node)
// if (elem->node(7) == std::min(elem->node(7), elem->node(5)))
// {
// // Case 5
// xi_mapped = -xi;
// eta_mapped = -eta;
// }
// else
// {
// // Case 6
// xi_mapped = -eta;
// eta_mapped = -xi;
// }
// else if (elem->node(7) == min_node)
// if (elem->node(4) == std::min(elem->node(4), elem->node(6)))
// {
// // Case 7
// xi_mapped = -eta;
// eta_mapped = xi;
// }
// else
// {
// // Case 8
// xi_mapped = xi;
// eta_mapped = eta;
// }
// }
// }
// libmesh_assert (j < 3);
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta_mapped));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi_mapped)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta_mapped));
// // d()/dzeta
// case 2:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta_mapped)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta_mapped));
// default:
// libmesh_error();
// }
// }
default:
libmesh_error();
}
}
// 4th-order Bernstein.
case FOURTH:
{
switch (type)
{
// Bernstein shape functions derivatives on the hexahedral.
case HEX27:
{
const Real eps = 1.e-6;
libmesh_assert (i < 125);
libmesh_assert (j < 3);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1), p(2));
const Point pm(p(0)-eps, p(1), p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps, p(2));
const Point pm(p(0), p(1)-eps, p(2));
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
// d()/dzeta
case 2:
{
const Point pp(p(0), p(1), p(2)+eps);
const Point pm(p(0), p(1), p(2)-eps);
return (FE<3,BERNSTEIN>::shape(elem, order, i, pp) -
FE<3,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
// // Compute hex shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// const Real zeta = p(2);
// Real xi_mapped = p(0);
// Real eta_mapped = p(1);
// Real zeta_mapped = p(2);
// // The only way to make any sense of this
// // is to look at the mgflo/mg2/mgf documentation
// // and make the cut-out cube!
// // Nodes 0 1 2 3 4 5 6 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 20 20 21 21 21 21 22 22 22 22 23 23 23 23 24 24 24 24 25 25 25 25 26 26 26 26 26 26 26 26
// // DOFS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 18 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 60 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
// static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4};
// // handle the edge orientation
// {
// // Edge 0
// if ((i1[i] == 0) && (i2[i] == 0))
// {
// if (elem->node(0) != std::min(elem->node(0), elem->node(1)))
// xi_mapped = -xi;
// }
// // Edge 1
// else if ((i0[i] == 1) && (i2[i] == 0))
// {
// if (elem->node(1) != std::min(elem->node(1), elem->node(2)))
// eta_mapped = -eta;
// }
// // Edge 2
// else if ((i1[i] == 1) && (i2[i] == 0))
// {
// if (elem->node(3) != std::min(elem->node(3), elem->node(2)))
// xi_mapped = -xi;
// }
// // Edge 3
// else if ((i0[i] == 0) && (i2[i] == 0))
// {
// if (elem->node(0) != std::min(elem->node(0), elem->node(3)))
// eta_mapped = -eta;
// }
// // Edge 4
// else if ((i0[i] == 0) && (i1[i] == 0))
// {
// if (elem->node(0) != std::min(elem->node(0), elem->node(4)))
// zeta_mapped = -zeta;
// }
// // Edge 5
// else if ((i0[i] == 1) && (i1[i] == 0))
// {
// if (elem->node(1) != std::min(elem->node(1), elem->node(5)))
// zeta_mapped = -zeta;
// }
// // Edge 6
// else if ((i0[i] == 1) && (i1[i] == 1))
// {
// if (elem->node(2) != std::min(elem->node(2), elem->node(6)))
// zeta_mapped = -zeta;
// }
// // Edge 7
// else if ((i0[i] == 0) && (i1[i] == 1))
// {
// if (elem->node(3) != std::min(elem->node(3), elem->node(7)))
// zeta_mapped = -zeta;
// }
// // Edge 8
// else if ((i1[i] == 0) && (i2[i] == 1))
// {
// if (elem->node(4) != std::min(elem->node(4), elem->node(5)))
// xi_mapped = -xi;
// }
// // Edge 9
// else if ((i0[i] == 1) && (i2[i] == 1))
// {
// if (elem->node(5) != std::min(elem->node(5), elem->node(6)))
// eta_mapped = -eta;
// }
// // Edge 10
// else if ((i1[i] == 1) && (i2[i] == 1))
// {
// if (elem->node(7) != std::min(elem->node(7), elem->node(6)))
// xi_mapped = -xi;
// }
// // Edge 11
// else if ((i0[i] == 0) && (i2[i] == 1))
// {
// if (elem->node(4) != std::min(elem->node(4), elem->node(7)))
// eta_mapped = -eta;
// }
// }
// // handle the face orientation
// {
// // Face 0
// if ( (i2[i] == 0) && (i0[i] >= 2) && (i1[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(1),
// std::min(elem->node(2),
// std::min(elem->node(0),
// elem->node(3))));
// if (elem->node(0) == min_node)
// if (elem->node(1) == std::min(elem->node(1), elem->node(3)))
// {
// // Case 1
// xi_mapped = xi;
// eta_mapped = eta;
// }
// else
// {
// // Case 2
// xi_mapped = eta;
// eta_mapped = xi;
// }
// else if (elem->node(3) == min_node)
// if (elem->node(0) == std::min(elem->node(0), elem->node(2)))
// {
// // Case 3
// xi_mapped = -eta;
// eta_mapped = xi;
// }
// else
// {
// // Case 4
// xi_mapped = xi;
// eta_mapped = -eta;
// }
// else if (elem->node(2) == min_node)
// if (elem->node(3) == std::min(elem->node(3), elem->node(1)))
// {
// // Case 5
// xi_mapped = -xi;
// eta_mapped = -eta;
// }
// else
// {
// // Case 6
// xi_mapped = -eta;
// eta_mapped = -xi;
// }
// else if (elem->node(1) == min_node)
// if (elem->node(2) == std::min(elem->node(2), elem->node(0)))
// {
// // Case 7
// xi_mapped = eta;
// eta_mapped = -xi;
// }
// else
// {
// // Case 8
// xi_mapped = -xi;
// eta_mapped = eta;
// }
// }
// // Face 1
// else if ((i1[i] == 0) && (i0[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(0),
// std::min(elem->node(1),
// std::min(elem->node(5),
// elem->node(4))));
// if (elem->node(0) == min_node)
// if (elem->node(1) == std::min(elem->node(1), elem->node(4)))
// {
// // Case 1
// xi_mapped = xi;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// xi_mapped = zeta;
// zeta_mapped = xi;
// }
// else if (elem->node(1) == min_node)
// if (elem->node(5) == std::min(elem->node(5), elem->node(0)))
// {
// // Case 3
// xi_mapped = zeta;
// zeta_mapped = -xi;
// }
// else
// {
// // Case 4
// xi_mapped = -xi;
// zeta_mapped = zeta;
// }
// else if (elem->node(5) == min_node)
// if (elem->node(4) == std::min(elem->node(4), elem->node(1)))
// {
// // Case 5
// xi_mapped = -xi;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// xi_mapped = -zeta;
// zeta_mapped = -xi;
// }
// else if (elem->node(4) == min_node)
// if (elem->node(0) == std::min(elem->node(0), elem->node(5)))
// {
// // Case 7
// xi_mapped = -xi;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 8
// xi_mapped = xi;
// zeta_mapped = -zeta;
// }
// }
// // Face 2
// else if ((i0[i] == 1) && (i1[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(1),
// std::min(elem->node(2),
// std::min(elem->node(6),
// elem->node(5))));
// if (elem->node(1) == min_node)
// if (elem->node(2) == std::min(elem->node(2), elem->node(5)))
// {
// // Case 1
// eta_mapped = eta;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// eta_mapped = zeta;
// zeta_mapped = eta;
// }
// else if (elem->node(2) == min_node)
// if (elem->node(6) == std::min(elem->node(6), elem->node(1)))
// {
// // Case 3
// eta_mapped = zeta;
// zeta_mapped = -eta;
// }
// else
// {
// // Case 4
// eta_mapped = -eta;
// zeta_mapped = zeta;
// }
// else if (elem->node(6) == min_node)
// if (elem->node(5) == std::min(elem->node(5), elem->node(2)))
// {
// // Case 5
// eta_mapped = -eta;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// eta_mapped = -zeta;
// zeta_mapped = -eta;
// }
// else if (elem->node(5) == min_node)
// if (elem->node(1) == std::min(elem->node(1), elem->node(6)))
// {
// // Case 7
// eta_mapped = -zeta;
// zeta_mapped = eta;
// }
// else
// {
// // Case 8
// eta_mapped = eta;
// zeta_mapped = -zeta;
// }
// }
// // Face 3
// else if ((i1[i] == 1) && (i0[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(2),
// std::min(elem->node(3),
// std::min(elem->node(7),
// elem->node(6))));
// if (elem->node(3) == min_node)
// if (elem->node(2) == std::min(elem->node(2), elem->node(7)))
// {
// // Case 1
// xi_mapped = xi;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// xi_mapped = zeta;
// zeta_mapped = xi;
// }
// else if (elem->node(7) == min_node)
// if (elem->node(3) == std::min(elem->node(3), elem->node(6)))
// {
// // Case 3
// xi_mapped = -zeta;
// zeta_mapped = xi;
// }
// else
// {
// // Case 4
// xi_mapped = xi;
// zeta_mapped = -zeta;
// }
// else if (elem->node(6) == min_node)
// if (elem->node(7) == std::min(elem->node(7), elem->node(2)))
// {
// // Case 5
// xi_mapped = -xi;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// xi_mapped = -zeta;
// zeta_mapped = -xi;
// }
// else if (elem->node(2) == min_node)
// if (elem->node(6) == std::min(elem->node(3), elem->node(6)))
// {
// // Case 7
// xi_mapped = zeta;
// zeta_mapped = -xi;
// }
// else
// {
// // Case 8
// xi_mapped = -xi;
// zeta_mapped = zeta;
// }
// }
// // Face 4
// else if ((i0[i] == 0) && (i1[i] >= 2) && (i2[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(3),
// std::min(elem->node(0),
// std::min(elem->node(4),
// elem->node(7))));
// if (elem->node(0) == min_node)
// if (elem->node(3) == std::min(elem->node(3), elem->node(4)))
// {
// // Case 1
// eta_mapped = eta;
// zeta_mapped = zeta;
// }
// else
// {
// // Case 2
// eta_mapped = zeta;
// zeta_mapped = eta;
// }
// else if (elem->node(4) == min_node)
// if (elem->node(0) == std::min(elem->node(0), elem->node(7)))
// {
// // Case 3
// eta_mapped = -zeta;
// zeta_mapped = eta;
// }
// else
// {
// // Case 4
// eta_mapped = eta;
// zeta_mapped = -zeta;
// }
// else if (elem->node(7) == min_node)
// if (elem->node(4) == std::min(elem->node(4), elem->node(3)))
// {
// // Case 5
// eta_mapped = -eta;
// zeta_mapped = -zeta;
// }
// else
// {
// // Case 6
// eta_mapped = -zeta;
// zeta_mapped = -eta;
// }
// else if (elem->node(3) == min_node)
// if (elem->node(7) == std::min(elem->node(7), elem->node(0)))
// {
// // Case 7
// eta_mapped = zeta;
// zeta_mapped = -eta;
// }
// else
// {
// // Case 8
// eta_mapped = -eta;
// zeta_mapped = zeta;
// }
// }
// // Face 5
// else if ((i2[i] == 1) && (i0[i] >= 2) && (i1[i] >= 2))
// {
// const unsigned int min_node = std::min(elem->node(4),
// std::min(elem->node(5),
// std::min(elem->node(6),
// elem->node(7))));
// if (elem->node(4) == min_node)
// if (elem->node(5) == std::min(elem->node(5), elem->node(7)))
// {
// // Case 1
// xi_mapped = xi;
// eta_mapped = eta;
// }
// else
// {
// // Case 2
// xi_mapped = eta;
// eta_mapped = xi;
// }
// else if (elem->node(5) == min_node)
// if (elem->node(6) == std::min(elem->node(6), elem->node(4)))
// {
// // Case 3
// xi_mapped = eta;
// eta_mapped = -xi;
// }
// else
// {
// // Case 4
// xi_mapped = -xi;
// eta_mapped = eta;
// }
// else if (elem->node(6) == min_node)
// if (elem->node(7) == std::min(elem->node(7), elem->node(5)))
// {
// // Case 5
// xi_mapped = -xi;
// eta_mapped = -eta;
// }
// else
// {
// // Case 6
// xi_mapped = -eta;
// eta_mapped = -xi;
// }
// else if (elem->node(7) == min_node)
// if (elem->node(4) == std::min(elem->node(4), elem->node(6)))
// {
// // Case 7
// xi_mapped = -eta;
// eta_mapped = xi;
// }
// else
// {
// // Case 8
// xi_mapped = xi;
// eta_mapped = eta;
// }
// }
// }
// libmesh_assert (j < 3);
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta_mapped));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi_mapped)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i2[i], zeta_mapped));
// // d()/dzeta
// case 2:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi_mapped)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta_mapped)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i2[i], 0, zeta_mapped));
// default:
// libmesh_error();
// }
// }
default:
libmesh_error();
}
}
default:
libmesh_error();
}
#endif
libmesh_error();
return 0.;
}
Definition at line 200 of file fe_monomial_shape_3D.C.
{
#if LIBMESH_DIM == 3
libmesh_assert (j<3);
libmesh_assert (i < (static_cast<unsigned int>(order)+1)*
(static_cast<unsigned int>(order)+2)*
(static_cast<unsigned int>(order)+3)/6);
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// monomials. since they are hierarchic we only need one case block.
switch (j)
{
// d()/dxi
case 0:
{
switch (i)
{
// constant
case 0:
return 0.;
// linear
case 1:
return 1.;
case 2:
return 0.;
case 3:
return 0.;
// quadratic
case 4:
return 2.*xi;
case 5:
return eta;
case 6:
return 0.;
case 7:
return zeta;
case 8:
return 0.;
case 9:
return 0.;
// cubic
case 10:
return 3.*xi*xi;
case 11:
return 2.*xi*eta;
case 12:
return eta*eta;
case 13:
return 0.;
case 14:
return 2.*xi*zeta;
case 15:
return eta*zeta;
case 16:
return 0.;
case 17:
return zeta*zeta;
case 18:
return 0.;
case 19:
return 0.;
// quartics
case 20:
return 4.*xi*xi*xi;
case 21:
return 3.*xi*xi*eta;
case 22:
return 2.*xi*eta*eta;
case 23:
return eta*eta*eta;
case 24:
return 0.;
case 25:
return 3.*xi*xi*zeta;
case 26:
return 2.*xi*eta*zeta;
case 27:
return eta*eta*zeta;
case 28:
return 0.;
case 29:
return 2.*xi*zeta*zeta;
case 30:
return eta*zeta*zeta;
case 31:
return 0.;
case 32:
return zeta*zeta*zeta;
case 33:
return 0.;
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx;
for (unsigned int index=1; index < nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
for (unsigned int index=0; index != nz; index++)
val *= zeta;
return val;
}
}
// d()/deta
case 1:
{
switch (i)
{
// constant
case 0:
return 0.;
// linear
case 1:
return 0.;
case 2:
return 1.;
case 3:
return 0.;
// quadratic
case 4:
return 0.;
case 5:
return xi;
case 6:
return 2.*eta;
case 7:
return 0.;
case 8:
return zeta;
case 9:
return 0.;
// cubic
case 10:
return 0.;
case 11:
return xi*xi;
case 12:
return 2.*xi*eta;
case 13:
return 3.*eta*eta;
case 14:
return 0.;
case 15:
return xi*zeta;
case 16:
return 2.*eta*zeta;
case 17:
return 0.;
case 18:
return zeta*zeta;
case 19:
return 0.;
// quartics
case 20:
return 0.;
case 21:
return xi*xi*xi;
case 22:
return 2.*xi*xi*eta;
case 23:
return 3.*xi*eta*eta;
case 24:
return 4.*eta*eta*eta;
case 25:
return 0.;
case 26:
return xi*xi*zeta;
case 27:
return 2.*xi*eta*zeta;
case 28:
return 3.*eta*eta*zeta;
case 29:
return 0.;
case 30:
return xi*zeta*zeta;
case 31:
return 2.*eta*zeta*zeta;
case 32:
return 0.;
case 33:
return zeta*zeta*zeta;
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = ny;
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=1; index < ny; index++)
val *= eta;
for (unsigned int index=0; index != nz; index++)
val *= zeta;
return val;
}
}
// d()/dzeta
case 2:
{
switch (i)
{
// constant
case 0:
return 0.;
// linear
case 1:
return 0.;
case 2:
return 0.;
case 3:
return 1.;
// quadratic
case 4:
return 0.;
case 5:
return 0.;
case 6:
return 0.;
case 7:
return xi;
case 8:
return eta;
case 9:
return 2.*zeta;
// cubic
case 10:
return 0.;
case 11:
return 0.;
case 12:
return 0.;
case 13:
return 0.;
case 14:
return xi*xi;
case 15:
return xi*eta;
case 16:
return eta*eta;
case 17:
return 2.*xi*zeta;
case 18:
return 2.*eta*zeta;
case 19:
return 3.*zeta*zeta;
// quartics
case 20:
return 0.;
case 21:
return 0.;
case 22:
return 0.;
case 23:
return 0.;
case 24:
return 0.;
case 25:
return xi*xi*xi;
case 26:
return xi*xi*eta;
case 27:
return xi*eta*eta;
case 28:
return eta*eta*eta;
case 29:
return 2.*xi*xi*zeta;
case 30:
return 2.*xi*eta*zeta;
case 31:
return 2.*eta*eta*zeta;
case 32:
return 3.*xi*zeta*zeta;
case 33:
return 3.*eta*zeta*zeta;
case 34:
return 4.*zeta*zeta*zeta;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nz;
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
for (unsigned int index=1; index < nz; index++)
val *= zeta;
return val;
}
}
}
#endif
libmesh_error();
return 0.;
}
Definition at line 636 of file fe_monomial_shape_3D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape function derivatives
return FE<3,MONOMIAL>::shape_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 209 of file fe_bernstein_shape_1D.C.
References Utility::factorial(), libMeshEnums::FIFTH, libMeshEnums::FIRST, libMeshEnums::FOURTH, Utility::pow(), Utility::pow< 2 >(), Utility::pow< 3 >(), Utility::pow< 4 >(), libMeshEnums::SECOND, libMeshEnums::SIXTH, and libMeshEnums::THIRD.
{
// only d()/dxi in 1D!
libmesh_assert (j == 0);
const Real xi = p(0);
using Utility::pow;
switch (order)
{
case FIRST:
switch(i)
{
case 0:
return -.5;
case 1:
return .5;
default:
std::cerr << 'Invalid shape function index ' << i << std::endl;
libmesh_error();
}
case SECOND:
switch(i)
{
case 0:
return (xi-1.)*.5;
case 1:
return (xi+1.)*.5;
case 2:
return -xi;
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case THIRD:
switch(i)
{
case 0:
return -0.375*pow<2>(1.-xi);
case 1:
return 0.375*pow<2>(1.+xi);
case 2:
return -0.375 -.75*xi +1.125*pow<2>(xi);
case 3:
return 0.375 -.75*xi -1.125*pow<2>(xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case FOURTH:
switch(i)
{
case 0:
return -0.25*pow<3>(1.-xi);
case 1:
return 0.25*pow<3>(1.+xi);
case 2:
return -0.5 +1.5*pow<2>(xi)-pow<3>(xi);
case 3:
return 1.5*(pow<3>(xi)-xi);
case 4:
return 0.5 -1.5*pow<2>(xi)-pow<3>(xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case FIFTH:
switch(i)
{
case 0:
return -(5./32.)*pow<4>(xi-1.);
case 1:
return (5./32.)*pow<4>(xi+1.);
case 2:
return (5./32.)*pow<4>(1.-xi) -(5./8.)*(1.+xi)*pow<3>(1.-xi);
case 3:
return (5./ 8.)*(1.+xi)*pow<3>(1.-xi) -(15./16.)*pow<2>(1.+xi)*pow<2>(1.-xi);
case 4:
return -(5./ 8.)*pow<3>(1.+xi)*(1.-xi) +(15./16.)*pow<2>(1.+xi)*pow<2>(1.-xi);
case 5:
return (5./ 8.)*pow<3>(1.+xi)*(1.-xi) -(5./32.)*pow<4>(1.+xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
case SIXTH:
switch(i)
{
case 0:
return -( 3./32.)*pow<5>(1.-xi);
case 1:
return ( 3./32.)*pow<5>(1.+xi);
case 2:
return ( 3./32.)*pow<5>(1.-xi)-(15./32.)*(1.+xi)*pow<4>(1.-xi);
case 3:
return (15./32.)*(1.+xi)*pow<4>(1.-xi)-(15./16.)*pow<2>(1.+xi)*pow<3>(1.-xi);
case 4:
return -(15./ 8.)*xi +(15./4.)*pow<3>(xi)-(15./8.)*pow<5>(xi);
case 5:
return -(15./32.)*(1.-xi)*pow<4>(1.+xi)+(15./16.)*pow<2>(1.-xi)*pow<3>(1.+xi);
case 6:
return (15./32.)*pow<4>(1.+xi)*(1.-xi)-(3./32.)*pow<5>(1.+xi);
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
default:
{
libmesh_assert (order>6);
// Use this for arbitrary orders
const int p_order = static_cast<unsigned int>(order);
const int m = p_order-(i-1);
const int n = (i-1);
unsigned int binomial_p_i = 1;
// the binomial coefficient (p choose n)
if (i>1)
binomial_p_i = Utility::factorial(p_order)
/ (Utility::factorial(n)*Utility::factorial(p_order-n));
switch(i)
{
case 0:
return binomial_p_i * (-1./2.) * p_order * std::pow((1.-xi)/2.,static_cast<Real>(p_order-1));
case 1:
return binomial_p_i * ( 1./2.) * p_order * std::pow((1.+xi)/2.,static_cast<Real>(p_order-1));
default:
{
return binomial_p_i * (1./2. * n * std::pow((1.+xi)/2.,static_cast<Real>(n-1)) * std::pow((1.-xi)/2.,static_cast<Real>(m))
- 1./2. * m * std::pow((1.+xi)/2.,static_cast<Real>(n)) * std::pow((1.-xi)/2.,static_cast<Real>(m-1)));
}
}
// we should never get here
libmesh_error();
}
}
libmesh_error();
return 0.;
}
Definition at line 184 of file fe_hierarchic_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,HIERARCHIC>::shape_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 56 of file fe_scalar_shape_3D.C.
{
return 0.;
}
Definition at line 379 of file fe_bernstein_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,BERNSTEIN>::shape_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 274 of file fe_hermite_shape_1D.C.
{
std::cerr << 'Hermite elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 291 of file fe_hermite_shape_1D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, FEHermite< Dim >::hermite_raw_shape_deriv(), Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// Hermite cubic shape functions
case THIRD:
{
switch (type)
{
// C1 functions on the C1 cubic edge
case EDGE2:
case EDGE3:
{
switch (i)
{
case 0:
return FEHermite<1>::hermite_raw_shape_deriv(0, p(0));
case 1:
return d1xd1x * FEHermite<1>::hermite_raw_shape_deriv(2, p(0));
case 2:
return FEHermite<1>::hermite_raw_shape_deriv(1, p(0));
case 3:
return d2xd2x * FEHermite<1>::hermite_raw_shape_deriv(3, p(0));
default:
return FEHermite<1>::hermite_raw_shape_deriv(i, p(0));
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 47 of file fe_scalar_shape_2D.C.
{
return 0.;
}
Definition at line 69 of file fe_hierarchic_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 102 of file fe_szabab_shape_1D.C.
References libMeshEnums::SEVENTH.
{
// only d()/dxi in 1D!
libmesh_assert (j == 0);
const Real xi = p(0);
const Real xi2 = xi*xi;
// Use this libmesh_assert rather than a switch with a single entry...
// It will go away in optimized mode, essentially has the same effect.
libmesh_assert (order <= SEVENTH);
// switch (order)
// {
// case FIRST:
// case SECOND:
// case THIRD:
// case FOURTH:
// case FIFTH:
// case SIXTH:
// case SEVENTH:
switch(i)
{
case 0: return -1./2.;
case 1: return 1./2.;
case 2: return 1./2.*2.4494897427831780982*xi;
case 3: return -1./4.*3.1622776601683793320+3./4.*3.1622776601683793320*xi2;
case 4: return 1./16.*3.7416573867739413856*(-12.+20*xi2)*xi;
case 5: return 9./16.*1.4142135623730950488+(-45./8.*1.4142135623730950488+105./16.*1.4142135623730950488*xi2)*xi2;
case 6: return 1./32.*4.6904157598234295546*(30.+(-140.+126.*xi2)*xi2)*xi;
case 7: return -5./32.*5.0990195135927848300+(105./32.*5.0990195135927848300+(-315./32.*5.0990195135927848300+231./32.*5.0990195135927848300*xi2)*xi2)*xi2;
case 8: return 1./256.*5.4772255750516611346*(-280.+(2520.+(-5544.+3432.*xi2)*xi2)*xi2)*xi;
default:
std::cerr << 'Invalid shape function index!' << std::endl;
libmesh_error();
}
// default:
// {
// std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
// libmesh_error();
// }
// }
libmesh_error();
return 0.;
}
Definition at line 46 of file fe_scalar_shape_1D.C.
{
return 0.;
}
Definition at line 57 of file fe_scalar_shape_2D.C.
{
return 0.;
}
Definition at line 55 of file fe_szabab_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Note, since the derivatives are computed using FE::shape the continuity along neighboring elements (shape_flip) is already considered.
Definition at line 969 of file fe_bernstein_shape_2D.C.
References libMeshEnums::EDGE3, Elem::p_level(), Elem::point(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, FE< Dim, T >::shape(), FE< Dim, T >::shape_deriv(), square_number_column, square_number_row, libMeshEnums::TRI3, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (type)
{
// Hierarchic shape functions on the quadrilateral.
case QUAD4:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < (totalorder+1u)*(totalorder+1u));
unsigned int i0, i1;
// Vertex DoFs
if (i == 0)
{ i0 = 0; i1 = 0; }
else if (i == 1)
{ i0 = 1; i1 = 0; }
else if (i == 2)
{ i0 = 1; i1 = 1; }
else if (i == 3)
{ i0 = 0; i1 = 1; }
// Edge DoFs
else if (i < totalorder + 3u)
{ i0 = i - 2; i1 = 0; }
else if (i < 2u*totalorder + 2)
{ i0 = 1; i1 = i - totalorder - 1; }
else if (i < 3u*totalorder + 1)
{ i0 = i - 2u*totalorder; i1 = 1; }
else if (i < 4u*totalorder)
{ i0 = 0; i1 = i - 3u*totalorder + 1; }
// Interior DoFs
else
{
unsigned int basisnum = i - 4*totalorder;
i0 = square_number_column[basisnum] + 2;
i1 = square_number_row[basisnum] + 2;
}
// Flip odd degree of freedom values if necessary
// to keep continuity on sides
if ((i>= 4 && i<= 4+ totalorder-2u) && elem->point(0) > elem->point(1)) i0=totalorder+2-i0; //
else if((i>= 4+ totalorder-1u && i<= 4+2*totalorder-3u) && elem->point(1) > elem->point(2)) i1=totalorder+2-i1;
else if((i>= 4+2*totalorder-2u && i<= 4+3*totalorder-4u) && elem->point(3) > elem->point(2)) i0=totalorder+2-i0;
else if((i>= 4+3*totalorder-3u && i<= 4+4*totalorder-5u) && elem->point(0) > elem->point(3)) i1=totalorder+2-i1;
switch (j)
{
// d()/dxi
case 0:
return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0, 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1, eta));
// d()/deta
case 1:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0, xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1, 0, eta));
}
}
// Bernstein shape functions on the 8-noded quadrilateral
// is handled separately.
case QUAD8:
{
libmesh_assert (totalorder < 3);
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < 8);
// 0 1 2 3 4 5 6 7 8
static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
static const Real scal[] = {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5};
switch (j)
{
// d()/dxi
case 0:
return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)
+scal[i]*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[8], 0, xi)*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[8], eta));
// d()/deta
case 1:
return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)
+scal[i]*
FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[8], xi)*
FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[8], 0, eta));
default:
libmesh_error();
}
}
case TRI3:
libmesh_assert (totalorder<2);
case TRI6:
{
// I have been lazy here and am using finite differences
// to compute the derivatives!
const Real eps = 1.e-6;
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,BERNSTEIN>::shape(elem, totalorder, i, pp) -
FE<2,BERNSTEIN>::shape(elem, totalorder, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,BERNSTEIN>::shape(elem, totalorder, i, pp) -
FE<2,BERNSTEIN>::shape(elem, totalorder, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
default:
{
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// old code
// switch (totalorder)
// {
// // 1st order Bernsteins are aquivalent to Lagrange elements.
// case FIRST:
// {
// switch (type)
// {
// // Bernstein shape functions on the triangle.
// case TRI6:
// {
// // I have been lazy here and am using finite differences
// // to compute the derivatives!
// const Real eps = 1.e-6;
// libmesh_assert (i < 3);
// libmesh_assert (j < 2);
// switch (j)
// {
// // d()/dxi
// case 0:
// {
// const Point pp(p(0)+eps, p(1));
// const Point pm(p(0)-eps, p(1));
// return (FE<2,BERNSTEIN>::shape(elem, order, i, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
// }
// // d()/deta
// case 1:
// {
// const Point pp(p(0), p(1)+eps);
// const Point pm(p(0), p(1)-eps);
// return (FE<2,BERNSTEIN>::shape(elem, order, i, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
// }
// default:
// libmesh_error();
// }
// }
// // Bernstein shape functions on the quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 4);
// // 0 1 2 3
// static const unsigned int i0[] = {0, 1, 1, 0};
// static const unsigned int i1[] = {0, 0, 1, 1};
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
// default:
// libmesh_error();
// }
// }
// default:
// libmesh_error();
// }
// }
// // second order Bernsteins.
// case SECOND:
// {
// switch (type)
// {
// // Bernstein shape functions on the triangle.
// case TRI6:
// {
// // I have been lazy here and am using finite differences
// // to compute the derivatives!
// const Real eps = 1.e-6;
// libmesh_assert (i < 6);
// libmesh_assert (j < 2);
// switch (j)
// {
// // d()/dxi
// case 0:
// {
// const Point pp(p(0)+eps, p(1));
// const Point pm(p(0)-eps, p(1));
// return (FE<2,BERNSTEIN>::shape(elem, order, i, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
// }
// // d()/deta
// case 1:
// {
// const Point pp(p(0), p(1)+eps);
// const Point pm(p(0), p(1)-eps);
// return (FE<2,BERNSTEIN>::shape(elem, order, i, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, i, pm))/2./eps;
// }
// default:
// libmesh_error();
// }
// }
// // Bernstein shape functions on the 8-noded quadrilateral.
// case QUAD8:
// {
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 8);
// // 0 1 2 3 4 5 6 7 8
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
// static const Real scal[] = {-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5};
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta)
// +scal[i]*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[8], 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[8], eta));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta)
// +scal[i]*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[8], xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[8], 0, eta));
// default:
// libmesh_error();
// }
// }
// // Bernstein shape functions on the 9-noded quadrilateral.
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 9);
// // 0 1 2 3 4 5 6 7 8
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
// default:
// libmesh_error();
// }
// }
// default:
// libmesh_error();
// }
// }
// // 3rd-order Bernsteins.
// case THIRD:
// {
// switch (type)
// {
// // Bernstein shape functions on the triangle.
// case TRI6:
// {
// // I have been lazy here and am using finite differences
// // to compute the derivatives!
// const Real eps = 1.e-6;
// libmesh_assert (i < 10);
// libmesh_assert (j < 2);
// unsigned int shape=i;
// /**
// * Note, since the derivatives are computed using FE::shape
// * the continuity along neighboring elements (shape_flip)
// * is already considered.
// */
// switch (j)
// {
// // d()/dxi
// case 0:
// {
// const Point pp(p(0)+eps, p(1));
// const Point pm(p(0)-eps, p(1));
// return (FE<2,BERNSTEIN>::shape(elem, totalorder, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, totalorder, shape, pm))/2./eps;
// }
// // d()/deta
// case 1:
// {
// const Point pp(p(0), p(1)+eps);
// const Point pm(p(0), p(1)-eps);
// return (FE<2,BERNSTEIN>::shape(elem, totalorder, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, totalorder, shape, pm))/2./eps;
// }
// default:
// libmesh_error();
// }
// }
// // Bernstein shape functions on the quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 16);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 1, 1, 2, 3, 0, 0, 2, 3, 2, 3};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 2, 3, 1, 1, 2, 3, 2, 2, 3, 3};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i== 4||i== 5) && elem->node(0) > elem->node(1)) i0=5-i0;
// if((i== 6||i== 7) && elem->node(1) > elem->node(2)) i1=5-i1;
// if((i== 8||i== 9) && elem->node(3) > elem->node(2)) i0=5-i0;
// if((i==10||i==11) && elem->node(0) > elem->node(3)) i1=5-i1;
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0, 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1, eta));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1, 0, eta));
// default:
// libmesh_error();
// }
// }
// default:
// libmesh_error();
// }
// }
// // 4th-order Bernsteins.
// case FOURTH:
// {
// switch (type)
// {
// // Bernstein shape functions on the triangle.
// case TRI6:
// {
// // I have been lazy here and am using finite differences
// // to compute the derivatives!
// const Real eps = 1.e-6;
// libmesh_assert (i < 15);
// libmesh_assert (j < 2);
// unsigned int shape=i;
// switch (j)
// {
// // d()/dxi
// case 0:
// {
// const Point pp(p(0)+eps, p(1));
// const Point pm(p(0)-eps, p(1));
// return (FE<2,BERNSTEIN>::shape(elem, order, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, shape, pm))/2./eps;
// }
// // d()/deta
// case 1:
// {
// const Point pp(p(0), p(1)+eps);
// const Point pm(p(0), p(1)-eps);
// return (FE<2,BERNSTEIN>::shape(elem, order, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, shape, pm))/2./eps;
// }
// default:
// libmesh_error();
// }
// }
// // Bernstein shape functions on the quadrilateral.
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 25);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 0, 0, 0, 2, 3, 4, 2, 3, 4, 2, 3, 4};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 0, 2, 3, 4, 1, 1, 1, 2, 3, 4, 2, 2, 2, 3, 3, 3, 4, 4, 4};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i== 4||i== 6) && elem->node(0) > elem->node(1)) i0=6-i0;
// if((i== 7||i== 9) && elem->node(1) > elem->node(2)) i1=6-i1;
// if((i==10||i==12) && elem->node(3) > elem->node(2)) i0=6-i0;
// if((i==13||i==15) && elem->node(0) > elem->node(3)) i1=6-i1;
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0, 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1, eta));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1, 0, eta));
// default:
// libmesh_error();
// }
// }
// default:
// libmesh_error();
// }
// }
// // 5th-order Bernsteins.
// case FIFTH:
// {
// // Bernstein shape functions on the quadrilateral.
// switch (type)
// {
// // Bernstein shape functions on the triangle.
// case TRI6:
// {
// // I have been lazy here and am using finite differences
// // to compute the derivatives!
// const Real eps = 1.e-6;
// libmesh_assert (i < 21);
// libmesh_assert (j < 2);
// unsigned int shape=i;
// switch (j)
// {
// // d()/dxi
// case 0:
// {
// const Point pp(p(0)+eps, p(1));
// const Point pm(p(0)-eps, p(1));
// return (FE<2,BERNSTEIN>::shape(elem, order, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, shape, pm))/2./eps;
// }
// // d()/deta
// case 1:
// {
// const Point pp(p(0), p(1)+eps);
// const Point pm(p(0), p(1)-eps);
// return (FE<2,BERNSTEIN>::shape(elem, order, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, shape, pm))/2./eps;
// }
// default:
// libmesh_error();
// }
// } // case TRI6
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 36);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i>= 4&&i<= 7) && elem->node(0) > elem->node(1)) i0=7-i0;
// if((i>= 8&&i<=11) && elem->node(1) > elem->node(2)) i1=7-i1;
// if((i>=12&&i<=15) && elem->node(3) > elem->node(2)) i0=7-i0;
// if((i>=16&&i<=19) && elem->node(0) > elem->node(3)) i1=7-i1;
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0, 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1, eta));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1, 0, eta));
// default:
// libmesh_error();
// }
// } // case QUAD8/9
// default:
// libmesh_error();
// }
// }
// // 6th-order Bernsteins.
// case SIXTH:
// {
// // Bernstein shape functions on the quadrilateral.
// switch (type)
// {
// // Bernstein shape functions on the triangle.
// case TRI6:
// {
// // I have been lazy here and am using finite differences
// // to compute the derivatives!
// const Real eps = 1.e-6;
// libmesh_assert (i < 28);
// libmesh_assert (j < 2);
// unsigned int shape=i;
// switch (j)
// {
// // d()/dxi
// case 0:
// {
// const Point pp(p(0)+eps, p(1));
// const Point pm(p(0)-eps, p(1));
// return (FE<2,BERNSTEIN>::shape(elem, order, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, shape, pm))/2./eps;
// }
// // d()/deta
// case 1:
// {
// const Point pp(p(0), p(1)+eps);
// const Point pm(p(0), p(1)-eps);
// return (FE<2,BERNSTEIN>::shape(elem, order, shape, pp) -
// FE<2,BERNSTEIN>::shape(elem, order, shape, pm))/2./eps;
// }
// default:
// libmesh_error();
// }
// } // case TRI6
// case QUAD8:
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 49);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
// static const unsigned int i0_reg[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6};
// static const unsigned int i1_reg[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6};
// unsigned int i0=i0_reg[i];
// unsigned int i1=i1_reg[i];
// if((i>= 4&&i<= 8) && elem->node(0) > elem->node(1)) i0=8-i0;
// if((i>= 9&&i<=13) && elem->node(1) > elem->node(2)) i1=8-i1;
// if((i>=14&&i<=18) && elem->node(3) > elem->node(2)) i0=8-i0;
// if((i>=19&&i<=23) && elem->node(0) > elem->node(3)) i1=8-i1;
// switch (j)
// {
// // d()/dxi
// case 0:
// return (FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0, 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1, eta));
// // d()/deta
// case 1:
// return (FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0, xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1, 0, eta));
// default:
// libmesh_error();
// }
// } // case QUAD8/9
// default:
// libmesh_error();
// }
// // 7th-order Bernstein.
// case SEVENTH:
// {
// // Szabo-Babuska shape functions on the quadrilateral.
// switch (type)
// {
// case QUAD9:
// {
// // Compute quad shape functions as a tensor-product
// const Real xi = p(0);
// const Real eta = p(1);
// libmesh_assert (i < 64);
// // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, 2, 3, 4, 5, 6, 7};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, 7, 1, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7};
// Real f=1.;
// switch(i)
// {
// case 5: // edge 0 nodes
// case 7:
// case 9:
// if (elem->node(0) > elem->node(1))f = -1.;
// break;
// case 11: // edge 1 nodes
// case 13:
// case 15:
// if (elem->node(1) > elem->node(2))f = -1.;
// break;
// case 17: // edge 2 nodes
// case 19:
// case 21:
// if (elem->node(3) > elem->node(2))f = -1.;
// break;
// case 23: // edge 3 nodes
// case 25:
// case 27:
// if (elem->node(0) > elem->node(3))f = -1.;
// break;
// }
// switch (j)
// {
// // d()/dxi
// case 0:
// return f*(FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i0[i], 0, xi)*
// FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i1[i], eta));
// // d()/deta
// case 1:
// return f*(FE<1,BERNSTEIN>::shape (EDGE3, totalorder, i0[i], xi)*
// FE<1,BERNSTEIN>::shape_deriv(EDGE3, totalorder, i1[i], 0, eta));
// default:
// libmesh_error();
// }
// }
// default:
// libmesh_error();
// }
// }
// }
// // by default throw an error;call the orientation-independent shape functions
// default:
// std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
// libmesh_error();
// }
libmesh_error();
return 0.;
}
Definition at line 257 of file fe_hermite_shape_2D.C.
{
std::cerr << 'Hermite elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 274 of file fe_hermite_shape_2D.C.
References FEHermite< Dim >::hermite_raw_shape(), FEHermite< Dim >::hermite_raw_shape_deriv(), Elem::p_level(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, and Elem::type().
{
libmesh_assert (elem != NULL);
libmesh_assert (j == 0 || j == 1);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (type)
{
case QUAD4:
libmesh_assert (totalorder < 4);
case QUAD8:
case QUAD9:
{
libmesh_assert (i<(totalorder+1u)*(totalorder+1u));
std::vector<unsigned int> bases1D;
Real coef = hermite_bases_2D(bases1D, dxdxi, totalorder, i);
switch (j)
{
case 0:
return coef *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1));
case 1:
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1));
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 56 of file fe_scalar_shape_1D.C.
{
return 0.;
}
Definition at line 130 of file fe_xyz_shape_1D.C.
References Elem::centroid(), and DofObject::id().
{
libmesh_assert (elem != NULL);
libmesh_assert (i <= order + elem->p_level());
// only d()/dxi in 1D!
libmesh_assert (j == 0);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real xc = centroid(0);
const Real dx = x - xc;
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
case 0:
return 0.;
case 1:
return 1.;
case 2:
return 2.*dx;
case 3:
return 3.*dx*dx;
case 4:
return 4.*dx*dx*dx;
default:
Real val = i;
for (unsigned int index = 1; index != i; ++index)
val *= dx;
return val;
}
libmesh_error();
return 0.;
}
Definition at line 952 of file fe_bernstein_shape_2D.C.
{
std::cerr << 'Bernstein polynomials require the element type
<< 'because edge orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 46 of file fe_scalar_shape_3D.C.
{
return 0.;
}
Definition at line 448 of file fe_hermite_shape_3D.C.
{
std::cerr << 'Hermite elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 465 of file fe_hermite_shape_3D.C.
References FEHermite< Dim >::hermite_raw_shape(), FEHermite< Dim >::hermite_raw_shape_deriv(), libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
libmesh_assert (j == 0 || j == 1 || j == 2);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 3rd-order tricubic Hermite functions
case THIRD:
{
switch (type)
{
case HEX8:
case HEX20:
case HEX27:
{
libmesh_assert (i<64);
std::vector<unsigned int> bases1D;
Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
switch (j) // Derivative type
{
case 0:
return coef *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
break;
case 1:
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
break;
case 2:
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[2],p(2));
break;
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 46 of file fe_scalar_shape_0D.C.
{
return 0.;
}
Definition at line 56 of file fe_scalar_shape_0D.C.
{
return 0.;
}
Definition at line 55 of file fe_hierarchic_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 721 of file fe_szabab_shape_2D.C.
{
std::cerr << 'Szabo-Babuska polynomials require the element type
<< 'because edge orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 1389 of file fe_bernstein_shape_3D.C.
{
std::cerr << 'Bernstein polynomials require the element type
<< 'because edge and face orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 113 of file fe_hierarchic_shape_1D.C.
References Utility::pow(), Utility::pow< 3 >(), Utility::pow< 4 >(), and Utility::pow< 6 >().
{
// only d()/dxi in 1D!
libmesh_assert (j == 0);
libmesh_assert(i < order+1u);
// Declare that we are using our own special power function
// from the Utility namespace. This saves typing later.
using Utility::pow;
const Real xi = p(0);
Real returnval = 1.;
switch (i)
{
case 0:
returnval = -.5;
break;
case 1:
returnval = .5;
break;
// All even-terms have the same form.
// xi^(p-1)/(p-1)!
case 2:
returnval = xi;
break;
case 4:
returnval = pow<3>(xi)/6.;
break;
case 6:
returnval = pow<5>(xi)/120.;
break;
// All odd-terms have the same form.
// (p*xi^(p-1) - 1.)/p!
case 3:
returnval = (3*xi*xi - 1.)/6.;
break;
case 5:
returnval = (5.*pow<4>(xi) - 1.)/120.;
break;
case 7:
returnval = (7.*pow<6>(xi) - 1.)/5040.;
break;
default:
Real denominator = 1.;
for (unsigned int n=1; n != i; ++n)
{
returnval *= xi;
denominator *= n;
}
// Odd:
if (i % 2)
returnval = (i * returnval - 1.)/denominator/i;
// Even:
else
returnval = returnval/denominator;
break;
}
return returnval;
}
Definition at line 55 of file fe_xyz_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 183 of file fe_xyz_shape_2D.C.
References Elem::centroid(), DofObject::id(), and Elem::p_level().
{
#if LIBMESH_DIM > 1
libmesh_assert (j<2);
libmesh_assert (elem != NULL);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real y = p(1);
const Real xc = centroid(0);
const Real yc = centroid(1);
const Real dx = x - xc;
const Real dy = y - yc;
#ifndef NDEBUG
// totalorder is only used in the assertion below, so
// we avoid declaring it when asserts are not active.
const unsigned int totalorder = order + elem->p_level();
#endif
libmesh_assert (i < (totalorder+1)*(totalorder+2)/2);
// monomials. since they are hierarchic we only need one case block.
switch (j)
{
// d()/dx
case 0:
{
switch (i)
{
// constants
case 0:
return 0.;
// linears
case 1:
return 1.;
case 2:
return 0.;
// quadratics
case 3:
return 2.*dx;
case 4:
return dy;
case 5:
return 0.;
// cubics
case 6:
return 3.*dx*dx;
case 7:
return 2.*dx*dy;
case 8:
return dy*dy;
case 9:
return 0.;
// quartics
case 10:
return 4.*dx*dx*dx;
case 11:
return 3.*dx*dx*dy;
case 12:
return 2.*dx*dy*dy;
case 13:
return dy*dy*dy;
case 14:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int i2 = i - (o*(o+1)/2);
Real val = o - i2;
for (unsigned int index=i2+1; index < o; index++)
val *= dx;
for (unsigned int index=0; index != i2; index++)
val *= dy;
return val;
}
}
// d()/dy
case 1:
{
switch (i)
{
// constants
case 0:
return 0.;
// linears
case 1:
return 0.;
case 2:
return 1.;
// quadratics
case 3:
return 0.;
case 4:
return dx;
case 5:
return 2.*dy;
// cubics
case 6:
return 0.;
case 7:
return dx*dx;
case 8:
return 2.*dx*dy;
case 9:
return 3.*dy*dy;
// quartics
case 10:
return 0.;
case 11:
return dx*dx*dx;
case 12:
return 2.*dx*dx*dy;
case 13:
return 3.*dx*dy*dy;
case 14:
return 4.*dy*dy*dy;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int i2 = i - (o*(o+1)/2);
Real val = i2;
for (unsigned int index=i2; index != o; index++)
val *= dx;
for (unsigned int index=1; index <= i2; index++)
val *= dy;
return val;
}
}
default:
libmesh_error();
}
libmesh_error();
return 0.;
#endif
}
Definition at line 235 of file fe_hierarchic_shape_2D.C.
{
std::cerr << 'Hierarchic polynomials require the element type
<< 'because edge orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 113 of file fe_xyz_shape_1D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 252 of file fe_hierarchic_shape_2D.C.
References libMeshEnums::EDGE3, Elem::p_level(), Elem::point(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, FE< Dim, T >::shape(), FE< Dim, T >::shape_deriv(), square_number_column, square_number_row, libMeshEnums::TRI3, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order+elem->p_level());
libmesh_assert (totalorder > 0);
switch (type)
{
// 1st & 2nd-order Hierarchics.
case TRI3:
case TRI6:
{
const Real eps = 1.e-6;
libmesh_assert (j < 2);
switch (j)
{
// d()/dxi
case 0:
{
const Point pp(p(0)+eps, p(1));
const Point pm(p(0)-eps, p(1));
return (FE<2,HIERARCHIC>::shape(elem, order, i, pp) -
FE<2,HIERARCHIC>::shape(elem, order, i, pm))/2./eps;
}
// d()/deta
case 1:
{
const Point pp(p(0), p(1)+eps);
const Point pm(p(0), p(1)-eps);
return (FE<2,HIERARCHIC>::shape(elem, order, i, pp) -
FE<2,HIERARCHIC>::shape(elem, order, i, pm))/2./eps;
}
default:
libmesh_error();
}
}
case QUAD4:
libmesh_assert (totalorder < 2);
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i < (totalorder+1u)*(totalorder+1u));
// Example i, i0, i1 values for totalorder = 5:
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// static const unsigned int i0[] = {0, 1, 1, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 0, 0, 0, 0, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5};
// static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 0, 0, 2, 3, 4, 5, 1, 1, 1, 1, 2, 3, 4, 5, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
unsigned int i0, i1;
// Vertex DoFs
if (i == 0)
{ i0 = 0; i1 = 0; }
else if (i == 1)
{ i0 = 1; i1 = 0; }
else if (i == 2)
{ i0 = 1; i1 = 1; }
else if (i == 3)
{ i0 = 0; i1 = 1; }
// Edge DoFs
else if (i < totalorder + 3u)
{ i0 = i - 2; i1 = 0; }
else if (i < 2u*totalorder + 2)
{ i0 = 1; i1 = i - totalorder - 1; }
else if (i < 3u*totalorder + 1u)
{ i0 = i - 2u*totalorder; i1 = 1; }
else if (i < 4u*totalorder)
{ i0 = 0; i1 = i - 3u*totalorder + 1; }
// Interior DoFs
else
{
unsigned int basisnum = i - 4*totalorder;
i0 = square_number_column[basisnum] + 2;
i1 = square_number_row[basisnum] + 2;
}
// Flip odd degree of freedom values if necessary
// to keep continuity on sides
Real f = 1.;
if ((i0%2) && (i0 > 2) && (i1 == 0))
f = (elem->point(0) > elem->point(1))?-1.:1.;
else if ((i0%2) && (i0>2) && (i1 == 1))
f = (elem->point(3) > elem->point(2))?-1.:1.;
else if ((i0 == 0) && (i1%2) && (i1>2))
f = (elem->point(0) > elem->point(3))?-1.:1.;
else if ((i0 == 1) && (i1%2) && (i1>2))
f = (elem->point(1) > elem->point(2))?-1.:1.;
switch (j)
{
// d()/dxi
case 0:
return f*(FE<1,HIERARCHIC>::shape_deriv(EDGE3, totalorder, i0, 0, xi)*
FE<1,HIERARCHIC>::shape (EDGE3, totalorder, i1, eta));
// d()/deta
case 1:
return f*(FE<1,HIERARCHIC>::shape (EDGE3, totalorder, i0, xi)*
FE<1,HIERARCHIC>::shape_deriv(EDGE3, totalorder, i1, 0, eta));
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
return 0.;
}
Definition at line 69 of file fe_monomial_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 166 of file fe_xyz_shape_2D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 215 of file fe_clough_shape_3D.C.
{
std::cerr << 'Clough-Tocher elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 248 of file fe_clough_shape_1D.C.
{
std::cerr << 'Clough-Tocher elements require the real element
<< 'to construct gradient-based degrees of freedom.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 253 of file fe_xyz_shape_3D.C.
References Elem::centroid(), DofObject::id(), and Elem::p_level().
{
#if LIBMESH_DIM == 3
libmesh_assert (elem != NULL);
libmesh_assert (j<3);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real y = p(1);
const Real z = p(2);
const Real xc = centroid(0);
const Real yc = centroid(1);
const Real zc = centroid(2);
const Real dx = x - xc;
const Real dy = y - yc;
const Real dz = z - zc;
#ifndef NDEBUG
// totalorder is only used in the assertion below, so
// we avoid declaring it when asserts are not active.
const unsigned int totalorder = static_cast<Order>(order + elem->p_level());
#endif
libmesh_assert (i < (static_cast<unsigned int>(totalorder)+1)*
(static_cast<unsigned int>(totalorder)+2)*
(static_cast<unsigned int>(totalorder)+2)/6);
switch (j)
{
// d()/dx
case 0:
{
switch (i)
{
// constant
case 0:
return 0.;
// linear
case 1:
return 1.;
case 2:
return 0.;
case 3:
return 0.;
// quadratic
case 4:
return 2.*dx;
case 5:
return dy;
case 6:
return 0.;
case 7:
return dz;
case 8:
return 0.;
case 9:
return 0.;
// cubic
case 10:
return 3.*dx*dx;
case 11:
return 2.*dx*dy;
case 12:
return dy*dy;
case 13:
return 0.;
case 14:
return 2.*dx*dz;
case 15:
return dy*dz;
case 16:
return 0.;
case 17:
return dz*dz;
case 18:
return 0.;
case 19:
return 0.;
// quartics
case 20:
return 4.*dx*dx*dx;
case 21:
return 3.*dx*dx*dy;
case 22:
return 2.*dx*dy*dy;
case 23:
return dy*dy*dy;
case 24:
return 0.;
case 25:
return 3.*dx*dx*dz;
case 26:
return 2.*dx*dy*dz;
case 27:
return dy*dy*dz;
case 28:
return 0.;
case 29:
return 2.*dx*dz*dz;
case 30:
return dy*dz*dz;
case 31:
return 0.;
case 32:
return dz*dz*dz;
case 33:
return 0.;
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx;
for (unsigned int index=1; index < nx; index++)
val *= dx;
for (unsigned int index=0; index != ny; index++)
val *= dy;
for (unsigned int index=0; index != nz; index++)
val *= dz;
return val;
}
}
// d()/dy
case 1:
{
switch (i)
{
// constant
case 0:
return 0.;
// linear
case 1:
return 0.;
case 2:
return 1.;
case 3:
return 0.;
// quadratic
case 4:
return 0.;
case 5:
return dx;
case 6:
return 2.*dy;
case 7:
return 0.;
case 8:
return dz;
case 9:
return 0.;
// cubic
case 10:
return 0.;
case 11:
return dx*dx;
case 12:
return 2.*dx*dy;
case 13:
return 3.*dy*dy;
case 14:
return 0.;
case 15:
return dx*dz;
case 16:
return 2.*dy*dz;
case 17:
return 0.;
case 18:
return dz*dz;
case 19:
return 0.;
// quartics
case 20:
return 0.;
case 21:
return dx*dx*dx;
case 22:
return 2.*dx*dx*dy;
case 23:
return 3.*dx*dy*dy;
case 24:
return 4.*dy*dy*dy;
case 25:
return 0.;
case 26:
return dx*dx*dz;
case 27:
return 2.*dx*dy*dz;
case 28:
return 3.*dy*dy*dz;
case 29:
return 0.;
case 30:
return dx*dz*dz;
case 31:
return 2.*dy*dz*dz;
case 32:
return 0.;
case 33:
return dz*dz*dz;
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = ny;
for (unsigned int index=0; index != nx; index++)
val *= dx;
for (unsigned int index=1; index < ny; index++)
val *= dy;
for (unsigned int index=0; index != nz; index++)
val *= dz;
return val;
}
}
// d()/dz
case 2:
{
switch (i)
{
// constant
case 0:
return 0.;
// linear
case 1:
return 0.;
case 2:
return 0.;
case 3:
return 1.;
// quadratic
case 4:
return 0.;
case 5:
return 0.;
case 6:
return 0.;
case 7:
return dx;
case 8:
return dy;
case 9:
return 2.*dz;
// cubic
case 10:
return 0.;
case 11:
return 0.;
case 12:
return 0.;
case 13:
return 0.;
case 14:
return dx*dx;
case 15:
return dx*dy;
case 16:
return dy*dy;
case 17:
return 2.*dx*dz;
case 18:
return 2.*dy*dz;
case 19:
return 3.*dz*dz;
// quartics
case 20:
return 0.;
case 21:
return 0.;
case 22:
return 0.;
case 23:
return 0.;
case 24:
return 0.;
case 25:
return dx*dx*dx;
case 26:
return dx*dx*dy;
case 27:
return dx*dy*dy;
case 28:
return dy*dy*dy;
case 29:
return 2.*dx*dx*dz;
case 30:
return 2.*dx*dy*dz;
case 31:
return 2.*dy*dy*dz;
case 32:
return 3.*dx*dz*dz;
case 33:
return 3.*dy*dz*dz;
case 34:
return 4.*dz*dz*dz;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nz;
for (unsigned int index=0; index != nx; index++)
val *= dx;
for (unsigned int index=0; index != ny; index++)
val *= dy;
for (unsigned int index=1; index < nz; index++)
val *= dz;
return val;
}
}
default:
libmesh_error();
}
#endif
libmesh_error();
return 0.;
}
Definition at line 55 of file fe_clough_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 69 of file fe_clough_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 131 of file fe_monomial_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,MONOMIAL>::shape_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 98 of file fe_hierarchic_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 1375 of file fe_szabab_shape_2D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Szabab elements '
<< ' are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 84 of file fe_hierarchic_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 189 of file fe_monomial_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,MONOMIAL>::shape_second_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 76 of file fe_scalar_shape_0D.C.
{
return 0.;
}
Definition at line 98 of file fe_szabab_shape_3D.C.
{
std::cerr << 'Szabo-Babuska polynomials are not defined in 3D << std::endl;
libmesh_error();
return 0.;
}
Definition at line 84 of file fe_szabab_shape_3D.C.
{
std::cerr << 'Szabo-Babuska polynomials are not defined in 3D << std::endl;
libmesh_error();
return 0.;
}
Definition at line 206 of file fe_xyz_shape_1D.C.
References Elem::centroid(), and DofObject::id().
{
libmesh_assert (elem != NULL);
libmesh_assert (i <= order + elem->p_level());
// only d2()/dxi2 in 1D!
libmesh_assert (j == 0);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real xc = centroid(0);
const Real dx = x - xc;
// monomials. since they are hierarchic we only need one case block.
switch (i)
{
case 0:
case 1:
return 0.;
case 2:
return 2.;
case 3:
return 6.*dx;
case 4:
return 12.*dx*dx;
default:
Real val = 2.;
for (unsigned int index = 2; index != i; ++index)
val *= (index+1) * dx;
return val;
}
libmesh_error();
return 0.;
}
Definition at line 194 of file fe_szabab_shape_1D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Szabab elements '
<< ' are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 84 of file fe_szabab_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 66 of file fe_scalar_shape_1D.C.
{
return 0.;
}
Definition at line 76 of file fe_scalar_shape_3D.C.
{
return 0.;
}
Definition at line 713 of file fe_xyz_shape_3D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 98 of file fe_bernstein_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 390 of file fe_hierarchic_shape_2D.C.
{
std::cerr << 'Hierarchic polynomials require the element type
<< 'because edge orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 2983 of file fe_bernstein_shape_3D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Bernstein elements '
<< 'are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 394 of file fe_bernstein_shape_1D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Bernstein elements '
<< 'are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 98 of file fe_hermite_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 391 of file fe_xyz_shape_2D.C.
References Elem::centroid(), DofObject::id(), and Elem::p_level().
{
#if LIBMESH_DIM > 1
libmesh_assert (j<=2);
libmesh_assert (elem != NULL);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real y = p(1);
const Real xc = centroid(0);
const Real yc = centroid(1);
const Real dx = x - xc;
const Real dy = y - yc;
#ifndef NDEBUG
// totalorder is only used in the assertion below, so
// we avoid declaring it when asserts are not active.
const unsigned int totalorder = order + elem->p_level();
#endif
libmesh_assert (i < (totalorder+1)*(totalorder+2)/2);
// monomials. since they are hierarchic we only need one case block.
switch (j)
{
// d^2()/dx^2
case 0:
{
switch (i)
{
// constants
case 0:
// linears
case 1:
case 2:
return 0.;
// quadratics
case 3:
return 2.;
case 4:
case 5:
return 0.;
// cubics
case 6:
return 6.*dx;
case 7:
return 2.*dy;
case 8:
case 9:
return 0.;
// quartics
case 10:
return 12.*dx*dx;
case 11:
return 6.*dx*dy;
case 12:
return 2.*dy*dy;
case 13:
case 14:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int i2 = i - (o*(o+1)/2);
Real val = (o - i2) * (o - i2 - 1);
for (unsigned int index=i2+2; index < o; index++)
val *= dx;
for (unsigned int index=0; index != i2; index++)
val *= dy;
return val;
}
}
// d^2()/dxdy
case 1:
{
switch (i)
{
// constants
case 0:
// linears
case 1:
case 2:
return 0.;
// quadratics
case 3:
return 0.;
case 4:
return 1.;
case 5:
return 0.;
// cubics
case 6:
return 0.;
case 7:
return 2.*dx;
case 8:
return 2.*dy;
case 9:
return 0.;
// quartics
case 10:
return 0.;
case 11:
return 3.*dx*dx;
case 12:
return 4.*dx*dy;
case 13:
return 3.*dy*dy;
case 14:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int i2 = i - (o*(o+1)/2);
Real val = (o - i2) * i2;
for (unsigned int index=i2+1; index < o; index++)
val *= dx;
for (unsigned int index=1; index < i2; index++)
val *= dy;
return val;
}
}
// d^2()/dy^2
case 2:
{
switch (i)
{
// constants
case 0:
// linears
case 1:
case 2:
return 0.;
// quadratics
case 3:
case 4:
return 0.;
case 5:
return 2.;
// cubics
case 6:
return 0.;
case 7:
return 0.;
case 8:
return 2.*dx;
case 9:
return 6.*dy;
// quartics
case 10:
case 11:
return 0.;
case 12:
return 2.*dx*dx;
case 13:
return 6.*dx*dy;
case 14:
return 12.*dy*dy;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int i2 = i - (o*(o+1)/2);
Real val = i2 * (i2 - 1);
for (unsigned int index=i2; index != o; index++)
val *= dx;
for (unsigned int index=2; index < i2; index++)
val *= dy;
return val;
}
}
}
libmesh_error();
return 0.;
#endif
}
Definition at line 407 of file fe_hierarchic_shape_2D.C.
References libMesh::invalid_uint.
{
libmesh_assert (elem != NULL);
// I have been lazy here and am using finite differences
// to compute the derivatives!
const Real eps = 1.e-6;
Point pp, pm;
unsigned int prevj = libMesh::invalid_uint;
switch (j)
{
// d^2()/dxi^2
case 0:
{
pp = Point(p(0)+eps, p(1));
pm = Point(p(0)-eps, p(1));
prevj = 0;
break;
}
// d^2()/dxideta
case 1:
{
pp = Point(p(0), p(1)+eps);
pm = Point(p(0), p(1)-eps);
prevj = 0;
break;
}
// d^2()/deta^2
case 2:
{
pp = Point(p(0), p(1)+eps);
pm = Point(p(0), p(1)-eps);
prevj = 1;
break;
}
default:
libmesh_error();
}
return (FE<2,HIERARCHIC>::shape_deriv(elem, order, i, prevj, pp) -
FE<2,HIERARCHIC>::shape_deriv(elem, order, i, prevj, pm)
)/2./eps;
}
Definition at line 76 of file fe_scalar_shape_1D.C.
{
return 0.;
}
Definition at line 328 of file fe_hermite_shape_2D.C.
References FEHermite< Dim >::hermite_raw_shape(), FEHermite< Dim >::hermite_raw_shape_deriv(), FEHermite< Dim >::hermite_raw_shape_second_deriv(), Elem::p_level(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, and Elem::type().
{
libmesh_assert (elem != NULL);
libmesh_assert (j == 0 || j == 1 || j == 2);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (type)
{
case QUAD4:
libmesh_assert (totalorder < 4);
case QUAD8:
case QUAD9:
{
libmesh_assert (i<(totalorder+1u)*(totalorder+1u));
std::vector<unsigned int> bases1D;
Real coef = hermite_bases_2D(bases1D, dxdxi, totalorder, i);
switch (j)
{
case 0:
return coef *
FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1));
case 1:
return coef *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1));
case 2:
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[1],p(1));
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 594 of file fe_lagrange_shape_2D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMeshEnums::SECOND, libMeshEnums::TRI3, and libMeshEnums::TRI6.
{
#if LIBMESH_DIM > 1
// j = 0 ==> d^2 phi / dxi^2
// j = 1 ==> d^2 phi / dxi deta
// j = 2 ==> d^2 phi / deta^2
libmesh_assert (j < 3);
switch (order)
{
// linear Lagrange shape functions
case FIRST:
{
switch (type)
{
case QUAD4:
case QUAD8:
case QUAD9:
{
// Compute quad shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<4);
// 0 1 2 3
static const unsigned int i0[] = {0, 1, 1, 0};
static const unsigned int i1[] = {0, 0, 1, 1};
switch (j)
{
// d^2() / dxi^2
case 0:
return 0.;
// d^2() / dxi deta
case 1:
return (FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE2, FIRST, i1[1], 0, eta));
// d^2() / deta^2
case 2:
return 0.;
default:
{
std::cerr << 'ERROR: Invalid derivative requested! '
<< std::endl;
libmesh_error();
}
}
}
case TRI3:
case TRI6:
{
// All second derivatives for linear triangles are zero.
return 0.;
}
default:
{
std::cerr << 'ERROR: Unsupported 2D element type!: ' << type
<< std::endl;
libmesh_error();
}
} // end switch (type)
} // end case FIRST
// quadratic Lagrange shape functions
case SECOND:
{
switch (type)
{
case QUAD8:
{
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (j < 3);
switch (j)
{
// d^2() / dxi^2
case 0:
{
switch (i)
{
case 0:
case 1:
return 0.5*(1.-eta);
case 2:
case 3:
return 0.5*(1.+eta);
case 4:
return eta - 1.;
case 5:
case 7:
return 0.0;
case 6:
return -1. - eta;
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
}
// d^2() / dxi deta
case 1:
{
switch (i)
{
case 0:
return 0.25*( 1. - 2.*xi - 2.*eta);
case 1:
return 0.25*(-1. - 2.*xi + 2.*eta);
case 2:
return 0.25*( 1. + 2.*xi + 2.*eta);
case 3:
return 0.25*(-1. + 2.*xi - 2.*eta);
case 4:
return xi;
case 5:
return -eta;
case 6:
return -xi;
case 7:
return eta;
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
}
// d^2() / deta^2
case 2:
{
switch (i)
{
case 0:
case 3:
return 0.5*(1.-xi);
case 1:
case 2:
return 0.5*(1.+xi);
case 4:
case 6:
return 0.0;
case 5:
return -1.0 - xi;
case 7:
return xi - 1.0;
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
}
default:
{
std::cerr << 'ERROR: Invalid derivative requested! '
<< std::endl;
libmesh_error();
}
} // end switch (j)
} // end case QUAD8
case QUAD9:
{
// Compute QUAD9 second derivatives as tensor product
const Real xi = p(0);
const Real eta = p(1);
libmesh_assert (i<9);
// 0 1 2 3 4 5 6 7 8
static const unsigned int i0[] = {0, 1, 1, 0, 2, 1, 2, 0, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 2, 1, 2, 2};
switch (j)
{
// d^2() / dxi^2
case 0:
return (FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i1[i], eta));
// d^2() / dxi deta
case 1:
return (FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i1[i], 0, eta));
// d^2() / deta^2
case 2:
return (FE<1,LAGRANGE>::shape (EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i1[i], 0, eta));
default:
{
std::cerr << 'ERROR: Invalid derivative requested! '
<< std::endl;
libmesh_error();
}
} // end switch (j)
} // end case QUAD9
case TRI6:
{
const Real dzeta0dxi = -1.;
const Real dzeta1dxi = 1.;
const Real dzeta2dxi = 0.;
const Real dzeta0deta = -1.;
const Real dzeta1deta = 0.;
const Real dzeta2deta = 1.;
libmesh_assert (j < 3);
switch (j)
{
// d^2() / dxi^2
case 0:
{
switch (i)
{
case 0:
return 4.*dzeta0dxi*dzeta0dxi;
case 1:
return 4.*dzeta1dxi*dzeta1dxi;
case 2:
return 4.*dzeta2dxi*dzeta2dxi;
case 3:
return 8.*dzeta0dxi*dzeta1dxi;
case 4:
return 8.*dzeta1dxi*dzeta2dxi;
case 5:
return 8.*dzeta0dxi*dzeta2dxi;
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
}
// d^2() / dxi deta
case 1:
{
switch (i)
{
case 0:
return 4.*dzeta0dxi*dzeta0deta;
case 1:
return 4.*dzeta1dxi*dzeta1deta;
case 2:
return 4.*dzeta2dxi*dzeta2deta;
case 3:
return 4.*dzeta1deta*dzeta0dxi + 4.*dzeta0deta*dzeta1dxi;
case 4:
return 4.*dzeta2deta*dzeta1dxi + 4.*dzeta1deta*dzeta2dxi;
case 5:
return 4.*dzeta2deta*dzeta0dxi + 4.*dzeta0deta*dzeta2dxi;
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
}
// d^2() / deta^2
case 2:
{
switch (i)
{
case 0:
return 4.*dzeta0deta*dzeta0deta;
case 1:
return 4.*dzeta1deta*dzeta1deta;
case 2:
return 4.*dzeta2deta*dzeta2deta;
case 3:
return 8.*dzeta0deta*dzeta1deta;
case 4:
return 8.*dzeta1deta*dzeta2deta;
case 5:
return 8.*dzeta0deta*dzeta2deta;
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
}
default:
{
std::cerr << 'ERROR: Invalid derivative requested! '
<< std::endl;
libmesh_error();
}
} // end switch (j)
} // end case TRI6
default:
{
std::cerr << 'ERROR: Unsupported 2D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
} // end case SECOND
// unsupported order
default:
{
std::cerr << 'ERROR: Unsupported 2D FE order!: ' << order
<< std::endl;
libmesh_error();
}
} // end switch (order)
libmesh_error();
return 0.;
#endif // LIBMESH_DIM > 1
}
Definition at line 66 of file fe_scalar_shape_0D.C.
{
return 0.;
}
Note: Computing second derivatives is not currently supported for all element types: C1 (Clough and Hermite), Lagrange, Hierarchic, and Monomial are supported. All other element types return an error when asked for second derivatives.
On a p-refined element, o should be the base order of the element.
Definition at line 651 of file fe_monomial_shape_3D.C.
{
#if LIBMESH_DIM == 3
libmesh_assert (j<6);
libmesh_assert (i < (static_cast<unsigned int>(order)+1)*
(static_cast<unsigned int>(order)+2)*
(static_cast<unsigned int>(order)+3)/6);
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// monomials. since they are hierarchic we only need one case block.
switch (j)
{
// d^2()/dxi^2
case 0:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
return 2.;
case 5:
case 6:
case 7:
case 8:
case 9:
return 0.;
// cubic
case 10:
return 6.*xi;
case 11:
return 2.*eta;
case 12:
case 13:
return 0.;
case 14:
return 2.*zeta;
case 15:
case 16:
case 17:
case 18:
case 19:
return 0.;
// quartics
case 20:
return 12.*xi*xi;
case 21:
return 6.*xi*eta;
case 22:
return 2.*eta*eta;
case 23:
case 24:
return 0.;
case 25:
return 6.*xi*zeta;
case 26:
return 2.*eta*zeta;
case 27:
case 28:
return 0.;
case 29:
return 2.*zeta*zeta;
case 30:
case 31:
case 32:
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx * (nx - 1);
for (unsigned int index=2; index < nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
for (unsigned int index=0; index != nz; index++)
val *= zeta;
return val;
}
}
// d^2()/dxideta
case 1:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
return 0.;
case 5:
return 1.;
case 6:
case 7:
case 8:
case 9:
return 0.;
// cubic
case 10:
return 0.;
case 11:
return 2.*xi;
case 12:
return 2.*eta;
case 13:
case 14:
return 0.;
case 15:
return zeta;
case 16:
case 17:
case 18:
case 19:
return 0.;
// quartics
case 20:
return 0.;
case 21:
return 3.*xi*xi;
case 22:
return 4.*xi*eta;
case 23:
return 3.*eta*eta;
case 24:
case 25:
return 0.;
case 26:
return 2.*xi*zeta;
case 27:
return 2.*eta*zeta;
case 28:
case 29:
return 0.;
case 30:
return zeta*zeta;
case 31:
case 32:
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx * ny;
for (unsigned int index=1; index < nx; index++)
val *= xi;
for (unsigned int index=1; index < ny; index++)
val *= eta;
for (unsigned int index=0; index != nz; index++)
val *= zeta;
return val;
}
}
// d^2()/deta^2
case 2:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
return 0.;
case 6:
return 2.;
case 7:
case 8:
case 9:
return 0.;
// cubic
case 10:
case 11:
return 0.;
case 12:
return 2.*xi;
case 13:
return 6.*eta;
case 14:
case 15:
return 0.;
case 16:
return 2.*zeta;
case 17:
case 18:
case 19:
return 0.;
// quartics
case 20:
case 21:
return 0.;
case 22:
return 2.*xi*xi;
case 23:
return 6.*xi*eta;
case 24:
return 12.*eta*eta;
case 25:
case 26:
return 0.;
case 27:
return 2.*xi*zeta;
case 28:
return 6.*eta*zeta;
case 29:
case 30:
return 0.;
case 31:
return 2.*zeta*zeta;
case 32:
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = ny * (ny - 1);
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=2; index < ny; index++)
val *= eta;
for (unsigned int index=0; index != nz; index++)
val *= zeta;
return val;
}
}
// d^2()/dxidzeta
case 3:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
case 6:
return 0.;
case 7:
return 1.;
case 8:
case 9:
return 0.;
// cubic
case 10:
case 11:
case 12:
case 13:
return 0.;
case 14:
return 2.*xi;
case 15:
return eta;
case 16:
return 0.;
case 17:
return 2.*zeta;
case 18:
case 19:
return 0.;
// quartics
case 20:
case 21:
case 22:
case 23:
case 24:
return 0.;
case 25:
return 3.*xi*xi;
case 26:
return 2.*xi*eta;
case 27:
return eta*eta;
case 28:
return 0.;
case 29:
return 4.*xi*zeta;
case 30:
return 2.*eta*zeta;
case 31:
return 0.;
case 32:
return 3.*zeta*zeta;
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx * nz;
for (unsigned int index=1; index < nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
for (unsigned int index=1; index < nz; index++)
val *= zeta;
return val;
}
}
// d^2()/detadzeta
case 4:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
case 6:
case 7:
return 0.;
case 8:
return 1.;
case 9:
return 0.;
// cubic
case 10:
case 11:
case 12:
case 13:
case 14:
return 0.;
case 15:
return xi;
case 16:
return 2.*eta;
case 17:
return 0.;
case 18:
return 2.*zeta;
case 19:
return 0.;
// quartics
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
return 0.;
case 26:
return xi*xi;
case 27:
return 2.*xi*eta;
case 28:
return 3.*eta*eta;
case 29:
return 0.;
case 30:
return 2.*xi*zeta;
case 31:
return 4.*eta*zeta;
case 32:
return 0.;
case 33:
return 3.*zeta*zeta;
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = ny * nz;
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=1; index < ny; index++)
val *= eta;
for (unsigned int index=1; index < nz; index++)
val *= zeta;
return val;
}
}
// d^2()/dzeta^2
case 5:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
case 6:
case 7:
case 8:
return 0.;
case 9:
return 2.;
// cubic
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
return 0.;
case 17:
return 2.*xi;
case 18:
return 2.*eta;
case 19:
return 6.*zeta;
// quartics
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
return 0.;
case 29:
return 2.*xi*xi;
case 30:
return 2.*xi*eta;
case 31:
return 2.*eta*eta;
case 32:
return 6.*xi*zeta;
case 33:
return 6.*eta*zeta;
case 34:
return 12.*zeta*zeta;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nz * (nz - 1);
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
for (unsigned int index=2; index < nz; index++)
val *= zeta;
return val;
}
}
default:
libmesh_error();
}
#endif
libmesh_error();
return 0.;
}
Definition at line 146 of file fe_monomial_shape_1D.C.
{
// only d()/dxi in 1D!
libmesh_assert (j == 0);
const Real xi = p(0);
libmesh_assert (i <= static_cast<unsigned int>(order));
switch (i)
{
case 0:
case 1:
return 0.;
case 2:
return 2.;
case 3:
return 6.*xi;
case 4:
return 12.*xi*xi;
default:
Real val = 2.;
for (unsigned int index = 2; index != i; ++index)
val *= (index+1) * xi;
return val;
}
libmesh_error();
return 0.;
}
Definition at line 534 of file fe_monomial_shape_2D.C.
References Elem::p_level(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// by default call the orientation-independent shape functions
return FE<2,MONOMIAL>::shape_second_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 84 of file fe_xyz_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 274 of file fe_clough_shape_3D.C.
References Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
std::cerr << '3D Clough elements not yet implemented.'
<< std::endl;
libmesh_error();
clough_compute_coefs(elem);
const ElemType type = elem->type();
switch (order+elem->p_level())
{
// 3rd-order Clough-Tocher element
case THIRD:
{
switch (type)
{
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 84 of file fe_monomial_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Note: Computing second derivatives is not currently supported for all element types: C1 (Clough and Hermite), Lagrange, Hierarchic, and Monomial are supported. All other element types return an error when asked for second derivatives.
On a p-refined element, o should be the total order of the element.
Referenced by FEXYZ< Dim >::compute_shape_functions(), FE< Dim, T >::init_edge_shape_functions(), FE< Dim, T >::init_face_shape_functions(), FEXYZ< Dim >::init_shape_functions(), FE< Dim, T >::init_shape_functions(), and FE< Dim, T >::shape_second_deriv().
Definition at line 189 of file fe_xyz_shape_1D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 98 of file fe_xyz_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 782 of file fe_hierarchic_shape_3D.C.
{
std::cerr << 'Hierarchic polynomials require the element type
<< 'because edge and face orientation is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 1483 of file fe_lagrange_shape_3D.C.
References Elem::p_level(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape function derivatives
return FE<3,LAGRANGE>::shape_second_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 1395 of file fe_szabab_shape_2D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Szabab elements '
<< ' are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 1233 of file fe_lagrange_shape_3D.C.
References libMeshEnums::EDGE3, libMeshEnums::FIRST, libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::PRISM18, libMeshEnums::SECOND, libMeshEnums::TET10, and libMeshEnums::TRI6.
{
#if LIBMESH_DIM == 3
libmesh_assert (j<6);
switch (order)
{
// linear Lagrange shape functions
case FIRST:
{
return 0.;
}
// quadratic Lagrange shape functions
case SECOND:
{
switch (type)
{
// serendipity hexahedral quadratic shape functions
case HEX20:
{
static bool warning_given_HEX20 = false;
if (!warning_given_HEX20)
std::cerr << 'Second derivatives for 2D Lagrangian HEX20'
<< ' elements are not yet implemented!'
<< std::endl;
warning_given_HEX20 = true;
}
// triquadraic hexahedral shape funcions
case HEX27:
{
libmesh_assert (i<27);
// Compute hex shape functions as a tensor-product
const Real xi = p(0);
const Real eta = p(1);
const Real zeta = p(2);
// The only way to make any sense of this
// is to look at the mgflo/mg2/mgf documentation
// and make the cut-out cube!
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 0, 2, 2, 1, 2, 0, 2, 2};
static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1, 0, 2, 1, 2, 0, 0, 1, 1, 0, 2, 1, 2, 2, 0, 2, 1, 2, 2, 2};
static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 1, 1, 0, 2, 2, 2, 2, 1, 2};
switch(j)
{
// d^2()/dxi^2
case 0:
return (FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i1[i], eta)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i2[i], zeta));
// d^2()/dxideta
case 1:
return (FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i1[i], 0, eta)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i2[i], zeta));
// d^2()/deta^2
case 2:
return (FE<1,LAGRANGE>::shape (EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i1[i], 0, eta)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i2[i], zeta));
// d^2()/dxidzeta
case 3:
return (FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, xi)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i1[i], eta)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i2[i], 0, zeta));
// d^2()/detadzeta
case 4:
return (FE<1,LAGRANGE>::shape (EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i1[i], 0, eta)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i2[i], 0, zeta));
// d^2()/dzeta^2
case 5:
return (FE<1,LAGRANGE>::shape (EDGE3, SECOND, i0[i], xi)*
FE<1,LAGRANGE>::shape (EDGE3, SECOND, i1[i], eta)*
FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i2[i], 0, zeta));
default:
{
libmesh_error();
}
}
}
// quadratic tetrahedral shape functions
case TET10:
{
// The area coordinates are the same as used for the
// shape() and shape_deriv() functions.
// const Real zeta0 = 1. - zeta1 - zeta2 - zeta3;
// const Real zeta1 = p(0);
// const Real zeta2 = p(1);
// const Real zeta3 = p(2);
static const Real dzetadxi[4][3] =
{
{-1., -1., -1.},
{1., 0., 0.},
{0., 1., 0.},
{0., 0., 1.}
};
// Convert from j -> (j,k) indices for independent variable
// (0=xi, 1=eta, 2=zeta)
static const unsigned short int independent_var_indices[6][2] =
{
{0, 0}, // d^2 phi / dxi^2
{0, 1}, // d^2 phi / dxi deta
{1, 1}, // d^2 phi / deta^2
{0, 2}, // d^2 phi / dxi dzeta
{1, 2}, // d^2 phi / deta dzeta
{2, 2} // d^2 phi / dzeta^2
};
// Convert from i -> zeta indices. Each quadratic shape
// function for the Tet10 depends on up to two of the zeta
// area coordinate functions (see the shape() function above).
// This table just tells which two area coords it uses.
static const unsigned short int zeta_indices[10][2] =
{
{0, 0},
{1, 1},
{2, 2},
{3, 3},
{0, 1},
{1, 2},
{2, 0},
{0, 3},
{1, 3},
{2, 3},
};
// Look up the independent variable indices for this value of j.
const unsigned int my_j = independent_var_indices[j][0];
const unsigned int my_k = independent_var_indices[j][1];
if (i<4)
{
return 4.*dzetadxi[i][my_j]*dzetadxi[i][my_k];
}
else if (i<10)
{
const unsigned short int my_m = zeta_indices[i][0];
const unsigned short int my_n = zeta_indices[i][1];
return 4.*(dzetadxi[my_n][my_j]*dzetadxi[my_m][my_k] +
dzetadxi[my_m][my_j]*dzetadxi[my_n][my_k] );
}
else
{
std::cerr<< 'Invalid shape function index ' << i << std::endl;
libmesh_error();
}
}
// quadradic prism shape functions
case PRISM18:
{
libmesh_assert (i<18);
// Compute prism shape functions as a tensor-product
// of a triangle and an edge
Point p2d(p(0),p(1));
Point p1d(p(2));
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
static const unsigned int i0[] = {0, 0, 0, 1, 1, 1, 0, 0, 0, 2, 2, 2, 1, 1, 1, 2, 2, 2};
static const unsigned int i1[] = {0, 1, 2, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 3, 4, 5};
switch (j)
{
// d^2()/dxi^2
case 0:
return (FE<2,LAGRANGE>::shape_second_deriv(TRI6, SECOND, i1[i], 0, p2d)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], p1d));
// d^2()/dxideta
case 1:
return (FE<2,LAGRANGE>::shape_second_deriv(TRI6, SECOND, i1[i], 1, p2d)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], p1d));
// d^2()/deta^2
case 2:
return (FE<2,LAGRANGE>::shape_second_deriv(TRI6, SECOND, i1[i], 2, p2d)*
FE<1,LAGRANGE>::shape(EDGE3, SECOND, i0[i], p1d));
// d^2()/dxidzeta
case 3:
return (FE<2,LAGRANGE>::shape_deriv(TRI6, SECOND, i1[i], 0, p2d)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, p1d));
// d^2()/detadzeta
case 4:
return (FE<2,LAGRANGE>::shape_deriv(TRI6, SECOND, i1[i], 1, p2d)*
FE<1,LAGRANGE>::shape_deriv(EDGE3, SECOND, i0[i], 0, p1d));
// d^2()/dzeta^2
case 5:
return (FE<2,LAGRANGE>::shape(TRI6, SECOND, i1[i], p2d)*
FE<1,LAGRANGE>::shape_second_deriv(EDGE3, SECOND, i0[i], 0, p1d));
}
}
default:
{
std::cerr << 'ERROR: Unsupported 3D element type!: ' << type
<< std::endl;
libmesh_error();
}
}
}
// unsupported order
default:
{
std::cerr << 'ERROR: Unsupported 3D FE order!: ' << order
<< std::endl;
libmesh_error();
}
}
#endif
libmesh_error();
return 0.;
}
Definition at line 84 of file fe_lagrange_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 199 of file fe_hierarchic_shape_1D.C.
References Utility::pow(), Utility::pow< 2 >(), Utility::pow< 3 >(), and Utility::pow< 4 >().
{
// only d2()/d2xi in 1D!
libmesh_assert (j == 0);
libmesh_assert (i < order+1u);
// Declare that we are using our own special power function
// from the Utility namespace. This saves typing later.
using Utility::pow;
const Real xi = p(0);
Real returnval = 1.;
switch (i)
{
case 0:
case 1:
returnval = 0;
break;
// All terms have the same form.
// xi^(p-2)/(p-2)!
case 2:
returnval = 1;
break;
case 3:
returnval = xi;
break;
case 4:
returnval = pow<2>(xi)/2.;
break;
case 5:
returnval = pow<3>(xi)/6.;
break;
case 6:
returnval = pow<4>(xi)/24.;
break;
case 7:
returnval = pow<5>(xi)/120.;
break;
default:
Real denominator = 1.;
for (unsigned int n=1; n != i; ++n)
{
returnval *= xi;
denominator *= n;
}
// Odd:
if (i % 2)
returnval = (i * returnval - 1.)/denominator/i;
// Even:
else
returnval = returnval/denominator;
break;
}
return returnval;
}
Definition at line 174 of file fe_szabab_shape_1D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Szabab elements '
<< ' are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 84 of file fe_bernstein_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 799 of file fe_hierarchic_shape_3D.C.
References libMesh::invalid_uint.
{
libmesh_assert (elem != NULL);
const Real eps = 1.e-6;
Point pp, pm;
unsigned int prevj = libMesh::invalid_uint;
switch (j)
{
// d^2()/dxi^2
case 0:
{
pp = Point(p(0)+eps, p(1), p(2));
pm = Point(p(0)-eps, p(1), p(2));
prevj = 0;
break;
}
// d^2()/dxideta
case 1:
{
pp = Point(p(0), p(1)+eps, p(2));
pm = Point(p(0), p(1)-eps, p(2));
prevj = 0;
break;
}
// d^2()/deta^2
case 2:
{
pp = Point(p(0), p(1)+eps, p(2));
pm = Point(p(0), p(1)-eps, p(2));
prevj = 1;
break;
}
// d^2()/dxidzeta
case 3:
{
pp = Point(p(0), p(1), p(2)+eps);
pm = Point(p(0), p(1), p(2)-eps);
prevj = 0;
break;
}
// d^2()/detadzeta
case 4:
{
pp = Point(p(0), p(1), p(2)+eps);
pm = Point(p(0), p(1), p(2)-eps);
prevj = 1;
break;
}
// d^2()/dzeta^2
case 5:
{
pp = Point(p(0), p(1), p(2)+eps);
pm = Point(p(0), p(1), p(2)-eps);
prevj = 2;
break;
}
default:
libmesh_error();
}
return (FE<3,HIERARCHIC>::shape_deriv(elem, order, i, prevj, pp) -
FE<3,HIERARCHIC>::shape_deriv(elem, order, i, prevj, pm))
/ 2. / eps;
}
Definition at line 98 of file fe_clough_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 348 of file fe_hermite_shape_1D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, FEHermite< Dim >::hermite_raw_shape_second_deriv(), Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// Hermite cubic shape functions
case THIRD:
{
switch (type)
{
// C1 functions on the C1 cubic edge
case EDGE2:
case EDGE3:
{
switch (i)
{
case 0:
return FEHermite<1>::hermite_raw_shape_second_deriv(0, p(0));
case 1:
return d1xd1x * FEHermite<1>::hermite_raw_shape_second_deriv(2, p(0));
case 2:
return FEHermite<1>::hermite_raw_shape_second_deriv(1, p(0));
case 3:
return d2xd2x * FEHermite<1>::hermite_raw_shape_second_deriv(3, p(0));
default:
return FEHermite<1>::hermite_raw_shape_second_deriv(i, p(0));
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 374 of file fe_xyz_shape_2D.C.
{
std::cerr << 'XYZ polynomials require the element
<< 'because the centroid is needed.'
<< std::endl;
libmesh_error();
return 0.;
}
Definition at line 415 of file fe_bernstein_shape_1D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Bernstein elements '
<< 'are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 1792 of file fe_bernstein_shape_2D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Bernstein elements '
<< 'are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 1301 of file fe_monomial_shape_3D.C.
References Elem::p_level(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape function derivatives
return FE<3,MONOMIAL>::shape_second_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 84 of file fe_hermite_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 98 of file fe_monomial_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 3003 of file fe_bernstein_shape_3D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Bernstein elements '
<< 'are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 337 of file fe_lagrange_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,LAGRANGE>::shape_second_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 1834 of file fe_clough_shape_2D.C.
References Elem::p_level(), libMeshEnums::SECOND, libMeshEnums::THIRD, libMeshEnums::TRI6, and Elem::type().
{
libmesh_assert (elem != NULL);
clough_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 2nd-order restricted Clough-Tocher element
case SECOND:
{
switch (type)
{
// C1 functions on the Clough-Tocher triangle.
case TRI6:
{
libmesh_assert (i<9);
// FIXME: it would be nice to calculate (and cache)
// clough_raw_shape(j,p) only once per triangle, not 1-7
// times
switch (i)
{
// Note: these DoF numbers are 'scrambled' because my
// initial numbering conventions didn't match libMesh
case 0:
return clough_raw_shape_second_deriv(0, j, p)
+ d1d2n * clough_raw_shape_second_deriv(10, j, p)
+ d1d3n * clough_raw_shape_second_deriv(11, j, p);
case 3:
return clough_raw_shape_second_deriv(1, j, p)
+ d2d3n * clough_raw_shape_second_deriv(11, j, p)
+ d2d1n * clough_raw_shape_second_deriv(9, j, p);
case 6:
return clough_raw_shape_second_deriv(2, j, p)
+ d3d1n * clough_raw_shape_second_deriv(9, j, p)
+ d3d2n * clough_raw_shape_second_deriv(10, j, p);
case 1:
return d1xd1x * clough_raw_shape_second_deriv(3, j, p)
+ d1xd1y * clough_raw_shape_second_deriv(4, j, p)
+ d1xd2n * clough_raw_shape_second_deriv(10, j, p)
+ d1xd3n * clough_raw_shape_second_deriv(11, j, p)
+ 0.5 * N01x * d3nd3n * clough_raw_shape_second_deriv(11, j, p)
+ 0.5 * N02x * d2nd2n * clough_raw_shape_second_deriv(10, j, p);
case 2:
return d1yd1y * clough_raw_shape_second_deriv(4, j, p)
+ d1yd1x * clough_raw_shape_second_deriv(3, j, p)
+ d1yd2n * clough_raw_shape_second_deriv(10, j, p)
+ d1yd3n * clough_raw_shape_second_deriv(11, j, p)
+ 0.5 * N01y * d3nd3n * clough_raw_shape_second_deriv(11, j, p)
+ 0.5 * N02y * d2nd2n * clough_raw_shape_second_deriv(10, j, p);
case 4:
return d2xd2x * clough_raw_shape_second_deriv(5, j, p)
+ d2xd2y * clough_raw_shape_second_deriv(6, j, p)
+ d2xd3n * clough_raw_shape_second_deriv(11, j, p)
+ d2xd1n * clough_raw_shape_second_deriv(9, j, p)
+ 0.5 * N10x * d3nd3n * clough_raw_shape_second_deriv(11, j, p)
+ 0.5 * N12x * d1nd1n * clough_raw_shape_second_deriv(9, j, p);
case 5:
return d2yd2y * clough_raw_shape_second_deriv(6, j, p)
+ d2yd2x * clough_raw_shape_second_deriv(5, j, p)
+ d2yd3n * clough_raw_shape_second_deriv(11, j, p)
+ d2yd1n * clough_raw_shape_second_deriv(9, j, p)
+ 0.5 * N10y * d3nd3n * clough_raw_shape_second_deriv(11, j, p)
+ 0.5 * N12y * d1nd1n * clough_raw_shape_second_deriv(9, j, p);
case 7:
return d3xd3x * clough_raw_shape_second_deriv(7, j, p)
+ d3xd3y * clough_raw_shape_second_deriv(8, j, p)
+ d3xd1n * clough_raw_shape_second_deriv(9, j, p)
+ d3xd2n * clough_raw_shape_second_deriv(10, j, p)
+ 0.5 * N20x * d2nd2n * clough_raw_shape_second_deriv(10, j, p)
+ 0.5 * N21x * d1nd1n * clough_raw_shape_second_deriv(9, j, p);
case 8:
return d3yd3y * clough_raw_shape_second_deriv(8, j, p)
+ d3yd3x * clough_raw_shape_second_deriv(7, j, p)
+ d3yd1n * clough_raw_shape_second_deriv(9, j, p)
+ d3yd2n * clough_raw_shape_second_deriv(10, j, p)
+ 0.5 * N20y * d2nd2n * clough_raw_shape_second_deriv(10, j, p)
+ 0.5 * N21y * d1nd1n * clough_raw_shape_second_deriv(9, j, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// 3rd-order Clough-Tocher element
case THIRD:
{
switch (type)
{
// C1 functions on the Clough-Tocher triangle.
case TRI6:
{
libmesh_assert (i<12);
// FIXME: it would be nice to calculate (and cache)
// clough_raw_shape(j,p) only once per triangle, not 1-7
// times
switch (i)
{
// Note: these DoF numbers are 'scrambled' because my
// initial numbering conventions didn't match libMesh
case 0:
return clough_raw_shape_second_deriv(0, j, p)
+ d1d2n * clough_raw_shape_second_deriv(10, j, p)
+ d1d3n * clough_raw_shape_second_deriv(11, j, p);
case 3:
return clough_raw_shape_second_deriv(1, j, p)
+ d2d3n * clough_raw_shape_second_deriv(11, j, p)
+ d2d1n * clough_raw_shape_second_deriv(9, j, p);
case 6:
return clough_raw_shape_second_deriv(2, j, p)
+ d3d1n * clough_raw_shape_second_deriv(9, j, p)
+ d3d2n * clough_raw_shape_second_deriv(10, j, p);
case 1:
return d1xd1x * clough_raw_shape_second_deriv(3, j, p)
+ d1xd1y * clough_raw_shape_second_deriv(4, j, p)
+ d1xd2n * clough_raw_shape_second_deriv(10, j, p)
+ d1xd3n * clough_raw_shape_second_deriv(11, j, p);
case 2:
return d1yd1y * clough_raw_shape_second_deriv(4, j, p)
+ d1yd1x * clough_raw_shape_second_deriv(3, j, p)
+ d1yd2n * clough_raw_shape_second_deriv(10, j, p)
+ d1yd3n * clough_raw_shape_second_deriv(11, j, p);
case 4:
return d2xd2x * clough_raw_shape_second_deriv(5, j, p)
+ d2xd2y * clough_raw_shape_second_deriv(6, j, p)
+ d2xd3n * clough_raw_shape_second_deriv(11, j, p)
+ d2xd1n * clough_raw_shape_second_deriv(9, j, p);
case 5:
return d2yd2y * clough_raw_shape_second_deriv(6, j, p)
+ d2yd2x * clough_raw_shape_second_deriv(5, j, p)
+ d2yd3n * clough_raw_shape_second_deriv(11, j, p)
+ d2yd1n * clough_raw_shape_second_deriv(9, j, p);
case 7:
return d3xd3x * clough_raw_shape_second_deriv(7, j, p)
+ d3xd3y * clough_raw_shape_second_deriv(8, j, p)
+ d3xd1n * clough_raw_shape_second_deriv(9, j, p)
+ d3xd2n * clough_raw_shape_second_deriv(10, j, p);
case 8:
return d3yd3y * clough_raw_shape_second_deriv(8, j, p)
+ d3yd3x * clough_raw_shape_second_deriv(7, j, p)
+ d3yd1n * clough_raw_shape_second_deriv(9, j, p)
+ d3yd2n * clough_raw_shape_second_deriv(10, j, p);
case 10:
return d1nd1n * clough_raw_shape_second_deriv(9, j, p);
case 11:
return d2nd2n * clough_raw_shape_second_deriv(10, j, p);
case 9:
return d3nd3n * clough_raw_shape_second_deriv(11, j, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 322 of file fe_clough_shape_1D.C.
References libMeshEnums::EDGE2, libMeshEnums::EDGE3, Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
clough_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 3rd-order C1 cubic element
case THIRD:
{
switch (type)
{
// C1 functions on the C1 cubic edge
case EDGE2:
case EDGE3:
{
switch (i)
{
case 0:
return clough_raw_shape_second_deriv(0, j, p);
case 1:
return clough_raw_shape_second_deriv(1, j, p);
case 2:
return d1xd1x * clough_raw_shape_second_deriv(2, j, p);
case 3:
return d2xd2x * clough_raw_shape_second_deriv(3, j, p);
default:
libmesh_error();
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 730 of file fe_xyz_shape_3D.C.
References Elem::centroid(), DofObject::id(), and Elem::p_level().
{
#if LIBMESH_DIM == 3
libmesh_assert (elem != NULL);
libmesh_assert (j<3);
// Only recompute the centroid if the element
// has changed from the last one we computed.
// This avoids repeated centroid calculations
// when called in succession with the same element.
if (elem->id() != old_elem_id)
{
centroid = elem->centroid();
old_elem_id = elem->id();
}
const Real x = p(0);
const Real y = p(1);
const Real z = p(2);
const Real xc = centroid(0);
const Real yc = centroid(1);
const Real zc = centroid(2);
const Real dx = x - xc;
const Real dy = y - yc;
const Real dz = z - zc;
#ifndef NDEBUG
// totalorder is only used in the assertion below, so
// we avoid declaring it when asserts are not active.
const unsigned int totalorder = static_cast<Order>(order + elem->p_level());
#endif
libmesh_assert (i < (static_cast<unsigned int>(totalorder)+1)*
(static_cast<unsigned int>(totalorder)+2)*
(static_cast<unsigned int>(totalorder)+2)/6);
// monomials. since they are hierarchic we only need one case block.
switch (j)
{
// d^2()/dx^2
case 0:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
return 2.;
case 5:
case 6:
case 7:
case 8:
case 9:
return 0.;
// cubic
case 10:
return 6.*dx;
case 11:
return 2.*dy;
case 12:
case 13:
return 0.;
case 14:
return 2.*dz;
case 15:
case 16:
case 17:
case 18:
case 19:
return 0.;
// quartics
case 20:
return 12.*dx*dx;
case 21:
return 6.*dx*dy;
case 22:
return 2.*dy*dy;
case 23:
case 24:
return 0.;
case 25:
return 6.*dx*dz;
case 26:
return 2.*dy*dz;
case 27:
case 28:
return 0.;
case 29:
return 2.*dz*dz;
case 30:
case 31:
case 32:
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx * (nx - 1);
for (unsigned int index=2; index < nx; index++)
val *= dx;
for (unsigned int index=0; index != ny; index++)
val *= dy;
for (unsigned int index=0; index != nz; index++)
val *= dz;
return val;
}
}
// d^2()/dxdy
case 1:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
return 0.;
case 5:
return 1.;
case 6:
case 7:
case 8:
case 9:
return 0.;
// cubic
case 10:
return 0.;
case 11:
return 2.*dx;
case 12:
return 2.*dy;
case 13:
case 14:
return 0.;
case 15:
return dz;
case 16:
case 17:
case 18:
case 19:
return 0.;
// quartics
case 20:
return 0.;
case 21:
return 3.*dx*dx;
case 22:
return 4.*dx*dy;
case 23:
return 3.*dy*dy;
case 24:
case 25:
return 0.;
case 26:
return 2.*dx*dz;
case 27:
return 2.*dy*dz;
case 28:
case 29:
return 0.;
case 30:
return dz*dz;
case 31:
case 32:
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx * ny;
for (unsigned int index=1; index < nx; index++)
val *= dx;
for (unsigned int index=1; index < ny; index++)
val *= dy;
for (unsigned int index=0; index != nz; index++)
val *= dz;
return val;
}
}
// d^2()/dy^2
case 2:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
return 0.;
case 6:
return 2.;
case 7:
case 8:
case 9:
return 0.;
// cubic
case 10:
case 11:
return 0.;
case 12:
return 2.*dx;
case 13:
return 6.*dy;
case 14:
case 15:
return 0.;
case 16:
return 2.*dz;
case 17:
case 18:
case 19:
return 0.;
// quartics
case 20:
case 21:
return 0.;
case 22:
return 2.*dx*dx;
case 23:
return 6.*dx*dy;
case 24:
return 12.*dy*dy;
case 25:
case 26:
return 0.;
case 27:
return 2.*dx*dz;
case 28:
return 6.*dy*dz;
case 29:
case 30:
return 0.;
case 31:
return 2.*dz*dz;
case 32:
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = ny * (ny - 1);
for (unsigned int index=0; index != nx; index++)
val *= dx;
for (unsigned int index=2; index < ny; index++)
val *= dy;
for (unsigned int index=0; index != nz; index++)
val *= dz;
return val;
}
}
// d^2()/dxdz
case 3:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
case 6:
return 0.;
case 7:
return 1.;
case 8:
case 9:
return 0.;
// cubic
case 10:
case 11:
case 12:
case 13:
return 0.;
case 14:
return 2.*dx;
case 15:
return dy;
case 16:
return 0.;
case 17:
return 2.*dz;
case 18:
case 19:
return 0.;
// quartics
case 20:
case 21:
case 22:
case 23:
case 24:
return 0.;
case 25:
return 3.*dx*dx;
case 26:
return 2.*dx*dy;
case 27:
return dy*dy;
case 28:
return 0.;
case 29:
return 4.*dx*dz;
case 30:
return 2.*dy*dz;
case 31:
return 0.;
case 32:
return 3.*dz*dz;
case 33:
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nx * nz;
for (unsigned int index=1; index < nx; index++)
val *= dx;
for (unsigned int index=0; index != ny; index++)
val *= dy;
for (unsigned int index=1; index < nz; index++)
val *= dz;
return val;
}
}
// d^2()/dydz
case 4:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
case 6:
case 7:
return 0.;
case 8:
return 1.;
case 9:
return 0.;
// cubic
case 10:
case 11:
case 12:
case 13:
case 14:
return 0.;
case 15:
return dx;
case 16:
return 2.*dy;
case 17:
return 0.;
case 18:
return 2.*dz;
case 19:
return 0.;
// quartics
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
return 0.;
case 26:
return dx*dx;
case 27:
return 2.*dx*dy;
case 28:
return 3.*dy*dy;
case 29:
return 0.;
case 30:
return 2.*dx*dz;
case 31:
return 4.*dy*dz;
case 32:
return 0.;
case 33:
return 3.*dz*dz;
case 34:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = ny * nz;
for (unsigned int index=0; index != nx; index++)
val *= dx;
for (unsigned int index=1; index < ny; index++)
val *= dy;
for (unsigned int index=1; index < nz; index++)
val *= dz;
return val;
}
}
// d^2()/dz^2
case 5:
{
switch (i)
{
// constant
case 0:
// linear
case 1:
case 2:
case 3:
return 0.;
// quadratic
case 4:
case 5:
case 6:
case 7:
case 8:
return 0.;
case 9:
return 2.;
// cubic
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
case 16:
return 0.;
case 17:
return 2.*dx;
case 18:
return 2.*dy;
case 19:
return 6.*dz;
// quartics
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
case 26:
case 27:
case 28:
return 0.;
case 29:
return 2.*dx*dx;
case 30:
return 2.*dx*dy;
case 31:
return 2.*dy*dy;
case 32:
return 6.*dx*dz;
case 33:
return 6.*dy*dz;
case 34:
return 12.*dz*dz;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)*(o+3)/6; o++) { }
unsigned int i2 = i - (o*(o+1)*(o+2)/6);
unsigned int block=o, nz = 0;
for (; block < i2; block += (o-nz+1)) { nz++; }
const unsigned int nx = block - i2;
const unsigned int ny = o - nx - nz;
Real val = nz * (nz - 1);
for (unsigned int index=0; index != nx; index++)
val *= dx;
for (unsigned int index=0; index != ny; index++)
val *= dy;
for (unsigned int index=2; index < nz; index++)
val *= dz;
return val;
}
}
default:
libmesh_error();
}
#endif
libmesh_error();
return 0.;
}
Definition at line 98 of file fe_szabab_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 1812 of file fe_bernstein_shape_2D.C.
{
static bool warning_given = false;
if (!warning_given)
std::cerr << 'Second derivatives for Bernstein elements '
<< 'are not yet implemented!'
<< std::endl;
warning_given = true;
return 0.;
}
Definition at line 84 of file fe_clough_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Definition at line 68 of file fe_scalar_shape_2D.C.
{
return 0.;
}
Definition at line 317 of file fe_monomial_shape_2D.C.
{
#if LIBMESH_DIM > 1
libmesh_assert (j<=2);
libmesh_assert (i < (static_cast<unsigned int>(order)+1)*
(static_cast<unsigned int>(order)+2)/2);
const Real xi = p(0);
const Real eta = p(1);
// monomials. since they are hierarchic we only need one case block.
switch (j)
{
// d^2()/dxi^2
case 0:
{
switch (i)
{
// constants
case 0:
// linears
case 1:
case 2:
return 0.;
// quadratics
case 3:
return 2.;
case 4:
case 5:
return 0.;
// cubics
case 6:
return 6.*xi;
case 7:
return 2.*eta;
case 8:
case 9:
return 0.;
// quartics
case 10:
return 12.*xi*xi;
case 11:
return 6.*xi*eta;
case 12:
return 2.*eta*eta;
case 13:
case 14:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int ny = i - (o*(o+1)/2);
unsigned int nx = o - ny;
Real val = nx * (nx - 1);
for (unsigned int index=2; index < nx; index++)
val *= xi;
for (unsigned int index=0; index != ny; index++)
val *= eta;
return val;
}
}
// d^2()/dxideta
case 1:
{
switch (i)
{
// constants
case 0:
// linears
case 1:
case 2:
return 0.;
// quadratics
case 3:
return 0.;
case 4:
return 1.;
case 5:
return 0.;
// cubics
case 6:
return 0.;
case 7:
return 2.*xi;
case 8:
return 2.*eta;
case 9:
return 0.;
// quartics
case 10:
return 0.;
case 11:
return 3.*xi*xi;
case 12:
return 4.*xi*eta;
case 13:
return 3.*eta*eta;
case 14:
return 0.;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int ny = i - (o*(o+1)/2);
unsigned int nx = o - ny;
Real val = nx * ny;
for (unsigned int index=1; index < nx; index++)
val *= xi;
for (unsigned int index=1; index < ny; index++)
val *= eta;
return val;
}
}
// d^2()/deta^2
case 2:
{
switch (i)
{
// constants
case 0:
// linears
case 1:
case 2:
return 0.;
// quadratics
case 3:
case 4:
return 0.;
case 5:
return 2.;
// cubics
case 6:
return 0.;
case 7:
return 0.;
case 8:
return 2.*xi;
case 9:
return 6.*eta;
// quartics
case 10:
case 11:
return 0.;
case 12:
return 2.*xi*xi;
case 13:
return 6.*xi*eta;
case 14:
return 12.*eta*eta;
default:
unsigned int o = 0;
for (; i >= (o+1)*(o+2)/2; o++) { }
unsigned int ny = i - (o*(o+1)/2);
unsigned int nx = o - ny;
Real val = ny * (ny - 1);
for (unsigned int index=0; index != nx; index++)
val *= xi;
for (unsigned int index=2; index < ny; index++)
val *= eta;
return val;
}
}
}
libmesh_error();
return 0.;
#endif
}
Definition at line 983 of file fe_lagrange_shape_2D.C.
References Elem::p_level(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
// call the orientation-independent shape functions
return FE<2,LAGRANGE>::shape_second_deriv(elem->type(), static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 253 of file fe_lagrange_shape_1D.C.
References libMeshEnums::FIRST, libMeshEnums::SECOND, and libMeshEnums::THIRD.
{
// Don't need to switch on j. 1D shape functions
// depend on xi only!
const Real xi = p(0);
libmesh_assert (j == 0);
switch (order)
{
// linear Lagrange shape functions
case FIRST:
{
// All second derivatives of linears are zero....
return 0.;
}
// quadratic Lagrange shape functions
case SECOND:
{
switch (i)
{
case 0:
return 1.;
case 1:
return 1.;
case 2:
return -2.;
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
} // end case SECOND
case THIRD:
{
switch (i)
{
case 0:
return -9./16.*(6.*xi-2);
case 1:
return -9./16.*(-6*xi-2.);
case 2:
return 27./16.*(6*xi-2./3.);
case 3:
return 27./16.*(-6*xi-2./3.);
default:
{
std::cerr << 'Invalid shape function index requested!'
<< std::endl;
libmesh_error();
}
}
} // end case THIRD
default:
{
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
} // end switch (order)
libmesh_error();
return 0.;
}
Definition at line 267 of file fe_hierarchic_shape_1D.C.
References Elem::p_level(), FE< Dim, T >::shape_second_deriv(), and Elem::type().
{
libmesh_assert (elem != NULL);
return FE<1,HIERARCHIC>::shape_second_deriv(elem->type(),
static_cast<Order>(order + elem->p_level()), i, j, p);
}
Definition at line 78 of file fe_scalar_shape_2D.C.
{
return 0.;
}
Definition at line 66 of file fe_scalar_shape_3D.C.
{
return 0.;
}
Definition at line 538 of file fe_hermite_shape_3D.C.
References FEHermite< Dim >::hermite_raw_shape(), FEHermite< Dim >::hermite_raw_shape_deriv(), FEHermite< Dim >::hermite_raw_shape_second_deriv(), libMeshEnums::HEX20, libMeshEnums::HEX27, libMeshEnums::HEX8, Elem::p_level(), libMeshEnums::THIRD, and Elem::type().
{
libmesh_assert (elem != NULL);
hermite_compute_coefs(elem);
const ElemType type = elem->type();
const Order totalorder = static_cast<Order>(order + elem->p_level());
switch (totalorder)
{
// 3rd-order tricubic Hermite functions
case THIRD:
{
switch (type)
{
case HEX8:
case HEX20:
case HEX27:
{
libmesh_assert (i<64);
std::vector<unsigned int> bases1D;
Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
switch (j) // Derivative type
{
case 0:
return coef *
FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
break;
case 1:
return coef *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
break;
case 2:
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape(bases1D[2],p(2));
break;
case 3:
return coef *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[2],p(2));
break;
case 4:
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape_deriv(bases1D[2],p(2));
break;
case 5:
return coef *
FEHermite<1>::hermite_raw_shape(bases1D[0],p(0)) *
FEHermite<1>::hermite_raw_shape(bases1D[1],p(1)) *
FEHermite<1>::hermite_raw_shape_second_deriv(bases1D[2],p(2));
break;
}
}
default:
std::cerr << 'ERROR: Unsupported element type!' << std::endl;
libmesh_error();
}
}
// by default throw an error
default:
std::cerr << 'ERROR: Unsupported polynomial order!' << std::endl;
libmesh_error();
}
libmesh_error();
return 0.;
}
Definition at line 98 of file fe_lagrange_shape_0D.C.
{
// No spatial derivatives in 0D!
libmesh_error();
return 0.;
}
Implements FEBase.
Definition at line 1627 of file fe_bernstein.C.
{
// reinit is only necessary for
// approximation orders >= 3,
// but we might reach that with p refinement
// if(this->fe_type.order == FIRST ||
// this->fe_type.order == SECOND)
// return false;
// else
return true;
}
Reimplemented from FEBase.
Definition at line 424 of file fe.h.
Definition at line 1108 of file fe_base.C.
{
fe.print_info(os);
return os;
}
Definition at line 110 of file reference_counter.h.
Referenced by ReferenceCounter::get_info(), ReferenceCounter::increment_constructor_count(), and ReferenceCounter::increment_destructor_count().
Definition at line 123 of file reference_counter.h.
Definition at line 118 of file reference_counter.h.
Referenced by ReferenceCounter::n_objects(), ReferenceCounter::ReferenceCounter(), and ReferenceCounter::~ReferenceCounter().
Definition at line 1215 of file fe_base.h.
Referenced by FEBase::get_order(), FEBase::get_p_level(), and REINIT_ERROR().
Definition at line 432 of file fe.h.
Definition at line 936 of file fe_base.h.
Referenced by FEBase::compute_map(), FEBase::compute_shape_functions(), FEBase::get_d2phi(), FEBase::get_d2phidx2(), FEBase::get_d2phidxdy(), FEBase::get_d2phidxdz(), FEBase::get_d2phidy2(), FEBase::get_d2phidydz(), and FEBase::get_d2phidz2().
Definition at line 931 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), FEBase::get_dphi(), FEBase::get_dphideta(), FEBase::get_dphidx(), FEBase::get_dphidxi(), FEBase::get_dphidy(), FEBase::get_dphidz(), and FEBase::get_dphidzeta().
Definition at line 926 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_phi().
Definition at line 921 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), FEBase::get_d2phi(), FEBase::get_d2phidx2(), FEBase::get_d2phidxdy(), FEBase::get_d2phidxdz(), FEBase::get_d2phidy2(), FEBase::get_d2phidydz(), FEBase::get_d2phidz2(), FEBase::get_dphi(), FEBase::get_dphideta(), FEBase::get_dphidx(), FEBase::get_dphidxi(), FEBase::get_dphidy(), FEBase::get_dphidz(), FEBase::get_dphidzeta(), and FEBase::get_phi().
Definition at line 1192 of file fe_base.h.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), and FEBase::get_curvatures().
Definition at line 979 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), FEBase::get_d2phi(), and FEBase::print_d2phi().
Definition at line 999 of file fe_base.h.
Referenced by FEBase::compute_shape_functions().
Definition at line 1086 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 1004 of file fe_base.h.
Referenced by FEBase::compute_shape_functions().
Definition at line 1091 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 1014 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_d2phidx2().
Definition at line 1019 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_d2phidxdy().
Definition at line 1024 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_d2phidxdz().
Definition at line 984 of file fe_base.h.
Referenced by FEBase::compute_shape_functions().
Definition at line 1071 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 989 of file fe_base.h.
Referenced by FEBase::compute_shape_functions().
Definition at line 1076 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 994 of file fe_base.h.
Referenced by FEBase::compute_shape_functions().
Definition at line 1081 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 1029 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_d2phidy2().
Definition at line 1034 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_d2phidydz().
Definition at line 1039 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_d2phidz2().
Definition at line 1009 of file fe_base.h.
Referenced by FEBase::compute_shape_functions().
Definition at line 1096 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 1140 of file fe_base.h.
Referenced by FEBase::compute_face_map(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), and FE< Dim, T >::init_face_shape_functions().
Definition at line 1126 of file fe_base.h.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), FE< Dim, T >::init_edge_shape_functions(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), and FE< Dim, T >::init_face_shape_functions().
Definition at line 1133 of file fe_base.h.
Referenced by FEBase::compute_face_map(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), and FE< Dim, T >::init_face_shape_functions().
Definition at line 827 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_single_point_map(), FEBase::get_d2xyzdeta2(), and FEBase::resize_map_vectors().
Definition at line 841 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_single_point_map(), FEBase::get_d2xyzdetadzeta(), and FEBase::resize_map_vectors().
Definition at line 815 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_single_point_map(), FEBase::get_d2xyzdxi2(), and FEBase::resize_map_vectors().
Definition at line 821 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_single_point_map(), FEBase::get_d2xyzdxideta(), and FEBase::resize_map_vectors().
Definition at line 835 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_single_point_map(), FEBase::get_d2xyzdxidzeta(), and FEBase::resize_map_vectors().
Definition at line 847 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_single_point_map(), FEBase::get_d2xyzdzeta2(), and FEBase::resize_map_vectors().
Definition at line 876 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_detadx(), and FEBase::resize_map_vectors().
Definition at line 882 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_detady(), and FEBase::resize_map_vectors().
Definition at line 888 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_detadz(), and FEBase::resize_map_vectors().
Definition at line 784 of file fe_base.h.
Referenced by JumpErrorEstimator::coarse_n_flux_faces_increment(), FEBase::coarsened_dof_values(), FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), JumpErrorEstimator::estimate_error(), and FEBase::resize_map_vectors().
Definition at line 1156 of file fe_base.h.
Referenced by FEBase::get_dphase().
Definition at line 941 of file fe_base.h.
Referenced by FEBase::compute_periodic_constraints(), FEBase::compute_proj_constraints(), FEBase::compute_shape_functions(), FEBase::get_dphi(), FEBase::print_d2phi(), and FEBase::print_dphi().
Definition at line 951 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_dphideta().
Definition at line 1059 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 961 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_dphidx().
Definition at line 946 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_dphidxi().
Definition at line 1054 of file fe_base.h.
Referenced by FEBase::compute_single_point_map(), and InfFE< Dim, T_radial, T_map >::init_face_shape_functions().
Definition at line 966 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_dphidy().
Definition at line 971 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_dphidz().
Definition at line 956 of file fe_base.h.
Referenced by FEBase::compute_shape_functions(), and FEBase::get_dphidzeta().
Definition at line 1064 of file fe_base.h.
Referenced by FEBase::compute_single_point_map().
Definition at line 1119 of file fe_base.h.
Referenced by FEBase::compute_face_map(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), and FE< Dim, T >::init_face_shape_functions().
Definition at line 1113 of file fe_base.h.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), FE< Dim, T >::init_edge_shape_functions(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), and FE< Dim, T >::init_face_shape_functions().
Definition at line 1163 of file fe_base.h.
Referenced by FEBase::get_Sobolev_dweight().
Definition at line 855 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_dxidx(), and FEBase::resize_map_vectors().
Definition at line 861 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_dxidy(), and FEBase::resize_map_vectors().
Definition at line 867 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_dxidz(), and FEBase::resize_map_vectors().
Definition at line 803 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_single_point_map(), FEBase::dxdeta_map(), FEBase::dydeta_map(), FEBase::dzdeta_map(), FEBase::get_dxyzdeta(), and FEBase::resize_map_vectors().
Definition at line 797 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_single_point_map(), FEBase::dxdxi_map(), FEBase::dydxi_map(), FEBase::dzdxi_map(), FEBase::get_dxyzdxi(), and FEBase::resize_map_vectors().
Definition at line 809 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_single_point_map(), FEBase::dxdzeta_map(), FEBase::dydzeta_map(), FEBase::dzdzeta_map(), FEBase::get_dxyzdzeta(), and FEBase::resize_map_vectors().
Definition at line 898 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_dzetadx(), and FEBase::resize_map_vectors().
Definition at line 904 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_dzetady(), and FEBase::resize_map_vectors().
Definition at line 910 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_shape_functions(), FEBase::compute_single_point_map(), FEBase::get_dzetadz(), and FEBase::resize_map_vectors().
Definition at line 1209 of file fe_base.h.
Referenced by FEBase::coarsened_dof_values(), FE< Dim, T >::edge_reinit(), FEBase::get_type(), InfFE< Dim, T_radial, T_map >::reinit(), and REINIT_ERROR().
Definition at line 1203 of file fe_base.h.
Referenced by FEBase::coarsened_dof_values(), JumpErrorEstimator::estimate_error(), FE< Dim, T >::FE(), FEBase::get_family(), FEBase::get_fe_type(), FEBase::get_order(), InfFE< Dim, T_radial, T_map >::InfFE(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), and InfFE< Dim, T_radial, T_map >::reinit().
Definition at line 1197 of file fe_base.h.
Referenced by FEBase::coarsened_dof_values(), FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_periodic_constraints(), FEBase::compute_proj_constraints(), FEBase::compute_single_point_map(), FE< Dim, T >::edge_reinit(), FEBase::get_JxW(), FEBase::print_JxW(), InfFE< Dim, T_radial, T_map >::reinit(), REINIT_ERROR(), and FEBase::resize_map_vectors().
Definition at line 437 of file fe.h.
Definition at line 437 of file fe.h.
Definition at line 1185 of file fe_base.h.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), and FEBase::get_normals().
Definition at line 915 of file fe_base.h.
Referenced by FEBase::compute_periodic_constraints(), FEBase::compute_proj_constraints(), FEBase::get_phi(), and FEBase::print_phi().
Definition at line 1049 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_single_point_map(), and InfFE< Dim, T_radial, T_map >::init_face_shape_functions().
Definition at line 1107 of file fe_base.h.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), FE< Dim, T >::init_edge_shape_functions(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), and FE< Dim, T >::init_face_shape_functions().
Definition at line 1220 of file fe_base.h.
Referenced by FEBase::coarsened_dof_values(), FE< Dim, T >::edge_reinit(), JumpErrorEstimator::estimate_error(), InfFE< Dim, T_radial, T_map >::init_face_shape_functions(), InfFE< Dim, T_radial, T_map >::reinit(), and REINIT_ERROR().
Definition at line 1226 of file fe_base.h.
Definition at line 1180 of file fe_base.h.
Referenced by FEBase::compute_edge_map(), FEBase::compute_face_map(), and FEBase::get_tangents().
Definition at line 1170 of file fe_base.h.
Referenced by FEBase::get_Sobolev_weight().
Definition at line 789 of file fe_base.h.
Referenced by FEBase::compute_affine_map(), FEBase::compute_edge_map(), FEBase::compute_face_map(), FEBase::compute_single_point_map(), FE< Dim, T >::edge_reinit(), FEBase::get_xyz(), FEBase::print_xyz(), InfFE< Dim, T_radial, T_map >::reinit(), REINIT_ERROR(), and FEBase::resize_map_vectors().
Generated automatically by Doxygen for libMesh from the source code.