https://mooseframework.inl.gov
WaterTightTest.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "gtest/gtest.h"
11 #include "MooseMesh.h"
12 #include "libmesh/face_tri3.h"
13 #include "libmesh/edge_edge2.h"
14 #include "SBMUtils.h"
15 #include <libmesh/serial_mesh.h>
16 
17 using namespace libMesh;
18 
19 TEST(WaterTightTest, TwoDGeoOpenAndClose)
20 {
21  libMesh::Parallel::Communicator comm(MPI_COMM_SELF);
22  std::vector<Point> points = {
23  Point(0.0, 0.0, 0.0), // p0
24  Point(1.0, 0.0, 0.0), // p1
25  Point(1.0, 1.0, 0.0), // p2
26  Point(0.0, 1.0, 0.0) // p3
27  };
28 
29  // (a) Test open geometry (missing last edge)
30  {
31  auto mesh = std::make_unique<libMesh::SerialMesh>(comm);
32  std::vector<Node *> node_ptrs;
33 
34  for (unsigned int i = 0; i < points.size(); ++i)
35  node_ptrs.push_back(mesh->add_point(points[i], i)); // Mesh owns the node
36 
37  std::vector<std::pair<unsigned int, unsigned int>> open_edges = {{0, 1}, {1, 2}, {2, 3}};
38  for (const auto & [id1, id2] : open_edges)
39  {
40  auto edge = new Edge2();
41  edge->set_node(0) = node_ptrs[id1];
42  edge->set_node(1) = node_ptrs[id2];
43  mesh->add_elem(edge); // Mesh owns the element
44  }
45 
46  mesh->prepare_for_use(false); // Neighbor info setup
47 
48  std::vector<const Elem *> raw_ptrs;
49  for (const auto * el : mesh->active_local_element_ptr_range())
50  raw_ptrs.push_back(el);
51 
52  EXPECT_FALSE(SBMUtils::checkWatertightnessFromRawElems(raw_ptrs));
53  }
54 
55  // (b) Test closed geometry
56  {
57  auto mesh = std::make_unique<libMesh::SerialMesh>(comm);
58  std::vector<Node *> node_ptrs;
59 
60  for (unsigned int i = 0; i < points.size(); ++i)
61  node_ptrs.push_back(mesh->add_point(points[i], i)); // Mesh owns the node
62 
63  std::vector<std::pair<unsigned int, unsigned int>> closed_edges = {
64  {0, 1}, {1, 2}, {2, 3}, {3, 0}};
65  for (const auto & [id1, id2] : closed_edges)
66  {
67  auto edge = new Edge2();
68  edge->set_node(0) = node_ptrs[id1];
69  edge->set_node(1) = node_ptrs[id2];
70  mesh->add_elem(edge); // Mesh owns the element
71  }
72 
73  mesh->prepare_for_use(false); // Neighbor info setup
74 
75  std::vector<const Elem *> raw_ptrs;
76  for (const auto * el : mesh->active_local_element_ptr_range())
77  raw_ptrs.push_back(el);
78 
79  EXPECT_TRUE(SBMUtils::checkWatertightnessFromRawElems(raw_ptrs));
80  }
81 }
82 
83 TEST(WaterTightTest, ThreeDGeoOpenAndClose)
84 {
85  libMesh::Parallel::Communicator comm(MPI_COMM_SELF);
86  std::vector<Point> points = {
87  Point(0.0, 0.0, 0.0), // p0
88  Point(1.0, 0.0, 0.0), // p1
89  Point(1.0, 1.0, 0.0), // p2
90  Point(0.0, 1.0, 0.0) // p3
91  };
92 
93  // (a) Test open geometry (missing last edge)
94  {
95  auto mesh = std::make_unique<libMesh::SerialMesh>(comm);
96  std::vector<Node *> node_ptrs;
97 
98  for (unsigned int i = 0; i < points.size(); ++i)
99  node_ptrs.push_back(mesh->add_point(points[i], i)); // Mesh owns the node
100 
101  std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> open_faces = {
102  {0, 1, 2}, {0, 1, 3}, {1, 2, 3}};
103  for (const auto & [id1, id2, id3] : open_faces)
104  {
105  auto tri = new Tri3();
106  tri->set_node(0) = node_ptrs[id1];
107  tri->set_node(1) = node_ptrs[id2];
108  tri->set_node(2) = node_ptrs[id3];
109  mesh->add_elem(tri); // Mesh owns the element
110  }
111 
112  mesh->prepare_for_use(false); // Neighbor info setup
113 
114  std::vector<const Elem *> raw_ptrs;
115  for (const auto * el : mesh->active_local_element_ptr_range())
116  raw_ptrs.push_back(el);
117 
118  EXPECT_FALSE(SBMUtils::checkWatertightnessFromRawElems(raw_ptrs));
119  }
120 
121  // (b) Test closed geometry
122  {
123  auto mesh = std::make_unique<libMesh::SerialMesh>(comm);
124  std::vector<Node *> node_ptrs;
125 
126  for (unsigned int i = 0; i < points.size(); ++i)
127  node_ptrs.push_back(mesh->add_point(points[i], i)); // Mesh owns the node
128 
129  std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> closed_faces = {
130  {0, 1, 2}, {0, 1, 3}, {1, 2, 3}, {0, 2, 3}};
131  for (const auto & [id1, id2, id3] : closed_faces)
132  {
133  auto tri = new Tri3();
134  tri->set_node(0) = node_ptrs[id1];
135  tri->set_node(1) = node_ptrs[id2];
136  tri->set_node(2) = node_ptrs[id3];
137  mesh->add_elem(tri); // Mesh owns the element
138  }
139 
140  mesh->prepare_for_use(false); // Neighbor info setup
141 
142  std::vector<const Elem *> raw_ptrs;
143  for (const auto * el : mesh->active_local_element_ptr_range())
144  raw_ptrs.push_back(el);
145 
146  EXPECT_TRUE(SBMUtils::checkWatertightnessFromRawElems(raw_ptrs));
147  }
148 }
void prepare_for_use(const bool skip_renumber_nodes_and_elements, const bool skip_find_neighbors)
MeshBase & mesh
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
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)=0
bool checkWatertightnessFromRawElems(const std::vector< const Elem *> &bd_elements)
Definition: SBMUtils.C:22
virtual Elem * add_elem(Elem *e)=0
TEST(WaterTightTest, TwoDGeoOpenAndClose)