21 #include "libmesh/elem.h"
22 #include "libmesh/fe.h"
23 #include "libmesh/fe_interface.h"
24 #include "libmesh/fe_macro.h"
25 #include "libmesh/libmesh_logging.h"
26 #include "libmesh/quadrature.h"
27 #include "libmesh/tensor_value.h"
28 #include "libmesh/enum_elem_type.h"
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>
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(),
91 static_cast<Order>(o + elem->
p_level()), n);
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)
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(),
117 static_cast<Order>(o + elem->
p_level()), n);
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;
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());
195 cached_nodes[n] = elem->
point(n);
202 cached_nodes_still_fit =
true;
203 if (cached_nodes.size() != elem->
n_nodes())
204 cached_nodes_still_fit =
false;
208 if (!(elem->
point(n) - elem->
point(0)).relative_fuzzy_equals
209 ((cached_nodes[n] - cached_nodes[0]), 1e-13))
211 cached_nodes_still_fit =
false;
216 if (this->shapes_need_reinit() && !cached_nodes_still_fit)
218 this->_fe_map->template init_reference_to_physical_map<Dim>
219 (this->qrule->get_points(), elem);
220 this->init_shape_functions (this->qrule->get_points(), elem);
221 cached_nodes.resize(elem->
n_nodes());
223 cached_nodes[n] = elem->
point(n);
228 this->shapes_on_quadrature =
true;
242 this->qrule->get_points() =
243 std::vector<Point>(1,
Point(0));
245 this->qrule->get_weights() =
246 std::vector<Real>(1,1);
250 this->qrule->get_points().clear();
251 this->qrule->get_weights().clear();
254 this->init_shape_functions (this->qrule->get_points(), elem);
257 this->init_shape_functions (*pts, elem);
263 if (weights !=
nullptr)
265 this->_fe_map->compute_map (this->
dim, *weights, elem, this->calculate_d2phi);
269 std::vector<Real> dummy_weights (pts->size(), 1.);
270 this->_fe_map->compute_map (this->
dim, dummy_weights, elem, this->calculate_d2phi);
275 this->_fe_map->compute_map (this->
dim, this->qrule->get_weights(), elem, this->calculate_d2phi);
280 if (!cached_nodes_still_fit)
283 this->compute_shape_functions (elem,*pts);
285 this->compute_shape_functions(elem,this->qrule->get_points());
291 template <
unsigned int Dim, FEFamily T>
296 LOG_SCOPE(
"init_shape_functions()",
"FE");
299 const unsigned int n_qp = cast_int<unsigned int>(qp.size());
303 const unsigned int n_approx_shape_functions =
304 this->n_shape_functions(this->get_type(),
310 if (this->calculate_phi)
311 this->phi.resize (n_approx_shape_functions);
313 if (this->calculate_dphi)
315 this->dphi.resize (n_approx_shape_functions);
316 this->dphidx.resize (n_approx_shape_functions);
317 this->dphidy.resize (n_approx_shape_functions);
318 this->dphidz.resize (n_approx_shape_functions);
321 if (this->calculate_dphiref)
324 this->dphidxi.resize (n_approx_shape_functions);
327 this->dphideta.resize (n_approx_shape_functions);
330 this->dphidzeta.resize (n_approx_shape_functions);
333 if (this->calculate_curl_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
334 this->curl_phi.resize(n_approx_shape_functions);
336 if (this->calculate_div_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
337 this->div_phi.resize(n_approx_shape_functions);
339 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
340 if (this->calculate_d2phi)
342 this->d2phi.resize (n_approx_shape_functions);
343 this->d2phidx2.resize (n_approx_shape_functions);
344 this->d2phidxdy.resize (n_approx_shape_functions);
345 this->d2phidxdz.resize (n_approx_shape_functions);
346 this->d2phidy2.resize (n_approx_shape_functions);
347 this->d2phidydz.resize (n_approx_shape_functions);
348 this->d2phidz2.resize (n_approx_shape_functions);
351 this->d2phidxi2.resize (n_approx_shape_functions);
355 this->d2phidxideta.resize (n_approx_shape_functions);
356 this->d2phideta2.resize (n_approx_shape_functions);
360 this->d2phidxidzeta.resize (n_approx_shape_functions);
361 this->d2phidetadzeta.resize (n_approx_shape_functions);
362 this->d2phidzeta2.resize (n_approx_shape_functions);
365 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
367 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
369 if (this->calculate_phi)
370 this->phi[i].resize (n_qp);
371 if (this->calculate_dphi)
373 this->dphi[i].resize (n_qp);
374 this->dphidx[i].resize (n_qp);
375 this->dphidy[i].resize (n_qp);
376 this->dphidz[i].resize (n_qp);
379 if (this->calculate_dphiref)
382 this->dphidxi[i].resize(n_qp);
385 this->dphideta[i].resize(n_qp);
388 this->dphidzeta[i].resize(n_qp);
391 if (this->calculate_curl_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
392 this->curl_phi[i].resize(n_qp);
394 if (this->calculate_div_phi && (FEInterface::field_type(T) ==
TYPE_VECTOR))
395 this->div_phi[i].resize(n_qp);
397 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
398 if (this->calculate_d2phi)
400 this->d2phi[i].resize (n_qp);
401 this->d2phidx2[i].resize (n_qp);
402 this->d2phidxdy[i].resize (n_qp);
403 this->d2phidxdz[i].resize (n_qp);
404 this->d2phidy2[i].resize (n_qp);
405 this->d2phidydz[i].resize (n_qp);
406 this->d2phidz2[i].resize (n_qp);
408 this->d2phidxi2[i].resize (n_qp);
411 this->d2phidxideta[i].resize (n_qp);
412 this->d2phideta2[i].resize (n_qp);
416 this->d2phidxidzeta[i].resize (n_qp);
417 this->d2phidetadzeta[i].resize (n_qp);
418 this->d2phidzeta2[i].resize (n_qp);
421 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
425 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
433 this->
weight.resize (n_qp);
434 this->dweight.resize (n_qp);
435 this->dphase.resize (n_qp);
437 for (
unsigned int p=0; p<n_qp; p++)
440 this->dweight[p].zero();
441 this->dphase[p].zero();
445 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
462 if (this->calculate_dphiref)
463 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
464 for (
unsigned int p=0; p<n_qp; p++)
466 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
467 if (this->calculate_d2phi)
468 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
469 for (
unsigned int p=0; p<n_qp; p++)
471 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
483 if (this->calculate_dphiref)
484 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
485 for (
unsigned int p=0; p<n_qp; p++)
490 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
491 if (this->calculate_d2phi)
492 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
493 for (
unsigned int p=0; p<n_qp; p++)
499 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
512 if (this->calculate_dphiref)
513 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
514 for (
unsigned int p=0; p<n_qp; p++)
520 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
521 if (this->calculate_d2phi)
522 for (
unsigned int i=0; i<n_approx_shape_functions; i++)
523 for (
unsigned int p=0; p<n_qp; p++)
532 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
539 libmesh_error_msg(
"Invalid dimension Dim = " << Dim);
545 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
547 template <
unsigned int Dim, FEFamily T>
551 this->elem_type = e->
type();
552 this->_fe_map->template init_reference_to_physical_map<Dim>(qp, e);
553 init_shape_functions(qp, e);
556 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS