14 #include "libmesh/replicated_mesh.h" 15 #include "libmesh/distributed_mesh.h" 16 #include "libmesh/boundary_info.h" 17 #include "libmesh/mesh_modification.h" 18 #include "libmesh/mesh_tools.h" 28 params.
addRequiredParam<std::vector<MeshGeneratorName>>(
"inputs",
"The input MeshGenerators.");
30 "x_width", 0,
"x_width>=0",
"The tile width in the x direction");
32 "y_width", 0,
"y_width>=0",
"The tile width in the y direction");
34 "z_width", 0,
"z_width>=0",
"The tile width in the z direction");
39 params.
addParam<BoundaryName>(
"left_boundary",
"left",
"name of the left (x) boundary");
40 params.
addParam<BoundaryName>(
"right_boundary",
"right",
"name of the right (x) boundary");
43 params.
addParam<BoundaryName>(
"top_boundary",
"top",
"name of the top (y) boundary");
44 params.
addParam<BoundaryName>(
"bottom_boundary",
"bottom",
"name of the bottom (y) boundary");
47 "pattern",
"A double-indexed array starting with the upper-left corner");
49 params.
addClassDescription(
"Creates a 2D mesh from a specified set of unique 'tiles' meshes and " 50 "a two-dimensional pattern.");
57 _input_names(getParam<
std::vector<MeshGeneratorName>>(
"inputs")),
58 _mesh_ptrs(getMeshes(
"inputs")),
59 _pattern(getParam<
std::vector<
std::vector<unsigned
int>>>(
"pattern")),
60 _x_width(getParam<
Real>(
"x_width")),
61 _y_width(getParam<
Real>(
"y_width")),
62 _z_width(getParam<
Real>(
"z_width"))
69 " is larger than the the maximum possible index, which is determined by the " 70 "number of MeshGenerators provided in inputs");
73 std::unique_ptr<MeshBase>
80 const std::vector<BoundaryName> boundary_names = {getParam<BoundaryName>(
"left_boundary"),
81 getParam<BoundaryName>(
"right_boundary"),
82 getParam<BoundaryName>(
"top_boundary"),
83 getParam<BoundaryName>(
"bottom_boundary")};
84 const std::vector<std::string> boundary_param_names = {
85 "left_boundary",
"right_boundary",
"top_boundary",
"bottom_boundary"};
88 std::vector<std::vector<boundary_id_type>> input_bids(
90 bool have_common_ids =
true;
93 std::vector<std::vector<boundary_id_type>> input_bids_unique(
_input_names.size());
96 size_t set_length = 0;
100 std::map<std::string, size_t> boundary_name_to_index_map;
103 std::set<boundary_id_type> all_boundary_ids;
114 "' is not a replicated mesh.\n\n",
116 " only works with inputs that are replicated.\n\n",
117 "Try running without distributed mesh.");
122 mooseAssert(ids.size() == boundary_names.size(),
123 "Unexpected number of ids returned for MooseMeshUtils::getBoundaryIDs");
126 std::map<boundary_id_type, size_t> seen_bid_to_index_map;
135 boundary_param_names[side],
136 "' parameter with value '",
137 boundary_names[side],
138 "' does not exist in input mesh '",
142 input_bids[i][side] = ids[side];
149 if (std::count(input_bids_unique[i].begin(), input_bids_unique[i].end(), ids[side]) == 0)
151 input_bids_unique[i].push_back(ids[side]);
152 seen_bid_to_index_map[ids[side]] = index;
153 boundary_name_to_index_map[boundary_param_names[side]] = index++;
156 boundary_name_to_index_map[boundary_param_names[side]] = seen_bid_to_index_map[ids[side]];
161 if (ids[side] != input_bids[i - 1][side])
162 have_common_ids =
false;
164 if (std::count(input_bids_unique[i].begin(), input_bids_unique[i].end(), ids[side]) == 0)
165 input_bids_unique[i].push_back(ids[side]);
170 if (i > 0 && set_length != input_bids_unique.size())
172 "Input meshes have incompatible boundary ids. This can occur when input meshes have " 173 "the same boundary id for multiple boundaries, but in a way that is different " 174 "between the meshes. Try assigning each left/right/top/bottom to its own boundary id.");
176 set_length = input_bids_unique.size();
179 const auto all_ids =
_meshes[i]->get_boundary_info().get_boundary_ids();
182 all_boundary_ids.insert(all_ids.begin(), all_ids.end());
187 auto bbox = MeshTools::create_bounding_box(*
_meshes[0]);
189 _x_width = bbox.max()(0) - bbox.min()(0);
191 _y_width = bbox.max()(1) - bbox.min()(1);
193 _z_width = bbox.max()(2) - bbox.min()(2);
196 std::vector<boundary_id_type> stitch_bids;
199 stitch_bids = input_bids_unique[0];
205 if (!all_boundary_ids.count(
id))
207 stitch_bids.push_back(
id);
210 if (stitch_bids.size() == input_bids_unique[0].size())
217 MeshTools::Modification::change_boundary_id(
218 *
_meshes[i], input_bids_unique[i][side], stitch_bids[side]);
225 const boundary_id_type &left_bid(stitch_bids[boundary_name_to_index_map[
"left_boundary"]]),
226 right_bid(stitch_bids[boundary_name_to_index_map[
"right_boundary"]]),
227 top_bid(stitch_bids[boundary_name_to_index_map[
"top_boundary"]]),
228 bottom_bid(stitch_bids[boundary_name_to_index_map[
"bottom_boundary"]]);
242 MeshTools::Modification::translate(*
_row_meshes[i], deltax, -deltay, 0);
250 MeshTools::Modification::translate(cell_mesh, deltax, -deltay, 0);
253 auto & main_subdomain_map =
_row_meshes[i]->set_subdomain_name_map();
256 const auto & increment_subdomain_map = cell_mesh.get_subdomain_name_map();
267 MeshTools::Modification::translate(cell_mesh, -deltax, deltay, 0);
276 auto & main_subdomain_map =
_row_meshes[0]->set_subdomain_name_map();
279 const auto & increment_subdomain_map =
_row_meshes[i]->get_subdomain_name_map();
291 if (!have_common_ids)
293 MeshTools::Modification::change_boundary_id(
294 *
_row_meshes[0], stitch_bids[side], input_bids_unique[0][side]);
302 std::map<subdomain_id_type, std::string> & main_subdomain_map,
303 const std::map<subdomain_id_type, std::string> & increment_subdomain_map)
306 main_subdomain_map.insert(increment_subdomain_map.begin(), increment_subdomain_map.end());
308 std::set<SubdomainName> main_subdomain_map_name_list;
309 for (
auto const & id_name_pair : main_subdomain_map)
311 const auto name_to_insert = id_name_pair.second;
312 if (main_subdomain_map_name_list.find(name_to_insert) != main_subdomain_map_name_list.end())
314 "Two of the input meshes contain a subdomain with the name '" + name_to_insert +
315 "' which corresponds to two conflicting subdomain ids.");
316 main_subdomain_map_name_list.emplace(name_to_insert);
Reads one or more 2D mesh files and stitches them together based on a provided two-dimensional patter...
void mergeSubdomainNameMaps(std::map< subdomain_id_type, std::string > &main_subdomain_map, const std::map< subdomain_id_type, std::string > &increment_subdomain_map)
Merges the subdomain name maps between two meshes, throws an error if input maps contain shared subdo...
PatternedMeshGenerator(const InputParameters ¶meters)
std::vector< std::unique_ptr< ReplicatedMesh > > _meshes
Holds the pointers to the input generated meshes.
const std::vector< std::vector< unsigned int > > & _pattern
The pattern, starting with the upper left corner.
const BoundaryID INVALID_BOUNDARY_ID
registerMooseObject("MooseApp", PatternedMeshGenerator)
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
std::vector< std::unique_ptr< ReplicatedMesh > > _row_meshes
Holds a mesh for each row, these will be stitched together in the end.
static InputParameters validParams()
const std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
Holds pointers to the meshes before they are generated.
const std::string & type() const
Get the type of this class.
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
static InputParameters validParams()
std::string stringify(const T &t)
conversion to string
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
MeshGenerators are objects that can modify or add to an existing mesh.
void ErrorVector unsigned int
auto index_range(const T &sizable)
const std::vector< MeshGeneratorName > & _input_names
The mesh generators to read.