37 libmesh_assert_equal_to(LIBMESH_DIM, 3);
45 A.resize(valence + 12, valence + 12);
51 A(valence+ 1,0 ) = 0.125;
52 A(valence+ 1,1 ) = 0.375;
53 A(valence+ 1,valence ) = 0.375;
54 A(valence+ 2,0 ) = 0.0625;
55 A(valence+ 2,1 ) = 0.625;
56 A(valence+ 2,2 ) = 0.0625;
57 A(valence+ 2,valence ) = 0.0625;
58 A(valence+ 3,0 ) = 0.125;
59 A(valence+ 3,1 ) = 0.375;
60 A(valence+ 3,2 ) = 0.375;
61 A(valence+ 4,0 ) = 0.0625;
62 A(valence+ 4,1 ) = 0.0625;
63 A(valence+ 4,valence-1) = 0.0625;
64 A(valence+ 4,valence ) = 0.625;
65 A(valence+ 5,0 ) = 0.125;
66 A(valence+ 5,valence-1) = 0.375;
67 A(valence+ 5,valence ) = 0.375;
68 A(valence+ 6,1 ) = 0.375;
69 A(valence+ 6,valence ) = 0.125;
70 A(valence+ 7,1 ) = 0.375;
71 A(valence+ 8,1 ) = 0.375;
72 A(valence+ 8,2 ) = 0.125;
73 A(valence+ 9,1 ) = 0.125;
74 A(valence+ 9,valence ) = 0.375;
75 A(valence+10,valence ) = 0.375;
76 A(valence+11,valence-1) = 0.125;
77 A(valence+11,valence ) = 0.375;
80 A(valence+ 1,valence+1) = 0.125;
81 A(valence+ 2,valence+1) = 0.0625;
82 A(valence+ 2,valence+2) = 0.0625;
83 A(valence+ 2,valence+3) = 0.0625;
84 A(valence+ 3,valence+3) = 0.125;
85 A(valence+ 4,valence+1) = 0.0625;
86 A(valence+ 4,valence+4) = 0.0625;
87 A(valence+ 4,valence+5) = 0.0625;
88 A(valence+ 5,valence+5) = 0.125;
89 A(valence+ 6,valence+1) = 0.375;
90 A(valence+ 6,valence+2) = 0.125;
91 A(valence+ 7,valence+1) = 0.125;
92 A(valence+ 7,valence+2) = 0.375;
93 A(valence+ 7,valence+3) = 0.125;
94 A(valence+ 8,valence+2) = 0.125;
95 A(valence+ 8,valence+3) = 0.375;
96 A(valence+ 9,valence+1) = 0.375;
97 A(valence+ 9,valence+4) = 0.125;
98 A(valence+10,valence+1) = 0.125;
99 A(valence+10,valence+4) = 0.375;
100 A(valence+10,valence+5) = 0.125;
101 A(valence+11,valence+4) = 0.125;
102 A(valence+11,valence+5) = 0.375;
105 std::vector<Real> weights;
107 for (
unsigned int i = 0; i <= valence; ++i)
114 A(1,valence) = 0.125;
117 for (
unsigned int i = 2; i < valence; ++i)
126 A(valence,0) = 0.375;
127 A(valence,1) = 0.125;
128 A(valence,valence-1) = 0.125;
129 A(valence,valence ) = 0.375;
141 const Real u = 1 - v - w;
142 libmesh_assert_less_equal(0, v);
143 libmesh_assert_less_equal(0, w);
144 libmesh_assert_less_equal(0, u);
147 const Real factor = 1. / 12;
152 return factor*(pow<4>(u) + 2*u*u*u*v);
154 return factor*(pow<4>(u) + 2*u*u*u*w);
156 return factor*(pow<4>(u) + 2*u*u*u*w + 6*u*u*u*v + 6*u*u*v*w + 12*u*u*v*v + 6*u*v*v*w + 6*u*v*v*v +
157 2*v*v*v*w + pow<4>(v));
159 return factor*(6*pow<4>(u) + 24*u*u*u*w + 24*u*u*w*w + 8*u*w*w*w + pow<4>(w) + 24*u*u*u*v +
160 60*u*u*v*w + 36*u*v*w*w + 6*v*w*w*w + 24*u*u*v*v + 36*u*v*v*w + 12*v*v*w*w + 8*u*v*v*v +
161 6*v*v*v*w + pow<4>(v));
163 return factor*(pow<4>(u) + 6*u*u*u*w + 12*u*u*w*w + 6*u*w*w*w + pow<4>(w) + 2*u*u*u*v + 6*u*u*v*w +
164 6*u*v*w*w + 2*v*w*w*w);
166 return factor*(2*u*v*v*v + pow<4>(v));
168 return factor*(pow<4>(u) + 6*u*u*u*w + 12*u*u*w*w + 6*u*w*w*w + pow<4>(w) + 8*u*u*u*v + 36*u*u*v*w +
169 36*u*v*w*w + 8*v*w*w*w + 24*u*u*v*v + 60*u*v*v*w + 24*v*v*w*w + 24*u*v*v*v + 24*v*v*v*w + 6*pow<4>(v));
171 return factor*(pow<4>(u) + 8*u*u*u*w + 24*u*u*w*w + 24*u*w*w*w + 6*pow<4>(w) + 6*u*u*u*v + 36*u*u*v*w +
172 60*u*v*w*w + 24*v*w*w*w + 12*u*u*v*v + 36*u*v*v*w + 24*v*v*w*w + 6*u*v*v*v + 8*v*v*v*w + pow<4>(v));
174 return factor*(2*u*w*w*w + pow<4>(w));
176 return factor*(2*v*v*v*w + pow<4>(v));
178 return factor*(2*u*w*w*w + pow<4>(w) + 6*u*v*w*w + 6*v*w*w*w + 6*u*v*v*w + 12*v*v*w*w + 2*u*v*v*v +
179 6*v*v*v*w + pow<4>(v));
181 return factor*(pow<4>(w) + 2*v*w*w*w);
184 libmesh_error_msg(
"Invalid i = " << i);
191 const unsigned int j,
195 const Real u = 1 - v - w;
196 const Real factor = 1. / 12;
205 return factor*(-6*v*u*u - 2*u*u*u);
207 return factor*(-4*u*u*u - 6*u*u*w);
209 return factor*(-2*v*v*v - 6*v*v*u + 6*v*u*u + 2*u*u*u);
211 return factor*(-4*v*v*v - 24*v*v*u - 24*v*u*u - 18*v*v*w - 48*v*u*w - 12*u*u*w -
212 12*v*w*w - 12*u*w*w - 2*w*w*w);
214 return factor*(-6*v*u*u - 2*u*u*u - 12*v*u*w-12*u*u*w - 6*v*w*w - 18*u*w*w - 4*w*w*w);
216 return factor*(2*v*v*v + 6*v*v*u);
218 return factor*(24*v*v*u + 24*v*u*u + 4*u*u*u + 12*v*v*w + 48*v*u*w + 18*u*u*w +
219 12*v*w*w + 12*u*w*w + 2*w*w*w);
221 return factor*(-2*v*v*v - 6*v*v*u + 6*v*u*u + 2*u*u*u - 12*v*v*w + 12*u*u*w -
222 12*v*w*w + 12*u*w*w);
226 return factor*(4*v*v*v + 6*v*v*w);
228 return factor*(2*v*v*v + 6*v*v*u + 12*v*v*w + 12*v*u*w + 18*v*w*w + 6*u*w*w + 4*w*w*w);
232 libmesh_error_msg(
"Invalid i = " << i);
240 return factor*(-6*v*u*u - 4*u*u*u);
242 return factor*(-2*u*u*u - 6*u*u*w);
244 return factor*(-4*v*v*v - 18*v*v*u - 12*v*u*u - 2*u*u*u - 6*v*v*w - 12*v*u*w -
247 return factor*(-2*v*v*v-12*v*v*u - 12*v*u*u - 12*v*v*w - 48*v*u*w - 24*u*u*w -
248 18*v*w*w - 24*u*w*w - 4*w*w*w);
250 return factor*(2*u*u*u + 6*u*u*w - 6*u*w*w - 2*w*w*w);
254 return factor*(12*v*v*u + 12*v*u*u + 2*u*u*u - 12*v*v*w + 6*u*u*w - 12*v*w*w -
257 return factor*(2*v*v*v + 12*v*v*u + 18*v*u*u + 4*u*u*u + 12*v*v*w + 48*v*u*w +
258 24*u*u*w + 12*v*w*w + 24*u*w*w);
260 return factor*(6*u*w*w + 2*w*w*w);
264 return factor*(4*v*v*v + 6*v*v*u + 18*v*v*w + 12*v*u*w + 12*v*w*w + 6*u*w*w +
267 return factor*(6*v*w*w + 4*w*w*w);
269 libmesh_error_msg(
"Invalid i = " << i);
273 libmesh_error_msg(
"Invalid j = " << j);
280 const unsigned int j,
284 const Real u = 1 - v - w;
285 const Real factor = 1. / 12;
300 return v*v - 2*u*u + v*w - 2*u*w;
302 return v*u + v*w + u*w + w*w;
306 return factor*(-24*v*v + 12*u*u - 24*v*w + 12*u*w);
308 return -2*v*u - 2*v*w - 2*u*w - 2*w*w;
314 return v*u + v*w + u*w + w*w;
318 libmesh_error_msg(
"Invalid i = " << i);
326 return factor*(12*v*u + 6*u*u);
328 return factor*(6*u*u + 12*u*w);
330 return factor*(6*v*v - 12*v*u - 6*u*u);
332 return factor*(6*v*v - 12*u*u + 24*v*w + 6*w*w);
334 return factor*(-6*u*u - 12*u*w + 6*w*w);
338 return factor*(-12*v*v + 6*u*u - 24*v*w - 12*u*w - 6*w*w);
340 return factor*(-6*v*v - 12*v*u + 6*u*u - 24*v*w - 12*w*w);
346 return factor*(6*v*v + 12*v*u + 24*v*w + 12*u*w + 6*w*w);
350 libmesh_error_msg(
"Invalid i = " << i);
362 return v*v + v*u + v*w + u*w;
364 return -2*v*u - 2*u*u + v*w + w*w;
370 return -2*v*v - 2*v*u - 2*v*w - 2*u*w;
372 return v*u + u*u - 2*v*w - 2*w*w;
378 return v*v + v*u + v*w + u*w;
382 libmesh_error_msg(
"Invalid i = " << i);
386 libmesh_error_msg(
"Invalid j = " << j);
393 const unsigned int valence)
395 libmesh_assert_greater(valence, 0);
397 const Real nb_weight = (0.625 - Utility::pow<2>(0.375 + 0.25 * cs)) / valence;
398 weights.resize(1 + valence, nb_weight);
399 weights[0] = 1.0 - valence * nb_weight;
407 libmesh_assert(elem);
411 LOG_SCOPE(
"init_shape_functions()",
"FESubdivision");
415 const unsigned int valence = sd_elem->get_ordered_valence(0);
416 const unsigned int n_qp = cast_int<unsigned int>(qp.size());
417 const unsigned int n_approx_shape_functions = valence + 6;
420 phi.resize (n_approx_shape_functions);
421 dphi.resize (n_approx_shape_functions);
422 dphidxi.resize (n_approx_shape_functions);
423 dphideta.resize (n_approx_shape_functions);
424 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 425 d2phi.resize (n_approx_shape_functions);
426 d2phidxi2.resize (n_approx_shape_functions);
431 for (
unsigned int i = 0; i < n_approx_shape_functions; ++i)
433 phi[i].resize (n_qp);
434 dphi[i].resize (n_qp);
437 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 438 d2phi[i].resize (n_qp);
446 static const unsigned int cvi[12] = {3,6,2,0,1,4,7,10,9,5,11,8};
450 for (
unsigned int i = 0; i < n_approx_shape_functions; ++i)
452 for (
unsigned int p = 0; p < n_qp; ++p)
459 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 472 static const Real eps = 1e-10;
475 std::vector<Real> tphi(12);
476 std::vector<Real> tdphidxi(12);
477 std::vector<Real> tdphideta(12);
478 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 479 std::vector<Real> td2phidxi2(12);
480 std::vector<Real> td2phidxideta(12);
481 std::vector<Real> td2phideta2(12);
484 for (
unsigned int p = 0; p < n_qp; ++p)
492 while (!(u >
min-eps && u <
max+eps))
504 libmesh_assert_less(u, 0.5 + eps);
505 libmesh_assert_greater(u, -eps);
530 else if (w > 0.5 - eps)
536 P( 1,valence- 1) = 1;
539 P( 4,valence+ 5) = 1;
540 P( 5,valence+ 2) = 1;
541 P( 6,valence+ 1) = 1;
542 P( 7,valence+ 4) = 1;
543 P( 8,valence+11) = 1;
544 P( 9,valence+ 6) = 1;
545 P(10,valence+ 9) = 1;
546 P(11,valence+10) = 1;
568 if ((u > 1 + eps) || (u < -eps))
569 libmesh_error_msg(
"SUBDIVISION irregular patch: u is outside valid range!");
578 for (
int e = 1; e < k; ++e)
579 A.right_multiply(Acopy);
583 const Point transformed_p(v,w);
585 for (
unsigned int i = 0; i < 12; ++i)
591 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 600 Real sum1, sum2, sum3, sum4, sum5, sum6;
601 for (
unsigned int j = 0; j < n_approx_shape_functions; ++j)
603 sum1 = sum2 = sum3 = sum4 = sum5 = sum6 = 0;
604 for (
unsigned int i = 0; i < 12; ++i)
606 sum1 += P(i,j) * tphi[i];
607 sum2 += P(i,j) * tdphidxi[i];
608 sum3 += P(i,j) * tdphideta[i];
610 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 611 sum4 += P(i,j) * td2phidxi2[i];
612 sum5 += P(i,j) * td2phidxideta[i];
613 sum6 += P(i,j) * td2phideta2[i];
622 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 639 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 661 const std::vector<Point> *
const libmesh_dbg_var(pts),
662 const std::vector<Real> *
const)
664 libmesh_assert(elem);
670 LOG_SCOPE(
"reinit()",
"FESubdivision");
672 libmesh_assert(!sd_elem->is_ghost());
673 libmesh_assert(sd_elem->is_subdivision_updated());
676 libmesh_assert_equal_to(sd_elem->get_ordered_valence(1), 6);
677 libmesh_assert_equal_to(sd_elem->get_ordered_valence(2), 6);
683 libmesh_assert(pts ==
nullptr);
684 libmesh_assert(
qrule);
702 const unsigned int i,
712 libmesh_assert_less(i, 12);
713 return FESubdivision::regular_shape(i,p(0),p(1));
715 libmesh_error_msg(
"ERROR: Unsupported element type!");
719 libmesh_error_msg(
"ERROR: Unsupported polynomial order!");
728 const unsigned int i,
731 libmesh_assert(elem);
740 const unsigned int i,
741 const unsigned int j,
751 libmesh_assert_less(i, 12);
752 return FESubdivision::regular_shape_deriv(i,j,p(0),p(1));
754 libmesh_error_msg(
"ERROR: Unsupported element type!");
758 libmesh_error_msg(
"ERROR: Unsupported polynomial order!");
767 const unsigned int i,
768 const unsigned int j,
771 libmesh_assert(elem);
780 const unsigned int i,
781 const unsigned int j,
791 libmesh_assert_less(i, 12);
792 return FESubdivision::regular_shape_second_deriv(i,j,p(0),p(1));
794 libmesh_error_msg(
"ERROR: Unsupported element type!");
798 libmesh_error_msg(
"ERROR: Unsupported polynomial order!");
807 const unsigned int i,
808 const unsigned int j,
811 libmesh_assert(elem);
820 const std::vector<Number> & elem_soln,
821 std::vector<Number> & nodal_soln)
823 libmesh_assert(elem);
827 nodal_soln.resize(3);
830 if (sd_elem->is_ghost())
840 nodal_soln[j] = elem_soln[0];
843 j = sd_elem->local_node_number(sd_elem->get_ordered_node(1)->id());
844 nodal_soln[j] = elem_soln[1];
847 j = sd_elem->local_node_number(sd_elem->get_ordered_node(2)->id());
848 nodal_soln[j] = elem_soln[sd_elem->get_ordered_valence(0)];
859 const std::vector<Point> &,
860 std::vector<Point> &)
862 libmesh_not_implemented();
869 const std::vector<Point> *
const,
870 const std::vector<Real> *
const)
872 libmesh_not_implemented();
881 libmesh_not_implemented();
886 const std::vector<Point> &,
887 std::vector<Point> &,
891 libmesh_not_implemented();
std::vector< std::vector< OutputTensor > > d2phi
Manages the family, order, etc. parameters for a given FE.
virtual void init(const ElemType type=INVALID_ELEM, unsigned int p_level=0)
std::vector< std::vector< OutputShape > > dphidxi
FESubdivision(const FEType &fet)
static Real regular_shape(const unsigned int i, const Real v, const Real w)
bool calculations_started
bool shapes_on_quadrature
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
static void init_subdivision_matrix(DenseMatrix< Real > &A, unsigned int valence)
static void loop_subdivision_mask(std::vector< Real > &weights, const unsigned int valence)
std::vector< std::vector< OutputShape > > d2phidxideta
The base class for all geometric element types.
const std::vector< Real > & get_weights() const
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
long double max(long double a, double b)
virtual void attach_quadrature_rule(QBase *q) override
Template class which generates the different FE families and orders.
std::vector< std::vector< OutputShape > > phi
std::vector< std::vector< OutputShape > > d2phideta2
static Real regular_shape_second_deriv(const unsigned int i, const unsigned int j, const Real v, const Real w)
virtual void right_multiply(const DenseMatrixBase< T > &M2) override
A surface shell element used in mechanics calculations.
static Real regular_shape_deriv(const unsigned int i, const unsigned int j, const Real v, const Real w)
unsigned int local_node_number(unsigned int node_id) const
void determine_calculations()
double pow(double a, int b)
std::vector< std::vector< OutputGradient > > dphi
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const std::vector< Point > & get_points() const
static PetscErrorCode Mat * A
std::vector< std::vector< OutputShape > > d2phidxi2
virtual void init_shape_functions(const std::vector< Point > &qp, const Elem *elem) override
std::unique_ptr< FEMap > _fe_map
A matrix object used for finite element assembly and numerics.
virtual ElemType type() const =0
long double min(long double a, double b)
A geometric point in (x,y,z) space.
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr) override
Base class for all quadrature families and orders.
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
std::vector< std::vector< OutputShape > > dphideta