libMesh
connected_components.C
Go to the documentation of this file.
1 #include <libmesh/libmesh.h>
2 #include <libmesh/elem.h>
3 #include <libmesh/mesh_generation.h>
4 #include <libmesh/mesh_tools.h>
5 #include <libmesh/mesh.h>
6 #include <libmesh/node.h>
7 #include <libmesh/sparse_matrix.h>
8 #include <libmesh/system.h>
9 
11 
12 #include "test_comm.h"
13 #include "libmesh_cppunit.h"
14 
15 
16 using namespace libMesh;
17 
18 class ConnectedComponentsTest : public CppUnit::TestCase
19 {
25 public:
26  LIBMESH_CPPUNIT_TEST_SUITE( ConnectedComponentsTest );
27 
33 #ifdef LIBMESH_HAVE_SOLVER
34  CPPUNIT_TEST( testEdge2 );
35  CPPUNIT_TEST( testEdge3 );
36  CPPUNIT_TEST( testEdge4 );
37 #endif
38 
39  CPPUNIT_TEST_SUITE_END();
40 
41 protected:
42 
43  void testEdge(unsigned n_elem,
44  ElemType elem_type)
45  {
47 
48  // We don't yet support n_connected_components() on distributed
49  // meshes
51 
53  n_elem,
54  /*xmin=*/0.,
55  /*xmax=*/1.,
56  elem_type);
57 
58  const dof_id_type n_components_orig =
60 
61  CPPUNIT_ASSERT_EQUAL(n_components_orig, dof_id_type(1));
62 
63  // We can't disconnect a too-small mesh
64  if (n_elem < 3)
65  return;
66 
67  for (const auto & elem : mesh.element_ptr_range())
68  {
69  const Point c = elem->vertex_average();
70 
71  if (std::abs(c(0) - 0.5) < 0.2)
72  mesh.delete_elem(elem);
73  }
74 
76 
77  const dof_id_type n_components_broken =
79 
80  CPPUNIT_ASSERT_EQUAL(n_components_broken, dof_id_type(2));
81 
82  // Add a constraint connecting the original end nodes
83  auto matrix = SparseMatrix<Number>::build (mesh.comm());
84 
85  dof_id_type left_node = 0, right_node = 0;
86  for (const auto & elem : mesh.element_ptr_range())
87  for (const auto & node : elem->node_ref_range())
88  {
89  if (node(0) == Real(0))
90  left_node = node.id();
91  if (node(0) == Real(1))
92  right_node = node.id();
93  }
94 
95  mesh.comm().max(left_node);
96  mesh.comm().max(right_node);
97 
98  const dof_id_type n_nodes = mesh.n_nodes();
99  CPPUNIT_ASSERT_EQUAL(n_nodes, mesh.max_node_id());
100 
101  processor_id_type my_rank = mesh.comm().rank();
102  matrix->init(n_nodes, n_nodes-1,
103  (my_rank ? 0 : n_nodes),
104  (my_rank ? 0 : n_nodes-1),
105  (my_rank ? 0 : n_nodes-1),
106  0);
107 
108  if (!my_rank)
109  {
110  for (auto i : make_range(n_nodes))
111  {
112  if (i < right_node)
113  matrix->set(i,i,1);
114  if (i > right_node)
115  matrix->set(i,i-1,1);
116  }
117  if (left_node > right_node)
118  matrix->set(right_node, left_node-1, 1);
119  else
120  matrix->set(right_node, left_node, 1);
121  }
122 
123  matrix->close();
124 
125  mesh.copy_constraint_rows(*matrix);
126 
127  const dof_id_type n_components_constrained =
129 
130  CPPUNIT_ASSERT_EQUAL(n_components_constrained, dof_id_type(1));
131  }
132 
133 public:
134  void setUp() {}
135 
136  void tearDown() {}
137 
138  void testEdge2()
139  {
140  LOG_UNIT_TEST;
141 
142  testEdge(/*n_elem=*/10, EDGE2);
143  }
144 
145  void testEdge3()
146  {
147  LOG_UNIT_TEST;
148 
149  testEdge(/*n_elem=*/10, EDGE3);
150  }
151 
152  void testEdge4()
153  {
154  LOG_UNIT_TEST;
155 
156  testEdge(/*n_elem=*/10, EDGE4);
157  }
158 };
159 
160 
ElemType
Defines an enum for geometric element types.
dof_id_type n_elem(const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
Count up the number of elements of a specific type (as defined by an iterator range).
Definition: mesh_tools.C:969
libMesh::Parallel::Communicator * TestCommWorld
Definition: driver.C:171
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:759
MeshBase & mesh
processor_id_type rank() const
void copy_constraint_rows(const MeshBase &other_mesh)
Copy the constraints from the other mesh to this mesh.
Definition: mesh_base.C:2063
const Parallel::Communicator & comm() const
The libMesh namespace provides an interface to certain functionality in the library.
static std::unique_ptr< SparseMatrix< T > > build(const Parallel::Communicator &comm, const SolverPackage solver_package=libMesh::default_solver_package(), const MatrixBuildType matrix_build_type=MatrixBuildType::AUTOMATIC)
Builds a SparseMatrix<T> using the linear solver package specified by solver_package.
CPPUNIT_TEST_SUITE_REGISTRATION(ConnectedComponentsTest)
uint8_t processor_id_type
void allow_remote_element_removal(bool allow)
If false is passed in then this mesh will no longer have remote elements deleted when being prepared ...
Definition: mesh_base.h:1212
const dof_id_type n_nodes
Definition: tecplot_io.C:67
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
dof_id_type n_connected_components(const MeshBase &mesh, Real constraint_tol=0)
Definition: mesh_tools.C:840
void testEdge(unsigned n_elem, ElemType elem_type)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void max(const T &r, T &o, Request &req) const
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:140
void build_line(UnstructuredMesh &mesh, const unsigned int nx, const Real xmin=0., const Real xmax=1., const ElemType type=INVALID_ELEM, const bool gauss_lobatto_grid=false)
A specialized build_cube() for 1D meshes.
virtual dof_id_type max_node_id() const =0
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:39
virtual dof_id_type n_nodes() const =0
uint8_t dof_id_type
Definition: id_types.h:67