37 void xyz_nodal_soln(
const Elem * elem,
39 const std::vector<Number> & elem_soln,
40 std::vector<Number> & nodal_soln,
43 const unsigned int n_nodes = elem->n_nodes();
45 const ElemType elem_type = elem->type();
49 const Order totalorder =
static_cast<Order>(order + elem->p_level());
56 libmesh_assert_equal_to (elem_soln.size(), 1);
58 const Number val = elem_soln[0];
60 for (
unsigned int n=0; n<
n_nodes; n++)
72 FEType fe_type(totalorder,
XYZ);
74 const unsigned int n_sf =
78 for (
unsigned int n=0; n<
n_nodes; n++)
80 libmesh_assert_equal_to (elem_soln.size(), n_sf);
86 for (
unsigned int i=0; i<n_sf; i++)
87 nodal_soln[n] += elem_soln[i] *
297 const unsigned int order =
static_cast<unsigned int>(o);
315 return (order+1)*(order+2)/2;
328 return (order+1)*(order+2)*(order+3)/6;
343 unsigned int xyz_n_dofs_per_elem(
const ElemType t,
544 const unsigned int order =
static_cast<unsigned int>(o);
562 return (order+1)*(order+2)/2;
575 return (order+1)*(order+2)*(order+3)/6;
597 template <
unsigned int Dim>
599 const Elem * libmesh_dbg_var(elem))
601 libmesh_assert(elem);
602 this->calculations_started =
true;
606 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 607 if (!this->calculate_phi && !this->calculate_dphi && !this->calculate_d2phi)
608 this->calculate_phi = this->calculate_dphi = this->calculate_d2phi =
true;
610 if (!this->calculate_phi && !this->calculate_dphi)
611 this->calculate_phi = this->calculate_dphi =
true;
612 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 615 LOG_SCOPE(
"init_shape_functions()",
"FE");
618 const std::size_t n_qp = qp.size();
622 const unsigned int n_approx_shape_functions =
623 this->n_shape_functions(this->get_type(),
630 if (this->calculate_phi)
631 this->phi.resize (n_approx_shape_functions);
632 if (this->calculate_dphi)
634 this->dphi.resize (n_approx_shape_functions);
635 this->dphidx.resize (n_approx_shape_functions);
636 this->dphidy.resize (n_approx_shape_functions);
637 this->dphidz.resize (n_approx_shape_functions);
640 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 641 if (this->calculate_d2phi)
643 this->d2phi.resize (n_approx_shape_functions);
644 this->d2phidx2.resize (n_approx_shape_functions);
645 this->d2phidxdy.resize (n_approx_shape_functions);
646 this->d2phidxdz.resize (n_approx_shape_functions);
647 this->d2phidy2.resize (n_approx_shape_functions);
648 this->d2phidydz.resize (n_approx_shape_functions);
649 this->d2phidz2.resize (n_approx_shape_functions);
650 this->d2phidxi2.resize (n_approx_shape_functions);
652 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 654 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
656 if (this->calculate_phi)
657 this->phi[i].resize (n_qp);
658 if (this->calculate_dphi)
660 this->dphi[i].resize (n_qp);
661 this->dphidx[i].resize (n_qp);
662 this->dphidy[i].resize (n_qp);
663 this->dphidz[i].resize (n_qp);
665 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 666 if (this->calculate_d2phi)
668 this->d2phi[i].resize (n_qp);
669 this->d2phidx2[i].resize (n_qp);
670 this->d2phidxdy[i].resize (n_qp);
671 this->d2phidxdz[i].resize (n_qp);
672 this->d2phidy2[i].resize (n_qp);
673 this->d2phidydz[i].resize (n_qp);
674 this->d2phidz2[i].resize (n_qp);
676 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 682 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 690 this->
weight.resize (n_qp);
691 this->dweight.resize (n_qp);
692 this->dphase.resize (n_qp);
694 for (
unsigned int p=0; p<n_qp; p++)
697 this->dweight[p].zero();
698 this->dphase[p].zero();
702 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 708 template <
unsigned int Dim>
710 const std::vector<Point> &)
712 libmesh_assert(elem);
720 LOG_SCOPE(
"compute_shape_functions()",
"FE");
722 const std::vector<Point> & xyz_qp = this->get_xyz();
730 if (this->calculate_phi)
735 if (this->calculate_dphi)
739 this->dphi[i][p](0) =
742 this->dphi[i][p](1) = this->dphidy[i][p] = 0.;
743 this->dphi[i][p](2) = this->dphidz[i][p] = 0.;
745 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 746 if (this->calculate_d2phi)
750 this->d2phi[i][p](0,0) =
754 this->d2phi[i][p](0,1) = this->d2phidxdy[i][p] =
755 this->d2phi[i][p](1,0) = 0.;
756 this->d2phi[i][p](1,1) = this->d2phidy2[i][p] = 0.;
758 this->d2phi[i][p](0,2) = this->d2phidxdz[i][p] =
759 this->d2phi[i][p](2,0) = 0.;
760 this->d2phi[i][p](1,2) = this->d2phidydz[i][p] =
761 this->d2phi[i][p](2,1) = 0.;
762 this->d2phi[i][p](2,2) = this->d2phidz2[i][p] = 0.;
766 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 774 if (this->calculate_phi)
779 if (this->calculate_dphi)
783 this->dphi[i][p](0) =
786 this->dphi[i][p](1) =
790 this->dphi[i][p](2) =
792 this->dphidz[i][p] = 0.;
794 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 795 if (this->calculate_d2phi)
799 this->d2phi[i][p](0,0) =
802 this->d2phi[i][p](0,1) = this->d2phidxdy[i][p] =
804 this->d2phi[i][p](1,1) =
807 this->d2phi[i][p](0,2) = this->d2phidxdz[i][p] =
808 this->d2phi[i][p](2,0) = 0.;
809 this->d2phi[i][p](1,2) = this->d2phidydz[i][p] =
810 this->d2phi[i][p](2,1) = 0.;
811 this->d2phi[i][p](2,2) = this->d2phidz2[i][p] = 0.;
814 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 822 if (this->calculate_phi)
827 if (this->calculate_dphi)
831 this->dphi[i][p](0) =
834 this->dphi[i][p](1) =
837 this->dphi[i][p](2) =
840 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 841 if (this->calculate_d2phi)
845 this->d2phi[i][p](0,0) =
848 this->d2phi[i][p](0,1) = this->d2phidxdy[i][p] =
850 this->d2phi[i][p](1,1) =
852 this->d2phi[i][p](0,2) = this->d2phidxdz[i][p] =
854 this->d2phi[i][p](1,2) = this->d2phidydz[i][p] =
858 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 865 libmesh_error_msg(
"ERROR: Invalid dimension " << this->dim);
878 const std::vector<Number> & elem_soln,
879 std::vector<Number> & nodal_soln)
880 { xyz_nodal_soln(elem, order, elem_soln, nodal_soln, 0); }
885 const std::vector<Number> & elem_soln,
886 std::vector<Number> & nodal_soln)
887 { xyz_nodal_soln(elem, order, elem_soln, nodal_soln, 1); }
892 const std::vector<Number> & elem_soln,
893 std::vector<Number> & nodal_soln)
894 { xyz_nodal_soln(elem, order, elem_soln, nodal_soln, 2); }
899 const std::vector<Number> & elem_soln,
900 std::vector<Number> & nodal_soln)
901 { xyz_nodal_soln(elem, order, elem_soln, nodal_soln, 3); }
937 #ifdef LIBMESH_ENABLE_AMR 945 #endif // #ifdef LIBMESH_ENABLE_AMR static unsigned int n_dofs(const ElemType t, const Order o)
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
The base class for all geometric element types.
IntRange< std::size_t > index_range(const std::vector< T > &vec)
static unsigned int n_dofs_at_node(const ElemType t, const Order o, const unsigned int n)
virtual bool shapes_need_reinit() const override
virtual void init_shape_functions(const std::vector< Point > &qp, const Elem *e) override
virtual bool is_hierarchic() const override
Manages the degrees of freedom (DOFs) in a simulation.
Template class which generates the different FE families and orders.
const dof_id_type n_nodes
static unsigned int n_shape_functions(const unsigned int dim, const FEType &fe_t, const ElemType t)
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
static unsigned int n_dofs_per_elem(const ElemType t, const Order o)
virtual FEContinuity get_continuity() const override
std::string enum_to_string(const T e)
static void compute_constraints(DofConstraints &constraints, DofMap &dof_map, const unsigned int variable_number, const Elem *elem)
virtual void compute_shape_functions(const Elem *elem, const std::vector< Point > &qp) override
static void nodal_soln(const Elem *elem, const Order o, const std::vector< Number > &elem_soln, std::vector< Number > &nodal_soln)
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)