36 template <
unsigned int Dim, FEFamily T>
45 libmesh_assert_equal_to (T, this->get_family());
49 template <
unsigned int Dim, FEFamily T>
53 static_cast<Order>(this->fe_type.order + this->_p_level));
57 template <
unsigned int Dim, FEFamily T>
68 template <
unsigned int Dim, FEFamily T>
71 libmesh_assert(this->qrule);
72 return this->qrule->n_points();
76 template <
unsigned int Dim, FEFamily T>
80 std::vector<unsigned int> & di)
83 libmesh_assert_less (s, elem->
n_sides());
86 unsigned int nodenum = 0;
88 for (
unsigned int n = 0; n !=
n_nodes; ++n)
90 const unsigned int n_dofs = n_dofs_at_node(elem->
type(),
93 for (
unsigned int i = 0; i != n_dofs; ++i)
94 di.push_back(nodenum++);
102 template <
unsigned int Dim, FEFamily T>
106 std::vector<unsigned int> & di)
108 libmesh_assert(elem);
109 libmesh_assert_less (e, elem->
n_edges());
112 unsigned int nodenum = 0;
114 for (
unsigned int n = 0; n !=
n_nodes; ++n)
116 const unsigned int n_dofs = n_dofs_at_node(elem->
type(),
119 for (
unsigned int i = 0; i != n_dofs; ++i)
120 di.push_back(nodenum++);
128 template <
unsigned int Dim, FEFamily T>
130 const std::vector<Point> *
const pts,
131 const std::vector<Real> *
const weights)
138 this->determine_calculations();
142 bool cached_nodes_still_fit =
false;
152 this->elem_type = elem->
type();
153 this->_p_level = elem->
p_level();
156 this->_fe_map->template init_reference_to_physical_map<Dim>
158 this->init_shape_functions (*pts, elem);
161 this->shapes_on_quadrature =
false;
173 libmesh_assert(this->qrule);
176 if (this->qrule->shapes_need_reinit())
177 this->shapes_on_quadrature =
false;
179 if (this->elem_type != elem->
type() ||
180 this->_p_level != elem->
p_level() ||
181 !this->shapes_on_quadrature)
184 this->elem_type = elem->
type();
185 this->_p_level = elem->
p_level();
187 this->_fe_map->template init_reference_to_physical_map<Dim>
188 (this->qrule->get_points(), elem);
189 this->init_shape_functions (this->qrule->get_points(), elem);
191 if (this->shapes_need_reinit())
193 cached_nodes.resize(elem->
n_nodes());
194 for (
unsigned int n = 0; n != elem->
n_nodes(); ++n)
196 cached_nodes[n] = elem->
point(n);
204 cached_nodes_still_fit =
true;
205 if (cached_nodes.size() != elem->
n_nodes())
206 cached_nodes_still_fit =
false;
208 for (
unsigned int n = 1; n < elem->
n_nodes(); ++n)
210 if (!(elem->
point(n) - elem->
point(0)).relative_fuzzy_equals
211 ((cached_nodes[n] - cached_nodes[0]), 1e-13))
213 cached_nodes_still_fit =
false;
218 if (this->shapes_need_reinit() && !cached_nodes_still_fit)
220 this->_fe_map->template init_reference_to_physical_map<Dim>
221 (this->qrule->get_points(), elem);
222 this->init_shape_functions (this->qrule->get_points(), elem);
223 cached_nodes.resize(elem->
n_nodes());
224 for (
unsigned int n = 0; n != elem->
n_nodes(); ++n)
225 cached_nodes[n] = elem->
point(n);
230 this->shapes_on_quadrature =
true;
244 this->qrule->get_points() =
245 std::vector<Point>(1,
Point(0));
247 this->qrule->get_weights() =
248 std::vector<Real>(1,1);
252 this->qrule->get_points().clear();
253 this->qrule->get_weights().clear();
256 this->init_shape_functions (this->qrule->get_points(), elem);
259 this->init_shape_functions (*pts, elem);
265 if (weights !=
nullptr)
267 this->_fe_map->compute_map (this->dim, *weights, elem, this->calculate_d2phi);
271 std::vector<Real> dummy_weights (pts->size(), 1.);
272 this->_fe_map->compute_map (this->dim, dummy_weights, elem, this->calculate_d2phi);
277 this->_fe_map->compute_map (this->dim, this->qrule->get_weights(), elem, this->calculate_d2phi);
282 if (!cached_nodes_still_fit)
285 this->compute_shape_functions (elem,*pts);
287 this->compute_shape_functions(elem,this->qrule->get_points());
293 template <
unsigned int Dim, FEFamily T>
298 LOG_SCOPE(
"init_shape_functions()",
"FE");
301 const unsigned int n_qp = cast_int<unsigned int>(qp.size());
305 const unsigned int n_approx_shape_functions =
306 this->n_shape_functions(this->get_type(),
312 if (this->calculate_phi)
313 this->phi.resize (n_approx_shape_functions);
315 if (this->calculate_dphi)
317 this->dphi.resize (n_approx_shape_functions);
318 this->dphidx.resize (n_approx_shape_functions);
319 this->dphidy.resize (n_approx_shape_functions);
320 this->dphidz.resize (n_approx_shape_functions);
323 if (this->calculate_dphiref)
326 this->dphidxi.resize (n_approx_shape_functions);
329 this->dphideta.resize (n_approx_shape_functions);
332 this->dphidzeta.resize (n_approx_shape_functions);
335 if (this->calculate_curl_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
336 this->curl_phi.resize(n_approx_shape_functions);
338 if (this->calculate_div_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
339 this->div_phi.resize(n_approx_shape_functions);
341 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 342 if (this->calculate_d2phi)
344 this->d2phi.resize (n_approx_shape_functions);
345 this->d2phidx2.resize (n_approx_shape_functions);
346 this->d2phidxdy.resize (n_approx_shape_functions);
347 this->d2phidxdz.resize (n_approx_shape_functions);
348 this->d2phidy2.resize (n_approx_shape_functions);
349 this->d2phidydz.resize (n_approx_shape_functions);
350 this->d2phidz2.resize (n_approx_shape_functions);
353 this->d2phidxi2.resize (n_approx_shape_functions);
357 this->d2phidxideta.resize (n_approx_shape_functions);
358 this->d2phideta2.resize (n_approx_shape_functions);
362 this->d2phidxidzeta.resize (n_approx_shape_functions);
363 this->d2phidetadzeta.resize (n_approx_shape_functions);
364 this->d2phidzeta2.resize (n_approx_shape_functions);
367 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 369 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
371 if (this->calculate_phi)
372 this->phi[i].resize (n_qp);
373 if (this->calculate_dphi)
375 this->dphi[i].resize (n_qp);
376 this->dphidx[i].resize (n_qp);
377 this->dphidy[i].resize (n_qp);
378 this->dphidz[i].resize (n_qp);
381 if (this->calculate_dphiref)
384 this->dphidxi[i].resize(n_qp);
387 this->dphideta[i].resize(n_qp);
390 this->dphidzeta[i].resize(n_qp);
393 if (this->calculate_curl_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
394 this->curl_phi[i].resize(n_qp);
396 if (this->calculate_div_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
397 this->div_phi[i].resize(n_qp);
399 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 400 if (this->calculate_d2phi)
402 this->d2phi[i].resize (n_qp);
403 this->d2phidx2[i].resize (n_qp);
404 this->d2phidxdy[i].resize (n_qp);
405 this->d2phidxdz[i].resize (n_qp);
406 this->d2phidy2[i].resize (n_qp);
407 this->d2phidydz[i].resize (n_qp);
408 this->d2phidz2[i].resize (n_qp);
410 this->d2phidxi2[i].resize (n_qp);
413 this->d2phidxideta[i].resize (n_qp);
414 this->d2phideta2[i].resize (n_qp);
418 this->d2phidxidzeta[i].resize (n_qp);
419 this->d2phidetadzeta[i].resize (n_qp);
420 this->d2phidzeta2[i].resize (n_qp);
423 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 427 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 435 this->
weight.resize (n_qp);
436 this->dweight.resize (n_qp);
437 this->dphase.resize (n_qp);
439 for (
unsigned int p=0; p<n_qp; p++)
442 this->dweight[p].zero();
443 this->dphase[p].zero();
447 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 464 if (this->calculate_dphiref)
465 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
466 for (
unsigned int p=0; p<n_qp; p++)
468 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 469 if (this->calculate_d2phi)
470 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
471 for (
unsigned int p=0; p<n_qp; p++)
473 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 485 if (this->calculate_dphiref)
486 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
487 for (
unsigned int p=0; p<n_qp; p++)
492 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 493 if (this->calculate_d2phi)
494 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
495 for (
unsigned int p=0; p<n_qp; p++)
501 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 514 if (this->calculate_dphiref)
515 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
516 for (
unsigned int p=0; p<n_qp; p++)
522 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 523 if (this->calculate_d2phi)
524 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
525 for (
unsigned int p=0; p<n_qp; p++)
534 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 541 libmesh_error_msg(
"Invalid dimension Dim = " << Dim);
547 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 549 template <
unsigned int Dim, FEFamily T>
553 this->elem_type = e->
type();
554 this->_fe_map->template init_reference_to_physical_map<Dim>(qp, e);
555 init_shape_functions(qp, e);
558 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS Manages the family, order, etc. parameters for a given FE.
const unsigned int invalid_uint
INSTANTIATE_SUBDIVISION_FE
The base class for all geometric element types.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
unsigned int p_level() const
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const =0
Template class which generates the different FE families and orders.
const dof_id_type n_nodes
virtual unsigned int n_nodes() const =0
virtual unsigned int n_edges() const =0
virtual unsigned int n_sides() const =0
virtual ElemType type() const =0
A geometric point in (x,y,z) space.
const Point & point(const unsigned int i) const
Base class for all quadrature families and orders.