libMesh
mesh_function_dfem.C
Go to the documentation of this file.
1 #include <libmesh/equation_systems.h>
2 #include <libmesh/replicated_mesh.h>
3 #include <libmesh/mesh_generation.h>
4 #include <libmesh/edge_edge2.h>
5 #include <libmesh/face_quad4.h>
6 #include <libmesh/face_tri3.h>
7 #include <libmesh/cell_hex8.h>
8 #include <libmesh/dof_map.h>
9 #include <libmesh/linear_implicit_system.h>
10 #include <libmesh/mesh_refinement.h>
11 #include <libmesh/mesh_function.h>
12 #include <libmesh/numeric_vector.h>
13 
14 #include "test_comm.h"
15 #include "libmesh_cppunit.h"
16 
17 
18 using namespace libMesh;
19 
21  const Parameters&,
22  const std::string&,
23  const std::string&)
24 {
25  if (p(1) > 0.0)
26  return 0.0;
27  else
28  return 1.0;
29 }
30 
32  const Parameters&,
33  const std::string&,
34  const std::string&)
35 {
36  if (p(1) > 0.0)
37  return 2.0 * p(1) + 1.0;
38  else
39  return p(1) + 1.0;
40 }
41 
42 class MeshfunctionDFEM : public CppUnit::TestCase
43 {
48 public:
49  CPPUNIT_TEST_SUITE( MeshfunctionDFEM );
50 
51 #if LIBMESH_DIM > 1
52  CPPUNIT_TEST( test_point_locator_dfem );
53 
54  CPPUNIT_TEST( test_mesh_function_dfem );
55 
56  CPPUNIT_TEST( test_mesh_function_dfem_grad );
57 #endif
58 
59  CPPUNIT_TEST_SUITE_END();
60 
61 protected:
63  std::unique_ptr<PointLocatorBase> _point_locator;
64 
65  void build_mesh()
66  {
67  _mesh = new ReplicatedMesh(*TestCommWorld);
68 
69  // (0,1) (1,1)
70  // x---------------x
71  // | |
72  // | |
73  // | |
74  // | |
75  // | |
76  // x---------------x
77  // (0,0) (1,0)
78  // | |
79  // | |
80  // | |
81  // | |
82  // x---------------x
83  // (0,-1) (1,-1)
84 
85  _mesh->set_mesh_dimension(2);
86 
87  _mesh->add_point( Point(0.0,-1.0), 4 );
88  _mesh->add_point( Point(1.0,-1.0), 5 );
89  _mesh->add_point( Point(1.0, 0.0), 1 );
90  _mesh->add_point( Point(1.0, 1.0), 2 );
91  _mesh->add_point( Point(0.0, 1.0), 3 );
92  _mesh->add_point( Point(0.0, 0.0), 0 );
93 
94  {
95  Elem* elem_top = _mesh->add_elem( new Quad4 );
96  elem_top->set_node(0) = _mesh->node_ptr(0);
97  elem_top->set_node(1) = _mesh->node_ptr(1);
98  elem_top->set_node(2) = _mesh->node_ptr(2);
99  elem_top->set_node(3) = _mesh->node_ptr(3);
100 
101  Elem* elem_bottom = _mesh->add_elem( new Quad4 );
102  elem_bottom->set_node(0) = _mesh->node_ptr(4);
103  elem_bottom->set_node(1) = _mesh->node_ptr(5);
104  elem_bottom->set_node(2) = _mesh->node_ptr(1);
105  elem_bottom->set_node(3) = _mesh->node_ptr(0);
106  }
107 
108  // libMesh will renumber, but we numbered according to its scheme
109  // anyway. We do this because when we call uniformly_refine subsequently,
110  // it's going use skip_renumber=false.
111  _mesh->prepare_for_use(false /*skip_renumber*/);
112 
113  // get a point locator
114  _point_locator = _mesh->sub_point_locator();
115  }
116 
117 public:
118  void setUp()
119  {
120 #if LIBMESH_DIM > 1
121  this->build_mesh();
122 #endif
123  }
124 
125  void tearDown()
126  {
127 #if LIBMESH_DIM > 1
128  delete _mesh;
129 #endif
130  }
131 
132  // test that point locator works correctly
134  {
135  // this point is in bottom element only
136  Point interior(0.5, -0.5, 0.0);
137 
138  // this point is on the face between bottom and top
139  Point face(0.5, 0.0, 0.0);
140 
141  // test interior point
142  std::set<const Elem *> int_cand;
143  (*_point_locator)(interior, int_cand, nullptr);
144  CPPUNIT_ASSERT (int_cand.size() == 1);
145  for (std::set<const Elem *>::iterator it = int_cand.begin(); it != int_cand.end(); ++it)
146  CPPUNIT_ASSERT ((*it)->id() == 1);
147 
148  // test interior point
149  std::set<const Elem *> face_cand;
150  (*_point_locator)(face, face_cand, nullptr);
151  CPPUNIT_ASSERT (face_cand.size() == 2);
152  int array[2] = {0, 0};
153  for (std::set<const Elem *>::iterator it = face_cand.begin(); it != face_cand.end(); ++it)
154  {
155  // first test that array entry hasn't been set before
156  CPPUNIT_ASSERT (array[(*it)->id()] == 0);
157  array[(*it)->id()] = 1;
158  }
159  CPPUNIT_ASSERT (array[0] == 1);
160  CPPUNIT_ASSERT (array[1] == 1);
161  }
162 
163  // test that mesh function works correctly
165  {
166  // this point is in top element only
167  Point top(0.5, 0.5, 0.0);
168 
169  // this point is in bottom element only
170  Point bottom(0.5, -0.5, 0.0);
171 
172  // this point is on the face between bottom and top
173  Point face(0.5, 0.0, 0.0);
174 
175  // set up some necessary objects
176  EquationSystems es(*_mesh);
177  System & sys = es.add_system<System> ("SimpleSystem");
178  sys.add_variable("u", CONSTANT, MONOMIAL);
179 
180  es.init();
182 
183  std::vector<unsigned int> variables;
184  sys.get_all_variable_numbers(variables);
185  std::unique_ptr<NumericVector<Number>> mesh_function_vector =
187  mesh_function_vector->init(sys.n_dofs(), false, SERIAL);
188  sys.solution->localize(*mesh_function_vector);
189 
190  MeshFunction mesh_function (es, *mesh_function_vector,
191  sys.get_dof_map(), variables);
192  mesh_function.init();
193 
194  // test mesh function in top
195  std::map<const Elem *, Number> top_val = mesh_function.discontinuous_value(top);
196 
197  // check that there is only one value
198  CPPUNIT_ASSERT (top_val.size() == 1);
199 
200  // check that this one value is the right one
201  for (std::map<const Elem *, Number>::const_iterator it = top_val.begin(); it != top_val.end(); ++it)
202  CPPUNIT_ASSERT (it->first->id() == 0 && std::abs(it->second) < 1.0e-10);
203 
204  // test mesh function in bottom
205  std::map<const Elem *, Number> bottom_val = mesh_function.discontinuous_value(bottom);
206 
207  // check that there is only one value
208  CPPUNIT_ASSERT (bottom_val.size() == 1);
209 
210  // check that this one value is the right one
211  for (std::map<const Elem *, Number>::const_iterator it = bottom_val.begin(); it != bottom_val.end(); ++it)
212  CPPUNIT_ASSERT (it->first->id() == 1 && std::abs(it->second - 1.0) < 1.0e-10);
213 
214  // test mesh function in face
215  std::map<const Elem *, Number> face_val = mesh_function.discontinuous_value(face);
216 
217  // check that there are two values
218  CPPUNIT_ASSERT (face_val.size() == 2);
219 
220  // check that the two values are attached to the right element
221  for (std::map<const Elem *, Number>::const_iterator it = face_val.begin(); it != face_val.end(); ++it)
222  if (it->first->id() == 0)
223  CPPUNIT_ASSERT (std::abs(it->second) < 1.0e-10);
224  else if (it->first->id() == 1)
225  CPPUNIT_ASSERT (std::abs(it->second - 1.0) < 1.0e-10);
226  else
227  CPPUNIT_ASSERT (false);
228 
229  }
230 
231  // test that gradient function works correctly
233  {
234  // this point is in top element only
235  Point top(0.5, 0.5, 0.0);
236 
237  // this point is in bottom element only
238  Point bottom(0.5, -0.5, 0.0);
239 
240  // this point is on the face between bottom and top
241  Point face(0.5, 0.0, 0.0);
242 
243  // set up some necessary objects
244  EquationSystems es(*_mesh);
245  System & sys = es.add_system<System> ("SimpleSystem");
246  sys.add_variable("u", FIRST, LAGRANGE);
247 
248  es.init();
250 
251  std::vector<unsigned int> variables;
252  sys.get_all_variable_numbers(variables);
253  std::unique_ptr<NumericVector<Number>> mesh_function_vector =
255  mesh_function_vector->init(sys.n_dofs(), false, SERIAL);
256  sys.solution->localize(*mesh_function_vector);
257 
258  MeshFunction mesh_function (es, *mesh_function_vector,
259  sys.get_dof_map(), variables);
260  mesh_function.init();
261 
262  // test mesh function in top
263  std::map<const Elem *, Gradient> top_val = mesh_function.discontinuous_gradient(top);
264 
265  // check that there is only one value
266  CPPUNIT_ASSERT (top_val.size() == 1);
267 
268  // check that this one value is the right one
269  for (std::map<const Elem *, Gradient>::const_iterator it = top_val.begin(); it != top_val.end(); ++it)
270  CPPUNIT_ASSERT (it->first->id() == 0 && std::abs(it->second(1) - 2.0) < 1.0e-10);
271 
272  // test mesh function in bottom
273  std::map<const Elem *, Gradient> bottom_val = mesh_function.discontinuous_gradient(bottom);
274 
275  // check that there is only one value
276  CPPUNIT_ASSERT (bottom_val.size() == 1);
277 
278  // check that this one value is the right one
279  for (std::map<const Elem *, Gradient>::const_iterator it = bottom_val.begin(); it != bottom_val.end(); ++it)
280  CPPUNIT_ASSERT (it->first->id() == 1 && std::abs(it->second(1) - 1.0) < 1.0e-10);
281 
282  // test mesh function in face
283  std::map<const Elem *, Gradient> face_val = mesh_function.discontinuous_gradient(face);
284 
285  // check that there are two values
286  CPPUNIT_ASSERT (face_val.size() == 2);
287 
288  // check that the two values are attached to the right element
289  for (std::map<const Elem *, Gradient>::const_iterator it = face_val.begin(); it != face_val.end(); ++it)
290  if (it->first->id() == 0)
291  CPPUNIT_ASSERT (std::abs(it->second(1) - 2.0) < 1.0e-10);
292  else if (it->first->id() == 1)
293  CPPUNIT_ASSERT (std::abs(it->second(1) - 1.0) < 1.0e-10);
294  else
295  CPPUNIT_ASSERT (false);
296  }
297 };
298 
299 
libMesh::System
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition: system.h:100
libMesh::Number
Real Number
Definition: libmesh_common.h:195
libMesh::EquationSystems::add_system
virtual System & add_system(const std::string &system_type, const std::string &name)
Add the system of type system_type named name to the systems array.
Definition: equation_systems.C:345
libMesh::MeshFunction::init
virtual void init() override
Override the FunctionBase::init() member function by calling our own and specifying the Trees::NODES ...
Definition: mesh_function.h:110
libMesh::ReplicatedMesh::node_ptr
virtual const Node * node_ptr(const dof_id_type i) const override
Definition: replicated_mesh.C:182
libMesh::MeshFunction
This class provides function-like objects for data distributed over a mesh.
Definition: mesh_function.h:53
libMesh::SERIAL
Definition: enum_parallel_type.h:35
MeshfunctionDFEM::build_mesh
void build_mesh()
Definition: mesh_function_dfem.C:65
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
MeshfunctionDFEM::test_mesh_function_dfem
void test_mesh_function_dfem()
Definition: mesh_function_dfem.C:164
MeshfunctionDFEM
Definition: mesh_function_dfem.C:42
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::ReplicatedMesh::add_elem
virtual Elem * add_elem(Elem *e) override
Add elem e to the end of the element array.
Definition: replicated_mesh.C:282
position_function
Number position_function(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: mesh_function_dfem.C:20
libMesh::NumericVector::build
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package())
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Definition: numeric_vector.C:49
libMesh::ReplicatedMesh
The ReplicatedMesh class is derived from the MeshBase class, and is used to store identical copies of...
Definition: replicated_mesh.h:47
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
libMesh::System::add_variable
unsigned int add_variable(const std::string &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:1069
TestCommWorld
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:111
libMesh::EquationSystems::init
virtual void init()
Initialize all the systems.
Definition: equation_systems.C:96
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
MeshfunctionDFEM::test_mesh_function_dfem_grad
void test_mesh_function_dfem_grad()
Definition: mesh_function_dfem.C:232
libMesh::CONSTANT
Definition: enum_order.h:41
position_function2
Number position_function2(const Point &p, const Parameters &, const std::string &, const std::string &)
Definition: mesh_function_dfem.C:31
MeshfunctionDFEM::_mesh
ReplicatedMesh * _mesh
Definition: mesh_function_dfem.C:62
libMesh::Quad4
The QUAD4 is an element in 2D composed of 4 nodes.
Definition: face_quad4.h:51
libMesh::MONOMIAL
Definition: enum_fe_family.h:39
libMesh::EquationSystems
This is the EquationSystems class.
Definition: equation_systems.h:74
libMesh::Elem::set_node
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2059
MeshfunctionDFEM::setUp
void setUp()
Definition: mesh_function_dfem.C:118
MeshfunctionDFEM::test_point_locator_dfem
void test_point_locator_dfem()
Definition: mesh_function_dfem.C:133
libMesh::MeshBase::sub_point_locator
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:672
libMesh::System::solution
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1539
libmesh_cppunit.h
MeshfunctionDFEM::tearDown
void tearDown()
Definition: mesh_function_dfem.C:125
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::System::get_dof_map
const DofMap & get_dof_map() const
Definition: system.h:2099
libMesh::System::n_dofs
dof_id_type n_dofs() const
Definition: system.C:150
libMesh::LAGRANGE
Definition: enum_fe_family.h:36
test_comm.h
libMesh::MeshBase::prepare_for_use
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:318
MeshfunctionDFEM::_point_locator
std::unique_ptr< PointLocatorBase > _point_locator
Definition: mesh_function_dfem.C:63
libMesh::System::get_all_variable_numbers
void get_all_variable_numbers(std::vector< unsigned int > &all_variable_numbers) const
Fills all_variable_numbers with all the variable numbers for the variables that have been added to th...
Definition: system.C:1240
libMesh::System::project_solution
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr) const
Projects arbitrary functions onto the current solution.
Definition: system_projection.C:950
libMesh::MeshBase::set_mesh_dimension
void set_mesh_dimension(unsigned char d)
Resets the logical dimension of the mesh.
Definition: mesh_base.h:218
libMesh::FIRST
Definition: enum_order.h:42
libMesh::Parameters
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:59
CPPUNIT_TEST_SUITE_REGISTRATION
CPPUNIT_TEST_SUITE_REGISTRATION(MeshfunctionDFEM)
libMesh::ReplicatedMesh::add_point
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id) override
functions for adding /deleting nodes elements.
Definition: replicated_mesh.C:417
libMesh::EquationSystems::parameters
Parameters parameters
Data structure holding arbitrary parameters.
Definition: equation_systems.h:557