https://mooseframework.inl.gov
Loading...
Searching...
No Matches
RefineBlockGenerator.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "MooseMeshUtils.h"
12
13#include "libmesh/elem.h"
14#include "libmesh/mesh_refinement.h"
15#include "CastUniquePointer.h"
16
18
21{
23
24 params.addClassDescription("Mesh generator which refines one or more blocks in an existing mesh");
25 params.addRequiredParam<MeshGeneratorName>("input", "Input mesh to refine");
26 params.addRequiredParam<std::vector<SubdomainName>>("block", "The list of blocks to be refined");
27 params.addRequiredParam<std::vector<unsigned int>>(
28 "refinement",
29 "Minimum amount of times to refine each block, corresponding to their index in 'block'. A "
30 "single value can be specified to refine all blocks.");
31 params.addParam<bool>(
32 "enable_neighbor_refinement",
33 true,
34 "Toggles whether neighboring level one elements should be refined or not. Defaults to true. "
35 "False may lead to unsupported mesh non-conformality without great care.");
36 params.addParam<Real>(
37 "max_element_volume", 1e8, "If elements are above that size, they will be refined more");
38
39 return params;
40}
41
43 : MeshGenerator(parameters),
44 _input(getMesh("input")),
45 _block(getParam<std::vector<SubdomainName>>("block")),
46 _refinement(getParam<std::vector<unsigned int>>("refinement")),
47 _enable_neighbor_refinement(getParam<bool>("enable_neighbor_refinement")),
48 _max_element_volume(getParam<Real>("max_element_volume"))
49{
50 if (_refinement.size() == 1)
51 _refinement.resize(_block.size(), _refinement[0]);
52 if (_block.size() != _refinement.size())
53 paramError("refinement", "The blocks and refinement parameter vectors should be the same size");
54}
55
56std::unique_ptr<MeshBase>
58{
59 // Get the list of block ids from the block names
60 const auto block_ids =
61 MooseMeshUtils::getSubdomainIDs(*_input, getParam<std::vector<SubdomainName>>("block"));
62
63 // Check that the block ids/names exist in the mesh
64 if (!_input->preparation().has_cached_elem_data)
65 _input->cache_elem_data();
66 std::set<SubdomainID> mesh_blocks;
67 _input->subdomain_ids(mesh_blocks);
68
69 for (std::size_t i = 0; i < block_ids.size(); ++i)
70 if (!MooseMeshUtils::hasSubdomainID(*_input, block_ids[i]))
71 paramError("block",
72 "The block '",
73 getParam<std::vector<SubdomainName>>("block")[i],
74 "' was not found within the mesh.\nBlock ID: ",
75 block_ids[i],
76 "\nBlock IDs in the mesh: ",
77 Moose::stringify(mesh_blocks));
78
79 std::unique_ptr<MeshBase> mesh = std::move(_input);
80 int max = *std::max_element(_refinement.begin(), _refinement.end());
81
82 if (max > 0 && !mesh->is_replicated() && !mesh->is_prepared())
83 // refinement requires that (or at least it asserts that) the mesh is either replicated or
84 // prepared
85 mesh->prepare_for_use();
86
87 auto mesh_ptr = recursive_refine(block_ids, mesh, _refinement, max);
88
89 if (max > 0 && !mesh_ptr->is_replicated() && !mesh_ptr->is_prepared())
90 // refinement requires that (or at least it asserts that) the mesh is either replicated or
91 // prepared
92 mesh_ptr->prepare_for_use();
93
94 // Refine elements that are too big
95 bool found_element_to_refine = true;
96 bool refined_on_size = false;
97 while (found_element_to_refine)
98 {
99 found_element_to_refine = false;
100 for (auto bid : block_ids)
101 for (auto & elem : mesh_ptr->active_subdomain_elements_ptr_range(bid))
102 if (elem->volume() >= _max_element_volume)
103 {
104 elem->set_refinement_flag(Elem::REFINE);
105 found_element_to_refine = true;
106 }
107 // Refinement needs to be done on all ranks at the same time
108 mesh_ptr->comm().max(found_element_to_refine);
109
110 if (found_element_to_refine)
111 {
112 libMesh::MeshRefinement refinedmesh(*mesh_ptr);
114 refinedmesh.face_level_mismatch_limit() = 0;
115 refinedmesh.refine_elements();
116 refined_on_size = true;
117 }
118 }
119
120 if (refined_on_size || max > 0)
121 mesh_ptr->unset_is_prepared();
122
123 return mesh_ptr;
124}
125
126std::unique_ptr<MeshBase>
127RefineBlockGenerator::recursive_refine(std::vector<subdomain_id_type> block_ids,
128 std::unique_ptr<MeshBase> & mesh,
129 std::vector<unsigned int> refinement,
130 unsigned int max,
131 unsigned int ref_step)
132{
133 if (ref_step == max)
134 return dynamic_pointer_cast<MeshBase>(mesh);
135 for (std::size_t i = 0; i < block_ids.size(); i++)
136 {
137 if (refinement[i] > 0 && refinement[i] > ref_step)
138 {
139 for (const auto & elem : mesh->active_subdomain_elements_ptr_range(block_ids[i]))
140 elem->set_refinement_flag(Elem::REFINE);
141 }
142 }
143 libMesh::MeshRefinement refinedmesh(*mesh);
145 refinedmesh.face_level_mismatch_limit() = 0;
146 refinedmesh.refine_elements();
147
148 ref_step++;
149 return recursive_refine(block_ids, mesh, refinement, max, ref_step);
150}
registerMooseObject("MooseApp", RefineBlockGenerator)
void ErrorVector unsigned int
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
MeshGenerators are objects that can modify or add to an existing mesh.
static InputParameters validParams()
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition MooseBase.h:406
MeshGenerator for refining one or more blocks.
virtual std::unique_ptr< MeshBase > recursive_refine(const std::vector< subdomain_id_type > block_ids, std::unique_ptr< MeshBase > &mesh, const std::vector< unsigned int > refinement, const unsigned int max, unsigned int ref_step=0)
The actual function refining the blocks.
virtual std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
const bool _enable_neighbor_refinement
Toggles whether neighboring level one elements should be refined or not. Defaults to true.
RefineBlockGenerator(const InputParameters &parameters)
static InputParameters validParams()
std::vector< unsigned int > _refinement
The amount of times to refine each block, corresponding to their index in 'block'.
const std::vector< SubdomainName > _block
List of block(s) to refine.
const Real _max_element_volume
maximum element size over which elements are refined
std::unique_ptr< MeshBase > & _input
Input mesh to refine.
unsigned char & face_level_mismatch_limit()
MeshBase & mesh
bool hasSubdomainID(const MeshBase &input_mesh, const SubdomainID &id)
Whether a particular subdomain ID exists in the mesh.
std::vector< subdomain_id_type > getSubdomainIDs(const libMesh::MeshBase &mesh, const std::vector< SubdomainName > &subdomain_name)
Get the associated subdomainIDs for the subdomain names that are passed in.
std::string stringify(const T &t)
conversion to string
Definition Conversion.h:64