2 #include <libmesh/boundary_info.h> 3 #include <libmesh/distributed_mesh.h> 4 #include <libmesh/elem.h> 5 #include <libmesh/mesh.h> 6 #include <libmesh/mesh_generation.h> 7 #include <libmesh/mesh_modification.h> 8 #include <libmesh/parallel_implementation.h> 9 #include <libmesh/node.h> 10 #include <libmesh/replicated_mesh.h> 11 #include <libmesh/utility.h> 28 CPPUNIT_TEST( testReplicatedMeshStitch );
29 CPPUNIT_TEST( testDistributedMeshStitch );
30 CPPUNIT_TEST( testReplicatedBoundaryInfo );
31 CPPUNIT_TEST( testDistributedBoundaryInfo );
32 CPPUNIT_TEST( testReplicatedMeshStitchElemsets );
33 CPPUNIT_TEST( testRemappingStitch );
34 CPPUNIT_TEST( testAmbiguousRemappingStitch );
35 #endif // LIBMESH_DIM > 2 37 CPPUNIT_TEST_SUITE_END();
50 const std::string & boundary_name_prefix)
54 for (
auto rit = mesh_boundary_ids.rbegin(); rit != mesh_boundary_ids.rend(); ++rit)
56 const auto old_sideset_name = boundary_info.
sideset_name(*rit);
57 const auto old_nodeset_name = boundary_info.
nodeset_name(*rit);
62 boundary_name_prefix + old_sideset_name;
64 boundary_name_prefix + old_nodeset_name;
69 template <
typename MeshType>
77 MeshTools::Generation::build_cube(mesh0, ps, ps, ps, -1, 0, 0, 1, 0, 1,
HEX8);
78 MeshTools::Generation::build_cube(mesh1, ps, ps, ps, 0, 1, 0, 1, 0, 1,
HEX8);
81 renameAndShift(mesh0, 0,
"zero_");
82 renameAndShift(mesh1, 6,
"one_");
84 mesh0.stitch_meshes(mesh1, 2, 10,
TOLERANCE,
true,
true,
false,
false);
86 CPPUNIT_ASSERT_EQUAL(mesh0.n_elem(),
static_cast<dof_id_type>(16));
87 CPPUNIT_ASSERT_EQUAL(mesh0.n_nodes(),
static_cast<dof_id_type>(45));
93 typename std::decay<decltype(sbi.size())>::type expected_size = 10;
94 CPPUNIT_ASSERT_EQUAL(expected_size, sbi.size());
98 CPPUNIT_ASSERT_EQUAL(expected_size, nbi.size());
102 std::set<std::string> expected_names = {{
"zero_left",
112 std::set<std::string> ss_names;
114 ss_names.insert(pr.second);
115 CPPUNIT_ASSERT(ss_names == expected_names);
117 std::set<std::string> ns_names;
119 ns_names.insert(pr.second);
120 CPPUNIT_ASSERT(ns_names == expected_names);
126 testBoundaryInfo<ReplicatedMesh>();
132 testBoundaryInfo<DistributedMesh>();
136 template <
typename MeshType>
152 std::vector<std::string> names2 {
"bar",
"baz"};
153 mesh2.add_elem_integers(names2);
155 std::vector<std::string> names3 {
"bar",
"foo"};
156 mesh3.add_elem_integers(names3);
159 MeshTools::Generation::build_cube (mesh0, ps, ps, ps, -1, 0, 0, 1, 0, 1,
HEX27);
160 MeshTools::Generation::build_cube (mesh1, ps, ps, ps, 0, 1, 0, 1, 0, 1,
HEX27);
161 MeshTools::Generation::build_cube (mesh2, ps, ps, ps, -1, 0, -1, 0, 0, 1,
HEX27);
162 MeshTools::Generation::build_cube (mesh3, ps, ps, ps, 0, 1, -1, 0, 0, 1,
HEX27);
164 struct trivially_copyable_pair
169 mesh0.add_node_integer(
"baz");
170 unsigned int foo1e_idx = mesh1.add_elem_integer(
"foo");
171 mesh2.template add_elem_datum<trivially_copyable_pair>(
"qux");
172 unsigned int qux2n_idx = mesh2.template add_node_datum<trivially_copyable_pair>(
"qux");
173 mesh3.add_node_integers(names3);
175 for (
const auto & elem : mesh1.element_ptr_range())
176 elem->set_extra_integer(foo1e_idx, 2);
178 for (
const auto & node : mesh2.node_ptr_range())
179 node->template set_extra_datum<trivially_copyable_pair>
183 mesh0.stitch_meshes(mesh1, 2, 4,
TOLERANCE,
true,
true,
false,
false);
184 mesh2.stitch_meshes(mesh3, 2, 4,
TOLERANCE,
true,
true,
false,
false);
185 mesh0.stitch_meshes(mesh2, 1, 3,
TOLERANCE,
true,
true,
false,
false);
187 CPPUNIT_ASSERT_EQUAL(mesh0.n_elem(),
static_cast<dof_id_type>(32));
188 CPPUNIT_ASSERT_EQUAL(mesh0.n_nodes(),
static_cast<dof_id_type>(405));
189 CPPUNIT_ASSERT_EQUAL(mesh0.n_elem_integers(), 5u);
190 CPPUNIT_ASSERT_EQUAL(mesh0.n_node_integers(), 5u);
191 std::vector<std::string> all_names {
"foo",
"bar",
"baz",
"qux"};
192 std::vector<unsigned int> node_name_indices {4, 3, 0, 1};
193 for (
unsigned int i=0; i != 4; ++i)
195 CPPUNIT_ASSERT(mesh0.has_elem_integer(all_names[i]));
196 CPPUNIT_ASSERT_EQUAL(mesh0.get_elem_integer_index(all_names[i]), i);
197 CPPUNIT_ASSERT(mesh0.has_node_integer(all_names[i]));
198 CPPUNIT_ASSERT_EQUAL(mesh0.get_node_integer_index(all_names[i]), node_name_indices[i]);
201 unsigned int foo0e_idx = mesh0.get_elem_integer_index(
"foo");
202 for (
const auto & elem : mesh0.element_ptr_range())
204 CPPUNIT_ASSERT_EQUAL(elem->n_extra_integers(), 5u);
205 const Point c = elem->vertex_average();
206 if (c(0) > 0 && c(1) > 0)
207 CPPUNIT_ASSERT_EQUAL(elem->get_extra_integer(foo0e_idx),
static_cast<dof_id_type>(2));
212 unsigned int qux0n_idx = mesh0.get_node_integer_index(
"qux");
213 for (
const auto & node : mesh0.node_ptr_range())
215 CPPUNIT_ASSERT_EQUAL(node->n_extra_integers(), 5u);
216 trivially_copyable_pair datum =
217 node->template get_extra_datum<trivially_copyable_pair>(qux0n_idx);
218 if ((*node)(0) <= 0 && (*node)(1) < 0)
220 CPPUNIT_ASSERT_EQUAL(datum.first, static_cast<dof_id_type>(3));
221 CPPUNIT_ASSERT_EQUAL(datum.second, static_cast<dof_id_type>(4));
233 testMeshStitch<ReplicatedMesh>();
238 testMeshStitch<DistributedMesh>();
241 template <
typename MeshType>
248 auto mesh0 = std::make_unique<MeshType>(*TestCommWorld);
262 auto mesh1 = mesh0->clone();
273 unsigned int elemset_index =
279 for (
const auto & elem :
mesh.element_ptr_range())
282 elem->set_extra_integer(elemset_index, 1);
284 elem->set_extra_integer(elemset_index, 2);
293 mesh1->change_elemset_code(1, 3);
294 mesh1->change_elemset_code(2, 4);
298 mesh1->change_elemset_id(1, 100);
299 mesh1->change_elemset_id(2, 200);
302 mesh0->stitch_meshes(dynamic_cast<UnstructuredMesh &>(*mesh1),
312 dof_id_type n_elem_prestitch = Utility::pow<3>(ps);
315 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(2 * n_elem_prestitch), mesh0->n_elem());
319 unsigned int elemset_index = mesh0->get_elem_integer_index(
"elemset_code");
320 CPPUNIT_ASSERT_EQUAL(0u, elemset_index);
325 for (
dof_id_type elemset_code=1; elemset_code<5; ++elemset_code)
327 mesh0->get_elemsets(elemset_code, id_set_to_fill);
330 CPPUNIT_ASSERT_EQUAL(static_cast<std::size_t>(1), id_set_to_fill.size());
331 CPPUNIT_ASSERT(id_set_to_fill.count(code_to_type[elemset_code]));
334 bool ps_odd = ps % 2;
336 for (
const auto & elem : mesh0->element_ptr_range())
338 dof_id_type elemset_code = elem->get_extra_integer(elemset_index);
339 bool elem_id_odd = elem->id() % 2;
345 if (elem->id() < n_elem_prestitch)
348 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(1), elemset_code);
350 CPPUNIT_ASSERT_EQUAL(static_cast<dof_id_type>(2), elemset_code);
360 CPPUNIT_ASSERT_EQUAL(ps_odd ? static_cast<dof_id_type>(4) : static_cast<dof_id_type>(3), elemset_code);
362 CPPUNIT_ASSERT_EQUAL(ps_odd ? static_cast<dof_id_type>(3) : static_cast<dof_id_type>(4), elemset_code);
369 testMeshStitchElemsets<ReplicatedMesh>(2);
370 testMeshStitchElemsets<ReplicatedMesh>(3);
381 MeshTools::Generation::build_cube(mesh0, ps, ps, ps, -1, 0, 0, 1, 0, 1,
HEX8);
382 MeshTools::Generation::build_cube(mesh1, ps, ps, ps, 0, 1, 0, 1, 0, 1,
HEX8);
385 renameAndShift(mesh0, 0,
"zero_");
386 renameAndShift(mesh1, 6,
"one_");
389 for (
const auto & elem : mesh0.element_ptr_range())
390 elem->subdomain_id() = 123;
392 for (
const auto & elem : mesh1.element_ptr_range())
393 elem->subdomain_id() = 456;
396 mesh0.subdomain_name(123) =
"OneTwoThree";
399 mesh0.stitch_meshes(mesh1, 2, 10,
TOLERANCE,
true,
false,
false,
402 CPPUNIT_ASSERT_EQUAL(mesh0.n_elem(),
static_cast<dof_id_type>(16));
403 CPPUNIT_ASSERT_EQUAL(mesh0.n_nodes(),
static_cast<dof_id_type>(45));
406 for (
const auto & elem : mesh0.element_ptr_range())
418 MeshTools::Generation::build_cube(mesh0, ps, ps, ps, -1, 0, 0, 1, 0, 1,
HEX8);
419 MeshTools::Generation::build_cube(mesh1, ps, ps, ps, 0, 1, 0, 1, 0, 1,
HEX8);
422 renameAndShift(mesh0, 0,
"zero_");
423 renameAndShift(mesh1, 6,
"one_");
426 for (
const auto & elem : mesh0.element_ptr_range())
427 elem->subdomain_id() = 123;
429 for (
const auto & elem : mesh1.element_ptr_range())
430 elem->subdomain_id() = 123;
435 #ifdef LIBMESH_ENABLE_EXCEPTIONS 436 bool threw_error =
false;
439 mesh0.stitch_meshes(mesh1, 2, 10,
TOLERANCE,
true,
false,
false,
444 std::regex msg_regex(
"safely stitch with a mesh");
445 CPPUNIT_ASSERT(std::regex_search(e.what(), msg_regex));
449 CPPUNIT_ASSERT(threw_error);
450 #endif // LIBMESH_ENABLE_EXCEPTIONS
const std::set< boundary_id_type > & get_side_boundary_ids() const
CPPUNIT_TEST_SUITE_REGISTRATION(MeshStitchTest)
void testAmbiguousRemappingStitch()
std::string & nodeset_name(boundary_id_type id)
libMesh::Parallel::Communicator * TestCommWorld
static constexpr Real TOLERANCE
TestClass subdomain_id_type
Based on the 4-byte comment warning above, this probably doesn't work with exodusII at all...
void testDistributedMeshStitch()
void testMeshStitchElemsets(unsigned int ps)
unsigned int add_elem_integer(std::string name, bool allocate_data=true, dof_id_type default_value=DofObject::invalid_id)
Register an integer datum (of type dof_id_type) to be added to each element in the mesh...
void add_elemset_code(dof_id_type code, MeshBase::elemset_type id_set)
Tabulate a user-defined "code" for elements which belong to the element sets specified in id_set...
const std::map< boundary_id_type, std::string > & get_sideset_name_map() const
The libMesh namespace provides an interface to certain functionality in the library.
void renameAndShift(UnstructuredMesh &mesh, const boundary_id_type boundary_id_offset, const std::string &boundary_name_prefix)
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
This is the MeshBase class.
void testReplicatedMeshStitch()
const std::set< boundary_id_type > & get_node_boundary_ids() const
void testRemappingStitch()
const std::map< boundary_id_type, std::string > & get_nodeset_name_map() const
The UnstructuredMesh class is derived from the MeshBase class.
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
void testReplicatedBoundaryInfo()
std::string & subdomain_name(subdomain_id_type id)
void testDistributedBoundaryInfo()
std::string & sideset_name(boundary_id_type id)
void testReplicatedMeshStitchElemsets()
std::set< elemset_id_type > elemset_type
Typedef for the "set" container used to store elemset ids.
A class to represent the internal "this should never happen" errors, to be thrown by "libmesh_error()...
const std::set< boundary_id_type > & get_global_boundary_ids() const
The Mesh class is a thin wrapper, around the ReplicatedMesh class by default.
A Point defines a location in LIBMESH_DIM dimensional Real space.
void set_union(T &data, const unsigned int root_id) const