libMesh
fe_rational_map.C
Go to the documentation of this file.
1 #include "test_comm.h"
2 
3 #include <libmesh/dof_map.h>
4 #include <libmesh/elem.h>
5 #include <libmesh/equation_systems.h>
6 #include <libmesh/fe_base.h>
7 #include <libmesh/fe_interface.h>
8 #include <libmesh/mesh.h>
9 #include <libmesh/mesh_generation.h>
10 #include <libmesh/numeric_vector.h>
11 #include <libmesh/system.h>
12 
13 #include <vector>
14 
15 #include "libmesh_cppunit.h"
16 
17 
18 using namespace libMesh;
19 
20 
21 template <ElemType elem_type>
22 class RationalMapTest : public CppUnit::TestCase {
23 
24 private:
25  unsigned int _dim, _nx, _ny, _nz;
27  std::vector<dof_id_type> _dof_indices;
28  std::unique_ptr<Mesh> _mesh;
29  std::unique_ptr<EquationSystems> _es;
30  std::unique_ptr<FEBase> _fe;
31 
32 protected:
33  std::string libmesh_suite_name;
34 
35 public:
36  void setUp()
37  {
38  _mesh = std::make_unique<Mesh>(*TestCommWorld);
39  const std::unique_ptr<Elem> test_elem = Elem::build(elem_type);
40  _dim = test_elem->dim();
41  const unsigned int ny = _dim > 1;
42  const unsigned int nz = _dim > 2;
43 
44  // Make sure we can handle non-zero weight indices
45  _mesh->add_node_integer("buffer integer1");
46  _mesh->add_node_integer("buffer integer2");
47 
48  // Default weight to 1.0 so we don't get NaN from contains_point
49  // checks with a default GhostPointNeighbors ghosting
50  const Real default_weight = 1.0;
51  unsigned char weight_index = cast_int<unsigned char>
52  (_mesh->add_node_datum<Real>("rational_weight", true,
53  &default_weight));
54 
55  libmesh_assert_not_equal_to(weight_index, 0);
56 
57  _mesh->set_default_mapping_type(RATIONAL_BERNSTEIN_MAP);
58  _mesh->set_default_mapping_data(weight_index);
59 
61  1, ny, nz,
62  0., 1., 0., ny, 0., nz,
63  elem_type);
64 
65  for (auto elem : _mesh->element_ptr_range())
66  {
67  CPPUNIT_ASSERT_EQUAL(elem->mapping_type(), RATIONAL_BERNSTEIN_MAP);
68  CPPUNIT_ASSERT_EQUAL(elem->mapping_data(), weight_index);
69  }
70 
71  // Transform the cube / square into a rotated quarter-annulus,
72  // with central axis at (-.5, 0) and radii ranging from .5 to 1.5
73 
74  for (auto node : _mesh->node_ptr_range())
75  {
76  Real & x = (*node)(0);
77  Real & y = (*node)(1);
78  node->set_extra_datum<Real>(weight_index, 1);
79  if (y > .6)
80  {
81  y = .5 + x;
82  x = -.5;
83  }
84  else if (y > .4)
85  {
86  y = .5 + x;
87  x = y - .5;
88  node->set_extra_datum<Real>(weight_index, sqrt(Real(2))/2);
89  }
90  }
91 
92  _es = std::make_unique<EquationSystems>(*_mesh);
93  System * sys = &(_es->add_system<System> ("SimpleSystem"));
94  sys->add_variable("u", FIRST);
95  _es->init();
96 
97  _fe = FEBase::build(_dim, sys->variable_type("u"));
98  _fe->get_xyz();
99  _fe->get_phi();
100  _fe->get_dphi();
101  _fe->get_dphidx();
102 #if LIBMESH_DIM > 1
103  _fe->get_dphidy();
104 #endif
105 #if LIBMESH_DIM > 2
106  _fe->get_dphidz();
107 #endif
108 
109  auto rng = _mesh->active_local_element_ptr_range();
110  _elem = rng.begin() == rng.end() ? nullptr : *(rng.begin());
111 
112  _nx = 10;
113  _ny = (_dim > 1) ? _nx : 0;
114  _nz = (_dim > 2) ? _nx : 0;
115  }
116 
117  void tearDown() {}
118 
120  {
121  LOG_UNIT_TEST;
122 
123  // Handle the "more processors than elements" case
124  if (!_elem)
125  return;
126 
127  // These tests require exceptions to be enabled because a
128  // TypeTensor::solve() call down in Elem::contains_point()
129  // actually throws a non-fatal exception for a certain Point which
130  // is not in the Elem. When exceptions are not enabled, this test
131  // simply aborts.
132 #ifdef LIBMESH_ENABLE_EXCEPTIONS
133  for (unsigned int j=0; j != _ny+1; ++j)
134  for (unsigned int k=0; k != _nz+1; ++k)
135  {
136  for (int i=-1; i != int(_nx+2); ++i)
137  {
138  Real r = (Real(i)/_nx) + 0.5,
139  theta = (Real(j)/_nx)*pi/2,
140  z = (Real(k)/_nx);
141  Real x = -.5 + r * std::cos(theta),
142  y = r * std::sin(theta);
143  Point p(x,y,z);
144  // Test for false negatives
145  if (i >= 0 && i <= int(_nx))
146  CPPUNIT_ASSERT(_elem->contains_point(p));
147  // Also test for false positives
148  else
149  CPPUNIT_ASSERT(!_elem->contains_point(p));
150  }
151  }
152 #endif
153  }
154 };
155 
156 
157 #define INSTANTIATE_RATIONALMAP_TEST(elemtype) \
158  class RationalMapTest_##elemtype : public RationalMapTest<elemtype> { \
159  public: \
160  RationalMapTest_##elemtype() : \
161  RationalMapTest<elemtype>() { \
162  if (unitlog->summarized_logs_enabled()) \
163  this->libmesh_suite_name = "RationalMapTest"; \
164  else \
165  this->libmesh_suite_name = "RationalMapTest_" #elemtype; \
166  } \
167  CPPUNIT_TEST_SUITE( RationalMapTest_##elemtype ); \
168  CPPUNIT_TEST( testContainsPoint ); \
169  CPPUNIT_TEST_SUITE_END(); \
170  }; \
171  \
172  CPPUNIT_TEST_SUITE_REGISTRATION( RationalMapTest_##elemtype );
173 
unsigned int _nz
std::vector< dof_id_type > _dof_indices
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
INSTANTIATE_RATIONALMAP_TEST(EDGE3)
The libMesh namespace provides an interface to certain functionality in the library.
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2751
std::unique_ptr< FEBase > _fe
std::unique_ptr< EquationSystems > _es
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:96
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:444
static std::unique_ptr< FEGenericBase > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
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
std::string libmesh_suite_name
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::unique_ptr< Mesh > _mesh
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
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.
const Real pi
.
Definition: libmesh.h:299