Line data Source code
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 "PeripheralTriangleMeshGenerator.h" 11 : 12 : // Moose headers 13 : #include "MooseApp.h" 14 : #include "MooseMeshUtils.h" 15 : #include "Factory.h" 16 : #include "libmesh/elem.h" 17 : 18 : registerMooseObject("ReactorApp", PeripheralTriangleMeshGenerator); 19 : 20 : InputParameters 21 56 : PeripheralTriangleMeshGenerator::validParams() 22 : { 23 56 : InputParameters params = MeshGenerator::validParams(); 24 112 : params.addRequiredParam<MeshGeneratorName>("input", "The input mesh to be modified."); 25 112 : params.addRequiredRangeCheckedParam<Real>("peripheral_ring_radius", 26 : "peripheral_ring_radius>0", 27 : "Radius of the peripheral ring to be added."); 28 112 : params.addRequiredRangeCheckedParam<unsigned int>("peripheral_ring_num_segments", 29 : "peripheral_ring_num_segments>0", 30 : "Number of segments of the peripheral ring."); 31 112 : params.addRangeCheckedParam<Real>( 32 : "desired_area", 33 : 0, 34 : "desired_area>=0", 35 : "Desired (maximum) triangle area, or 0 to skip uniform refinement"); 36 112 : params.addParam<std::string>( 37 : "desired_area_func", 38 56 : std::string(), 39 : "Desired area as a function of x,y; omit to skip non-uniform refinement"); 40 : 41 112 : params.addParam<bool>( 42 112 : "use_auto_area_func", false, "Use the automatic area function in the peripheral region."); 43 112 : params.addParam<Real>( 44 : "auto_area_func_default_size", 45 112 : 0, 46 : "Background size for automatic area function, or 0 to use non background size"); 47 112 : params.addParam<Real>("auto_area_func_default_size_dist", 48 112 : -1.0, 49 : "Effective distance of background size for automatic area " 50 : "function, or negative to use non background size"); 51 112 : params.addParam<unsigned int>("auto_area_function_num_points", 52 112 : 10, 53 : "Maximum number of nearest points used for the inverse distance " 54 : "interpolation algorithm for automatic area function calculation."); 55 168 : params.addRangeCheckedParam<Real>( 56 : "auto_area_function_power", 57 112 : 1.0, 58 : "auto_area_function_power>0", 59 : "Polynomial power of the inverse distance interpolation algorithm for automatic area " 60 : "function calculation."); 61 : 62 112 : params.addParam<SubdomainName>( 63 : "peripheral_ring_block_name", "", "The block name assigned to the created peripheral layer."); 64 112 : params.addParam<BoundaryName>("external_boundary_name", 65 : "Optional customized external boundary name."); 66 112 : MooseEnum tri_elem_type("TRI3 TRI6 TRI7 DEFAULT", "DEFAULT"); 67 112 : params.addParam<MooseEnum>( 68 : "tri_element_type", tri_elem_type, "Type of the triangular elements to be generated."); 69 112 : params.addParam<bool>( 70 : "preserve_volumes", 71 112 : false, 72 : "Whether the volume of the peripheral region is preserved by fixing the radius."); 73 56 : params.addClassDescription("This PeripheralTriangleMeshGenerator object is designed to generate " 74 : "a triangulated mesh between a generated outer circle boundary " 75 : "and a provided inner mesh."); 76 112 : params.addParamNamesToGroup("desired_area desired_area_func use_auto_area_func " 77 : "auto_area_func_default_size auto_area_func_default_size_dist " 78 : "auto_area_function_num_points auto_area_function_power", 79 : "Peripheral Area Delaunay"); 80 56 : return params; 81 56 : } 82 : 83 28 : PeripheralTriangleMeshGenerator::PeripheralTriangleMeshGenerator(const InputParameters & parameters) 84 : : MeshGenerator(parameters), 85 56 : _input_name(getParam<MeshGeneratorName>("input")), 86 56 : _peripheral_ring_radius(getParam<Real>("peripheral_ring_radius")), 87 56 : _peripheral_ring_num_segments(getParam<unsigned int>("peripheral_ring_num_segments")), 88 56 : _desired_area(getParam<Real>("desired_area")), 89 56 : _desired_area_func(getParam<std::string>("desired_area_func")), 90 84 : _preserve_volumes(getParam<bool>("preserve_volumes")) 91 : { 92 : // Calculate outer boundary points 93 : 94 : std::vector<libMesh::Point> outer_polyline; 95 : // radial spacing 96 28 : Real d_theta = 2.0 * M_PI / _peripheral_ring_num_segments; 97 1778 : for (unsigned int i = 0; i < _peripheral_ring_num_segments; i++) 98 : { 99 : // sqrt{2 * pi / Sigma_i [sin (azi_i)]} 100 : const Real radius_correction_factor = 101 1750 : _preserve_volumes ? std::sqrt(2. * M_PI / _peripheral_ring_num_segments / 102 350 : std::sin(2. * M_PI / _peripheral_ring_num_segments)) 103 : : 1.0; 104 : 105 : // rotation angle 106 1750 : Real theta = i * d_theta; 107 : // calculate (x, y) coords 108 1750 : Real x = _peripheral_ring_radius * std::cos(theta) * radius_correction_factor; 109 1750 : Real y = _peripheral_ring_radius * std::sin(theta) * radius_correction_factor; 110 : 111 : // add to outer boundary list 112 1750 : outer_polyline.emplace_back(x, y, 0); 113 : } 114 : 115 : // Generate outer boundary polyline 116 : { 117 28 : auto params = _app.getFactory().getValidParams("PolyLineMeshGenerator"); 118 28 : params.set<std::vector<Point>>("points") = outer_polyline; 119 28 : params.set<std::vector<unsigned int>>("nums_edges_between_points") = {1}; 120 28 : params.set<bool>("loop") = true; 121 56 : addMeshSubgenerator("PolyLineMeshGenerator", _input_name + "_periphery_polyline", params); 122 28 : } 123 : 124 : // Generate periphery region 125 : { 126 28 : declareMeshForSub("input"); 127 56 : auto params = _app.getFactory().getValidParams("XYDelaunayGenerator"); 128 56 : params.set<MeshGeneratorName>("boundary") = 129 28 : (MeshGeneratorName)_input_name + "_periphery_polyline"; 130 28 : params.set<std::vector<MeshGeneratorName>>("holes") = 131 84 : std::vector<MeshGeneratorName>{_input_name}; 132 28 : params.set<unsigned int>("add_nodes_per_boundary_segment") = 0; 133 28 : params.set<Real>("desired_area") = _desired_area; 134 28 : params.set<std::string>("desired_area_func") = _desired_area_func; 135 56 : params.set<bool>("use_auto_area_func") = getParam<bool>("use_auto_area_func"); 136 56 : if (isParamSetByUser("auto_area_func_default_size")) 137 0 : params.set<Real>("auto_area_func_default_size") = 138 0 : getParam<Real>("auto_area_func_default_size"); 139 56 : if (isParamSetByUser("auto_area_func_default_size_dist")) 140 0 : params.set<Real>("auto_area_func_default_size_dist") = 141 0 : getParam<Real>("auto_area_func_default_size_dist"); 142 56 : if (isParamSetByUser("auto_area_function_num_points")) 143 0 : params.set<unsigned int>("auto_area_function_num_points") = 144 0 : getParam<unsigned int>("auto_area_function_num_points"); 145 56 : if (isParamSetByUser("auto_area_function_power")) 146 0 : params.set<Real>("auto_area_function_power") = getParam<Real>("auto_area_function_power"); 147 28 : params.set<bool>("refine_boundary") = false; 148 56 : params.set<std::vector<bool>>("refine_holes") = std::vector<bool>{false}; 149 56 : params.set<std::vector<bool>>("stitch_holes") = std::vector<bool>{true}; 150 56 : if (isParamValid("external_boundary_name")) 151 14 : params.set<BoundaryName>("output_boundary") = 152 14 : getParam<BoundaryName>("external_boundary_name"); 153 56 : params.set<SubdomainName>("output_subdomain_name") = 154 28 : getParam<SubdomainName>("peripheral_ring_block_name"); 155 84 : params.set<MooseEnum>("tri_element_type") = getParam<MooseEnum>("tri_element_type"); 156 28 : params.set<bool>("verbose_stitching") = false; 157 56 : addMeshSubgenerator("XYDelaunayGenerator", _input_name + "_periphery", params); 158 56 : _build_mesh = &getMeshByName(_input_name + "_periphery"); 159 28 : } 160 28 : } 161 : 162 : std::unique_ptr<MeshBase> 163 28 : PeripheralTriangleMeshGenerator::generate() 164 : { 165 28 : (*_build_mesh)->find_neighbors(); 166 28 : return std::move(*_build_mesh); 167 : }