libMesh
Loading...
Searching...
No Matches
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
18using 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
42class MeshfunctionDFEM : public CppUnit::TestCase
43{
48public:
50
51#if LIBMESH_DIM > 1
53
55
57#endif
58
60
61protected:
62 std::unique_ptr<ReplicatedMesh> _mesh;
63 std::unique_ptr<PointLocatorBase> _point_locator;
64
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
115public:
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
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
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
std::unique_ptr< ReplicatedMesh > _mesh
std::unique_ptr< PointLocatorBase > _point_locator
CPPUNIT_TEST(test_mesh_function_dfem)
CPPUNIT_TEST(test_mesh_function_dfem_grad)
CPPUNIT_TEST(test_point_locator_dfem)
LIBMESH_CPPUNIT_TEST_SUITE(MeshfunctionDFEM)
The goal of this test is to verify proper operation of mesh function for discontinuous shape function...
This is the base class from which all geometric element types are derived.
Definition elem.h:96
virtual Node *& set_node(const unsigned int i)
Definition elem.h:2567
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition elem.C:442
This is the EquationSystems class.
Parameters parameters
Data structure holding arbitrary parameters.
virtual void init()
Initialize all the systems.
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.
This class provides function-like objects for data distributed over a mesh.
std::map< const Elem *, Number > discontinuous_value(const Point &p, const Real time=0.)
virtual void init() override
Override the FunctionBase::init() member function.
std::map< const Elem *, Gradient > discontinuous_gradient(const Point &p, const Real time=0.)
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...
const Parallel::Communicator & comm() const
This class provides the ability to map between arbitrary, user-defined strings and several data types...
Definition parameters.h:75
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
void project_solution(FunctionBase< Number > *f, FunctionBase< Gradient > *g=nullptr, std::optional< ConstElemRange > active_local_range=std::nullopt, std::optional< std::vector< unsigned int > > variable_numbers=std::nullopt) const
Projects arbitrary functions onto the current solution.
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:1403
dof_id_type n_dofs() const
Definition system.C:118
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:1344
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
const DofMap & get_dof_map() const
Definition system.h:2417
Communicator * TestCommWorld
Number position_function2(const Point &p, const Parameters &, const std::string &, const std::string &)
Number position_function(const Point &p, const Parameters &, const std::string &, const std::string &)
CPPUNIT_TEST_SUITE_REGISTRATION(MeshfunctionDFEM)
The libMesh namespace provides an interface to certain functionality in the library.