22 #include "libmesh/fe.h"
23 #include "libmesh/elem.h"
24 #include "libmesh/fe_interface.h"
25 #include "libmesh/number_lookups.h"
32 void hermite_compute_coefs(
const Elem * elem, std::vector<std::vector<Real>> & dxdxi
35 , std::vector<Real> & dydxi, std::vector<Real> & dzdeta, std::vector<Real> & dxdzeta,
36 std::vector<Real> & dzdxi, std::vector<Real> & dxdeta, std::vector<Real> & dydzeta
44 const FEType map_fe_type(mapping_order, mapping_family);
46 const int n_mapping_shape_functions =
55 for (
int p = 0; p != 2; ++p)
68 for (
int i = 0; i != n_mapping_shape_functions; ++i)
70 const Real ddxi = shape_deriv_ptr
71 (elem, mapping_order, i, 0, dofpt[p],
false);
72 const Real ddeta = shape_deriv_ptr
73 (elem, mapping_order, i, 1, dofpt[p],
false);
74 const Real ddzeta = shape_deriv_ptr
75 (elem, mapping_order, i, 2, dofpt[p],
false);
80 dxdxi[0][p] += point_i(0) * ddxi;
81 dxdxi[1][p] += point_i(1) * ddeta;
82 dxdxi[2][p] += point_i(2) * ddzeta;
84 dydxi[p] += point_i(1) * ddxi;
85 dzdeta[p] += point_i(2) * ddeta;
86 dxdzeta[p] += point_i(0) * ddzeta;
87 dzdxi[p] += point_i(2) * ddxi;
88 dxdeta[p] += point_i(0) * ddeta;
89 dydzeta[p] += point_i(1) * ddzeta;
111 Real hermite_bases_3D (std::vector<unsigned int> & bases1D,
112 const std::vector<std::vector<Real>> & dxdxi,
120 unsigned int e = o-2;
156 libmesh_error_msg(
"Invalid basis node = " << i/8);
159 unsigned int basisnum = i%8;
166 coef = dxdxi[0][bases1D[0]];
167 bases1D[0] += 2;
break;
169 coef = dxdxi[1][bases1D[1]];
170 bases1D[1] += 2;
break;
172 coef = dxdxi[0][bases1D[0]] * dxdxi[1][bases1D[1]];
173 bases1D[0] += 2; bases1D[1] += 2;
break;
175 coef = dxdxi[2][bases1D[2]];
176 bases1D[2] += 2;
break;
178 coef = dxdxi[0][bases1D[0]] * dxdxi[2][bases1D[2]];
179 bases1D[0] += 2; bases1D[2] += 2;
break;
181 coef = dxdxi[1][bases1D[1]] * dxdxi[2][bases1D[2]];
182 bases1D[1] += 2; bases1D[2] += 2;
break;
184 coef = dxdxi[0][bases1D[0]] * dxdxi[1][bases1D[1]] * dxdxi[2][bases1D[2]];
185 bases1D[0] += 2; bases1D[1] += 2; bases1D[2] += 2;
break;
187 libmesh_error_msg(
"Invalid basisnum = " << basisnum);
191 else if (i < 64 + 12*4*e)
193 unsigned int basisnum = (i - 64) % (4*e);
194 switch ((i - 64) / (4*e))
197 bases1D[0] = basisnum / 4 + 4;
198 bases1D[1] = basisnum % 4 / 2 * 2;
199 bases1D[2] = basisnum % 2 * 2;
200 if (basisnum % 4 / 2)
206 bases1D[0] = basisnum % 4 / 2 * 2 + 1;
207 bases1D[1] = basisnum / 4 + 4;
208 bases1D[2] = basisnum % 2 * 2;
209 if (basisnum % 4 / 2)
215 bases1D[0] = basisnum / 4 + 4;
216 bases1D[1] = basisnum % 4 / 2 * 2 + 1;
217 bases1D[2] = basisnum % 2 * 2;
218 if (basisnum % 4 / 2)
224 bases1D[0] = basisnum % 4 / 2 * 2;
225 bases1D[1] = basisnum / 4 + 4;
226 bases1D[2] = basisnum % 2 * 2;
227 if (basisnum % 4 / 2)
233 bases1D[0] = basisnum % 4 / 2 * 2;
234 bases1D[1] = basisnum % 2 * 2;
235 bases1D[2] = basisnum / 4 + 4;
236 if (basisnum % 4 / 2)
242 bases1D[0] = basisnum % 4 / 2 * 2 + 1;
243 bases1D[1] = basisnum % 2 * 2;
244 bases1D[2] = basisnum / 4 + 4;
245 if (basisnum % 4 / 2)
251 bases1D[0] = basisnum % 4 / 2 * 2 + 1;
252 bases1D[1] = basisnum % 2 * 2 + 1;
253 bases1D[2] = basisnum / 4 + 4;
254 if (basisnum % 4 / 2)
260 bases1D[0] = basisnum % 4 / 2 * 2;
261 bases1D[1] = basisnum % 2 * 2 + 1;
262 bases1D[2] = basisnum / 4 + 4;
263 if (basisnum % 4 / 2)
269 bases1D[0] = basisnum / 4 + 4;
270 bases1D[1] = basisnum % 4 / 2 * 2;
271 bases1D[2] = basisnum % 2 * 2 + 1;
272 if (basisnum % 4 / 2)
278 bases1D[0] = basisnum % 4 / 2 * 2 + 1;
279 bases1D[1] = basisnum / 4 + 4;
280 bases1D[2] = basisnum % 2 * 2;
281 if (basisnum % 4 / 2)
287 bases1D[0] = basisnum / 4 + 4;
288 bases1D[1] = basisnum % 4 / 2 * 2 + 1;
289 bases1D[2] = basisnum % 2 * 2 + 1;
290 if (basisnum % 4 / 2)
296 bases1D[0] = basisnum % 4 / 2 * 2;
297 bases1D[1] = basisnum / 4 + 4;
298 bases1D[2] = basisnum % 2 * 2 + 1;
299 if (basisnum % 4 / 2)
305 libmesh_error_msg(
"Invalid basis node = " << (i - 64) / (4*e));
309 else if (i < 64 + 12*4*e + 6*2*e*e)
311 unsigned int basisnum = (i - 64 - 12*4*e) % (2*e*e);
312 switch ((i - 64 - 12*4*e) / (2*e*e))
317 bases1D[2] = basisnum % 2 * 2;
323 bases1D[1] = basisnum % 2 * 2;
329 bases1D[0] = basisnum % 2 * 2 + 1;
337 bases1D[1] = basisnum % 2 * 2 + 1;
343 bases1D[0] = basisnum % 2 * 2;
352 bases1D[2] = basisnum % 2 * 2 + 1;
357 libmesh_error_msg(
"Invalid basis node = " << (i - 64 - 12*4*e) / (2*e*e));
363 unsigned int basisnum = i - 64 - 12*4*e;
388 libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
397 const unsigned int i,
399 const bool add_p_level)
403 std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
406 std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
407 std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
410 hermite_compute_coefs(elem, dxdxi
412 , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
418 const Order totalorder =
419 static_cast<Order>(order + add_p_level * elem->
p_level());
432 libmesh_assert_less (i, 64);
434 std::vector<unsigned int> bases1D;
436 Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
444 libmesh_error_msg(
"ERROR: Unsupported element type " << type);
449 libmesh_error_msg(
"ERROR: Unsupported polynomial order " << totalorder);
462 libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
471 const unsigned int i,
472 const unsigned int j,
474 const bool add_p_level)
479 std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
482 std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
483 std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
486 hermite_compute_coefs(elem, dxdxi
488 , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
494 const Order totalorder =
495 static_cast<Order>(order + add_p_level * elem->
p_level());
508 libmesh_assert_less (i, 64);
510 std::vector<unsigned int> bases1D;
512 Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
535 libmesh_error_msg(
"Invalid shape function derivative j = " << j);
540 libmesh_error_msg(
"ERROR: Unsupported element type " << type);
545 libmesh_error_msg(
"ERROR: Unsupported polynomial order " << totalorder);
550 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
559 libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
567 const unsigned int i,
568 const unsigned int j,
570 const bool add_p_level)
574 std::vector<std::vector<Real>> dxdxi(3, std::vector<Real>(2, 0));
577 std::vector<Real> dydxi(2), dzdeta(2), dxdzeta(2);
578 std::vector<Real> dzdxi(2), dxdeta(2), dydzeta(2);
581 hermite_compute_coefs(elem, dxdxi
583 , dydxi, dzdeta, dxdzeta, dzdxi, dxdeta, dydzeta
589 const Order totalorder =
590 static_cast<Order>(order + add_p_level * elem->
p_level());
603 libmesh_assert_less (i, 64);
605 std::vector<unsigned int> bases1D;
607 Real coef = hermite_bases_3D(bases1D, dxdxi, totalorder, i);
648 libmesh_error_msg(
"Invalid shape function derivative j = " << j);
653 libmesh_error_msg(
"ERROR: Unsupported element type " << type);
658 libmesh_error_msg(
"ERROR: Unsupported polynomial order " << totalorder);
662 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES