|
1 | 1 | #include "libmesh_cppunit.h"
|
2 | 2 |
|
| 3 | +#include "test_comm.h" |
| 4 | + |
3 | 5 | #include <libmesh/intersection_tools.h>
|
4 | 6 | #include <libmesh/point.h>
|
5 | 7 | #include <libmesh/int_range.h>
|
| 8 | +#include <libmesh/enum_elem_type.h> |
| 9 | +#include <libmesh/mesh.h> |
| 10 | +#include <libmesh/mesh_generation.h> |
| 11 | +#include <libmesh/elem.h> |
| 12 | +#include <libmesh/elem_extrema.h> |
6 | 13 |
|
7 | 14 | using namespace libMesh;
|
8 | 15 |
|
@@ -80,3 +87,146 @@ public:
|
80 | 87 | };
|
81 | 88 |
|
82 | 89 | CPPUNIT_TEST_SUITE_REGISTRATION( IntersectionToolsTest );
|
| 90 | + |
| 91 | +template <ElemType elem_type> |
| 92 | +class MeshedIntersectionToolsTest : public CppUnit::TestCase { |
| 93 | + |
| 94 | +private: |
| 95 | + std::unique_ptr<Mesh> _mesh; |
| 96 | + |
| 97 | +protected: |
| 98 | + std::string libmesh_suite_name; |
| 99 | + |
| 100 | +public: |
| 101 | + void setUp() |
| 102 | + { |
| 103 | + const Real minpos = 1.5, maxpos = 4.86; |
| 104 | + const unsigned int N = 3; |
| 105 | + |
| 106 | + _mesh = std::make_unique<Mesh>(*TestCommWorld); |
| 107 | + auto test_elem = Elem::build(elem_type); |
| 108 | + |
| 109 | + const unsigned int dim = test_elem->dim(); |
| 110 | + const unsigned int use_y = dim > 1; |
| 111 | + const unsigned int use_z = dim > 2; |
| 112 | + |
| 113 | + MeshTools::Generation::build_cube (*_mesh, |
| 114 | + N, N*use_y, N*use_z, |
| 115 | + minpos, maxpos, |
| 116 | + minpos, use_y*maxpos, |
| 117 | + minpos, use_z*maxpos, |
| 118 | + elem_type); |
| 119 | + } |
| 120 | + |
| 121 | + void test_within_edge_on_side() |
| 122 | + { |
| 123 | + LOG_UNIT_TEST; |
| 124 | + |
| 125 | + if (_mesh->mesh_dimension() != 3) |
| 126 | + return; |
| 127 | + |
| 128 | + // check locations at every node |
| 129 | + for (const auto & elem : _mesh->active_local_element_ptr_range()) |
| 130 | + for (const auto s : elem->side_index_range()) |
| 131 | + for (const auto e : elem->edge_index_range()) |
| 132 | + for (const auto n : elem->nodes_on_edge(e)) |
| 133 | + { |
| 134 | + ElemExtrema extrema; |
| 135 | + const auto within = IntersectionTools::within_edge_on_side(*elem, |
| 136 | + elem->point(n), |
| 137 | + s, |
| 138 | + extrema); |
| 139 | + |
| 140 | + CPPUNIT_ASSERT_EQUAL(within, elem->is_node_on_side(n, s)); |
| 141 | + if (elem->is_node_on_side(n, s)) |
| 142 | + { |
| 143 | + CPPUNIT_ASSERT_EQUAL(elem->is_vertex(n), extrema.at_vertex(n)); |
| 144 | + CPPUNIT_ASSERT_EQUAL(elem->is_vertex(n), !extrema.at_edge(*elem, e)); |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + // cut edges into segments |
| 149 | + for (const auto & elem : _mesh->active_local_element_ptr_range()) |
| 150 | + for (const auto e : elem->edge_index_range()) |
| 151 | + for (const auto s : elem->side_index_range()) |
| 152 | + if (elem->is_edge_on_side(e, s)) |
| 153 | + { |
| 154 | + const auto nodes_on_edge = elem->nodes_on_edge(e); |
| 155 | + const auto & p1 = elem->point(nodes_on_edge[0]); |
| 156 | + const auto & p2 = elem->point(nodes_on_edge[1]); |
| 157 | + const auto length_vec = p2 - p1; |
| 158 | + const auto length = length_vec.norm(); |
| 159 | + const auto p1_to_p2 = length_vec / length; |
| 160 | + |
| 161 | + int segments = 5; |
| 162 | + Real dx = (Real)1 / segments * length; |
| 163 | + for (const auto i : make_range(-1, segments + 1)) |
| 164 | + { |
| 165 | + const auto p = p1 + Real(i) * dx * p1_to_p2; |
| 166 | + ElemExtrema extrema; |
| 167 | + const auto within = IntersectionTools::within_edge_on_side(*elem, |
| 168 | + p, |
| 169 | + s, |
| 170 | + extrema); |
| 171 | + |
| 172 | + CPPUNIT_ASSERT_EQUAL(within, i >= 0 && i <= segments); |
| 173 | + CPPUNIT_ASSERT_EQUAL(extrema.at_vertex(nodes_on_edge[0]), i == 0); |
| 174 | + CPPUNIT_ASSERT_EQUAL(extrema.at_vertex(nodes_on_edge[1]), i == segments); |
| 175 | + CPPUNIT_ASSERT_EQUAL(extrema.at_edge(*elem, e), i > 0 && i < segments); |
| 176 | + } |
| 177 | + } |
| 178 | + |
| 179 | + // check elem centroids |
| 180 | + for (const auto & elem : _mesh->active_local_element_ptr_range()) |
| 181 | + for (const auto s : elem->side_index_range()) |
| 182 | + { |
| 183 | + ElemExtrema extrema; |
| 184 | + CPPUNIT_ASSERT(!IntersectionTools::within_edge_on_side(*elem, |
| 185 | + elem->vertex_average(), |
| 186 | + s, |
| 187 | + extrema)); |
| 188 | + } |
| 189 | + } |
| 190 | + |
| 191 | +}; |
| 192 | + |
| 193 | +#define MESHEDINTERSECTIONTOOLSTEST \ |
| 194 | + CPPUNIT_TEST( test_within_edge_on_side ); |
| 195 | + |
| 196 | +#define INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(elemtype) \ |
| 197 | + class MeshedIntersectionToolsTest_##elemtype : public MeshedIntersectionToolsTest<elemtype> { \ |
| 198 | + public: \ |
| 199 | + MeshedIntersectionToolsTest_##elemtype() : \ |
| 200 | + MeshedIntersectionToolsTest<elemtype>() { \ |
| 201 | + if (unitlog->summarized_logs_enabled()) \ |
| 202 | + this->libmesh_suite_name = "MeshedIntersectionToolsTest"; \ |
| 203 | + else \ |
| 204 | + this->libmesh_suite_name = "MeshedIntersectionToolsTest_" #elemtype; \ |
| 205 | + } \ |
| 206 | + CPPUNIT_TEST_SUITE( MeshedIntersectionToolsTest_##elemtype ); \ |
| 207 | + MESHEDINTERSECTIONTOOLSTEST; \ |
| 208 | + CPPUNIT_TEST_SUITE_END(); \ |
| 209 | + }; \ |
| 210 | + \ |
| 211 | + CPPUNIT_TEST_SUITE_REGISTRATION( MeshedIntersectionToolsTest_##elemtype ) |
| 212 | + |
| 213 | + |
| 214 | +#if LIBMESH_DIM > 2 |
| 215 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(TET4); |
| 216 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(TET10); |
| 217 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(TET14); |
| 218 | + |
| 219 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(HEX8); |
| 220 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(HEX20); |
| 221 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(HEX27); |
| 222 | + |
| 223 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PRISM6); |
| 224 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PRISM15); |
| 225 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PRISM18); |
| 226 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PRISM20); |
| 227 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PRISM21); |
| 228 | + |
| 229 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PYRAMID5); |
| 230 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PYRAMID13); |
| 231 | +INSTANTIATE_MESHEDINTERSECTIONTOOLSTEST(PYRAMID14); |
| 232 | +#endif // LIBMESH_DIM > 2 |
0 commit comments