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,
false,
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,
false,
false,
false);
184 mesh2.stitch_meshes(mesh3, 2, 4,
TOLERANCE,
true,
false,
false,
false);
185 mesh0.stitch_meshes(mesh2, 1, 3,
TOLERANCE,
true,
false,
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
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
The UnstructuredMesh class is derived from the MeshBase class.
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
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