https://mooseframework.inl.gov
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 
10 #include "RefineBlockGenerator.h"
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 
56 std::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 
126 std::unique_ptr<MeshBase>
127 RefineBlockGenerator::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 }
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:467
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
Definition: MooseBase.h:416
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
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< 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.
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.
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...
auto max(const L &left, const R &right)
RefineBlockGenerator(const InputParameters &parameters)
std::unique_ptr< MeshBase > & _input
Input mesh to refine.
bool hasSubdomainID(const MeshBase &input_mesh, const SubdomainID &id)
Whether a particular subdomain ID exists in the mesh.
const Real _max_element_volume
maximum element size over which elements are refined
const std::vector< SubdomainName > _block
List of block(s) to refine.
static InputParameters validParams()
Definition: MeshGenerator.C:23
std::string stringify(const T &t)
conversion to string
Definition: Conversion.h:64
unsigned char & face_level_mismatch_limit()
const bool _enable_neighbor_refinement
Toggles whether neighboring level one elements should be refined or not. Defaults to true...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::vector< unsigned int > _refinement
The amount of times to refine each block, corresponding to their index in &#39;block&#39;.
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...
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...
registerMooseObject("MooseApp", RefineBlockGenerator)
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:33
void ErrorVector unsigned int
static InputParameters validParams()
MeshGenerator for refining one or more blocks.