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

#include <fe_test.h>

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

Public Member Functions

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, unsigned int build_nx>
class FETestBase< order, family, elem_type, build_nx >

Definition at line 266 of file fe_test.h.

Member Function Documentation

◆ setUp()

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
void FETestBase< order, family, elem_type, build_nx >::setUp ( )
inline

Definition at line 350 of file fe_test.h.

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

351  {
352  _mesh = std::make_unique<Mesh>(*TestCommWorld);
353  _dim = Elem::type_to_dim_map[elem_type];
354  const unsigned int build_ny = (_dim > 1) * build_nx;
355  const unsigned int build_nz = (_dim > 2) * build_nx;
356 
357  unsigned char weight_index = 0;
358 
359  if (family == RATIONAL_BERNSTEIN)
360  {
361  // Make sure we can handle non-zero weight indices
362  _mesh->add_node_integer("buffer integer");
363 
364  // Default weight to 1.0 so we don't get NaN from contains_point
365  // checks with a default GhostPointNeighbors ghosting
366  const Real default_weight = 1.0;
367  weight_index = cast_int<unsigned char>
368  (_mesh->add_node_datum<Real>("rational_weight", true,
369  &default_weight));
370  libmesh_assert_not_equal_to(weight_index, 0);
371 
372  // Set mapping data but not type, since here we're testing
373  // rational basis functions in the FE space but testing then
374  // with Lagrange bases for the mapping space.
375  _mesh->set_default_mapping_data(weight_index);
376  }
377 
378  if (elem_type == C0POLYGON)
379  {
380  // Build a pentagon by hand for testing purposes. Make this
381  // one non-skewed so a MONOMIAL basis will be able to exactly
382  // represent the polynomials we're projecting.
383 
384  _mesh->add_point(Point(0, 0), 0);
385  _mesh->add_point(Point(1, 0), 1);
386  _mesh->add_point(Point(1+cos(2*libMesh::pi/5), sin(2*libMesh::pi/5)), 2);
387  _mesh->add_point(Point(0.5, sin(2*libMesh::pi/5)+sin(libMesh::pi/5)), 3);
388  _mesh->add_point(Point(-cos(2*libMesh::pi/5), sin(2*libMesh::pi/5)), 4);
389 
390  std::unique_ptr<Elem> polygon = std::make_unique<C0Polygon>(5);
391  for (auto i : make_range(5))
392  polygon->set_node(i, _mesh->node_ptr(i));
393  polygon->set_id() = 0;
394 
395  _mesh->add_elem(std::move(polygon));
396  _mesh->prepare_for_use();
397  }
398  else if (elem_type == C0POLYHEDRON)
399  {
400  // Build a plain cube by hand for testing purposes. We could
401  // upgrade this, but it should be to something non-skewed so a
402  // MONOMIAL basis will be able to exactly represent the
403  // polynomials we're projecting.
404  //
405  // See elem_test.h for the limitations here.
406 
407  _mesh->add_point(Point(0, 0, 0), 0);
408  _mesh->add_point(Point(1, 0, 0), 1);
409  _mesh->add_point(Point(1, 1, 0), 2);
410  _mesh->add_point(Point(0, 1, 0), 3);
411  _mesh->add_point(Point(0, 0, 1), 4);
412  _mesh->add_point(Point(1, 0, 1), 5);
413  _mesh->add_point(Point(1, 1, 1), 6);
414  _mesh->add_point(Point(0, 1, 1), 7);
415 
416  const std::vector<std::vector<unsigned int>> nodes_on_side =
417  { {0, 1, 2, 3}, // min z
418  {0, 1, 5, 4}, // min y
419  {2, 6, 5, 1}, // max x
420  {2, 3, 7, 6}, // max y
421  {0, 4, 7, 3}, // min x
422  {5, 6, 7, 4} }; // max z
423 
424  // Build all the sides.
425  std::vector<std::shared_ptr<Polygon>> sides(nodes_on_side.size());
426 
427  for (auto s : index_range(nodes_on_side))
428  {
429  const auto & nodes_on_s = nodes_on_side[s];
430  sides[s] = std::make_shared<C0Polygon>(nodes_on_s.size());
431  for (auto i : index_range(nodes_on_s))
432  sides[s]->set_node(i, _mesh->node_ptr(nodes_on_s[i]));
433  }
434 
435  std::unique_ptr<Elem> polyhedron = std::make_unique<C0Polyhedron>(sides);
436  _mesh->add_elem(std::move(polyhedron));
437  _mesh->prepare_for_use();
438  }
439  else
440  {
442  build_nx, build_ny, build_nz,
443  0., 1., 0., 1., 0., 1.,
444  elem_type);
445  }
446 
447  // For debugging purposes it can be helpful to only consider one
448  // element even when we're using an element type that requires
449  // more than one element to fill out a square or cube.
450 #if 0
451  for (dof_id_type i = 0; i != _mesh->max_elem_id(); ++i)
452  {
453  Elem * elem = _mesh->query_elem_ptr(i);
454  if (elem && elem->id())
455  _mesh->delete_elem(elem);
456  }
457  _mesh->prepare_for_use();
458  CPPUNIT_ASSERT_EQUAL(_mesh->n_elem(), dof_id_type(1));
459 #endif
460 
461  // Permute our elements randomly and rotate and skew our mesh so
462  // we test all sorts of orientations ... except with Hermite
463  // elements, which are only designed to support meshes with a
464  // single orientation shared by all elements. We're also not
465  // rotating and/or skewing the rational elements, since our test
466  // solution was designed for a specific weighted mesh.
467  if (family != HERMITE &&
468  family != RATIONAL_BERNSTEIN)
469  {
471 
472  // Not yet testing manifolds embedded in higher-D space
473  if (_dim > 1)
475  8*(_dim>2), 16*(_dim>2));
476 
477  SkewFunc skew_func;
479  }
480 
481  // Set rational weights so we can exactly match our test solution
482  if (family == RATIONAL_BERNSTEIN)
483  {
484  for (auto elem : _mesh->active_element_ptr_range())
485  {
486  const unsigned int nv = elem->n_vertices();
487  const unsigned int nn = elem->n_nodes();
488  // We want interiors in lower dimensional elements treated
489  // like edges or faces as appropriate.
490  const unsigned int n_edges =
491  (elem->type() == EDGE3) ? 1 : elem->n_edges();
492  const unsigned int n_faces =
493  (elem->type() == QUAD9) ? 1 : elem->n_faces();
494  const unsigned int nve = std::min(nv + n_edges, nn);
495  const unsigned int nvef = std::min(nve + n_faces, nn);
496 
497  for (unsigned int i = 0; i != nv; ++i)
498  elem->node_ref(i).set_extra_datum<Real>(weight_index, 1.);
499  for (unsigned int i = nv; i != nve; ++i)
500  elem->node_ref(i).set_extra_datum<Real>(weight_index, rational_w);
501  const Real w2 = rational_w * rational_w;
502  for (unsigned int i = nve; i != nvef; ++i)
503  elem->node_ref(i).set_extra_datum<Real>(weight_index, w2);
504  const Real w3 = rational_w * w2;
505  for (unsigned int i = nvef; i != nn; ++i)
506  elem->node_ref(i).set_extra_datum<Real>(weight_index, w3);
507  }
508  }
509 
510  _es = std::make_unique<EquationSystems>(*_mesh);
511  _sys = &(_es->add_system<System> ("SimpleSystem"));
512  _sys->add_variable("u", order, family);
513  _es->init();
514 
515  if (family == RATIONAL_BERNSTEIN && order > 1)
516  {
518  }
519  else if (order > 3)
520  {
522  }
523  // Lagrange "cubic" on Tet7 only supports a bubble function, not
524  // all of P^3
525  else if (FE_CAN_TEST_CUBIC)
526  {
528  }
529  else if (order > 1)
530  {
532  }
533  else
534  {
536  }
537 
538  FEType fe_type = _sys->variable_type(0);
539  _fe = FEBase::build(_dim, fe_type);
540 
541  // Create quadrature rule for use in computing dual shape coefficients
542  _qrule = std::make_unique<QGauss>(_dim, fe_type.default_quadrature_order());
543  _fe->attach_quadrature_rule(_qrule.get());
544 
545  auto rng = _mesh->active_local_element_ptr_range();
546  this->_elem = rng.begin() == rng.end() ? nullptr : *(rng.begin());
547 
549 
550  _nx = 10;
551  _ny = (_dim > 1) ? _nx : 1;
552  _nz = (_dim > 2) ? _nx : 1;
553 
554  this->_value_tol = TOLERANCE * sqrt(TOLERANCE);
555 
556  // We see 6.5*tol*sqrt(tol) errors on cubic Hermites with the fe_cubic
557  // hermite test function
558  // On Tri7 we see 10*tol*sqrt(tol) errors, even!
559  // On Tet14 Monomial gives us at least 13*tol*sqrt(tol) in some
560  // cases
561  this->_grad_tol = 15 * TOLERANCE * sqrt(TOLERANCE);
562 
563  this->_hess_tol = sqrt(TOLERANCE); // FIXME: we see some ~1e-5 errors?!?
564 
565  // Prerequest everything we'll want to calculate later.
566  _fe->get_phi();
567  _fe->get_dphi();
568  _fe->get_dphidx();
569 #if LIBMESH_DIM > 1
570  _fe->get_dphidy();
571 #endif
572 #if LIBMESH_DIM > 2
573  _fe->get_dphidz();
574 #endif
575 
576 #if LIBMESH_ENABLE_SECOND_DERIVATIVES
577 
578  // Szabab elements don't have second derivatives yet
579  if (family == SZABAB)
580  return;
581 
582  _fe->get_d2phi();
583  _fe->get_d2phidx2();
584 #if LIBMESH_DIM > 1
585  _fe->get_d2phidxdy();
586  _fe->get_d2phidy2();
587 #endif
588 #if LIBMESH_DIM > 2
589  _fe->get_d2phidxdz();
590  _fe->get_d2phidydz();
591  _fe->get_d2phidz2();
592 #endif
593 
594 #endif
595  }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
unsigned int _nz
Definition: fe_test.h:271
unsigned int _nx
Definition: fe_test.h:271
Real _grad_tol
Definition: fe_test.h:280
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition: dof_map.C:2164
static constexpr Real TOLERANCE
std::unique_ptr< QGauss > _qrule
Definition: fe_test.h:278
Gradient quadratic_test_grad(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:111
Elem * _elem
Definition: fe_test.h:272
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:220
Order default_quadrature_order() const
Definition: fe_type.h:371
System * _sys
Definition: fe_test.h:274
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
Number fe_cubic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:131
static const Real rational_w
Definition: fe_test.h:200
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:276
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:69
Number rational_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:203
const Node & node_ref(const unsigned int i) const
Definition: elem.h:2529
dof_id_type id() const
Definition: dof_object.h:828
Real _hess_tol
Definition: fe_test.h:280
virtual unsigned int n_nodes() const =0
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
unsigned int _dim
Definition: fe_test.h:271
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:1357
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:1126
Number quadratic_test(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:98
virtual unsigned int n_edges() const =0
Real _value_tol
Definition: fe_test.h:280
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:275
virtual unsigned int n_vertices() const =0
const FEType & variable_type(const unsigned int i) const
Definition: system.h:2508
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< dof_id_type > _dof_indices
Definition: fe_test.h:273
unsigned int _ny
Definition: fe_test.h:271
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:140
void redistribute(MeshBase &mesh, const FunctionBase< Real > &mapfunc)
Deterministically perturb the nodal locations.
std::unique_ptr< FEBase > _fe
Definition: fe_test.h:277
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:164
Gradient linear_test_grad(const Point &, const Parameters &, const std::string &, const std::string &)
Definition: fe_test.h:82
const DofMap & get_dof_map() const
Definition: system.h:2374
virtual ElemType type() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
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
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
const Real pi
.
Definition: libmesh.h:299

◆ tearDown()

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
void FETestBase< order, family, elem_type, build_nx >::tearDown ( )
inline

Definition at line 597 of file fe_test.h.

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

597 {}

◆ true_gradient()

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
static RealGradient FETestBase< order, family, elem_type, build_nx >::true_gradient ( Point  p)
inlinestaticprotected

Definition at line 283 of file fe_test.h.

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()

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
static RealTensor FETestBase< order, family, elem_type, build_nx >::true_hessian ( Point  p)
inlinestaticprotected

Definition at line 321 of file fe_test.h.

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

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
unsigned int FETestBase< order, family, elem_type, build_nx >::_dim
protected

Definition at line 271 of file fe_test.h.

◆ _dof_indices

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
std::vector<dof_id_type> FETestBase< order, family, elem_type, build_nx >::_dof_indices
protected

Definition at line 273 of file fe_test.h.

◆ _elem

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
Elem* FETestBase< order, family, elem_type, build_nx >::_elem
protected

Definition at line 272 of file fe_test.h.

◆ _es

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
std::unique_ptr<EquationSystems> FETestBase< order, family, elem_type, build_nx >::_es
protected

Definition at line 276 of file fe_test.h.

◆ _fe

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
std::unique_ptr<FEBase> FETestBase< order, family, elem_type, build_nx >::_fe
protected

Definition at line 277 of file fe_test.h.

◆ _grad_tol

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
Real FETestBase< order, family, elem_type, build_nx >::_grad_tol
protected

Definition at line 280 of file fe_test.h.

◆ _hess_tol

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
Real FETestBase< order, family, elem_type, build_nx >::_hess_tol
protected

Definition at line 280 of file fe_test.h.

◆ _mesh

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
std::unique_ptr<Mesh> FETestBase< order, family, elem_type, build_nx >::_mesh
protected

Definition at line 275 of file fe_test.h.

◆ _nx

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
unsigned int FETestBase< order, family, elem_type, build_nx >::_nx
protected

Definition at line 271 of file fe_test.h.

◆ _ny

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
unsigned int FETestBase< order, family, elem_type, build_nx >::_ny
protected

Definition at line 271 of file fe_test.h.

◆ _nz

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
unsigned int FETestBase< order, family, elem_type, build_nx >::_nz
protected

Definition at line 271 of file fe_test.h.

◆ _qrule

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
std::unique_ptr<QGauss> FETestBase< order, family, elem_type, build_nx >::_qrule
protected

Definition at line 278 of file fe_test.h.

◆ _sys

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
System* FETestBase< order, family, elem_type, build_nx >::_sys
protected

Definition at line 274 of file fe_test.h.

◆ _value_tol

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
Real FETestBase< order, family, elem_type, build_nx >::_value_tol
protected

Definition at line 280 of file fe_test.h.

◆ libmesh_suite_name

template<Order order, FEFamily family, ElemType elem_type, unsigned int build_nx>
std::string FETestBase< order, family, elem_type, build_nx >::libmesh_suite_name
protected

Definition at line 269 of file fe_test.h.


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