6 template <
typename MyTensor,
typename MyVector>
7 MyTensor tangential_hessian (
const MyTensor hess,
10 auto full_hess_n = hess*normal;
11 MyTensor tang_hess = hess;
14 for (
unsigned int k=0; k != 3; ++k)
18 const auto Hkn = ek * full_hess_n;
19 const auto Hkn_ek = Hkn*ek;
22 tang_hess += 2.*(Hkn_ek*normal) * n_n;
24 tang_hess -= normal*(full_hess_n) * n_n;
32 CPPUNIT_TEST( testU ); \ 33 CPPUNIT_TEST( testGradU ); \ 34 CPPUNIT_TEST( testGradUComp ); \ 35 CPPUNIT_TEST( testHessU ); \ 36 CPPUNIT_TEST( testHessUComp ); 38 const unsigned int N_x=2;
40 template <Order order, FEFamily family, ElemType elem_type>
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)
59 FEType fe_type = this->
_sys->variable_type(0);
60 _fe_side = FEBase::build(this->
_dim, fe_type);
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());
77 #if LIBMESH_ENABLE_SECOND_DERIVATIVES 107 template <
typename Functor>
114 for (
auto e : this->
_mesh->active_local_element_ptr_range())
120 for (
unsigned int s=0; s != this->
_elem->n_sides(); ++s)
136 auto phi = this->_fe_side->get_phi();
137 CPPUNIT_ASSERT(phi.size());
138 CPPUNIT_ASSERT_EQUAL(phi.size(), this->
_dof_indices.size());
140 std::size_t n_qp = phi[0].size();
141 CPPUNIT_ASSERT(n_qp > 0);
143 auto xyz = this->_fe_side->get_xyz();
144 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
150 u += phi[d][qp] * (*this->
_sys->current_local_solution)(this->
_dof_indices[d]);
152 const Point p = xyz[qp];
154 y = LIBMESH_DIM > 1 ? p(1) : 0,
155 z = LIBMESH_DIM > 2 ? p(2) : 0;
158 LIBMESH_ASSERT_NUMBERS_EQUAL
161 LIBMESH_ASSERT_NUMBERS_EQUAL
164 LIBMESH_ASSERT_NUMBERS_EQUAL
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,
172 LIBMESH_ASSERT_NUMBERS_EQUAL (x + 0.25*y + 0.0625*z, u,
187 auto dphi = this->_fe_side->get_dphi();
188 CPPUNIT_ASSERT(dphi.size() > 0);
189 CPPUNIT_ASSERT_EQUAL(dphi.size(), this->
_dof_indices.size());
191 std::size_t n_qp = dphi[0].size();
192 CPPUNIT_ASSERT(n_qp > 0);
194 auto xyz = this->_fe_side->get_xyz();
195 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
197 auto normals = this->_fe_side->get_normals();
198 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
200 const Point c = this->
_elem->vertex_average();
206 grad_u += dphi[d][qp] * (*this->
_sys->current_local_solution)(this->
_dof_indices[d]);
208 const Point p = xyz[qp];
209 const Point n = normals[qp];
212 LIBMESH_ASSERT_FP_EQUAL(
Real(n.norm()),
219 CPPUNIT_ASSERT_GREATER(
Real(0), (p-c)*n);
228 const Gradient tangential_grad_u = grad_u - ((grad_u * n) * n);
240 const Gradient true_tangential_grad = true_grad - ((true_grad * n) * n);
242 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(0),
243 true_tangential_grad(0),
246 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(1),
247 true_tangential_grad(1),
250 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(2),
251 true_tangential_grad(2),
266 auto dphidx = this->_fe_side->get_dphidx();
267 CPPUNIT_ASSERT(dphidx.size() > 0);
268 CPPUNIT_ASSERT_EQUAL(dphidx.size(), this->
_dof_indices.size());
270 auto dphidy = this->_fe_side->get_dphidy();
271 CPPUNIT_ASSERT_EQUAL(dphidy.size(), this->
_dof_indices.size());
274 auto dphidz = this->_fe_side->get_dphidz();
275 CPPUNIT_ASSERT_EQUAL(dphidz.size(), this->
_dof_indices.size());
278 std::size_t n_qp = dphidx[0].size();
279 CPPUNIT_ASSERT(n_qp > 0);
281 auto xyz = this->_fe_side->get_xyz();
282 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
284 auto normals = this->_fe_side->get_normals();
285 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
289 Number grad_u_x = 0, grad_u_y = 0, grad_u_z = 0;
292 grad_u_x += dphidx[d][qp] * (*this->
_sys->current_local_solution)(this->
_dof_indices[d]);
294 grad_u_y += dphidy[d][qp] * (*this->
_sys->current_local_solution)(this->
_dof_indices[d]);
297 grad_u_z += dphidz[d][qp] * (*this->
_sys->current_local_solution)(this->
_dof_indices[d]);
301 const Point p = xyz[qp];
309 Point n = normals[qp];
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);
324 const Gradient true_tangential_grad = true_grad - ((true_grad * n) * n);
326 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(0),
327 true_tangential_grad(0),
330 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(1),
331 true_tangential_grad(1),
334 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_grad_u(2),
335 true_tangential_grad(2),
348 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 356 auto d2phi = this->_fe_side->get_d2phi();
357 CPPUNIT_ASSERT(d2phi.size() > 0);
358 CPPUNIT_ASSERT_EQUAL(d2phi.size(), this->
_dof_indices.size());
360 std::size_t n_qp = d2phi[0].size();
361 CPPUNIT_ASSERT(n_qp > 0);
363 auto xyz = this->_fe_side->get_xyz();
364 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
366 auto normals = this->_fe_side->get_normals();
367 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
373 hess_u += d2phi[d][qp] * (*this->
_sys->current_local_solution)(this->
_dof_indices[d]);
382 Point n = normals[qp];
383 hess_u = tangential_hessian(hess_u, n);
391 const Point p = xyz[qp];
395 RealTensor tangential_hess = tangential_hessian(true_hess, n);
397 LIBMESH_ASSERT_NUMBERS_EQUAL(tangential_hess(0,0),
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);
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);
425 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 432 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 440 auto d2phidx2 = this->_fe_side->get_d2phidx2();
441 CPPUNIT_ASSERT(d2phidx2.size() > 0);
442 CPPUNIT_ASSERT_EQUAL(d2phidx2.size(), this->
_dof_indices.size());
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());
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());
458 std::size_t n_qp = d2phidx2[0].size();
459 CPPUNIT_ASSERT(n_qp > 0);
461 auto xyz = this->_fe_side->get_xyz();
462 CPPUNIT_ASSERT_EQUAL(n_qp, xyz.size());
464 auto normals = this->_fe_side->get_normals();
465 CPPUNIT_ASSERT_EQUAL(n_qp, normals.size());
472 hess_u(0,0) += d2phidx2[d][qp] * (*this->
_sys->current_local_solution)(this->
_dof_indices[d]);
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]);
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]);
485 hess_u(1,0) = hess_u(0,1);
488 hess_u(2,0) = hess_u(0,2);
489 hess_u(2,1) = hess_u(1,2);
499 Point n = normals[qp];
500 hess_u = tangential_hessian(hess_u, n);
505 const Point p = xyz[qp];
509 RealTensor tangential_hess = tangential_hessian(true_hess, n);
511 LIBMESH_ASSERT_NUMBERS_EQUAL
512 (tangential_hess(0,0), hess_u(0,0), this->
_hess_tol);
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);
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);
533 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES 539 #define INSTANTIATE_FESIDETEST(order, family, elemtype) \ 540 class FESideTest_##order##_##family##_##elemtype : public FESideTest<order, family, elemtype> { \ 542 FESideTest_##order##_##family##_##elemtype() : \ 543 FESideTest<order,family,elemtype>() { \ 544 if (unitlog->summarized_logs_enabled()) \ 545 this->libmesh_suite_name = "FESideTest"; \ 547 this->libmesh_suite_name = "FESideTest_" #order "_" #family "_" #elemtype; \ 549 CPPUNIT_TEST_SUITE( FESideTest_##order##_##family##_##elemtype ); \ 551 CPPUNIT_TEST_SUITE_END(); \ 554 CPPUNIT_TEST_SUITE_REGISTRATION( FESideTest_##order##_##family##_##elemtype );
INSTANTIATE_FESIDETEST(CONSTANT, SIDE_HIERARCHIC, EDGE3)
RealVectorValue RealGradient
std::unique_ptr< FEBase > _fe_side
TypeTensor< typename CompareTypes< T, T2 >::supertype > outer_product(const TypeVector< T > &a, const TypeVector< T2 > &b)
std::unique_ptr< QGauss > _qrule_side
RealTensorValue RealTensor
Number fe_cubic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Number rational_test(const Point &p, const Parameters &, const std::string &, const std::string &)
static RealTensor true_hessian(Point p)
NumberVectorValue Gradient
void testSideLoop(Functor f)
std::unique_ptr< Mesh > _mesh
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< dof_id_type > _dof_indices
static RealGradient true_gradient(Point p)
Number fe_quartic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...