Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
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  LIBMESH_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:
62  std::unique_ptr<ReplicatedMesh> _mesh;
63  std::unique_ptr<PointLocatorBase> _point_locator;
64 
65  void build_mesh()
66  {
67  _mesh = std::make_unique<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(Elem::build(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(Elem::build(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  _mesh->allow_renumbering(true);
109  _mesh->prepare_for_use();
110 
111  // get a point locator
112  _point_locator = _mesh->sub_point_locator();
113  }
114 
115 public:
116  void setUp()
117  {
118 #if LIBMESH_DIM > 1
119  this->build_mesh();
120 #endif
121  }
122 
123  void tearDown() {}
124 
125  // test that point locator works correctly
127  {
128  LOG_UNIT_TEST;
129 
130  // this point is in bottom element only
131  Point interior(0.5, -0.5, 0.0);
132 
133  // this point is on the face between bottom and top
134  Point face(0.5, 0.0, 0.0);
135 
136  // test interior point
137  std::set<const Elem *> int_cand;
138  (*_point_locator)(interior, int_cand, nullptr);
139  CPPUNIT_ASSERT (int_cand.size() == 1);
140  for (std::set<const Elem *>::iterator it = int_cand.begin(); it != int_cand.end(); ++it)
141  CPPUNIT_ASSERT ((*it)->id() == 1);
142 
143  // test interior point
144  std::set<const Elem *> face_cand;
145  (*_point_locator)(face, face_cand, nullptr);
146  CPPUNIT_ASSERT (face_cand.size() == 2);
147  int array[2] = {0, 0};
148  for (std::set<const Elem *>::iterator it = face_cand.begin(); it != face_cand.end(); ++it)
149  {
150  // first test that array entry hasn't been set before
151  CPPUNIT_ASSERT (array[(*it)->id()] == 0);
152  array[(*it)->id()] = 1;
153  }
154  CPPUNIT_ASSERT (array[0] == 1);
155  CPPUNIT_ASSERT (array[1] == 1);
156  }
157 
158  // test that mesh function works correctly
160  {
161  LOG_UNIT_TEST;
162 
163  // this point is in top element only
164  Point top(0.5, 0.5, 0.0);
165 
166  // this point is in bottom element only
167  Point bottom(0.5, -0.5, 0.0);
168 
169  // this point is on the face between bottom and top
170  Point face(0.5, 0.0, 0.0);
171 
172  // set up some necessary objects
173  EquationSystems es(*_mesh);
174  System & sys = es.add_system<System> ("SimpleSystem");
175  sys.add_variable("u", CONSTANT, MONOMIAL);
176 
177  es.init();
179 
180  std::vector<unsigned int> variables;
181  sys.get_all_variable_numbers(variables);
182  std::unique_ptr<NumericVector<Number>> mesh_function_vector =
184  mesh_function_vector->init(sys.n_dofs(), false, SERIAL);
185  sys.solution->localize(*mesh_function_vector);
186 
187  MeshFunction mesh_function (es, *mesh_function_vector,
188  sys.get_dof_map(), variables);
189  mesh_function.init();
190 
191  // test mesh function in top
192  std::map<const Elem *, Number> top_val = mesh_function.discontinuous_value(top);
193 
194  // check that there is only one value
195  CPPUNIT_ASSERT (top_val.size() == 1);
196 
197  // check that this one value is the right one
198  for (std::map<const Elem *, Number>::const_iterator it = top_val.begin(); it != top_val.end(); ++it)
199  CPPUNIT_ASSERT (it->first->id() == 0 && std::abs(it->second) < 1.0e-10);
200 
201  // test mesh function in bottom
202  std::map<const Elem *, Number> bottom_val = mesh_function.discontinuous_value(bottom);
203 
204  // check that there is only one value
205  CPPUNIT_ASSERT (bottom_val.size() == 1);
206 
207  // check that this one value is the right one
208  for (std::map<const Elem *, Number>::const_iterator it = bottom_val.begin(); it != bottom_val.end(); ++it)
209  CPPUNIT_ASSERT (it->first->id() == 1 && std::abs(it->second - 1.0) < 1.0e-10);
210 
211  // test mesh function in face
212  std::map<const Elem *, Number> face_val = mesh_function.discontinuous_value(face);
213 
214  // check that there are two values
215  CPPUNIT_ASSERT (face_val.size() == 2);
216 
217  // check that the two values are attached to the right element
218  for (std::map<const Elem *, Number>::const_iterator it = face_val.begin(); it != face_val.end(); ++it)
219  if (it->first->id() == 0)
220  CPPUNIT_ASSERT (std::abs(it->second) < 1.0e-10);
221  else if (it->first->id() == 1)
222  CPPUNIT_ASSERT (std::abs(it->second - 1.0) < 1.0e-10);
223  else
224  CPPUNIT_ASSERT (false);
225 
226  }
227 
228  // test that gradient function works correctly
230  {
231  LOG_UNIT_TEST;
232 
233  // this point is in top element only
234  Point top(0.5, 0.5, 0.0);
235 
236  // this point is in bottom element only
237  Point bottom(0.5, -0.5, 0.0);
238 
239  // this point is on the face between bottom and top
240  Point face(0.5, 0.0, 0.0);
241 
242  // set up some necessary objects
243  EquationSystems es(*_mesh);
244  System & sys = es.add_system<System> ("SimpleSystem");
245  sys.add_variable("u", FIRST, LAGRANGE);
246 
247  es.init();
249 
250  std::vector<unsigned int> variables;
251  sys.get_all_variable_numbers(variables);
252  std::unique_ptr<NumericVector<Number>> mesh_function_vector =
254  mesh_function_vector->init(sys.n_dofs(), false, SERIAL);
255  sys.solution->localize(*mesh_function_vector);
256 
257  MeshFunction mesh_function (es, *mesh_function_vector,
258  sys.get_dof_map(), variables);
259  mesh_function.init();
260 
261  // test mesh function in top
262  std::map<const Elem *, Gradient> top_val = mesh_function.discontinuous_gradient(top);
263 
264  // check that there is only one value
265  CPPUNIT_ASSERT (top_val.size() == 1);
266 
267  // check that this one value is the right one
268  for (std::map<const Elem *, Gradient>::const_iterator it = top_val.begin(); it != top_val.end(); ++it)
269  CPPUNIT_ASSERT (it->first->id() == 0 && std::abs(it->second(1) - 2.0) < 1.0e-10);
270 
271  // test mesh function in bottom
272  std::map<const Elem *, Gradient> bottom_val = mesh_function.discontinuous_gradient(bottom);
273 
274  // check that there is only one value
275  CPPUNIT_ASSERT (bottom_val.size() == 1);
276 
277  // check that this one value is the right one
278  for (std::map<const Elem *, Gradient>::const_iterator it = bottom_val.begin(); it != bottom_val.end(); ++it)
279  CPPUNIT_ASSERT (it->first->id() == 1 && std::abs(it->second(1) - 1.0) < 1.0e-10);
280 
281  // test mesh function in face
282  std::map<const Elem *, Gradient> face_val = mesh_function.discontinuous_gradient(face);
283 
284  // check that there are two values
285  CPPUNIT_ASSERT (face_val.size() == 2);
286 
287  // check that the two values are attached to the right element
288  for (std::map<const Elem *, Gradient>::const_iterator it = face_val.begin(); it != face_val.end(); ++it)
289  if (it->first->id() == 0)
290  CPPUNIT_ASSERT (std::abs(it->second(1) - 2.0) < 1.0e-10);
291  else if (it->first->id() == 1)
292  CPPUNIT_ASSERT (std::abs(it->second(1) - 1.0) < 1.0e-10);
293  else
294  CPPUNIT_ASSERT (false);
295  }
296 };
297 
298 
Number position_function2(const Point &p, const Parameters &, const std::string &, const std::string &)
This is the EquationSystems class.
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2527
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition: parameters.h:67
std::unique_ptr< PointLocatorBase > _point_locator
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
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:1595
The libMesh namespace provides an interface to certain functionality in the library.
dof_id_type n_dofs() const
Definition: system.C:118
void test_mesh_function_dfem_grad()
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr) const
Projects arbitrary functions onto the current solution.
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:447
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1590
virtual void init() override
Override the FunctionBase::init() member function.
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:1335
Number position_function(const Point &p, const Parameters &, const std::string &, const std::string &)
static std::unique_ptr< NumericVector< T > > build(const Parallel::Communicator &comm, SolverPackage solver_package=libMesh::default_solver_package(), ParallelType parallel_type=AUTOMATIC)
Builds a NumericVector on the processors in communicator comm using the linear solver package specifi...
Parameters parameters
Data structure holding arbitrary parameters.
CPPUNIT_TEST_SUITE_REGISTRATION(MeshfunctionDFEM)
virtual void init()
Initialize all the systems.
This class provides function-like objects for data distributed over a mesh.
Definition: mesh_function.h:54
virtual System & add_system(std::string_view system_type, std::string_view name)
Add the system of type system_type named name to the systems array.
const DofMap & get_dof_map() const
Definition: system.h:2361
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
std::unique_ptr< ReplicatedMesh > _mesh