libMesh
Public Member Functions | Static Protected Member Functions | Protected Attributes | Private Attributes | List of all members
FESideTest< order, family, elem_type > Class Template Reference
Inheritance diagram for FESideTest< order, family, elem_type >:
[legend]

Public Member Functions

void setUp ()
 
void tearDown ()
 
template<typename Functor >
void testSideLoop (Functor f)
 
void testU ()
 
void testGradU ()
 
void testGradUComp ()
 
void testHessU ()
 
void testHessUComp ()
 

Static Protected Member Functions

static RealGradient true_gradient (Point p)
 
static RealTensor true_hessian (Point p)
 

Protected Attributes

std::string libmesh_suite_name
 
unsigned int _dim
 
unsigned int _nx
 
unsigned int _ny
 
unsigned int _nz
 
Elem_elem
 
std::vector< dof_id_type_dof_indices
 
System_sys
 
std::unique_ptr< Mesh_mesh
 
std::unique_ptr< EquationSystems_es
 
std::unique_ptr< FEBase_fe
 
std::unique_ptr< QGauss_qrule
 
Real _value_tol
 
Real _grad_tol
 
Real _hess_tol
 

Private Attributes

std::unique_ptr< FEBase > _fe_side
 
std::unique_ptr< QGauss > _qrule_side
 

Detailed Description

template<Order order, FEFamily family, ElemType elem_type>
class FESideTest< order, family, elem_type >

Definition at line 41 of file fe_side_test.C.

Member Function Documentation

◆ setUp()

template<Order order, FEFamily family, ElemType elem_type>
void FESideTest< order, family, elem_type >::setUp ( )
inline

Definition at line 48 of file fe_side_test.C.

References FETestBase< order, family, elem_type, N_x >::_dim, FESideTest< order, family, elem_type >::_fe_side, FETestBase< order, family, elem_type, N_x >::_mesh, FESideTest< order, family, elem_type >::_qrule_side, FETestBase< order, family, elem_type, N_x >::_sys, libMesh::CLOUGH, libMesh::n_threads(), FETestBase< order, family, elem_type, build_nx >::setUp(), and libMesh::SZABAB.

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  }
std::unique_ptr< FEBase > _fe_side
Definition: fe_side_test.C:44
unsigned int n_threads()
Definition: libmesh_base.h:96
std::unique_ptr< QGauss > _qrule_side
Definition: fe_side_test.C:45
void setUp()
Definition: fe_test.h:350

◆ tearDown()

template<Order order, FEFamily family, ElemType elem_type>
void FESideTest< order, family, elem_type >::tearDown ( )
inline

◆ testGradU()

template<Order order, FEFamily family, ElemType elem_type>
void FESideTest< order, family, elem_type >::testGradU ( )
inline

Definition at line 180 of file fe_side_test.C.

References FETestBase< order, family, elem_type, N_x >::_dim, FETestBase< order, family, elem_type, N_x >::_dof_indices, FETestBase< order, family, elem_type, N_x >::_elem, FETestBase< order, family, elem_type, N_x >::_grad_tol, FETestBase< order, family, elem_type, N_x >::_sys, libMesh::index_range(), libMesh::RATIONAL_BERNSTEIN, libMesh::Real, FESideTest< order, family, elem_type >::testSideLoop(), and FETestBase< order, family, elem_type, N_x >::true_gradient().

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  }
RealVectorValue RealGradient
std::unique_ptr< FEBase > _fe_side
Definition: fe_side_test.C:44
NumberVectorValue Gradient
void testSideLoop(Functor f)
Definition: fe_side_test.C:108
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:273
static RealGradient true_gradient(Point p)
Definition: fe_test.h:283
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117

◆ testGradUComp()

template<Order order, FEFamily family, ElemType elem_type>
void FESideTest< order, family, elem_type >::testGradUComp ( )
inline

Definition at line 259 of file fe_side_test.C.

References FETestBase< order, family, elem_type, N_x >::_dim, FETestBase< order, family, elem_type, N_x >::_dof_indices, FETestBase< order, family, elem_type, N_x >::_grad_tol, FETestBase< order, family, elem_type, N_x >::_sys, libMesh::index_range(), libMesh::RATIONAL_BERNSTEIN, FESideTest< order, family, elem_type >::testSideLoop(), and FETestBase< order, family, elem_type, N_x >::true_gradient().

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  }
RealVectorValue RealGradient
std::unique_ptr< FEBase > _fe_side
Definition: fe_side_test.C:44
NumberVectorValue Gradient
void testSideLoop(Functor f)
Definition: fe_side_test.C:108
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:273
static RealGradient true_gradient(Point p)
Definition: fe_test.h:283
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117

◆ testHessU()

template<Order order, FEFamily family, ElemType elem_type>
void FESideTest< order, family, elem_type >::testHessU ( )
inline

Definition at line 344 of file fe_side_test.C.

References FETestBase< order, family, elem_type, N_x >::_dim, FETestBase< order, family, elem_type, N_x >::_dof_indices, FETestBase< order, family, elem_type, N_x >::_hess_tol, FETestBase< order, family, elem_type, N_x >::_sys, libMesh::index_range(), libMesh::RATIONAL_BERNSTEIN, libMesh::SZABAB, FESideTest< order, family, elem_type >::testSideLoop(), and FETestBase< order, family, elem_type, N_x >::true_hessian().

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  }
std::unique_ptr< FEBase > _fe_side
Definition: fe_side_test.C:44
RealTensorValue RealTensor
static RealTensor true_hessian(Point p)
Definition: fe_test.h:321
void testSideLoop(Functor f)
Definition: fe_side_test.C:108
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:273
NumberTensorValue Tensor
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117

◆ testHessUComp()

template<Order order, FEFamily family, ElemType elem_type>
void FESideTest< order, family, elem_type >::testHessUComp ( )
inline

Definition at line 428 of file fe_side_test.C.

References FETestBase< order, family, elem_type, N_x >::_dim, FETestBase< order, family, elem_type, N_x >::_dof_indices, FETestBase< order, family, elem_type, N_x >::_hess_tol, FETestBase< order, family, elem_type, N_x >::_sys, libMesh::index_range(), libMesh::RATIONAL_BERNSTEIN, libMesh::SZABAB, FESideTest< order, family, elem_type >::testSideLoop(), and FETestBase< order, family, elem_type, N_x >::true_hessian().

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  }
std::unique_ptr< FEBase > _fe_side
Definition: fe_side_test.C:44
RealTensorValue RealTensor
static RealTensor true_hessian(Point p)
Definition: fe_test.h:321
void testSideLoop(Functor f)
Definition: fe_side_test.C:108
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:273
NumberTensorValue Tensor
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117

◆ testSideLoop()

template<Order order, FEFamily family, ElemType elem_type>
template<typename Functor >
void FESideTest< order, family, elem_type >::testSideLoop ( Functor  f)
inline

Definition at line 108 of file fe_side_test.C.

References FETestBase< order, family, elem_type, N_x >::_dof_indices, FETestBase< order, family, elem_type, N_x >::_elem, FESideTest< order, family, elem_type >::_fe_side, FETestBase< order, family, elem_type, N_x >::_mesh, FETestBase< order, family, elem_type, N_x >::_sys, libMesh::CLOUGH, and libMesh::n_threads().

Referenced by FESideTest< order, family, elem_type >::testGradU(), FESideTest< order, family, elem_type >::testGradUComp(), FESideTest< order, family, elem_type >::testHessU(), FESideTest< order, family, elem_type >::testHessUComp(), and FESideTest< order, family, elem_type >::testU().

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  }
std::unique_ptr< FEBase > _fe_side
Definition: fe_side_test.C:44
unsigned int n_threads()
Definition: libmesh_base.h:96
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:273

◆ testU()

template<Order order, FEFamily family, ElemType elem_type>
void FESideTest< order, family, elem_type >::testU ( )
inline

Definition at line 129 of file fe_side_test.C.

References FETestBase< order, family, elem_type, N_x >::_dof_indices, FETestBase< order, family, elem_type, N_x >::_sys, FETestBase< order, family, elem_type, N_x >::_value_tol, fe_cubic_test(), fe_quartic_test(), libMesh::index_range(), libMesh::RATIONAL_BERNSTEIN, rational_test(), libMesh::Real, and FESideTest< order, family, elem_type >::testSideLoop().

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  }
std::unique_ptr< FEBase > _fe_side
Definition: fe_side_test.C:44
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
void testSideLoop(Functor f)
Definition: fe_side_test.C:108
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:273
Number fe_quartic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:164
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:117

◆ true_gradient()

static RealGradient FETestBase< order, family, elem_type, build_nx >::true_gradient ( Point  p)
inlinestaticprotectedinherited

Definition at line 283 of file fe_test.h.

Referenced by FESideTest< order, family, elem_type >::testGradU(), and FESideTest< order, family, elem_type >::testGradUComp().

284  {
285  Parameters dummy;
286 
287  Gradient true_grad;
288  RealGradient returnval;
289 
290  if (family == RATIONAL_BERNSTEIN && order > 1)
291  true_grad = rational_test_grad(p, dummy, "", "");
292  else if (order > 3)
293  true_grad = fe_quartic_test_grad(p, dummy, "", "");
294  else if (FE_CAN_TEST_CUBIC)
295  true_grad = fe_cubic_test_grad(p, dummy, "", "");
296  else if (order > 1)
297  {
298  const Real & x = p(0);
299  const Real & y = (LIBMESH_DIM > 1) ? p(1) : 0;
300  const Real & z = (LIBMESH_DIM > 2) ? p(2) : 0;
301 
302  true_grad = Gradient(2*x+0.125*y+0.0625*z,
303  y+0.125*x+0.03125*z,
304  0.5*z+0.0625*x+0.03125*y);
305  }
306  else
307  true_grad = Gradient(1.0, 0.25, 0.0625);
308 
309  for (unsigned int d=0; d != LIBMESH_DIM; ++d)
310  {
311  CPPUNIT_ASSERT(true_grad(d) ==
312  Number(libmesh_real(true_grad(d))));
313 
314  returnval(d) = libmesh_real(true_grad(d));
315  }
316 
317  return returnval;
318  }
T libmesh_real(T a)
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:67
Gradient rational_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:220
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
Gradient fe_cubic_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:144
Gradient fe_quartic_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:177
NumberVectorValue Gradient
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ true_hessian()

static RealTensor FETestBase< order, family, elem_type, build_nx >::true_hessian ( Point  p)
inlinestaticprotectedinherited

Definition at line 321 of file fe_test.h.

Referenced by FESideTest< order, family, elem_type >::testHessU(), and FESideTest< order, family, elem_type >::testHessUComp().

322  {
323  const Real & x = p(0);
324  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;
325  const Real & z = LIBMESH_DIM > 2 ? p(2) : 0;
326 
327  if (order > 3)
328  return RealTensor
329  { 12*x*x-12*x+2+2*z*(1-y)-2*(1-y)*(1-z), -2*x*z-(1-2*x)*(1-z)-(1-2*y)*z, 2*x*(1-y)-(1-2*x)*(1-y)-y*(1-y),
330  -2*x*z-(1-2*x)*(1-z)-(1-2*y)*z, -2*(1-x)*z, -x*x+x*(1-x)+(1-x)*(1-2*y),
331  2*x*(1-y)-(1-2*x)*(1-y)-y*(1-y), -x*x+x*(1-x)+(1-x)*(1-2*y), 12*z*z-12*z+2 };
332  else if (FE_CAN_TEST_CUBIC)
333  return RealTensor
334  { 6*x-4+2*(1-y), -2*x+z-1, y-1,
335  -2*x+z-1, -2*z, x+1-2*y,
336  y-1, x+1-2*y, 6*z-4 };
337  else if (order > 1)
338  return RealTensor
339  { 2, 0.125, 0.0625,
340  0.125, 1, 0.03125,
341  0.0625, 0.03125, 0.5 };
342 
343  return RealTensor
344  { 0, 0, 0,
345  0, 0, 0,
346  0, 0, 0 };
347  }
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.

Member Data Documentation

◆ _dim

unsigned int FETestBase< order, family, elem_type, build_nx >::_dim
protectedinherited

◆ _dof_indices

std::vector<dof_id_type> FETestBase< order, family, elem_type, build_nx >::_dof_indices
protectedinherited

◆ _elem

Elem* FETestBase< order, family, elem_type, build_nx >::_elem
protectedinherited

◆ _es

std::unique_ptr<EquationSystems> FETestBase< order, family, elem_type, build_nx >::_es
protectedinherited

Definition at line 276 of file fe_test.h.

◆ _fe

std::unique_ptr<FEBase> FETestBase< order, family, elem_type, build_nx >::_fe
protectedinherited

Definition at line 277 of file fe_test.h.

◆ _fe_side

template<Order order, FEFamily family, ElemType elem_type>
std::unique_ptr<FEBase> FESideTest< order, family, elem_type >::_fe_side
private

◆ _grad_tol

Real FETestBase< order, family, elem_type, build_nx >::_grad_tol
protectedinherited

◆ _hess_tol

Real FETestBase< order, family, elem_type, build_nx >::_hess_tol
protectedinherited

◆ _mesh

std::unique_ptr<Mesh> FETestBase< order, family, elem_type, build_nx >::_mesh
protectedinherited

◆ _nx

unsigned int FETestBase< order, family, elem_type, build_nx >::_nx
protectedinherited

Definition at line 271 of file fe_test.h.

◆ _ny

unsigned int FETestBase< order, family, elem_type, build_nx >::_ny
protectedinherited

Definition at line 271 of file fe_test.h.

◆ _nz

unsigned int FETestBase< order, family, elem_type, build_nx >::_nz
protectedinherited

Definition at line 271 of file fe_test.h.

◆ _qrule

std::unique_ptr<QGauss> FETestBase< order, family, elem_type, build_nx >::_qrule
protectedinherited

Definition at line 278 of file fe_test.h.

◆ _qrule_side

template<Order order, FEFamily family, ElemType elem_type>
std::unique_ptr<QGauss> FESideTest< order, family, elem_type >::_qrule_side
private

Definition at line 45 of file fe_side_test.C.

Referenced by FESideTest< order, family, elem_type >::setUp().

◆ _sys

System* FETestBase< order, family, elem_type, build_nx >::_sys
protectedinherited

◆ _value_tol

Real FETestBase< order, family, elem_type, build_nx >::_value_tol
protectedinherited

Definition at line 280 of file fe_test.h.

Referenced by FESideTest< order, family, elem_type >::testU().

◆ libmesh_suite_name

std::string FETestBase< order, family, elem_type, build_nx >::libmesh_suite_name
protectedinherited

Definition at line 269 of file fe_test.h.


The documentation for this class was generated from the following file: