83 std::vector<std::unique_ptr<ReplicatedMesh>> local_meshes;
84 auto & meshes = input_meshes ? *input_meshes : local_meshes;
89 const std::vector<BoundaryName> boundary_names = {getParam<BoundaryName>(
"left_boundary"),
90 getParam<BoundaryName>(
"right_boundary"),
91 getParam<BoundaryName>(
"top_boundary"),
92 getParam<BoundaryName>(
"bottom_boundary")};
93 const std::vector<std::string> boundary_param_names = {
94 "left_boundary",
"right_boundary",
"top_boundary",
"bottom_boundary"};
97 std::vector<std::vector<boundary_id_type>> input_bids(
99 bool have_common_ids =
true;
102 std::vector<std::vector<boundary_id_type>> input_bids_unique(
_input_names.size());
105 size_t set_length = 0;
109 std::map<std::string, size_t> boundary_name_to_index_map;
112 std::set<boundary_id_type> all_boundary_ids;
118 std::unique_ptr<ReplicatedMesh>
mesh = dynamic_pointer_cast<ReplicatedMesh>(*
_mesh_ptrs[i]);
123 "' is not a replicated mesh.\n\n",
125 " only works with inputs that are replicated.\n\n",
126 "Try running without distributed mesh.");
127 meshes[i] = dynamic_pointer_cast<ReplicatedMesh>(
mesh);
131 mooseAssert(ids.size() == boundary_names.size(),
132 "Unexpected number of ids returned for MooseMeshUtils::getBoundaryIDs");
135 std::map<boundary_id_type, size_t> seen_bid_to_index_map;
138 for (
const auto side : make_range(4))
144 boundary_param_names[side],
145 "' parameter with value '",
146 boundary_names[side],
147 "' does not exist in input mesh '",
151 input_bids[i][side] = ids[side];
158 if (std::count(input_bids_unique[i].begin(), input_bids_unique[i].end(), ids[side]) == 0)
160 input_bids_unique[i].push_back(ids[side]);
161 seen_bid_to_index_map[ids[side]] = index;
162 boundary_name_to_index_map[boundary_param_names[side]] = index++;
165 boundary_name_to_index_map[boundary_param_names[side]] = seen_bid_to_index_map[ids[side]];
170 if (ids[side] != input_bids[i - 1][side])
171 have_common_ids =
false;
173 if (std::count(input_bids_unique[i].begin(), input_bids_unique[i].end(), ids[side]) == 0)
174 input_bids_unique[i].push_back(ids[side]);
179 if (i > 0 && set_length != input_bids_unique.size())
181 "Input meshes have incompatible boundary ids. This can occur when input meshes have "
182 "the same boundary id for multiple boundaries, but in a way that is different "
183 "between the meshes. Try assigning each left/right/top/bottom to its own boundary id.");
185 set_length = input_bids_unique.size();
188 const auto all_ids = meshes[i]->get_boundary_info().get_boundary_ids();
191 all_boundary_ids.insert(all_ids.begin(), all_ids.end());
198 _x_width = bbox.max()(0) - bbox.min()(0);
200 _y_width = bbox.max()(1) - bbox.min()(1);
202 _z_width = bbox.max()(2) - bbox.min()(2);
205 std::vector<boundary_id_type> stitch_bids;
208 stitch_bids = input_bids_unique[0];
214 if (!all_boundary_ids.count(
id))
216 stitch_bids.push_back(
id);
219 if (stitch_bids.size() == input_bids_unique[0].size())
224 for (
const auto i : index_range(meshes))
225 for (
const auto side : index_range(stitch_bids))
226 MeshTools::Modification::change_boundary_id(
227 *meshes[i], input_bids_unique[i][side], stitch_bids[side]);
231 std::vector<std::unique_ptr<ReplicatedMesh>> row_meshes(
_pattern.size());
234 const boundary_id_type &left_bid(stitch_bids[boundary_name_to_index_map[
"left_boundary"]]),
235 right_bid(stitch_bids[boundary_name_to_index_map[
"right_boundary"]]),
236 top_bid(stitch_bids[boundary_name_to_index_map[
"top_boundary"]]),
237 bottom_bid(stitch_bids[boundary_name_to_index_map[
"bottom_boundary"]]);
248 auto clone = meshes[
_pattern[i][j]]->clone();
249 row_meshes[i] = dynamic_pointer_cast<ReplicatedMesh>(clone);
251 MeshTools::Modification::translate(*row_meshes[i], deltax, -deltay, 0);
256 ReplicatedMesh & cell_mesh = *meshes[
_pattern[i][j]];
259 MeshTools::Modification::translate(cell_mesh, deltax, -deltay, 0);
262 auto & main_subdomain_map = row_meshes[i]->set_subdomain_name_map();
265 const auto & increment_subdomain_map = cell_mesh.get_subdomain_name_map();
268 row_meshes[i]->stitch_meshes(cell_mesh,
276 MeshTools::Modification::translate(cell_mesh, -deltax, deltay, 0);
285 auto & main_subdomain_map = row_meshes[0]->set_subdomain_name_map();
288 const auto & increment_subdomain_map = row_meshes[i]->get_subdomain_name_map();
291 row_meshes[0]->stitch_meshes(*row_meshes[i],
300 if (!have_common_ids)
301 for (
const auto side : index_range(stitch_bids))
302 MeshTools::Modification::change_boundary_id(
303 *row_meshes[0], stitch_bids[side], input_bids_unique[0][side]);
305 row_meshes[0]->unset_is_prepared();
306 return dynamic_pointer_cast<MeshBase>(row_meshes[0]);