libMesh
Public Member Functions | Static Protected Member Functions | Protected Attributes | List of all members
FETest< order, family, elem_type > Class Template Reference

#include <fe_test.h>

Inheritance diagram for FETest< order, family, elem_type >:
[legend]

Public Member Functions

template<typename Functor >
void testLoop (Functor f)
 
void testPartitionOfUnity ()
 
void testFEInterface ()
 
void testU ()
 
void testDualDoesntScreamAndDie ()
 
void testGradU ()
 
void testGradUComp ()
 
void testHessU ()
 
void testHessUComp ()
 
void testCustomReinit ()
 
void setUp ()
 
void tearDown ()
 

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
 

Detailed Description

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

Definition at line 535 of file fe_test.h.

Member Function Documentation

◆ setUp()

void FETestBase< order, family, elem_type, build_nx >::setUp ( )
inlineinherited

Definition at line 347 of file fe_test.h.

References libMesh::System::add_variable(), libMesh::FEGenericBase< OutputType >::build(), libMesh::Elem::build(), libMesh::MeshTools::Generation::build_cube(), libMesh::FEType::default_quadrature_order(), libMesh::DofMap::dof_indices(), libMesh::EDGE3, fe_cubic_test(), fe_cubic_test_grad(), fe_quartic_test(), fe_quartic_test_grad(), libMesh::System::get_dof_map(), libMesh::HERMITE, libMesh::DofObject::id(), linear_test(), linear_test_grad(), libMesh::MeshTools::Modification::permute_elements(), libMesh::System::project_solution(), libMesh::QUAD9, quadratic_test(), quadratic_test_grad(), libMesh::RATIONAL_BERNSTEIN, rational_test(), rational_test_grad(), rational_w, libMesh::Real, libMesh::MeshTools::Modification::redistribute(), libMesh::MeshTools::Modification::rotate(), std::sqrt(), libMesh::SZABAB, libMesh::TOLERANCE, and libMesh::System::variable_type().

348  {
349  _mesh = std::make_unique<Mesh>(*TestCommWorld);
350  const std::unique_ptr<Elem> test_elem = Elem::build(elem_type);
351  _dim = test_elem->dim();
352  const unsigned int build_ny = (_dim > 1) * build_nx;
353  const unsigned int build_nz = (_dim > 2) * build_nx;
354 
355  unsigned char weight_index = 0;
356 
357  if (family == RATIONAL_BERNSTEIN)
358  {
359  // Make sure we can handle non-zero weight indices
360  _mesh->add_node_integer("buffer integer");
361 
362  // Default weight to 1.0 so we don't get NaN from contains_point
363  // checks with a default GhostPointNeighbors ghosting
364  const Real default_weight = 1.0;
365  weight_index = cast_int<unsigned char>
366  (_mesh->add_node_datum<Real>("rational_weight", true,
367  &default_weight));
368  libmesh_assert_not_equal_to(weight_index, 0);
369 
370  // Set mapping data but not type, since here we're testing
371  // rational basis functions in the FE space but testing then
372  // with Lagrange bases for the mapping space.
373  _mesh->set_default_mapping_data(weight_index);
374  }
375 
377  build_nx, build_ny, build_nz,
378  0., 1., 0., 1., 0., 1.,
379  elem_type);
380 
381  // For debugging purposes it can be helpful to only consider one
382  // element even when we're using an element type that requires
383  // more than one element to fill out a square or cube.
384 #if 0
385  for (dof_id_type i = 0; i != _mesh->max_elem_id(); ++i)
386  {
387  Elem * elem = _mesh->query_elem_ptr(i);
388  if (elem && elem->id())
389  _mesh->delete_elem(elem);
390  }
391  _mesh->prepare_for_use();
392  CPPUNIT_ASSERT_EQUAL(_mesh->n_elem(), dof_id_type(1));
393 #endif
394 
395  // Permute our elements randomly and rotate and skew our mesh so
396  // we test all sorts of orientations ... except with Hermite
397  // elements, which are only designed to support meshes with a
398  // single orientation shared by all elements. We're also not
399  // rotating and/or skewing the rational elements, since our test
400  // solution was designed for a specific weighted mesh.
401  if (family != HERMITE &&
402  family != RATIONAL_BERNSTEIN)
403  {
405 
406  // Not yet testing manifolds embedded in higher-D space
407  if (_dim > 1)
409  8*(_dim>2), 16*(_dim>2));
410 
411  SkewFunc skew_func;
413  }
414 
415  // Set rational weights so we can exactly match our test solution
416  if (family == RATIONAL_BERNSTEIN)
417  {
418  for (auto elem : _mesh->active_element_ptr_range())
419  {
420  const unsigned int nv = elem->n_vertices();
421  const unsigned int nn = elem->n_nodes();
422  // We want interiors in lower dimensional elements treated
423  // like edges or faces as appropriate.
424  const unsigned int n_edges =
425  (elem->type() == EDGE3) ? 1 : elem->n_edges();
426  const unsigned int n_faces =
427  (elem->type() == QUAD9) ? 1 : elem->n_faces();
428  const unsigned int nve = std::min(nv + n_edges, nn);
429  const unsigned int nvef = std::min(nve + n_faces, nn);
430 
431  for (unsigned int i = 0; i != nv; ++i)
432  elem->node_ref(i).set_extra_datum<Real>(weight_index, 1.);
433  for (unsigned int i = nv; i != nve; ++i)
434  elem->node_ref(i).set_extra_datum<Real>(weight_index, rational_w);
435  const Real w2 = rational_w * rational_w;
436  for (unsigned int i = nve; i != nvef; ++i)
437  elem->node_ref(i).set_extra_datum<Real>(weight_index, w2);
438  const Real w3 = rational_w * w2;
439  for (unsigned int i = nvef; i != nn; ++i)
440  elem->node_ref(i).set_extra_datum<Real>(weight_index, w3);
441  }
442  }
443 
444  _es = std::make_unique<EquationSystems>(*_mesh);
445  _sys = &(_es->add_system<System> ("SimpleSystem"));
446  _sys->add_variable("u", order, family);
447  _es->init();
448 
449  if (family == RATIONAL_BERNSTEIN && order > 1)
450  {
452  }
453  else if (order > 3)
454  {
456  }
457  // Lagrange "cubic" on Tet7 only supports a bubble function, not
458  // all of P^3
459  else if (FE_CAN_TEST_CUBIC)
460  {
462  }
463  else if (order > 1)
464  {
466  }
467  else
468  {
470  }
471 
472  FEType fe_type = _sys->variable_type(0);
473  _fe = FEBase::build(_dim, fe_type);
474 
475  // Create quadrature rule for use in computing dual shape coefficients
476  _qrule = std::make_unique<QGauss>(_dim, fe_type.default_quadrature_order());
477  _fe->attach_quadrature_rule(_qrule.get());
478 
479  auto rng = _mesh->active_local_element_ptr_range();
480  this->_elem = rng.begin() == rng.end() ? nullptr : *(rng.begin());
481 
483 
484  _nx = 10;
485  _ny = (_dim > 1) ? _nx : 1;
486  _nz = (_dim > 2) ? _nx : 1;
487 
488  this->_value_tol = TOLERANCE * sqrt(TOLERANCE);
489 
490  // We see 6.5*tol*sqrt(tol) errors on cubic Hermites with the fe_cubic
491  // hermite test function
492  // On Tri7 we see 10*tol*sqrt(tol) errors, even!
493  this->_grad_tol = 12 * TOLERANCE * sqrt(TOLERANCE);
494 
495  this->_hess_tol = sqrt(TOLERANCE); // FIXME: we see some ~1e-5 errors?!?
496 
497  // Prerequest everything we'll want to calculate later.
498  _fe->get_phi();
499  _fe->get_dphi();
500  _fe->get_dphidx();
501 #if LIBMESH_DIM > 1
502  _fe->get_dphidy();
503 #endif
504 #if LIBMESH_DIM > 2
505  _fe->get_dphidz();
506 #endif
507 
508 #if LIBMESH_ENABLE_SECOND_DERIVATIVES
509 
510  // Szabab elements don't have second derivatives yet
511  if (family == SZABAB)
512  return;
513 
514  _fe->get_d2phi();
515  _fe->get_d2phidx2();
516 #if LIBMESH_DIM > 1
517  _fe->get_d2phidxdy();
518  _fe->get_d2phidy2();
519 #endif
520 #if LIBMESH_DIM > 2
521  _fe->get_d2phidxdz();
522  _fe->get_d2phidydz();
523  _fe->get_d2phidz2();
524 #endif
525 
526 #endif
527  }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:182
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:1992
static constexpr Real TOLERANCE
std::unique_ptr< QGauss > _qrule
Definition: fe_test.h:275
Gradient quadratic_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:108
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
Gradient rational_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:217
Order default_quadrature_order() const
Definition: fe_type.h:357
Gradient fe_cubic_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:141
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
Definition: type_vector.h:53
Gradient fe_quartic_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:174
Number fe_cubic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:128
static const Real rational_w
Definition: fe_test.h:197
void permute_elements(MeshBase &mesh)
Randomly permute the nodal ordering of each element (without twisting the element mapping)...
std::unique_ptr< EquationSystems > _es
Definition: fe_test.h:273
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr) const
Projects arbitrary functions onto the current solution.
Number linear_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:66
Number rational_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:200
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2353
dof_id_type id() const
Definition: dof_object.h:823
virtual unsigned int n_nodes() const =0
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
unsigned int add_variable(std::string_view var, const FEType &type, const std::set< subdomain_id_type > *const active_subdomains=nullptr)
Adds the variable var to the list of variables for this system.
Definition: system.C:1305
void set_extra_datum(const unsigned int index, const T value)
Sets the value on this object of the extra datum associated with index, which should have been obtain...
Definition: dof_object.h:1119
Number quadratic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:95
virtual unsigned int n_edges() const =0
RealTensorValue rotate(MeshBase &mesh, const Real phi, const Real theta=0., const Real psi=0.)
Rotates the mesh in the xy plane.
std::unique_ptr< Mesh > _mesh
Definition: fe_test.h:272
virtual unsigned int n_vertices() const =0
const FEType & variable_type(const unsigned int i) const
Definition: system.h:2427
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:270
void redistribute(MeshBase &mesh, const FunctionBase< Real > &mapfunc)
Deterministically perturb the nodal locations.
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274
virtual unsigned int n_faces() const =0
Number fe_quartic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:161
Gradient linear_test_grad(const Point &, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:79
const DofMap & get_dof_map() const
Definition: system.h:2293
virtual ElemType type() const =0
void build_cube(UnstructuredMesh &mesh, const unsigned int nx=0, const unsigned int ny=0, const unsigned int nz=0, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const Real zmin=0., const Real zmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
Builds a (elements) cube.
uint8_t dof_id_type
Definition: id_types.h:67

◆ tearDown()

void FETestBase< order, family, elem_type, build_nx >::tearDown ( )
inlineinherited

Definition at line 529 of file fe_test.h.

529 {}

◆ testCustomReinit()

template<Order order, FEFamily family, ElemType elem_type>
void FETest< order, family, elem_type >::testCustomReinit ( )
inline

Definition at line 900 of file fe_test.h.

References libMesh::FEGenericBase< OutputType >::build(), libMesh::FEType::default_quadrature_rule(), and libMesh::Real.

901  {
902  LOG_UNIT_TEST;
903 
904  std::vector<Point> q_points;
905  std::vector<Real> weights;
906  q_points.resize(3); weights.resize(3);
907  q_points[0](0) = 0.0; q_points[0](1) = 0.0; weights[0] = Real(1)/6;
908  q_points[1](0) = 1.0; q_points[1](1) = 0.0; weights[1] = weights[0];
909  q_points[2](0) = 0.0; q_points[2](1) = 1.0; weights[2] = weights[0];
910 
911  FEType fe_type = this->_sys->variable_type(0);
912  std::unique_ptr<FEBase> fe (FEBase::build(this->_dim, fe_type));
913  const int extraorder = 3;
914  std::unique_ptr<QBase> qrule (fe_type.default_quadrature_rule (this->_dim, extraorder));
915  fe->attach_quadrature_rule (qrule.get());
916 
917  const std::vector<Point> & q_pos = fe->get_xyz();
918 
919  for (const auto & elem : this->_mesh->active_local_element_ptr_range()) {
920  fe->reinit (elem, &q_points, &weights);
921  CPPUNIT_ASSERT_EQUAL(q_points.size(), std::size_t(3));
922  CPPUNIT_ASSERT_EQUAL(q_pos.size(), std::size_t(3)); // 6? bug?
923  }
924  }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:182
std::unique_ptr< QBase > default_quadrature_rule(const unsigned int dim, const int extraorder=0) const
Definition: fe_type.C:34
std::unique_ptr< Mesh > _mesh
Definition: fe_test.h:272
const FEType & variable_type(const unsigned int i) const
Definition: system.h:2427
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ testDualDoesntScreamAndDie()

template<Order order, FEFamily family, ElemType elem_type>
void FETest< order, family, elem_type >::testDualDoesntScreamAndDie ( )
inline

Definition at line 713 of file fe_test.h.

714  {
715  LOG_UNIT_TEST;
716 
717  // Handle the "more processors than elements" case
718  if (!this->_elem)
719  return;
720 
721  // Request dual calculations
722  this->_fe->get_dual_phi();
723 
724  // reinit using the default quadrature rule in order to calculate the dual coefficients
725  this->_fe->reinit(this->_elem);
726  }
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274

◆ testFEInterface()

template<Order order, FEFamily family, ElemType elem_type>
void FETest< order, family, elem_type >::testFEInterface ( )
inline

Definition at line 655 of file fe_test.h.

References libMesh::FEInterface::get_continuity(), libMesh::FEInterface::is_hierarchic(), and libMesh::FEInterface::n_shape_functions().

656  {
657  LOG_UNIT_TEST;
658 
659  // Handle the "more processors than elements" case
660  if (!this->_elem)
661  return;
662 
663  this->_fe->reinit(this->_elem);
664 
665  const FEType fe_type = this->_sys->variable_type(0);
666 
667  CPPUNIT_ASSERT_EQUAL(
668  FEInterface::n_shape_functions(fe_type, this->_elem),
669  this->_fe->n_shape_functions());
670 
671  CPPUNIT_ASSERT_EQUAL(
672  FEInterface::get_continuity(fe_type),
673  this->_fe->get_continuity());
674 
675  CPPUNIT_ASSERT_EQUAL(
676  FEInterface::is_hierarchic(fe_type),
677  this->_fe->is_hierarchic());
678  }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:182
const FEType & variable_type(const unsigned int i) const
Definition: system.h:2427
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274

◆ testGradU()

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

Definition at line 729 of file fe_test.h.

References libMesh::libmesh_real().

730  {
731  LOG_UNIT_TEST;
732 
733  auto f = [this](Point p)
734  {
735  Parameters dummy;
736 
737  Gradient grad_u = 0;
738  for (std::size_t d = 0; d != this->_dof_indices.size(); ++d)
739  grad_u += this->_fe->get_dphi()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
740 
741  RealGradient true_grad = this->true_gradient(p);
742 
743  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(grad_u(0)),
744  true_grad(0), this->_grad_tol);
745  if (this->_dim > 1)
746  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(grad_u(1)),
747  true_grad(1), this->_grad_tol);
748  if (this->_dim > 2)
749  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(grad_u(2)),
750  true_grad(2), this->_grad_tol);
751  };
752 
753  testLoop(f);
754  }
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
void testLoop(Functor f)
Definition: fe_test.h:540
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:270
static RealGradient true_gradient(Point p)
Definition: fe_test.h:280
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1585
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ testGradUComp()

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

Definition at line 756 of file fe_test.h.

References libMesh::libmesh_real().

757  {
758  LOG_UNIT_TEST;
759 
760  auto f = [this](Point p)
761  {
762  Parameters dummy;
763 
764  Number grad_u_x = 0, grad_u_y = 0, grad_u_z = 0;
765  for (std::size_t d = 0; d != this->_dof_indices.size(); ++d)
766  {
767  grad_u_x += this->_fe->get_dphidx()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
768 #if LIBMESH_DIM > 1
769  grad_u_y += this->_fe->get_dphidy()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
770 #endif
771 #if LIBMESH_DIM > 2
772  grad_u_z += this->_fe->get_dphidz()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
773 #endif
774  }
775 
776  RealGradient true_grad = this->true_gradient(p);
777 
778  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(grad_u_x),
779  true_grad(0), this->_grad_tol);
780  if (this->_dim > 1)
781  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(grad_u_y),
782  true_grad(1), this->_grad_tol);
783  if (this->_dim > 2)
784  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(grad_u_z),
785  true_grad(2), this->_grad_tol);
786  };
787 
788  testLoop(f);
789  }
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
void testLoop(Functor f)
Definition: fe_test.h:540
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:270
static RealGradient true_gradient(Point p)
Definition: fe_test.h:280
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1585
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ testHessU()

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

Definition at line 792 of file fe_test.h.

References libMesh::libmesh_real(), libMesh::RATIONAL_BERNSTEIN, and libMesh::SZABAB.

793  {
794  LOG_UNIT_TEST;
795 
796  // Szabab elements don't have second derivatives yet
797  if (family == SZABAB)
798  return;
799 
800 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
801  auto f = [this](Point p)
802  {
803  Tensor hess_u;
804  for (std::size_t d = 0; d != this->_dof_indices.size(); ++d)
805  hess_u += this->_fe->get_d2phi()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
806 
807  // TODO: Yeah we'll test the ugly expressions later.
808  if (family == RATIONAL_BERNSTEIN && order > 1)
809  return;
810 
811  RealTensor true_hess = this->true_hessian(p);
812 
813  LIBMESH_ASSERT_FP_EQUAL(true_hess(0,0), libmesh_real(hess_u(0,0)),
814  this->_hess_tol);
815  if (this->_dim > 1)
816  {
817  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(hess_u(0,1)), libmesh_real(hess_u(1,0)),
818  this->_hess_tol);
819  LIBMESH_ASSERT_FP_EQUAL(true_hess(0,1), libmesh_real(hess_u(0,1)),
820  this->_hess_tol);
821  LIBMESH_ASSERT_FP_EQUAL(true_hess(1,1), libmesh_real(hess_u(1,1)),
822  this->_hess_tol);
823  }
824  if (this->_dim > 2)
825  {
826  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(hess_u(0,2)), libmesh_real(hess_u(2,0)),
827  this->_hess_tol);
828  LIBMESH_ASSERT_FP_EQUAL(libmesh_real(hess_u(1,2)), libmesh_real(hess_u(2,1)),
829  this->_hess_tol);
830  LIBMESH_ASSERT_FP_EQUAL(true_hess(0,2), libmesh_real(hess_u(0,2)),
831  this->_hess_tol);
832  LIBMESH_ASSERT_FP_EQUAL(true_hess(1,2), libmesh_real(hess_u(1,2)),
833  this->_hess_tol);
834  LIBMESH_ASSERT_FP_EQUAL(true_hess(2,2), libmesh_real(hess_u(2,2)),
835  this->_hess_tol);
836  }
837  };
838 
839  testLoop(f);
840 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
841  }
T libmesh_real(T a)
void testLoop(Functor f)
Definition: fe_test.h:540
static RealTensor true_hessian(Point p)
Definition: fe_test.h:318
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:270
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1585
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.

◆ testHessUComp()

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

Definition at line 843 of file fe_test.h.

References libMesh::libmesh_real(), libMesh::RATIONAL_BERNSTEIN, and libMesh::SZABAB.

844  {
845 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
846  LOG_UNIT_TEST;
847 
848  // Szabab elements don't have second derivatives yet
849  if (family == SZABAB)
850  return;
851 
852  auto f = [this](Point p)
853  {
854  Number hess_u_xx = 0, hess_u_xy = 0, hess_u_yy = 0,
855  hess_u_xz = 0, hess_u_yz = 0, hess_u_zz = 0;
856  for (std::size_t d = 0; d != this->_dof_indices.size(); ++d)
857  {
858  hess_u_xx += this->_fe->get_d2phidx2()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
859 #if LIBMESH_DIM > 1
860  hess_u_xy += this->_fe->get_d2phidxdy()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
861  hess_u_yy += this->_fe->get_d2phidy2()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
862 #endif
863 #if LIBMESH_DIM > 2
864  hess_u_xz += this->_fe->get_d2phidxdz()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
865  hess_u_yz += this->_fe->get_d2phidydz()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
866  hess_u_zz += this->_fe->get_d2phidz2()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
867 #endif
868  }
869 
870  // TODO: Yeah we'll test the ugly expressions later.
871  if (family == RATIONAL_BERNSTEIN && order > 1)
872  return;
873 
874  RealTensor true_hess = this->true_hessian(p);
875 
876  LIBMESH_ASSERT_FP_EQUAL(true_hess(0,0), libmesh_real(hess_u_xx),
877  this->_hess_tol);
878  if (this->_dim > 1)
879  {
880  LIBMESH_ASSERT_FP_EQUAL(true_hess(0,1), libmesh_real(hess_u_xy),
881  this->_hess_tol);
882  LIBMESH_ASSERT_FP_EQUAL(true_hess(1,1), libmesh_real(hess_u_yy),
883  this->_hess_tol);
884  }
885  if (this->_dim > 2)
886  {
887  LIBMESH_ASSERT_FP_EQUAL(true_hess(0,2), libmesh_real(hess_u_xz),
888  this->_hess_tol);
889  LIBMESH_ASSERT_FP_EQUAL(true_hess(1,2), libmesh_real(hess_u_yz),
890  this->_hess_tol);
891  LIBMESH_ASSERT_FP_EQUAL(true_hess(2,2), libmesh_real(hess_u_zz),
892  this->_hess_tol);
893  }
894  };
895 
896  testLoop(f);
897 #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
898  }
T libmesh_real(T a)
void testLoop(Functor f)
Definition: fe_test.h:540
static RealTensor true_hessian(Point p)
Definition: fe_test.h:318
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:270
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1585
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.

◆ testLoop()

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

Definition at line 540 of file fe_test.h.

References libMesh::invalid_uint, libMesh::FEMap::inverse_map(), and libMesh::Real.

541  {
542  // Handle the "more processors than elements" case
543  if (!this->_elem)
544  return;
545 
546  // These tests require exceptions to be enabled because a
547  // TypeTensor::solve() call down in Elem::contains_point()
548  // actually throws a non-fatal exception for a certain Point which
549  // is not in the Elem. When exceptions are not enabled, this test
550  // simply aborts.
551 #ifdef LIBMESH_ENABLE_EXCEPTIONS
552  for (unsigned int i=0; i != this->_nx; ++i)
553  for (unsigned int j=0; j != this->_ny; ++j)
554  for (unsigned int k=0; k != this->_nz; ++k)
555  {
556  Point p = Real(i)/this->_nx;
557  if (j > 0)
558  p(1) = Real(j)/this->_ny;
559  if (k > 0)
560  p(2) = Real(k)/this->_nz;
561  if (!this->_elem->contains_point(p))
562  continue;
563 
564  // If at a singular node, cannot use FEMap::map
565  if (this->_elem->local_singular_node(p) != invalid_uint)
566  continue;
567 
568  std::vector<Point> master_points
569  (1, FEMap::inverse_map(this->_dim, this->_elem, p));
570 
571  // Reinit at point to test against analytic solution
572  this->_fe->reinit(this->_elem, &master_points);
573 
574  f(p);
575  }
576 #endif // LIBMESH_ENABLE_EXCEPTIONS
577  }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:286
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2375
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual unsigned int local_singular_node(const Point &, const Real=TOLERANCE *TOLERANCE) const
Definition: elem.h:1684
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ testPartitionOfUnity()

template<Order order, FEFamily family, ElemType elem_type>
void FETest< order, family, elem_type >::testPartitionOfUnity ( )
inline

Definition at line 579 of file fe_test.h.

References libMesh::BERNSTEIN, libMesh::CLOUGH, libMesh::CONSTANT, libMesh::FIRST, libMesh::HERMITE, libMesh::HIERARCHIC, libMesh::L2_HIERARCHIC, libMesh::L2_LAGRANGE, libMesh::LAGRANGE, libMesh::make_range(), libMesh::MONOMIAL, libMesh::RATIONAL_BERNSTEIN, libMesh::Real, libMesh::SZABAB, libMesh::TOLERANCE, and libMesh::XYZ.

580  {
581  if (!this->_elem)
582  return;
583 
584  this->_fe->reinit(this->_elem);
585 
586  bool satisfies_partition_of_unity = true;
587  for (const auto qp : make_range(this->_qrule->n_points()))
588  {
589  Real phi_sum = 0;
590  for (std::size_t d = 0; d != this->_dof_indices.size(); ++d)
591  phi_sum += this->_fe->get_phi()[d][qp];
592  if (phi_sum < (1 - TOLERANCE) || phi_sum > (1 + TOLERANCE))
593  {
594  satisfies_partition_of_unity = false;
595  break;
596  }
597  }
598 
599  switch (this->_fe->get_family())
600  {
601  case MONOMIAL:
602  {
603  switch (this->_fe->get_order())
604  {
605  case CONSTANT:
606  CPPUNIT_ASSERT(satisfies_partition_of_unity);
607  break;
608 
609  default:
610  CPPUNIT_ASSERT(!satisfies_partition_of_unity);
611  break;
612  }
613  break;
614  }
615  case SZABAB:
616  case HIERARCHIC:
617  case L2_HIERARCHIC:
618  {
619  switch (this->_fe->get_order())
620  {
621  case FIRST:
622  CPPUNIT_ASSERT(satisfies_partition_of_unity);
623  break;
624 
625  default:
626  CPPUNIT_ASSERT(!satisfies_partition_of_unity);
627  break;
628  }
629  break;
630  }
631 
632  case XYZ:
633  case CLOUGH:
634  case HERMITE:
635  {
636  CPPUNIT_ASSERT(!satisfies_partition_of_unity);
637  break;
638  }
639 
640  case LAGRANGE:
641  case L2_LAGRANGE:
642  case BERNSTEIN:
643  case RATIONAL_BERNSTEIN:
644  {
645  CPPUNIT_ASSERT(satisfies_partition_of_unity);
646  break;
647  }
648 
649  default:
650  CPPUNIT_FAIL("Uncovered FEFamily");
651  }
652  }
static constexpr Real TOLERANCE
std::unique_ptr< QGauss > _qrule
Definition: fe_test.h:275
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:270
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:134
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274

◆ testU()

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

Definition at line 680 of file fe_test.h.

References fe_cubic_test(), fe_quartic_test(), libMesh::libmesh_real(), libMesh::RATIONAL_BERNSTEIN, and rational_test().

681  {
682  LOG_UNIT_TEST;
683 
684  auto f = [this](Point p)
685  {
686  Parameters dummy;
687 
688  Number u = 0;
689  for (std::size_t d = 0; d != this->_dof_indices.size(); ++d)
690  u += this->_fe->get_phi()[d][0] * (*this->_sys->current_local_solution)(this->_dof_indices[d]);
691 
692  Number true_u;
693 
694  if (family == RATIONAL_BERNSTEIN && order > 1)
695  true_u = rational_test(p, dummy, "", "");
696  else if (order > 3)
697  true_u = fe_quartic_test(p, dummy, "", "");
698  else if (FE_CAN_TEST_CUBIC)
699  true_u = fe_cubic_test(p, dummy, "", "");
700  else if (order > 1)
701  true_u = p(0)*p(0) + 0.5*p(1)*p(1) + 0.25*p(2)*p(2) +
702  0.125*p(0)*p(1) + 0.0625*p(0)*p(2) + 0.03125*p(1)*p(2);
703  else
704  true_u = p(0) + 0.25*p(1) + 0.0625*p(2);
705 
706  LIBMESH_ASSERT_FP_EQUAL
707  (libmesh_real(true_u), libmesh_real(u), this->_value_tol);
708  };
709 
710  testLoop(f);
711  }
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
void testLoop(Functor f)
Definition: fe_test.h:540
Number fe_cubic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:128
Number rational_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:200
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:270
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1585
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:274
Number fe_quartic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:161
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ true_gradient()

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

Definition at line 280 of file fe_test.h.

References fe_cubic_test_grad(), fe_quartic_test_grad(), libMesh::libmesh_real(), libMesh::RATIONAL_BERNSTEIN, rational_test_grad(), and libMesh::Real.

281  {
282  Parameters dummy;
283 
284  Gradient true_grad;
285  RealGradient returnval;
286 
287  if (family == RATIONAL_BERNSTEIN && order > 1)
288  true_grad = rational_test_grad(p, dummy, "", "");
289  else if (order > 3)
290  true_grad = fe_quartic_test_grad(p, dummy, "", "");
291  else if (FE_CAN_TEST_CUBIC)
292  true_grad = fe_cubic_test_grad(p, dummy, "", "");
293  else if (order > 1)
294  {
295  const Real & x = p(0);
296  const Real & y = (LIBMESH_DIM > 1) ? p(1) : 0;
297  const Real & z = (LIBMESH_DIM > 2) ? p(2) : 0;
298 
299  true_grad = Gradient(2*x+0.125*y+0.0625*z,
300  y+0.125*x+0.03125*z,
301  0.5*z+0.0625*x+0.03125*y);
302  }
303  else
304  true_grad = Gradient(1.0, 0.25, 0.0625);
305 
306  for (unsigned int d=0; d != LIBMESH_DIM; ++d)
307  {
308  CPPUNIT_ASSERT(true_grad(d) ==
309  Number(libmesh_real(true_grad(d))));
310 
311  returnval(d) = libmesh_real(true_grad(d));
312  }
313 
314  return returnval;
315  }
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:217
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:141
Gradient fe_quartic_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:174
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 318 of file fe_test.h.

References libMesh::Real.

319  {
320  const Real & x = p(0);
321  const Real & y = LIBMESH_DIM > 1 ? p(1) : 0;
322  const Real & z = LIBMESH_DIM > 2 ? p(2) : 0;
323 
324  if (order > 3)
325  return RealTensor
326  { 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),
327  -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),
328  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 };
329  else if (FE_CAN_TEST_CUBIC)
330  return RealTensor
331  { 6*x-4+2*(1-y), -2*x+z-1, y-1,
332  -2*x+z-1, -2*z, x+1-2*y,
333  y-1, x+1-2*y, 6*z-4 };
334  else if (order > 1)
335  return RealTensor
336  { 2, 0.125, 0.0625,
337  0.125, 1, 0.03125,
338  0.0625, 0.03125, 0.5 };
339 
340  return RealTensor
341  { 0, 0, 0,
342  0, 0, 0,
343  0, 0, 0 };
344  }
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

Definition at line 268 of file fe_test.h.

◆ _dof_indices

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

Definition at line 270 of file fe_test.h.

◆ _elem

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

Definition at line 269 of file fe_test.h.

◆ _es

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

Definition at line 273 of file fe_test.h.

◆ _fe

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

Definition at line 274 of file fe_test.h.

◆ _grad_tol

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

Definition at line 277 of file fe_test.h.

◆ _hess_tol

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

Definition at line 277 of file fe_test.h.

◆ _mesh

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

Definition at line 272 of file fe_test.h.

◆ _nx

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

Definition at line 268 of file fe_test.h.

◆ _ny

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

Definition at line 268 of file fe_test.h.

◆ _nz

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

Definition at line 268 of file fe_test.h.

◆ _qrule

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

Definition at line 275 of file fe_test.h.

◆ _sys

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

Definition at line 271 of file fe_test.h.

◆ _value_tol

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

Definition at line 277 of file fe_test.h.

◆ libmesh_suite_name

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

Definition at line 266 of file fe_test.h.


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