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
34 , std::vector<Real> & dxdeta, std::vector<Real> & dydxi
42 const FEType map_fe_type(mapping_order, mapping_family);
44 const int n_mapping_shape_functions =
48 std::vector<Point> dofpt;
49 dofpt.push_back(
Point(-1,-1));
50 dofpt.push_back(
Point(1,1));
55 for (
int p = 0; p != 2; ++p)
63 for (
int i = 0; i != n_mapping_shape_functions; ++i)
65 const Real ddxi = shape_deriv_ptr
66 (elem, mapping_order, i, 0, dofpt[p],
false);
67 const Real ddeta = shape_deriv_ptr
68 (elem, mapping_order, i, 1, dofpt[p],
false);
70 dxdxi[0][p] += elem->
point(i)(0) * ddxi;
71 dxdxi[1][p] += elem->
point(i)(1) * ddeta;
74 dxdeta[p] += elem->
point(i)(0) * ddeta;
75 dydxi[p] += elem->
point(i)(1) * ddxi;
83 libmesh_assert_less (
std::abs(dxdeta[p]), 1e-9);
84 libmesh_assert_less (
std::abs(dydxi[p]), 1e-9);
91 Real hermite_bases_2D (std::vector<unsigned int> & bases1D,
92 const std::vector<std::vector<Real>> & dxdxi,
100 unsigned int e = o-3;
120 libmesh_error_msg(
"Invalid basis node = " << i/4);
123 unsigned int basisnum = i%4;
130 coef = dxdxi[0][bases1D[0]];
131 bases1D[0] += 2;
break;
133 coef = dxdxi[1][bases1D[1]];
134 bases1D[1] += 2;
break;
136 coef = dxdxi[0][bases1D[0]] * dxdxi[1][bases1D[1]];
137 bases1D[0] += 2; bases1D[1] += 2;
break;
139 libmesh_error_msg(
"Invalid basisnum = " << basisnum);
143 else if (i < 16 + 4*2*e)
145 unsigned int basisnum = (i - 16) % (2*e);
146 switch ((i - 16) / (2*e))
149 bases1D[0] = basisnum/2 + 4;
150 bases1D[1] = basisnum%2*2;
155 bases1D[0] = basisnum%2*2 + 1;
156 bases1D[1] = basisnum/2 + 4;
161 bases1D[0] = basisnum/2 + 4;
162 bases1D[1] = basisnum%2*2 + 1;
167 bases1D[0] = basisnum%2*2;
168 bases1D[1] = basisnum/2 + 4;
173 libmesh_error_msg(
"Invalid basisnum = " << basisnum);
179 unsigned int basisnum = i - 16 - 8*e;
202 libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
211 const unsigned int i,
213 const bool add_p_level)
217 std::vector<std::vector<Real>> dxdxi(2, std::vector<Real>(2, 0));
220 std::vector<Real> dxdeta(2), dydxi(2);
223 hermite_compute_coefs(elem,dxdxi
231 const Order totalorder =
232 static_cast<Order>(order + add_p_level * elem->
p_level());
238 libmesh_assert_less (totalorder, 4);
239 libmesh_fallthrough();
244 libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u));
246 std::vector<unsigned int> bases1D;
248 Real coef = hermite_bases_2D(bases1D, dxdxi, totalorder, i);
254 libmesh_error_msg(
"ERROR: Unsupported element type = " << type);
267 libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
276 const unsigned int i,
277 const unsigned int j,
279 const bool add_p_level)
284 std::vector<std::vector<Real>> dxdxi(2, std::vector<Real>(2, 0));
287 std::vector<Real> dxdeta(2), dydxi(2);
290 hermite_compute_coefs(elem,dxdxi
298 const Order totalorder =
299 static_cast<Order>(order + add_p_level * elem->
p_level());
305 libmesh_assert_less (totalorder, 4);
306 libmesh_fallthrough();
311 libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u));
313 std::vector<unsigned int> bases1D;
315 Real coef = hermite_bases_2D(bases1D, dxdxi, totalorder, i);
328 libmesh_error_msg(
"Invalid derivative index j = " << j);
332 libmesh_error_msg(
"ERROR: Unsupported element type = " << type);
337 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
346 libmesh_error_msg(
"Hermite elements require the real element \nto construct gradient-based degrees of freedom.");
355 const unsigned int i,
356 const unsigned int j,
358 const bool add_p_level)
363 std::vector<std::vector<Real>> dxdxi(2, std::vector<Real>(2, 0));
366 std::vector<Real> dxdeta(2), dydxi(2);
369 hermite_compute_coefs(elem,dxdxi
377 const Order totalorder =
378 static_cast<Order>(order + add_p_level * elem->
p_level());
384 libmesh_assert_less (totalorder, 4);
385 libmesh_fallthrough();
390 libmesh_assert_less (i, (totalorder+1u)*(totalorder+1u));
392 std::vector<unsigned int> bases1D;
394 Real coef = hermite_bases_2D(bases1D, dxdxi, totalorder, i);
411 libmesh_error_msg(
"Invalid derivative index j = " << j);
415 libmesh_error_msg(
"ERROR: Unsupported element type = " << type);