https://mooseframework.inl.gov
FillBetweenCurvesGenerator.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 
12 
13 #include "CastUniquePointer.h"
14 #include "libmesh/node.h"
15 
17 
20 {
22  params.addRequiredParam<MeshGeneratorName>("input_mesh_1",
23  "The input mesh that contains curve 1");
24  params.addRequiredParam<MeshGeneratorName>("input_mesh_2",
25  "The input mesh that contains curve 1");
26  params.addParam<Point>(
27  "mesh_1_shift", Point(0.0, 0.0, 0.0), "Translation vector to be applied to input_mesh_1");
28  params.addParam<Point>(
29  "mesh_2_shift", Point(0.0, 0.0, 0.0), "Translation vector to be applied to input_mesh_2");
30  params.addRequiredRangeCheckedParam<unsigned int>(
31  "num_layers", "num_layers>0", "Number of layers of elements created between the boundaries.");
32  params.addParam<subdomain_id_type>("block_id", 1, "ID to be assigned to the transition layer.");
33  params.addParam<boundary_id_type>(
34  "input_boundary_1_id",
35  10000,
36  "Boundary ID to be assigned to the boundary defined by positions_vector_1.");
37  params.addParam<boundary_id_type>(
38  "input_boundary_2_id",
39  10000,
40  "Boundary ID to be assigned to the boundary defined by positions_vector_2.");
41  params.addParam<boundary_id_type>("begin_side_boundary_id",
42  10000,
43  "Boundary ID to be assigned to the boundary connecting "
44  "starting points of the positions_vectors.");
45  params.addParam<boundary_id_type>("end_side_boundary_id",
46  10000,
47  "Boundary ID to be assigned to the boundary connecting ending "
48  "points of the positions_vectors.");
49  params.addParam<bool>(
50  "use_quad_elements",
51  false,
52  "Whether QUAD4 instead of TRI3 elements are used to construct the transition layer.");
53  params.addRangeCheckedParam<Real>(
54  "bias_parameter",
55  1.0,
56  "bias_parameter>=0",
57  "Parameter used to set up biasing of the layers: bias_parameter > 0.0 is used as the biasing "
58  "factor; bias_parameter = 0.0 activates automatic biasing based on local node density on "
59  "both input boundaries.");
60  params.addRangeCheckedParam<Real>(
61  "gaussian_sigma",
62  3.0,
63  "gaussian_sigma>0.0",
64  "Gaussian parameter used to smoothen local node density for automatic biasing; this "
65  "parameter is not used if another biasing option is selected.");
66  params.addClassDescription("This FillBetweenCurvesGenerator object is designed to generate a "
67  "transition layer to connect two boundaries of two input meshes.");
68  return params;
69 }
70 
72  : MeshGenerator(parameters),
73  _input_name_1(getParam<MeshGeneratorName>("input_mesh_1")),
74  _input_name_2(getParam<MeshGeneratorName>("input_mesh_2")),
75  _mesh_1_shift(getParam<Point>("mesh_1_shift")),
76  _mesh_2_shift(getParam<Point>("mesh_2_shift")),
77  _num_layers(getParam<unsigned int>("num_layers")),
78  _block_id(getParam<subdomain_id_type>("block_id")),
79  _input_boundary_1_id(getParam<boundary_id_type>("input_boundary_1_id")),
80  _input_boundary_2_id(getParam<boundary_id_type>("input_boundary_2_id")),
81  _begin_side_boundary_id(getParam<boundary_id_type>("begin_side_boundary_id")),
82  _end_side_boundary_id(getParam<boundary_id_type>("end_side_boundary_id")),
83  _use_quad_elements(getParam<bool>("use_quad_elements")),
84  _bias_parameter(getParam<Real>("bias_parameter")),
85  _sigma(getParam<Real>("gaussian_sigma")),
86  _input_1(getMeshByName(_input_name_1)),
87  _input_2(getMeshByName(_input_name_2))
88 {
89  if (_input_name_1.compare(_input_name_2) == 0)
90  paramError("input_mesh_2", "This parameter must be different from input_mesh_1.");
91 }
92 
93 std::unique_ptr<MeshBase>
95 {
96  auto input_mesh_1 = dynamic_pointer_cast<ReplicatedMesh>(std::move(_input_1));
97  auto input_mesh_2 = dynamic_pointer_cast<ReplicatedMesh>(std::move(_input_2));
98  if (!input_mesh_1)
99  paramError("input_mesh_1", "Input is not a replicated mesh, which is required.");
100  if (!input_mesh_2)
101  paramError("input_mesh_2", "Input is not a replicated mesh, which is required.");
102 
103  MeshTools::Modification::translate(
104  *input_mesh_1, _mesh_1_shift(0), _mesh_1_shift(1), _mesh_1_shift(2));
105  MeshTools::Modification::translate(
106  *input_mesh_2, _mesh_2_shift(0), _mesh_2_shift(1), _mesh_2_shift(2));
107 
108  Real max_input_mesh_1_node_radius;
109  Real max_input_mesh_2_node_radius;
110  std::vector<dof_id_type> curve_1_ordered_nodes;
111  std::vector<dof_id_type> curve_2_ordered_nodes;
112 
113  try
114  {
116  max_input_mesh_1_node_radius,
117  curve_1_ordered_nodes,
118  curveCentroidPoint(*input_mesh_1));
119  }
120  catch (MooseException & e)
121  {
122  paramError("input_mesh_1", e.what());
123  }
124 
125  try
126  {
128  max_input_mesh_2_node_radius,
129  curve_2_ordered_nodes,
130  curveCentroidPoint(*input_mesh_2));
131  }
132  catch (MooseException & e)
133  {
134  paramError("input_mesh_2", e.what());
135  }
136 
137  std::vector<Point> positions_vector_1;
138  std::vector<Point> positions_vector_2;
139 
140  for (auto & curve_1_node_id : curve_1_ordered_nodes)
141  positions_vector_1.push_back(*input_mesh_1->node_ptr(curve_1_node_id));
142 
143  for (auto & curve_2_node_id : curve_2_ordered_nodes)
144  positions_vector_2.push_back(*input_mesh_2->node_ptr(curve_2_node_id));
145 
146  const boundary_id_type input_boundary_1_id = _input_boundary_1_id;
147  const boundary_id_type input_boundary_2_id = _input_boundary_2_id;
148  auto mesh = buildReplicatedMesh(2);
150  positions_vector_1,
151  positions_vector_2,
152  _num_layers,
153  _block_id,
154  input_boundary_1_id,
155  input_boundary_2_id,
158  _type,
159  _name,
162  _sigma);
163 
164  // Transfer over the nodesets
165  BoundaryInfo & boundary = mesh->get_boundary_info();
166  const BoundaryInfo & input_bdy_1 = input_mesh_1->get_boundary_info();
167  const BoundaryInfo & input_bdy_2 = input_mesh_2->get_boundary_info();
168 
169  // Nodes could have been re-ordered during the FillBetweenPointVectors operation
170  // We need to locate the nodes from input nodesets in the new mesh
171  if (!mesh->is_prepared())
172  mesh->prepare_for_use();
173  auto pl = mesh->sub_point_locator();
174 
175  boundary_id_type offset = 0;
176  const auto node_list_mesh1 = input_bdy_1.build_node_list();
177  for (const auto & t : node_list_mesh1)
178  {
179  mooseAssert(pl->locate_node(*input_mesh_1->node_ptr(std::get<0>(t))),
180  "We should have found the old node in input mesh 1");
181  boundary.add_node(pl->locate_node(*input_mesh_1->node_ptr(std::get<0>(t))), std::get<1>(t));
182  offset = std::max(std::get<1>(t), offset);
183  }
184 
185  const auto node_list_mesh2 = input_bdy_2.build_node_list();
186  for (const auto & t : node_list_mesh2)
187  {
188  mooseAssert(pl->locate_node(*input_mesh_1->node_ptr(std::get<0>(t))),
189  "We should have found the old node in input mesh 2");
190  boundary.add_node(pl->locate_node(*input_mesh_2->node_ptr(std::get<0>(t))),
191  std::get<1>(t) + offset);
192  }
193 
194  for (const auto & nodeset_pair : input_bdy_1.get_nodeset_name_map())
195  boundary.set_nodeset_name_map().insert(nodeset_pair);
196  for (const auto & [bnd_id, bnd_name] : input_bdy_2.get_nodeset_name_map())
197  boundary.set_nodeset_name_map()[bnd_id + offset] = bnd_name;
198  if (node_list_mesh1.size() + node_list_mesh2.size())
199  mesh->set_isnt_prepared();
200 
201  return dynamic_pointer_cast<MeshBase>(mesh);
202 }
203 
204 Point
206 {
207  Point pt_tmp = Point(0.0, 0.0, 0.0);
208  Real length_tmp = 0.0;
209  for (const auto elem : curve.element_ptr_range())
210  {
211  Real elem_length = elem->hmax();
212  pt_tmp += (elem->vertex_average()) * elem_length;
213  length_tmp += elem_length;
214  }
215  return pt_tmp / length_tmp;
216 }
FillBetweenCurvesGenerator(const InputParameters &parameters)
const boundary_id_type _end_side_boundary_id
ID to be assigned to the boundary that connects the ending points of positions_vectors.
void addRequiredRangeCheckedParam(const std::string &name, const std::string &parsed_function, const std::string &doc_string)
These methods add an range checked parameters.
const MeshGeneratorName _input_name_1
Name of the mesh which contains the first input boundary.
virtual const char * what() const
Get out the error message.
const std::string & _name
The name of this class.
Definition: MooseBase.h:359
std::unique_ptr< ReplicatedMesh > buildReplicatedMesh(unsigned int dim=libMesh::invalid_uint)
Build a replicated mesh.
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:435
const Real _sigma
Parameter used for Gaussian blurring of local node density.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
const boundary_id_type _begin_side_boundary_id
ID to be assigned to the boundary that connects the starting points of positions_vectors.
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.
Point curveCentroidPoint(const ReplicatedMesh &curve)
Calculates the centroid of a curve mesh.
const bool _use_quad_elements
A boolean parameter to determine whether QUAD4 elements are used instead of TRI3 elements.
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)
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
const unsigned int _num_layers
Number of sublayers of the mesh to be generated.
int8_t boundary_id_type
const subdomain_id_type _block_id
Subdomain ID to be assigned to the generated transition layer.
std::unique_ptr< MeshBase > & _input_1
The mesh which contains the first input boundary.
void fillBetweenPointVectorsGenerator(MeshBase &mesh, const std::vector< Point > &boundary_points_vec_1, const std::vector< Point > &boundary_points_vec_2, const unsigned int num_layers, const subdomain_id_type transition_layer_id, const boundary_id_type input_boundary_1_id, const boundary_id_type input_boundary_2_id, const boundary_id_type begin_side_boundary_id, const boundary_id_type end_side_boundary_id, const std::string type, const std::string name, const bool quad_elem=false, const Real bias_parameter=1.0, const Real sigma=3.0)
Generates a 2D mesh with triangular elements for a region defined by two curves (sets of Points) ...
const boundary_id_type _input_boundary_2_id
ID to be assigned to the boundary that corresponds to the input boundary on the second input mesh...
const Point _mesh_2_shift
Translation applied to the second input mesh.
static InputParameters validParams()
Definition: MeshGenerator.C:23
const Point _mesh_1_shift
Translation applied to the first input mesh.
std::unique_ptr< MeshBase > & _input_2
The mesh which contains the second input boundary.
This FillBetweenCurvesGenerator object is designed to generate a transition layer to connect two curv...
bool isCurveOpenSingleSegment(MeshBase &mesh, Real &max_node_radius, std::vector< dof_id_type > &ordered_node_list, const Point origin_pt)
Decides whether a curve contained in a given mesh is an open single-segment curve.
Provides a way for users to bail out of the current solve.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const boundary_id_type _input_boundary_1_id
ID to be assigned to the boundary that corresponds to the input boundary on the first input mesh...
registerMooseObject("MooseApp", FillBetweenCurvesGenerator)
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...
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
const MeshGeneratorName _input_name_2
Name of the mesh which contains the second input boundary.
const Real _bias_parameter
A parameter used to set up mesh biasing of the layers.
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
void ErrorVector unsigned int
const std::string & _type
The type of this class.
Definition: MooseBase.h:356
static InputParameters validParams()