https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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 "libmesh/int_range.h"
15#include "SBMUtils.h"
16#include <libmesh/serial_mesh.h>
17
18#include <array>
19#include <utility>
20
21namespace
22{
23// Add the points to the mesh (node id == index) and return the created nodes.
24std::vector<Node *>
25addNodes(MeshBase & mesh, const std::vector<Point> & points)
26{
27 std::vector<Node *> node_ptrs;
28 for (const auto i : index_range(points))
29 node_ptrs.push_back(mesh.add_point(points[i], i)); // Mesh owns the node
30 return node_ptrs;
31}
32
33// Finalize the mesh (with neighbor info) and return SBMUtils' watertightness verdict.
34bool
35isWatertight(MeshBase & mesh)
36{
37 mesh.prepare_for_use(false);
38
39 std::vector<const Elem *> raw_ptrs;
40 for (const auto * el : mesh.active_local_element_ptr_range())
41 raw_ptrs.push_back(el);
43}
44
45// Build an first-order line loop from the given points and 2-node connectivity, then test
46// watertightness.
47bool
48edgeLoopIsWatertight(const Parallel::Communicator & comm,
49 const std::vector<Point> & points,
50 const std::vector<std::pair<unsigned int, unsigned int>> & edges)
51{
53 const auto nodes = addNodes(mesh, points);
54 for (const auto & [id0, id1] : edges)
55 {
56 auto edge = new Edge2();
57 edge->set_node(0, nodes[id0]);
58 edge->set_node(1, nodes[id1]);
59 mesh.add_elem(edge); // Mesh owns the element
60 }
61 return isWatertight(mesh);
62}
63
64// Build a TRI3 surface from the given points and 3-node connectivity, then test watertightness.
65bool
66triSurfaceIsWatertight(const Parallel::Communicator & comm,
67 const std::vector<Point> & points,
68 const std::vector<std::array<unsigned int, 3>> & faces)
69{
71 const auto nodes = addNodes(mesh, points);
72 for (const auto & f : faces)
73 {
74 auto tri = new Tri3();
75 tri->set_node(0, nodes[f[0]]);
76 tri->set_node(1, nodes[f[1]]);
77 tri->set_node(2, nodes[f[2]]);
78 mesh.add_elem(tri); // Mesh owns the element
79 }
80 return isWatertight(mesh);
81}
82}
83
84// Unit square boundary: an open loop (missing the closing edge) is not watertight; the closed loop
85// is.
86TEST(WaterTightTest, TwoDGeoOpenAndClose)
87{
88 libMesh::Parallel::Communicator comm(MPI_COMM_SELF);
89 const std::vector<Point> points = {
90 Point(0.0, 0.0, 0.0), Point(1.0, 0.0, 0.0), Point(1.0, 1.0, 0.0), Point(0.0, 1.0, 0.0)};
91
92 EXPECT_FALSE(edgeLoopIsWatertight(comm, points, {{0, 1}, {1, 2}, {2, 3}}));
93 EXPECT_TRUE(edgeLoopIsWatertight(comm, points, {{0, 1}, {1, 2}, {2, 3}, {3, 0}}));
94}
95
96// Tetrahedron surface: three of the four triangular faces leave an opening (not watertight); all
97// four close it.
98TEST(WaterTightTest, ThreeDGeoOpenAndClose)
99{
100 libMesh::Parallel::Communicator comm(MPI_COMM_SELF);
101 const std::vector<Point> points = {
102 Point(0.0, 0.0, 0.0), Point(1.0, 0.0, 0.0), Point(1.0, 1.0, 0.0), Point(0.0, 1.0, 0.0)};
103
104 EXPECT_FALSE(triSurfaceIsWatertight(comm, points, {{{0, 1, 2}}, {{0, 1, 3}}, {{1, 2, 3}}}));
105 EXPECT_TRUE(
106 triSurfaceIsWatertight(comm, points, {{{0, 1, 2}}, {{0, 1, 3}}, {{1, 2, 3}}, {{0, 2, 3}}}));
107}
Real f(Real x)
Test function for Brents method.
TEST(WaterTightTest, TwoDGeoOpenAndClose)
MeshBase & mesh
bool checkWatertightnessFromRawElems(const std::vector< const Elem * > &bd_elements)
Definition SBMUtils.C:84
auto index_range(const T &sizable)