libMesh
Loading...
Searching...
No Matches
libmesh_netgen.C
Go to the documentation of this file.
1
2#include "libmesh_cppunit.h"
3
4#ifdef LIBMESH_HAVE_NETGEN
5namespace nglib {
6#include "netgen/nglib/nglib.h"
7}
8
9using namespace nglib;
10#endif
11
12#include <numeric>
13
14class LibMeshNetgenTest : public CppUnit::TestCase {
15public:
17
18#ifdef LIBMESH_HAVE_NETGEN
21
22 // Too expensive to do regularly...
23 // CPPUNIT_TEST( testAllPermutations );
24#endif
25
27
28private:
29
30public:
31
32 void setUp()
33 {}
34
35 void tearDown()
36 {}
37
38#ifdef LIBMESH_HAVE_NETGEN
40 {
41 LOG_UNIT_TEST;
42
43 auto ngmesh = Ng_NewMesh();
44 Ng_DeleteMesh(ngmesh);
45 }
46
47 std::size_t testPermutedHole (const std::vector<std::size_t> & permutation)
48 {
49 auto ngmesh = Ng_NewMesh();
50
51 Ng_Meshing_Parameters params;
52 params.elementsperedge = 1;
53 params.elementspercurve = 1;
54
55 std::vector<std::array<double, 3>> point_coords =
56 {{-4, 4, -4},
57 {-4, 4, 4},
58 {4, 4, 4},
59 {4, -4, 4},
60 {4, 4, -4},
61 {4, -4, -4},
62 {-4, -4, 4},
63 {-4, -4, -4},
64
65 {3, -3, -3},
66 {-3, -3, 3},
67 {-3, -3, -3},
68 {-3, 3, -3},
69 {-3, 3, 3},
70 {3, 3, 3},
71 {3, -3, 3},
72 {3, 3, -3}};
73
74 auto n_input_points = point_coords.size();
75
76 CPPUNIT_ASSERT_EQUAL(permutation.size(), n_input_points);
77
78 std::vector<std::size_t> inverse_permutation (n_input_points);
79
80 for (std::size_t i=0; i != n_input_points; ++i)
81 {
82 inverse_permutation[permutation[i]] = i;
83 Ng_AddPoint(ngmesh, point_coords[permutation[i]].data());
84 }
85
86 std::vector<std::array<int, 3>> tri_nodes =
87 {{1, 2, 3},
88 {4, 3, 2},
89 {5, 1, 3},
90 {5, 3, 4},
91 {1, 5, 6},
92 {6, 5, 4},
93 {6, 4, 7},
94 {7, 4, 2},
95 {8, 1, 6},
96 {8, 6, 7},
97 {1, 8, 2},
98 {8, 7, 2},
99
100 {11, 10, 9},
101 {11, 9, 12},
102 {10, 11, 13},
103 {13, 12, 14},
104 {12, 13, 11},
105 {9, 10, 15},
106 {13, 14, 15},
107 {13, 15, 10},
108 {15, 14, 16},
109 {16, 14, 12},
110 {15, 16, 9},
111 {9, 16, 12}};
112
113 for (auto & nodes : tri_nodes)
114 {
115 std::array<int, 3> permuted_nodes = nodes;
116 for (auto & node_i : permuted_nodes)
117 node_i = inverse_permutation[node_i-1]+1;
118 Ng_AddSurfaceElement(ngmesh, NG_TRIG, permuted_nodes.data());
119 }
120
121 Ng_GenerateVolumeMesh(ngmesh, &params);
122 const std::size_t n_elem = Ng_GetNE(ngmesh);
123 const std::size_t n_points = Ng_GetNP(ngmesh);
124 CPPUNIT_ASSERT_GREATEREQUAL(n_input_points, n_points);
125
126 std::set<int> nodes_seen;
127 for (std::size_t i = 0; i != n_elem; ++i)
128 {
129 // Avoid segfault even if ngtype isn't a tet4
130 int ngnodes[11];
131 Ng_Volume_Element_Type ngtype =
132 Ng_GetVolumeElement(ngmesh, i+1, ngnodes);
133 CPPUNIT_ASSERT(ngtype == NG_TET);
134 for (int n = 0; n != 4; ++n)
135 if (ngnodes[n] <= int(n_input_points) && ngnodes[n] > 0)
136 nodes_seen.insert(ngnodes[n]);
137 }
138
139 Ng_DeleteMesh(ngmesh);
140
141 return nodes_seen.size();
142 }
143
145 {
146 LOG_UNIT_TEST;
147
148 std::vector<std::size_t> permutation (16);
149 std::iota(permutation.begin(), permutation.end(), 0);
150
151 int n_original_nodes = testPermutedHole(permutation);
152
153 CPPUNIT_ASSERT_EQUAL(n_original_nodes, 16);
154 }
155
157 {
158 LOG_UNIT_TEST;
159
160 const std::size_t n_input_points = 16;
161
162 std::vector<std::size_t> permutation (n_input_points);
163 std::iota(permutation.begin(), permutation.end(), 0);
164
165 int fails=0, successes = 0;
166
167 auto run_test = [this, &fails, &successes, &permutation]()
168 {
169 int n_original_nodes = testPermutedHole(permutation);
170 fails += (n_original_nodes != n_input_points);
171 successes += (n_original_nodes == n_input_points);
172 std::cout << "Found " << n_original_nodes << "/" << n_input_points << " original nodes\n";
173 std::cout << "Fails = " << fails << ", successes = " << successes << std::endl;
174 };
175
176 // Heap's Algorithm, non-recursive version
177 run_test();
178
179 std::vector<std::size_t> c(permutation.size());
180
181 for (std::size_t i = 1; i != n_input_points ; ++i)
182 {
183 if (c[i] < i)
184 {
185 if (i%2)
186 std::swap(permutation[c[i]], permutation[i]);
187 else
188 std::swap(permutation[0], permutation[i]);
189 run_test();
190
191 ++c[i];
192 i = 0; // Yeah, this runs in factorial time
193 }
194 else
195 c[i] = 0;
196 }
197 }
198#endif
199};
200
CPPUNIT_TEST(testLibMeshNetgen)
LIBMESH_CPPUNIT_TEST_SUITE(LibMeshNetgenTest)
CPPUNIT_TEST(testBadHole)
std::size_t testPermutedHole(const std::vector< std::size_t > &permutation)
CPPUNIT_TEST_SUITE_REGISTRATION(LibMeshNetgenTest)