libMesh
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
BoundaryRefinedMeshTest Class Reference
Inheritance diagram for BoundaryRefinedMeshTest:
[legend]

Public Member Functions

 CPPUNIT_TEST_SUITE (BoundaryRefinedMeshTest)
 The goal of this test is the same as the previous, but now we do a uniform refinement and make sure the result mesh is consistent. More...
 
 CPPUNIT_TEST (testMesh)
 
 CPPUNIT_TEST_SUITE_END ()
 
void setUp ()
 
void testMesh ()
 
 CPPUNIT_TEST_SUITE (BoundaryMeshTest)
 The goal of this test is to ensure that a 2D mesh generates boundary meshes correctly. More...
 
void sanityCheck ()
 

Protected Member Functions

void build_mesh ()
 

Protected Attributes

UniquePtr< Mesh_mesh
 
UniquePtr< Mesh_all_boundary_mesh
 
UniquePtr< Mesh_left_boundary_mesh
 
UniquePtr< Mesh_internal_boundary_mesh
 

Detailed Description

Definition at line 337 of file boundary_mesh.C.

Member Function Documentation

void BoundaryMeshTest::build_mesh ( )
protectedinherited

Definition at line 46 of file boundary_mesh.C.

References libMesh::BoundaryInfo::add_side(), libMesh::MeshTools::Generation::build_square(), libMesh::Elem::centroid(), libMesh::QUAD9, libMesh::Elem::subdomain_id(), and TestCommWorld.

47  {
48  _mesh.reset(new Mesh(*TestCommWorld));
52 
54  0.2, 0.8, 0.2, 0.7, QUAD9);
55 
56  // We'll need to skip repartitioning with DistributedMesh for now;
57  // otherwise the boundary meshes' interior parents might get
58  // shuffled off to different processors.
59  if (!_mesh->is_serial())
60  {
61  _mesh->skip_partitioning(true);
62  _left_boundary_mesh->skip_partitioning(true);
63  _all_boundary_mesh->skip_partitioning(true);
64  _internal_boundary_mesh->skip_partitioning(true);
65  }
66 
67  // Set subdomain ids for specific elements. This allows us to later
68  // build an internal sideset with respect to a given
69  // subdomain. The element subdomains look like:
70  // ___________________
71  // | 2 | 2 | 2 |
72  // |_____|_____|_____|
73  // | 2 | 2 | 2 |
74  // |_____|_____|_____|
75  // | 2 | 2 | 2 |
76  // |_____|_____|_____|
77  // | 1 | 1 | 2 |
78  // |_____|_____|_____|
79  // | 1 | 1 | 2 |
80  // |_____|_____|_____|
81  //
82  // and we will create an internal sideset along the border between
83  // subdomains 1 and 2.
84 
85  for (MeshBase::element_iterator elem_it =
86  _mesh->active_elements_begin(),
87  elem_end =
88  _mesh->active_elements_end();
89  elem_it != elem_end; ++elem_it)
90  {
91  Elem * elem = *elem_it;
92  if (elem)
93  {
94  const Point c = elem->centroid();
95  if (c(0) < 0.6 &&
96  c(1) < 0.4)
97  elem->subdomain_id() = 1;
98  else
99  elem->subdomain_id() = 2;
100  }
101  }
102 
103  // Get the border of the square
104  _mesh->get_boundary_info().sync(*_all_boundary_mesh);
105 
106  std::set<boundary_id_type> left_id, right_id;
107  left_id.insert(3);
108  right_id.insert(1);
109 
110  // Add the right side of the square to the square; this should
111  // make it a mixed dimension mesh
112  _mesh->get_boundary_info().add_elements(right_id, *_mesh);
113  _mesh->prepare_for_use();
114 
115  // Add the left side of the square to its own boundary mesh.
116  _mesh->get_boundary_info().sync(left_id, *_left_boundary_mesh);
117 
118  // We create an internal sideset ID that does not conflict with
119  // sidesets 0-3 that get created by build_square().
120  boundary_id_type bid = 5;
121 
122  // To test the "relative to" feature, we add the same sides to the
123  // same sideset twice, from elements in subdomain 2 the second
124  // time. These should not show up in the BoundaryMesh, i.e. there
125  // should not be overlapped elems in the BoundaryMesh.
126  BoundaryInfo & bi = _mesh->get_boundary_info();
127 
128  for (MeshBase::element_iterator elem_it =
129  _mesh->active_elements_begin(),
130  elem_end =
131  _mesh->active_elements_end();
132  elem_it != elem_end; ++elem_it)
133  {
134  Elem * elem = *elem_it;
135  if (elem)
136  {
137  const Point c = elem->centroid();
138  if (c(0) < 0.6 &&
139  c(1) < 0.4)
140  {
141  if (c(0) > 0.4)
142  bi.add_side(elem, 1, bid);
143  if (c(1) > 0.3)
144  bi.add_side(elem, 2, bid);
145  }
146  else
147  {
148  if (c(0) < 0.75 &&
149  c(1) < 0.4)
150  bi.add_side(elem, 3, bid);
151  if (c(0) < 0.6 &&
152  c(1) < 0.5)
153  bi.add_side(elem, 0, bid);
154  }
155  }
156  }
157 
158 
159  // Create a BoundaryMesh from the internal sideset relative to subdomain 1.
160  {
161  std::set<boundary_id_type> requested_boundary_ids;
162  requested_boundary_ids.insert(bid);
163  std::set<subdomain_id_type> subdomains_relative_to;
164  subdomains_relative_to.insert(1);
165  _mesh->get_boundary_info().sync(requested_boundary_ids,
167  subdomains_relative_to);
168  }
169  }
The definition of the element_iterator struct.
Definition: mesh_base.h:1476
UniquePtr< Mesh > _left_boundary_mesh
Definition: boundary_mesh.C:43
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:28
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
void build_square(UnstructuredMesh &mesh, const unsigned int nx, const unsigned int ny, const Real xmin=0., const Real xmax=1., const Real ymin=0., const Real ymax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 2D meshes.
int8_t boundary_id_type
Definition: id_types.h:51
UniquePtr< Mesh > _mesh
Definition: boundary_mesh.C:41
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:56
subdomain_id_type subdomain_id() const
Definition: elem.h:1951
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure...
virtual Point centroid() const
Definition: elem.C:446
UniquePtr< Mesh > _internal_boundary_mesh
Definition: boundary_mesh.C:44
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
Definition: mesh.h:50
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
UniquePtr< Mesh > _all_boundary_mesh
Definition: boundary_mesh.C:42
BoundaryRefinedMeshTest::CPPUNIT_TEST ( testMesh  )
BoundaryMeshTest::CPPUNIT_TEST_SUITE ( BoundaryMeshTest  )
inherited

The goal of this test is to ensure that a 2D mesh generates boundary meshes correctly.

BoundaryRefinedMeshTest::CPPUNIT_TEST_SUITE ( BoundaryRefinedMeshTest  )

The goal of this test is the same as the previous, but now we do a uniform refinement and make sure the result mesh is consistent.

i.e. the new node shared between the 1D elements is the same as the node shared on the underlying quads, and so on.

BoundaryRefinedMeshTest::CPPUNIT_TEST_SUITE_END ( )
void BoundaryMeshTest::sanityCheck ( )
inherited

Definition at line 215 of file boundary_mesh.C.

References libMesh::Elem::centroid(), CPPUNIT_TEST_SUITE_REGISTRATION(), libMesh::EDGE3, libMesh::Elem::interior_parent(), libMesh::Elem::level(), libMesh::DofObject::processor_id(), libMesh::QUAD9, libMesh::Parallel::Communicator::rank(), libMesh::remote_elem, libMesh::Elem::subdomain_id(), TestCommWorld, libMesh::TOLERANCE, and libMesh::Elem::type().

216  {
217  // Sanity check all the elements
219  _mesh->active_elements_begin();
220  const MeshBase::const_element_iterator elem_end =
221  _mesh->active_elements_end();
222  for (; elem_it != elem_end; ++elem_it)
223  {
224  const Elem * elem = *elem_it;
225 
226  const Elem * pip = elem->interior_parent();
227 
228  // On a DistributedMesh we might not be able to see the
229  // interior_parent of a non-local element
230  if (pip == remote_elem)
231  {
232  CPPUNIT_ASSERT(elem->processor_id() != TestCommWorld->rank());
233  continue;
234  }
235 
236  // All the edges should have interior parents; none of the
237  // quads should.
238  if (pip)
239  {
240  CPPUNIT_ASSERT_EQUAL(elem->type(), EDGE3);
241  CPPUNIT_ASSERT_EQUAL(pip->type(), QUAD9);
242  CPPUNIT_ASSERT_EQUAL(pip->level(), elem->level());
243 
244  // We only added right edges
245  CPPUNIT_ASSERT_DOUBLES_EQUAL(elem->centroid()(0), 0.8,
247  }
248  else
249  {
250  CPPUNIT_ASSERT_EQUAL(elem->type(), QUAD9);
251  }
252  }
253 
254  MeshBase::const_element_iterator left_bdy_elem_it =
255  _left_boundary_mesh->active_elements_begin();
256  const MeshBase::const_element_iterator left_bdy_elem_end =
257  _left_boundary_mesh->active_elements_end();
258  for (; left_bdy_elem_it != left_bdy_elem_end; ++left_bdy_elem_it)
259  {
260  const Elem * elem = *left_bdy_elem_it;
261 
262  CPPUNIT_ASSERT_EQUAL(elem->type(), EDGE3);
263 
264  const Elem * pip = elem->interior_parent();
265 
266  // On a DistributedMesh we might not be able to see the
267  // interior_parent of a non-local element
268  if (pip == remote_elem)
269  {
270  CPPUNIT_ASSERT(elem->processor_id() != TestCommWorld->rank());
271  continue;
272  }
273 
274  // All the edges should have interior parents
275  CPPUNIT_ASSERT(pip);
276  CPPUNIT_ASSERT_EQUAL(pip->type(), QUAD9);
277  CPPUNIT_ASSERT_EQUAL(pip->level(), elem->level());
278 
279  // We only added left edges
280  CPPUNIT_ASSERT_DOUBLES_EQUAL(elem->centroid()(0), 0.2,
282  }
283 
284 
285  MeshBase::const_element_iterator all_bdy_elem_it =
286  _left_boundary_mesh->active_elements_begin();
287  const MeshBase::const_element_iterator all_bdy_elem_end =
288  _left_boundary_mesh->active_elements_end();
289  for (; all_bdy_elem_it != all_bdy_elem_end; ++all_bdy_elem_it)
290  {
291  const Elem * elem = *all_bdy_elem_it;
292 
293  CPPUNIT_ASSERT_EQUAL(elem->type(), EDGE3);
294 
295  const Elem * pip = elem->interior_parent();
296 
297  // On a DistributedMesh we might not be able to see the
298  // interior_parent of a non-local element
299  if (pip == remote_elem)
300  {
301  CPPUNIT_ASSERT(elem->processor_id() != TestCommWorld->rank());
302  continue;
303  }
304 
305  // All the edges should have interior parents
306  CPPUNIT_ASSERT(pip);
307  CPPUNIT_ASSERT_EQUAL(pip->type(), QUAD9);
308  CPPUNIT_ASSERT_EQUAL(pip->level(), elem->level());
309  }
310 
311 
312  // Sanity check for the internal sideset mesh.
314  internal_elem_it = _internal_boundary_mesh->active_elements_begin(),
315  internal_elem_end = _internal_boundary_mesh->active_elements_end();
316 
317  for (; internal_elem_it != internal_elem_end; ++internal_elem_it)
318  {
319  const Elem * elem = *internal_elem_it;
320 
321  CPPUNIT_ASSERT_EQUAL(elem->type(), EDGE3);
322 
323  // All of the elements in the internal sideset mesh should
324  // have the same subdomain id as the parent Elems (i.e. 1)
325  // they came from.
326  CPPUNIT_ASSERT_EQUAL(static_cast<subdomain_id_type>(1),
327  elem->subdomain_id());
328  }
329  }
UniquePtr< Mesh > _left_boundary_mesh
Definition: boundary_mesh.C:43
virtual ElemType type() const =0
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:28
The definition of the const_element_iterator struct.
Definition: mesh_base.h:1494
const Elem * interior_parent() const
Definition: elem.C:951
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
static const Real TOLERANCE
UniquePtr< Mesh > _mesh
Definition: boundary_mesh.C:41
subdomain_id_type subdomain_id() const
Definition: elem.h:1951
unsigned int level() const
Definition: elem.h:2388
virtual Point centroid() const
Definition: elem.C:446
unsigned int rank() const
Definition: parallel.h:724
UniquePtr< Mesh > _internal_boundary_mesh
Definition: boundary_mesh.C:44
processor_id_type processor_id() const
Definition: dof_object.h:694
const RemoteElem * remote_elem
Definition: remote_elem.C:57
void BoundaryRefinedMeshTest::setUp ( )

Definition at line 354 of file boundary_mesh.C.

References libMesh::MeshRefinement::uniformly_refine().

355  {
356  this->build_mesh();
357 
358  // Need to refine interior mesh before separate boundary meshes,
359  // if we want to get interior_parent links right.
360  MeshRefinement(*_mesh).uniformly_refine(1);
361  MeshRefinement(*_left_boundary_mesh).uniformly_refine(1);
362  MeshRefinement(*_all_boundary_mesh).uniformly_refine(1);
363  }
This is the MeshRefinement class.
void uniformly_refine(unsigned int n=1)
Uniformly refines the mesh n times.
void BoundaryRefinedMeshTest::testMesh ( )

Definition at line 365 of file boundary_mesh.C.

References CPPUNIT_TEST_SUITE_REGISTRATION().

366  {
367  // There'd better be 3*5*4 + 5*2 active elements in the interior
368  // plus right boundary
369  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(70),
370  _mesh->n_active_elem());
371 
372  // Plus the original 20 now-inactive elements
373  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(90),
374  _mesh->n_elem());
375 
376  // There'd better be only 13*21 nodes in the interior
377  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(273),
378  _mesh->n_nodes());
379 
380  // There'd better be only 2*2*(3+5) active elements on the full boundary
381  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(32),
382  _all_boundary_mesh->n_active_elem());
383 
384  // Plus the original 16 now-inactive elements
385  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(48),
386  _all_boundary_mesh->n_elem());
387 
388  // There'd better be only 2*2*2*(3+5) nodes on the full boundary
389  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(64),
390  _all_boundary_mesh->n_nodes());
391 
392  // There'd better be only 2*5 active elements on the left boundary
393  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(10),
394  _left_boundary_mesh->n_active_elem());
395 
396  // Plus the original 5 now-inactive elements
397  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(15),
398  _left_boundary_mesh->n_elem());
399 
400  // There'd better be only 2*2*5+1 nodes on the left boundary
401  CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(21),
402  _left_boundary_mesh->n_nodes());
403 
404  this->sanityCheck();
405  }
UniquePtr< Mesh > _left_boundary_mesh
Definition: boundary_mesh.C:43
UniquePtr< Mesh > _mesh
Definition: boundary_mesh.C:41
UniquePtr< Mesh > _all_boundary_mesh
Definition: boundary_mesh.C:42

Member Data Documentation

UniquePtr<Mesh> BoundaryMeshTest::_all_boundary_mesh
protectedinherited

Definition at line 42 of file boundary_mesh.C.

UniquePtr<Mesh> BoundaryMeshTest::_internal_boundary_mesh
protectedinherited

Definition at line 44 of file boundary_mesh.C.

UniquePtr<Mesh> BoundaryMeshTest::_left_boundary_mesh
protectedinherited

Definition at line 43 of file boundary_mesh.C.

UniquePtr<Mesh> BoundaryMeshTest::_mesh
protectedinherited

Definition at line 41 of file boundary_mesh.C.


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