libMesh
Loading...
Searching...
No Matches
fe_side_test.C
Go to the documentation of this file.
1#include "fe_test.h" // For linear_test(), headers, FETestBase, etc
2
3// Helper functions for restricting normal components
4namespace {
5
6template <typename MyTensor, typename MyVector>
7MyTensor tangential_hessian (const MyTensor hess,
8 const MyVector normal)
9{
10 auto full_hess_n = hess*normal;
11 MyTensor tang_hess = hess;
12
13 const MyTensor n_n = outer_product(normal, normal);
14 for (unsigned int k=0; k != 3; ++k)
15 {
16 MyVector ek {0};
17 ek(k) = 1;
18 const auto Hkn = ek * full_hess_n;
19 const auto Hkn_ek = Hkn*ek;
20 tang_hess -= outer_product(Hkn_ek, normal);
21 tang_hess -= outer_product(normal, Hkn_ek);
22 tang_hess += 2.*(Hkn_ek*normal) * n_n;
23 }
24 tang_hess -= normal*(full_hess_n) * n_n;
25
26 return tang_hess;
27}
28
29} // anonymous namespace
30
31#define SIDEFETEST \
32 CPPUNIT_TEST( testU ); \
33 CPPUNIT_TEST( testGradU ); \
34 CPPUNIT_TEST( testGradUComp ); \
35 CPPUNIT_TEST( testHessU ); \
36 CPPUNIT_TEST( testHessUComp );
37
38const unsigned int N_x=2;
39
40template <Order order, FEFamily family, ElemType elem_type>
41class FESideTest : public FETestBase<order, family, elem_type, N_x> {
42
43private:
44 std::unique_ptr<FEBase> _fe_side;
45 std::unique_ptr<QGauss> _qrule_side;
46
47public:
48 void setUp()
49 {
51
52 // If we're a 2D mesh on a 3D libMesh build we should be able to
53 // handle inverted elements just fine. Let's test that.
54 BoundaryInfo & bdy_info = this->_mesh->get_boundary_info();
55 for (auto e : this->_mesh->element_ptr_range())
56 if (!(e->id() % 3) && e->dim() < LIBMESH_DIM)
57 e->flip(&bdy_info);
58
59 FEType fe_type = this->_sys->variable_type(0);
60 _fe_side = FEBase::build(this->_dim, fe_type);
61
62 _qrule_side = std::make_unique<QGauss>(this->_dim-1, fe_type.default_quadrature_order());
63 _fe_side->attach_quadrature_rule(this->_qrule_side.get());
64
65 _fe_side->get_xyz();
66 _fe_side->get_normals();
67 _fe_side->get_phi();
68 _fe_side->get_dphi();
69 _fe_side->get_dphidx();
70#if LIBMESH_DIM > 1
71 _fe_side->get_dphidy();
72#endif
73#if LIBMESH_DIM > 2
74 _fe_side->get_dphidz();
75#endif
76
77#if LIBMESH_ENABLE_SECOND_DERIVATIVES
78
79 // Clough-Tocher elements still don't work multithreaded
80 if (family == CLOUGH && libMesh::n_threads() > 1)
81 return;
82
83 // Szabab elements don't have second derivatives yet
84 if (family == SZABAB)
85 return;
86
87 _fe_side->get_d2phi();
88 _fe_side->get_d2phidx2();
89#if LIBMESH_DIM > 1
90 _fe_side->get_d2phidxdy();
91 _fe_side->get_d2phidy2();
92#endif
93#if LIBMESH_DIM > 2
94 _fe_side->get_d2phidxdz();
95 _fe_side->get_d2phidydz();
96 _fe_side->get_d2phidz2();
97#endif
98
99#endif
100 }
101
106
107 template <typename Functor>
108 void testSideLoop(Functor f)
109 {
110 // Clough-Tocher elements still don't work multithreaded
111 if (family == CLOUGH && libMesh::n_threads() > 1)
112 return;
113
114 for (auto e : this->_mesh->active_local_element_ptr_range())
115 {
116 this->_elem = e;
117
118 this->_sys->get_dof_map().dof_indices(this->_elem, this->_dof_indices);
119
120 for (unsigned int s=0; s != this->_elem->n_sides(); ++s)
121 {
122 _fe_side->reinit(this->_elem, s);
123
124 f();
125 }
126 }
127 }
128
129 void testU()
130 {
131 LOG_UNIT_TEST;
132
133 auto f = [this]() {
134 Parameters dummy;
135
136 auto phi = this->_fe_side->get_phi();
137 CPPUNIT_ASSERT(phi.size());
138 CPPUNIT_ASSERT_EQUAL(phi.size(), this->_dof_indices.size());
139
140 std::size_t n_qp = phi[0].size();
141 CPPUNIT_ASSERT(n_qp > 0);
142
143 auto xyz = this->_fe_side->get_xyz();
144 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
145
146 for (auto qp : index_range(phi[0]))
147 {
148 Number u = 0;
149 for (auto d : index_range(phi))
150 u += phi[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
151
152 const Point p = xyz[qp];
153 Real x = p(0),
154 y = LIBMESH_DIM > 1 ? p(1) : 0,
155 z = LIBMESH_DIM > 2 ? p(2) : 0;
156
157 if (family == RATIONAL_BERNSTEIN && order > 1)
158 LIBMESH_ASSERT_NUMBERS_EQUAL
159 (rational_test(p, dummy, "", ""), u, this->_value_tol);
160 else if (order > 3)
161 LIBMESH_ASSERT_NUMBERS_EQUAL
162 (fe_quartic_test(p, dummy, "", ""), u, this->_value_tol);
163 else if (order > 2)
164 LIBMESH_ASSERT_NUMBERS_EQUAL
165 (fe_cubic_test(p, dummy, "", ""), u, this->_value_tol);
166 else if (order > 1)
167 LIBMESH_ASSERT_NUMBERS_EQUAL
168 (x*x + 0.5*y*y + 0.25*z*z + 0.125*x*y +
169 0.0625*x*z + 0.03125*y*z,
170 u, this->_value_tol);
171 else
172 LIBMESH_ASSERT_NUMBERS_EQUAL (x + 0.25*y + 0.0625*z, u,
173 this->_value_tol);
174 }
175 };
176
177 testSideLoop(f);
178 }
179
181 {
182 LOG_UNIT_TEST;
183
184 auto f = [this]() {
185 Parameters dummy;
186
187 auto dphi = this->_fe_side->get_dphi();
188 CPPUNIT_ASSERT(dphi.size() > 0);
189 CPPUNIT_ASSERT_EQUAL(dphi.size(), this->_dof_indices.size());
190
191 std::size_t n_qp = dphi[0].size();
192 CPPUNIT_ASSERT(n_qp > 0);
193
194 auto xyz = this->_fe_side->get_xyz();
195 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
196
197 auto normals = this->_fe_side->get_normals();
198 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
199
200 const Point c = this->_elem->vertex_average();
201
202 for (auto qp : index_range(dphi[0]))
203 {
204 Gradient grad_u = 0;
205 for (auto d : index_range(dphi))
206 grad_u += dphi[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
207
208 const Point p = xyz[qp];
209 const Point n = normals[qp];
210
211 // All our normals should be unit normals.
212 LIBMESH_ASSERT_FP_EQUAL(Real(n.norm()),
213 Real(1),
214 this->_grad_tol);
215
216 // All our normals should be outward-facing. For the simple
217 // meshes here this is sufficient to make sure they're not
218 // flipped:
219 CPPUNIT_ASSERT_GREATER(Real(0), (p-c)*n);
220
221 // We can only trust the tangential component of gradient to
222 // match! The gradient in the normal direction should be 0
223 // for a shape-preserving master->physical element
224 // transformation, and could be just about anything for a
225 // skew transformation (as occurs when we build meshes with
226 // triangles, tets, prisms, pyramids...)
227
228 const Gradient tangential_grad_u = grad_u - ((grad_u * n) * n);
229
230 if (family == RATIONAL_BERNSTEIN && order > 1)
231 {
232 // TODO: Yeah we'll test the ugly expressions later.
233 return;
234 }
235
236 RealGradient true_grad = this->true_gradient(p);
237 if (order == 0)
238 true_grad.zero();
239
240 const Gradient true_tangential_grad = true_grad - ((true_grad * n) * n);
241
242 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(0),
243 true_tangential_grad(0),
244 this->_grad_tol);
245 if (this->_dim > 1)
246 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(1),
247 true_tangential_grad(1),
248 this->_grad_tol);
249 if (this->_dim > 2)
250 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(2),
251 true_tangential_grad(2),
252 this->_grad_tol);
253 }
254 };
255
256 testSideLoop(f);
257 }
258
260 {
261 LOG_UNIT_TEST;
262
263 auto f = [this]() {
264 Parameters dummy;
265
266 auto dphidx = this->_fe_side->get_dphidx();
267 CPPUNIT_ASSERT(dphidx.size() > 0);
268 CPPUNIT_ASSERT_EQUAL(dphidx.size(), this->_dof_indices.size());
269#if LIBMESH_DIM > 1
270 auto dphidy = this->_fe_side->get_dphidy();
271 CPPUNIT_ASSERT_EQUAL(dphidy.size(), this->_dof_indices.size());
272#endif
273#if LIBMESH_DIM > 2
274 auto dphidz = this->_fe_side->get_dphidz();
275 CPPUNIT_ASSERT_EQUAL(dphidz.size(), this->_dof_indices.size());
276#endif
277
278 std::size_t n_qp = dphidx[0].size();
279 CPPUNIT_ASSERT(n_qp > 0);
280
281 auto xyz = this->_fe_side->get_xyz();
282 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
283
284 auto normals = this->_fe_side->get_normals();
285 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
286
287 for (auto qp : index_range(dphidx[0]))
288 {
289 Number grad_u_x = 0, grad_u_y = 0, grad_u_z = 0;
290 for (auto d : index_range(dphidx))
291 {
292 grad_u_x += dphidx[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
293#if LIBMESH_DIM > 1
294 grad_u_y += dphidy[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
295#endif
296#if LIBMESH_DIM > 2
297 grad_u_z += dphidz[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
298#endif
299 }
300
301 const Point p = xyz[qp];
302
303 // We can only trust the tangential component of gradient to
304 // match! The gradient in the normal direction should be 0
305 // for a shape-preserving master->physical element
306 // transformation, and could be just about anything for a
307 // skew transformation (as occurs when we build meshes with
308 // triangles, tets, prisms, pyramids...)
309 Point n = normals[qp];
310
311 const Gradient grad_u {grad_u_x, grad_u_y, grad_u_z};
312 const Gradient tangential_grad_u = grad_u - ((grad_u * n) * n);
313
314 if (family == RATIONAL_BERNSTEIN && order > 1)
315 {
316 // TODO: Yeah we'll test the ugly expressions later.
317 return;
318 }
319
320 RealGradient true_grad = this->true_gradient(p);
321 if (order == 0)
322 true_grad.zero();
323
324 const Gradient true_tangential_grad = true_grad - ((true_grad * n) * n);
325
326 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(0),
327 true_tangential_grad(0),
328 this->_grad_tol);
329 if (this->_dim > 1)
330 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(1),
331 true_tangential_grad(1),
332 this->_grad_tol);
333 if (this->_dim > 2)
334 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(2),
335 true_tangential_grad(2),
336 this->_grad_tol);
337 }
338 };
339
340 testSideLoop(f);
341 }
342
343
345 {
346 LOG_UNIT_TEST;
347
348#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
349 // Szabab elements don't have second derivatives yet
350 if (family == SZABAB)
351 return;
352
353 auto f = [this]() {
354 Parameters dummy;
355
356 auto d2phi = this->_fe_side->get_d2phi();
357 CPPUNIT_ASSERT(d2phi.size() > 0);
358 CPPUNIT_ASSERT_EQUAL(d2phi.size(), this->_dof_indices.size());
359
360 std::size_t n_qp = d2phi[0].size();
361 CPPUNIT_ASSERT(n_qp > 0);
362
363 auto xyz = this->_fe_side->get_xyz();
364 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
365
366 auto normals = this->_fe_side->get_normals();
367 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
368
369 for (auto qp : index_range(d2phi[0]))
370 {
371 Tensor hess_u;
372 for (auto d : index_range(d2phi))
373 hess_u += d2phi[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
374
375 // We can only trust the tangential-tangential components of
376 // hessians, t1'*H*t2 for tangential vectors t1 and t2, to
377 // match! The hessian components in the normal direction
378 // should be 0 for a shape-preserving master->physical
379 // element transformation, but could be just about anything
380 // for a skew transformation (as occurs when we build meshes
381 // with triangles, tets, prisms, pyramids...)
382 Point n = normals[qp];
383 hess_u = tangential_hessian(hess_u, n);
384
385 if (family == RATIONAL_BERNSTEIN && order > 1)
386 {
387 // TODO: Yeah we'll test the ugly expressions later.
388 return;
389 }
390
391 const Point p = xyz[qp];
392 RealTensor true_hess = this->true_hessian(p);
393
394 // Subtract off values only relevant in normal directions
395 RealTensor tangential_hess = tangential_hessian(true_hess, n);
396
397 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_hess(0,0),
398 hess_u(0,0), this->_hess_tol);
399 if (this->_dim > 1)
400 {
401 LIBMESH_ASSERT_NUMBERS_EQUAL
402 (hess_u(0,1), hess_u(1,0), this->_hess_tol);
403 LIBMESH_ASSERT_NUMBERS_EQUAL
404 (tangential_hess(0,1), hess_u(0,1), this->_hess_tol);
405 LIBMESH_ASSERT_NUMBERS_EQUAL
406 (tangential_hess(1,1), hess_u(1,1), this->_hess_tol);
407 }
408 if (this->_dim > 2)
409 {
410 LIBMESH_ASSERT_NUMBERS_EQUAL
411 (hess_u(0,2), hess_u(2,0), this->_hess_tol);
412 LIBMESH_ASSERT_NUMBERS_EQUAL
413 (hess_u(1,2), hess_u(2,1), this->_hess_tol);
414 LIBMESH_ASSERT_NUMBERS_EQUAL
415 (tangential_hess(0,2), hess_u(0,2), this->_hess_tol);
416 LIBMESH_ASSERT_NUMBERS_EQUAL
417 (tangential_hess(1,2), hess_u(1,2), this->_hess_tol);
418 LIBMESH_ASSERT_NUMBERS_EQUAL
419 (tangential_hess(2,2), hess_u(2,2), this->_hess_tol);
420 }
421 }
422 };
423
424 testSideLoop(f);
425#endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
426 }
427
429 {
430 LOG_UNIT_TEST;
431
432#ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
433 // Szabab elements don't have second derivatives yet
434 if (family == SZABAB)
435 return;
436
437 auto f = [this]() {
438 Parameters dummy;
439
440 auto d2phidx2 = this->_fe_side->get_d2phidx2();
441 CPPUNIT_ASSERT(d2phidx2.size() > 0);
442 CPPUNIT_ASSERT_EQUAL(d2phidx2.size(), this->_dof_indices.size());
443#if LIBMESH_DIM > 1
444 auto d2phidxdy = this->_fe_side->get_d2phidxdy();
445 CPPUNIT_ASSERT_EQUAL(d2phidxdy.size(), this->_dof_indices.size());
446 auto d2phidy2 = this->_fe_side->get_d2phidy2();
447 CPPUNIT_ASSERT_EQUAL(d2phidy2.size(), this->_dof_indices.size());
448#endif
449#if LIBMESH_DIM > 2
450 auto d2phidxdz = this->_fe_side->get_d2phidxdz();
451 CPPUNIT_ASSERT_EQUAL(d2phidxdz.size(), this->_dof_indices.size());
452 auto d2phidydz = this->_fe_side->get_d2phidydz();
453 CPPUNIT_ASSERT_EQUAL(d2phidydz.size(), this->_dof_indices.size());
454 auto d2phidz2 = this->_fe_side->get_d2phidz2();
455 CPPUNIT_ASSERT_EQUAL(d2phidz2.size(), this->_dof_indices.size());
456#endif
457
458 std::size_t n_qp = d2phidx2[0].size();
459 CPPUNIT_ASSERT(n_qp > 0);
460
461 auto xyz = this->_fe_side->get_xyz();
462 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
463
464 auto normals = this->_fe_side->get_normals();
465 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
466
467 for (auto qp : index_range(d2phidx2[0]))
468 {
469 Tensor hess_u;
470 for (auto d : index_range(d2phidx2))
471 {
472 hess_u(0,0) += d2phidx2[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
473#if LIBMESH_DIM > 1
474 hess_u(0,1) += d2phidxdy[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
475 hess_u(1,1) += d2phidy2[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
476#endif
477#if LIBMESH_DIM > 2
478 hess_u(0,2) += d2phidxdz[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
479 hess_u(1,2) += d2phidydz[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
480 hess_u(2,2) += d2phidz2[d][qp] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
481#endif
482 }
483
484#if LIBMESH_DIM > 1
485 hess_u(1,0) = hess_u(0,1);
486#endif
487#if LIBMESH_DIM > 2
488 hess_u(2,0) = hess_u(0,2);
489 hess_u(2,1) = hess_u(1,2);
490#endif
491
492 // We can only trust the tangential-tangential components of
493 // hessians, t1'*H*t2 for tangential vectors t1 and t2, to
494 // match! The hessian components in the normal direction
495 // should be 0 for a shape-preserving master->physical
496 // element transformation, but could be just about anything
497 // for a skew transformation (as occurs when we build meshes
498 // with triangles, tets, prisms, pyramids...)
499 Point n = normals[qp];
500 hess_u = tangential_hessian(hess_u, n);
501
502 if (family == RATIONAL_BERNSTEIN && order > 1)
503 return;
504
505 const Point p = xyz[qp];
506 RealTensor true_hess = this->true_hessian(p);
507
508 // Subtract off values only relevant in normal directions
509 RealTensor tangential_hess = tangential_hessian(true_hess, n);
510
511 LIBMESH_ASSERT_NUMBERS_EQUAL
512 (tangential_hess(0,0), hess_u(0,0), this->_hess_tol);
513 if (this->_dim > 1)
514 {
515 LIBMESH_ASSERT_NUMBERS_EQUAL
516 (tangential_hess(0,1), hess_u(0,1), this->_hess_tol);
517 LIBMESH_ASSERT_NUMBERS_EQUAL
518 (tangential_hess(1,1), hess_u(1,1), this->_hess_tol);
519 }
520 if (this->_dim > 2)
521 {
522 LIBMESH_ASSERT_NUMBERS_EQUAL
523 (tangential_hess(0,2), hess_u(0,2), this->_hess_tol);
524 LIBMESH_ASSERT_NUMBERS_EQUAL
525 (tangential_hess(1,2), hess_u(1,2), this->_hess_tol);
526 LIBMESH_ASSERT_NUMBERS_EQUAL
527 (tangential_hess(2,2), hess_u(2,2), this->_hess_tol);
528 }
529 }
530 };
531
532 testSideLoop(f);
533#endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
534 }
535
536};
537
538
539class SideHierarchicNodalSolnTest : public CppUnit::TestCase
540{
541public:
545
547 {
548 LOG_UNIT_TEST;
549
550#if LIBMESH_DIM > 1
551 Mesh mesh(*TestCommWorld);
552 MeshTools::Generation::build_square(mesh, 1, 1, 0., 1., 0., 1., QUAD9);
553
554 auto range = mesh.active_local_element_ptr_range();
555 if (range.begin() == range.end())
556 return;
557
558 const Elem * elem = *range.begin();
559 CPPUNIT_ASSERT_EQUAL(static_cast<int>(QUAD9),
560 static_cast<int>(elem->type()));
561
562 const FEType fe_type(CONSTANT, SIDE_HIERARCHIC);
563 const std::vector<Number> elem_soln = {1, 3, 5, 7};
564
565 std::vector<Number> nodal_soln;
566 FEInterface::nodal_soln(/*dim=*/2,
567 fe_type,
568 elem,
569 elem_soln,
570 nodal_soln,
571 /*add_p_level=*/false);
572
573 CPPUNIT_ASSERT_EQUAL(std::size_t(9), nodal_soln.size());
574
575 std::vector<Number> expected(nodal_soln.size(), 0);
576 std::vector<unsigned int> expected_count(nodal_soln.size(), 0);
577 for (const auto side : elem->side_index_range())
578 for (const auto n : elem->nodes_on_side(side))
579 {
580 expected[n] += elem_soln[side];
581 ++expected_count[n];
582 }
583
584 unsigned int n_nodes_without_side_value = 0;
585 for (const auto n : index_range(expected))
586 {
587 if (expected_count[n])
588 expected[n] /= expected_count[n];
589 else
590 ++n_nodes_without_side_value;
591
592 LIBMESH_ASSERT_NUMBERS_EQUAL(expected[n],
593 nodal_soln[n],
594 TOLERANCE * TOLERANCE);
595 }
596
597 CPPUNIT_ASSERT_EQUAL(1u, n_nodes_without_side_value);
598#endif
599 }
600};
601
603
604
605#define INSTANTIATE_FESIDETEST(order, family, elemtype) \
606 class FESideTest_##order##_##family##_##elemtype : public FESideTest<order, family, elemtype> { \
607 public: \
608 FESideTest_##order##_##family##_##elemtype() : \
609 FESideTest<order,family,elemtype>() { \
610 if (unitlog->summarized_logs_enabled()) \
611 this->libmesh_suite_name = "FESideTest"; \
612 else \
613 this->libmesh_suite_name = "FESideTest_" #order "_" #family "_" #elemtype; \
614 } \
615 CPPUNIT_TEST_SUITE( FESideTest_##order##_##family##_##elemtype ); \
616 SIDEFETEST \
617 CPPUNIT_TEST_SUITE_END(); \
618 }; \
619 \
620 CPPUNIT_TEST_SUITE_REGISTRATION( FESideTest_##order##_##family##_##elemtype );
621
622
623INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, EDGE3);
624INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, EDGE3);
625INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, EDGE3);
626INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, EDGE3);
627INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, EDGE3);
628
629#if LIBMESH_DIM > 1
630INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, QUAD9);
631INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, QUAD9);
632INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, QUAD9);
633INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, QUAD9);
634INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, QUAD9);
635
636INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, QUAD8);
637INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, QUAD8);
638INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, QUAD8);
639INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, QUAD8);
640INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, QUAD8);
641
642INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, TRI6);
643INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, TRI6);
644INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, TRI6);
645INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, TRI6);
646INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, TRI6);
647
648INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, TRI7);
649INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, TRI7);
650INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, TRI7);
651INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, TRI7);
652INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, TRI7);
653#endif
654
655#if LIBMESH_DIM > 2
656INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, HEX27);
657INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, HEX27);
658INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, HEX27);
659INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, HEX27);
660INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, HEX27);
661//
662INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, TET14);
663INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, TET14);
664INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, TET14);
665INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, TET14);
666INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, TET14);
667//
668INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, PRISM20);
669INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, PRISM20);
670INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, PRISM20);
671INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, PRISM20);
672INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, PRISM20);
673//
674INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, PRISM21);
675INSTANTIATE_FESIDETEST(FIRST, SIDE_HIERARCHIC, PRISM21);
676INSTANTIATE_FESIDETEST(SECOND, SIDE_HIERARCHIC, PRISM21);
677INSTANTIATE_FESIDETEST(THIRD, SIDE_HIERARCHIC, PRISM21);
678INSTANTIATE_FESIDETEST(FOURTH, SIDE_HIERARCHIC, PRISM21);
679#endif
void setUp()
void testSideLoop(Functor f)
void tearDown()
std::unique_ptr< QGauss > _qrule_side
void testGradUComp()
void testHessUComp()
void testHessU()
std::unique_ptr< FEBase > _fe_side
void testGradU()
void tearDown()
Definition fe_test.h:621
std::vector< dof_id_type > _dof_indices
Definition fe_test.h:279
void setUp()
Definition fe_test.h:356
static RealTensor true_hessian(Point p)
Definition fe_test.h:327
static RealGradient true_gradient(Point p)
Definition fe_test.h:289
LIBMESH_CPPUNIT_TEST_SUITE(SideHierarchicNodalSolnTest)
CPPUNIT_TEST(testConstantQuad9)
Communicator * TestCommWorld
INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, EDGE3)
const unsigned int N_x
CPPUNIT_TEST_SUITE_REGISTRATION(SideHierarchicNodalSolnTest)
Number fe_cubic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition fe_test.h:131
Number rational_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition fe_test.h:203
Number fe_quartic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition fe_test.h:164
MeshBase & mesh
TypeTensor< typename CompareTypes< T, T2 >::supertype > outer_product(const TypeVector< T > &a, const TypeVector< T2 > &b)
unsigned int n_threads()