13 #include "libmesh/elem.h" 14 #include "libmesh/mesh_refinement.h" 26 "The list of boundaries to be modified");
29 "The amount of times to refine each sideset, corresponding to their index in 'boundaries'");
31 "enable_neighbor_refinement",
33 "Toggles whether neighboring level one elements should be refined or not. Defaults to true. " 34 "False may lead to unsupported mesh non-conformality without great care.");
38 "Whether the generator should refine itself(primary), its " 39 "neighbors(secondary), or itself and its neighbors(both)");
46 _input(getMesh(
"input")),
47 _boundaries(getParam<
std::vector<BoundaryName>>(
"boundaries")),
48 _refinement(getParam<
std::vector<
int>>(
"refinement")),
49 _enable_neighbor_refinement(getParam<bool>(
"enable_neighbor_refinement")),
54 "The boundaries and refinement parameter vectors should be the same size");
57 "The boundaries and boundary_side parameter vectors should be the same size");
60 std::unique_ptr<MeshBase>
65 *
_input,
getParam<std::vector<BoundaryName>>(
"boundaries"),
false);
68 for (std::size_t i = 0; i < boundary_ids.size(); ++i)
72 getParam<std::vector<BoundaryName>>(
"boundaries")[i],
73 "' was not found within the mesh");
74 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
79 std::unique_ptr<MeshBase>
81 std::unique_ptr<MeshBase> & mesh,
82 std::vector<int> refinement,
91 const bool old_allow_remote_element_removal =
mesh->allow_remote_element_removal();
92 if (
mesh->is_serial())
94 mesh->allow_remote_element_removal(
false);
95 if (!
mesh->is_prepared())
96 mesh->prepare_for_use();
98 std::vector<std::tuple<dof_id_type, unsigned short int, boundary_id_type>> sideList =
99 mesh->get_boundary_info().build_active_side_list();
107 std::vector<dof_id_type> neighbors_to_refine;
109 for (std::size_t i = 0; i < boundary_ids.size(); i++)
111 if (refinement[i] > 0 && refinement[i] > ref_step)
113 for (std::tuple<dof_id_type, unsigned short int, boundary_id_type> tuple : sideList)
115 if (std::get<2>(tuple) == boundary_ids[i])
117 Elem * elem =
mesh->elem_ptr(std::get<0>(tuple));
119 elem->set_refinement_flag(Elem::REFINE);
122 auto neighbor = elem->neighbor_ptr(std::get<1>(tuple));
128 if (neighbor->active())
130 neighbor->set_refinement_flag(Elem::REFINE);
131 if (!
mesh->is_serial())
132 neighbors_to_refine.push_back(neighbor->id());
137 neighbor->active_family_tree_by_neighbor(
family_tree, elem);
140 child_elem->set_refinement_flag(Elem::REFINE);
141 if (!
mesh->is_serial())
142 neighbors_to_refine.push_back(child_elem->id());
152 if (!
mesh->is_serial())
154 mesh->comm().allgather(neighbors_to_refine);
155 std::sort(neighbors_to_refine.begin(), neighbors_to_refine.end());
156 auto new_last = std::unique(neighbors_to_refine.begin(), neighbors_to_refine.end());
157 neighbors_to_refine.erase(new_last, neighbors_to_refine.end());
158 for (
const auto id : neighbors_to_refine)
159 if (Elem *
const elem =
mesh->query_elem_ptr(
id))
160 elem->set_refinement_flag(Elem::REFINE);
169 mesh->allow_remote_element_removal(old_allow_remote_element_removal);
static InputParameters validParams()
const BoundaryID INVALID_BOUNDARY_ID
unsigned int size() const
Return the number of active items in the MultiMooseEnum.
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.
MeshGenerator for refining one or more sidesets.
const std::vector< int > _refinement
The amount of times to refine each boundary, corresponding to their index in 'boundaries'.
registerMooseObject("MooseApp", RefineSidesetGenerator)
auto max(const L &left, const R &right)
const bool _enable_neighbor_refinement
Toggles whether neighboring level one elements should be refined or not. Defaults to true...
std::unique_ptr< MeshBase > recursive_refine(const std::vector< boundary_id_type > boundary_ids, std::unique_ptr< MeshBase > &mesh, const std::vector< int > refinement, const int max, int ref_step=0)
The actual function refining the boundaries.
const MultiMooseEnum _boundary_side
Side(s) of the boundary/boundaries to be refined. Can be either "primary"(just the boundary elements)...
void family_tree(T elem, std::vector< T > &family, bool reset=true)
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
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.
virtual std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
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()
unsigned char & face_level_mismatch_limit()
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type...
RefineSidesetGenerator(const InputParameters ¶meters)
MeshGenerators are objects that can modify or add to an existing mesh.
void ErrorVector unsigned int
const std::vector< BoundaryName > _boundaries
List of boundarie(s) to refine.
std::unique_ptr< MeshBase > & _input
Input mesh to refine.