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 "SurfaceDelaunayGeneratorBase.h" 11 : #include "libmesh/parallel_implementation.h" 12 : #include "libmesh/parallel_algebra.h" 13 : 14 : InputParameters 15 10324 : SurfaceDelaunayGeneratorBase::validParams() 16 : { 17 10324 : InputParameters params = MeshGenerator::validParams(); 18 : 19 30972 : params.addParam<bool>("use_auto_area_func", 20 20648 : false, 21 : "Use the automatic area function for the triangle meshing region."); 22 30972 : params.addParam<Real>( 23 : "auto_area_func_default_size", 24 20648 : 0, 25 : "Background size for automatic area function, or 0 to use non background size"); 26 30972 : params.addParam<Real>("auto_area_func_default_size_dist", 27 20648 : -1.0, 28 : "Effective distance of background size for automatic area " 29 : "function, or negative to use non background size"); 30 30972 : params.addParam<unsigned int>("auto_area_function_num_points", 31 20648 : 10, 32 : "Maximum number of nearest points used for the inverse distance " 33 : "interpolation algorithm for automatic area function calculation."); 34 51620 : params.addRangeCheckedParam<Real>( 35 : "auto_area_function_power", 36 20648 : 1.0, 37 : "auto_area_function_power>0", 38 : "Polynomial power of the inverse distance interpolation algorithm for automatic area " 39 : "function calculation."); 40 : 41 20648 : params.addClassDescription("Base class for Delaunay mesh generators applied to a surface."); 42 : 43 41296 : params.addParamNamesToGroup( 44 : "use_auto_area_func auto_area_func_default_size auto_area_func_default_size_dist " 45 : "auto_area_function_num_points auto_area_function_power", 46 : "Automatic triangle meshing area control"); 47 : 48 51620 : params.addRangeCheckedParam<Real>( 49 : "max_angle_deviation", 50 20648 : 60.0, 51 : "max_angle_deviation>0 & max_angle_deviation<90", 52 : "Maximum angle deviation from the global average normal vector in the input mesh."); 53 20648 : params.addParam<bool>( 54 20648 : "verbose", false, "Whether the generator should output additional information"); 55 10324 : return params; 56 0 : } 57 : 58 575 : SurfaceDelaunayGeneratorBase::SurfaceDelaunayGeneratorBase(const InputParameters & parameters) 59 : : MeshGenerator(parameters), 60 575 : _use_auto_area_func(getParam<bool>("use_auto_area_func")), 61 1150 : _auto_area_func_default_size(getParam<Real>("auto_area_func_default_size")), 62 1150 : _auto_area_func_default_size_dist(getParam<Real>("auto_area_func_default_size_dist")), 63 1150 : _auto_area_function_num_points(getParam<unsigned int>("auto_area_function_num_points")), 64 1150 : _auto_area_function_power(getParam<Real>("auto_area_function_power")), 65 1150 : _max_angle_deviation(getParam<Real>("max_angle_deviation")), 66 1725 : _verbose(getParam<bool>("verbose")) 67 : { 68 575 : } 69 : 70 : Point 71 14240 : SurfaceDelaunayGeneratorBase::elemNormal(const Elem & elem) 72 : { 73 : mooseAssert(elem.n_vertices() == 3 || elem.n_vertices() == 4, "unsupported element type."); 74 : // Only the first three vertices are used to calculate the normal vector 75 14240 : const Point & p0 = *elem.node_ptr(0); 76 14240 : const Point & p1 = *elem.node_ptr(1); 77 14240 : const Point & p2 = *elem.node_ptr(2); 78 : 79 14240 : if (elem.n_vertices() == 4) 80 : { 81 0 : const Point & p3 = *elem.node_ptr(3); 82 0 : return ((p2 - p0).cross(p3 - p1)).unit(); 83 : } 84 : 85 14240 : return ((p2 - p1).cross(p0 - p1)).unit(); 86 : } 87 : 88 : Point 89 363 : SurfaceDelaunayGeneratorBase::meshNormal2D(const MeshBase & mesh) 90 : { 91 363 : Point mesh_norm = Point(0.0, 0.0, 0.0); 92 363 : Real mesh_area = 0.0; 93 : 94 : // Check all the elements' normal vectors 95 3531 : for (const auto & elem : mesh.active_local_element_ptr_range()) 96 : { 97 3168 : const Real elem_area = elem->volume(); 98 3168 : mesh_norm += elemNormal(*elem) * elem_area; 99 3168 : mesh_area += elem_area; 100 363 : } 101 363 : mesh.comm().sum(mesh_norm); 102 363 : mesh.comm().sum(mesh_area); 103 363 : mesh_norm /= mesh_area; 104 363 : return mesh_norm.unit(); 105 : } 106 : 107 : Real 108 363 : SurfaceDelaunayGeneratorBase::meshNormalDeviation2D(const MeshBase & mesh, 109 : const Point & global_norm) 110 : { 111 363 : Real max_deviation(0.0); 112 : // Check all the elements' deviation from the global normal vector 113 6699 : for (const auto & elem : mesh.active_local_element_ptr_range()) 114 : { 115 3168 : const Real elem_deviation = std::acos(global_norm * elemNormal(*elem)) / M_PI * 180.0; 116 3168 : max_deviation = std::max(max_deviation, elem_deviation); 117 3168 : if (_verbose && elem_deviation > _max_angle_deviation) 118 0 : _console << "Element " << elem->id() << " from subdomain ID " << elem->subdomain_id() 119 0 : << " has normal deviation: " << elem_deviation << std::endl; 120 363 : } 121 363 : mesh.comm().max(max_deviation); 122 363 : return max_deviation; 123 : }