https://mooseframework.inl.gov
Loading...
Searching...
No Matches
XYMeshLineCutter.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 "XYMeshLineCutter.h"
12#include "MooseMeshUtils.h"
13
14#include "libmesh/mesh_modification.h"
15
16// C++ includes
17#include <cmath>
18
20
23{
25
26 MooseEnum cutting_type("CUT_ELEM_TRI MOV_NODE", "CUT_ELEM_TRI");
27 params.addParam<MooseEnum>(
28 "cutting_type",
29 cutting_type,
30 "Which method is to be used to cut the input mesh. 'CUT_ELEM_TRI' is the recommended method "
31 "but it may cause fine elements near the cutting line, while 'MOV_NODE' deforms subdomain "
32 "boundaries if they are not perpendicular to the cutting line.");
33
34 params.addRequiredParam<MeshGeneratorName>("input", "The input mesh that needs to be trimmed.");
35 params.addRequiredParam<std::vector<Real>>(
36 "cut_line_params",
37 "Cutting line parameters, which are a, b, and c in line equation a*x+b*y+c=0. Note that "
38 "a*x+b*y+c>0 part is being removed.");
39 params.addRequiredParam<boundary_id_type>(
40 "new_boundary_id", "Boundary id to be assigned to the boundary formed by the cutting.");
41 params.addParam<boundary_id_type>("input_mesh_external_boundary_id",
42 "Boundary id of the external boundary of the input mesh.");
43 params.addParam<std::vector<boundary_id_type>>(
44 "other_boundaries_to_conform",
45 "IDs of the other boundaries that need to be conformed to during nodes moving.");
46
47 params.addParam<SubdomainName>(
48 "tri_elem_subdomain_name_suffix",
49 "trimmer_tri",
50 "Suffix to the block name used for quad elements that are trimmed/converted into "
51 "triangular elements to avert degenerate quad elements");
52 params.addParam<subdomain_id_type>(
53 "tri_elem_subdomain_shift",
54 "Customized id shift to define subdomain ids of the converted triangular elements.");
55 params.addParam<bool>(
56 "improve_tri_elements", false, "Whether to improve TRI3 elements after CUT_ELEM_TRI method.");
57
59 "This XYMeshLineCutter object is designed to trim the input mesh by removing all the "
60 "elements on one side of a given straight line with special processing on the elements "
61 "crossed by the cutting line to ensure a smooth cross-section.");
62
63 return params;
64}
65
67 : MeshGenerator(parameters),
68 _cutting_type(getParam<MooseEnum>("cutting_type").template getEnum<CutType>()),
69 _input_name(getParam<MeshGeneratorName>("input")),
70 _cut_line_params(getParam<std::vector<Real>>("cut_line_params")),
71 _new_boundary_id(getParam<boundary_id_type>("new_boundary_id")),
72 _input_mesh_external_boundary_id(
73 isParamValid("input_mesh_external_boundary_id")
74 ? getParam<boundary_id_type>("input_mesh_external_boundary_id")
75 : Moose::INVALID_BOUNDARY_ID),
76 _other_boundaries_to_conform(
77 isParamValid("other_boundaries_to_conform")
78 ? getParam<std::vector<boundary_id_type>>("other_boundaries_to_conform")
79 : std::vector<boundary_id_type>()),
80 _tri_elem_subdomain_name_suffix(getParam<SubdomainName>("tri_elem_subdomain_name_suffix")),
81 _tri_elem_subdomain_shift(isParamValid("tri_elem_subdomain_shift")
82 ? getParam<subdomain_id_type>("tri_elem_subdomain_shift")
83 : Moose::INVALID_BLOCK_ID),
84 _improve_tri_elements(getParam<bool>("improve_tri_elements")),
85 _input(getMeshByName(_input_name))
86{
87 if (_cut_line_params.size() != 3)
88 paramError("cut_line_params", "this parameter must have three elements.");
89 if (MooseUtils::absoluteFuzzyEqual(_cut_line_params[0], 0.0) &&
90 MooseUtils::absoluteFuzzyEqual(_cut_line_params[1], 0.0))
91 paramError("cut_line_params", "At lease one of the first two elements must be non-zero.");
93 paramError("improve_tri_elements",
94 "This parameter is not supported when 'MOV_NODE' method is selected as "
95 "'cutting_type'.");
99 "input_mesh_external_boundary_id",
100 "This parameter must be provided if 'MOV_NODE' method is selected as 'cutting_type'.");
101}
102
103std::unique_ptr<MeshBase>
105{
106 // We're querying elem dim caches from our input mesh
107 if (!_input->preparation().has_cached_elem_data)
108 _input->cache_elem_data();
109
110 auto replicated_mesh_ptr = dynamic_cast<ReplicatedMesh *>(_input.get());
111 if (!replicated_mesh_ptr)
112 paramError("input", "Input is not a replicated mesh, which is required");
113 if (*(replicated_mesh_ptr->elem_dimensions().begin()) != 2 ||
114 *(replicated_mesh_ptr->elem_dimensions().rbegin()) != 2)
115 paramError("input", "Only 2D meshes are supported.");
116
117 // Check that the input boundaries are part of the mesh
118 if (isParamValid("input_mesh_external_boundary_id"))
120 paramError("input_mesh_external_boundary_id", "Boundary must exist in input mesh");
121
122 // Check that the other boundaries to conform to are part of the mesh
123 if (isParamValid("other_boundaries_to_conform"))
124 for (const auto bid : _other_boundaries_to_conform)
125 if (!MooseMeshUtils::hasBoundaryID(*replicated_mesh_ptr, bid))
126 paramError("other_boundaries_to_conform",
127 "Boundary '" + std::to_string(bid) + "' must exist in input mesh");
128
129 ReplicatedMesh & mesh = *replicated_mesh_ptr;
130 // Subdomain ID for TRI elements arising of QUAD element cuts must be new
131 std::set<subdomain_id_type> subdomain_ids_set;
132 mesh.subdomain_ids(subdomain_ids_set);
133 const subdomain_id_type max_subdomain_id = *subdomain_ids_set.rbegin();
134 const subdomain_id_type block_id_to_remove = max_subdomain_id + 1;
135 const subdomain_id_type tri_subdomain_id_shift =
136 _tri_elem_subdomain_shift == Moose::INVALID_BLOCK_ID ? max_subdomain_id + 2
138
139 // Use a unique new boundary id as the temporary boundary id for _new_boundary_id
140 // This help prevent issues when _new_boundary_id is already used in the mesh
141 boundary_id_type new_boundary_id_tmp = MooseMeshUtils::getNextFreeBoundaryID(mesh);
142
144 {
145 try
146 {
149 tri_subdomain_id_shift,
151 block_id_to_remove,
152 new_boundary_id_tmp,
154 }
155 catch (MooseException & e)
156 {
157 if (((std::string)e.what()).compare("The new subdomain name already exists in the mesh.") ==
158 0)
159 paramError("tri_elem_subdomain_name_suffix", e.what());
160 else
161 mooseError("In XYMeshLineCutter with 'CUT_ELEM_TRI' mode, " + (std::string)e.what());
162 }
163 }
164 else
165 {
166 try
167 {
170 block_id_to_remove,
171 subdomain_ids_set,
172 new_boundary_id_tmp,
175 }
176 catch (MooseException & e)
177 {
178 if (((std::string)e.what())
179 .compare("The input mesh has degenerate quad element before trimming.") == 0)
180 paramError("input", e.what());
181 else if (((std::string)e.what())
182 .compare("The new subdomain name already exists in the mesh.") == 0)
183 paramError("tri_elem_subdomain_name_suffix", e.what());
184 else
185 mooseError("In XYMeshLineCutter with 'MOV_NODE' mode, " + (std::string)e.what());
186 }
188 mesh, subdomain_ids_set, tri_subdomain_id_shift, _tri_elem_subdomain_name_suffix);
189 }
190
191 // Then rename the temporary boundary id to _new_boundary_id
192 MeshTools::Modification::change_boundary_id(mesh, new_boundary_id_tmp, _new_boundary_id);
193
194 mesh.prepare_for_use();
195 return std::move(_input);
196}
registerMooseObject("MooseApp", XYMeshLineCutter)
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
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition MooseBase.h:271
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition MooseEnum.h:55
Provides a way for users to bail out of the current solve.
virtual const char * what() const
Get out the error message.
This XYMeshLineCutter object is designed to trim the input mesh by removing all the elements on one s...
const SubdomainName _tri_elem_subdomain_name_suffix
SubdomainName suffix used to rename the converted triangular elements.
const boundary_id_type _new_boundary_id
Boundary id to be assigned to the boundary formed by the cutting.
const bool _improve_tri_elements
Whether to improve TRI3 elements after CUT_ELEM_TRI method.
XYMeshLineCutter(const InputParameters &parameters)
std::unique_ptr< MeshBase > & _input
Reference to input mesh pointer.
const std::vector< Real > _cut_line_params
Cutting line parameters, which are a, b, and c in line equation a*x+b*y+c=0. Note that a*x+b*y+c>0 pa...
enum XYMeshLineCutter::CutType _cutting_type
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
CutType
Method to cut the input mesh.
static InputParameters validParams()
const boundary_id_type _input_mesh_external_boundary_id
Boundary id of the external boundary of the input mesh (only needed for MOV_NODE method)
const subdomain_id_type _tri_elem_subdomain_shift
Customized id shift to define subdomain ids of the converted triangular elements.
const std::vector< boundary_id_type > _other_boundaries_to_conform
IDs of the other boundaries that need to be conformed to during nodes moving (only needed for MOV_NOD...
MeshBase & mesh
bool hasBoundaryID(const MeshBase &input_mesh, const BoundaryID id)
Whether a particular boundary ID exists in the mesh.
BoundaryID getNextFreeBoundaryID(MeshBase &input_mesh)
Checks input mesh and returns the largest boundary ID in the mesh plus one, which is a boundary ID in...
void lineRemoverCutElem(libMesh::ReplicatedMesh &mesh, const std::vector< Real > &cut_line_params, const dof_id_type tri_subdomain_id_shift, const SubdomainName tri_elem_subdomain_name_suffix, const subdomain_id_type block_id_to_remove, const boundary_id_type new_boundary_id, const bool improve_boundary_tri_elems=false)
Trim the 2D mesh by removing all the elements on one side of the given line.
void lineRemoverMoveNode(libMesh::ReplicatedMesh &mesh, const std::vector< Real > &bdry_pars, const subdomain_id_type block_id_to_remove, const std::set< subdomain_id_type > &subdomain_ids_set, const boundary_id_type trimming_section_boundary_id, const boundary_id_type external_boundary_id, const std::vector< boundary_id_type > &other_boundaries_to_conform=std::vector< boundary_id_type >(), const bool assign_ext_to_new=false, const bool side_to_remove=true)
Removes all the elements on one side of a given line and deforms the elements intercepted by the line...
bool quasiTriElementsFixer(libMesh::ReplicatedMesh &mesh, const std::set< subdomain_id_type > &subdomain_ids_set, const subdomain_id_type tri_elem_subdomain_shift=Moose::INVALID_BLOCK_ID, const SubdomainName tri_elem_subdomain_name_suffix="tri")
Fixes degenerate QUAD elements created by the hexagonal mesh trimming by converting them into TRI ele...
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
const BoundaryID INVALID_BOUNDARY_ID
Definition MooseTypes.C:22
const SubdomainID INVALID_BLOCK_ID
Definition MooseTypes.C:20