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 "AllSideSetsByNormalsGenerator.h" 11 : #include "Parser.h" 12 : #include "InputParameters.h" 13 : #include "CastUniquePointer.h" 14 : 15 : #include "libmesh/fe_base.h" 16 : #include "libmesh/mesh_generation.h" 17 : #include "libmesh/mesh.h" 18 : #include "libmesh/string_to_enum.h" 19 : #include "libmesh/quadrature_gauss.h" 20 : #include "libmesh/point_locator_base.h" 21 : #include "libmesh/distributed_mesh.h" 22 : #include "libmesh/elem.h" 23 : 24 : #include <typeinfo> 25 : 26 : registerMooseObject("MooseApp", AllSideSetsByNormalsGenerator); 27 : 28 : InputParameters 29 14345 : AllSideSetsByNormalsGenerator::validParams() 30 : { 31 14345 : InputParameters params = SideSetsGeneratorBase::validParams(); 32 : 33 : // This is the expected behavior of this sideset generator 34 : // This is the expected behavior of this sideset generator 35 14345 : params.setParameters("include_only_external_sides", true); 36 14345 : params.suppressParameter<bool>("include_only_external_sides"); 37 : 38 : // The normals are found from the actual orientation of sidesets, not user-specified 39 : // The normals are found from the actual orientation of sidesets, not user-specified 40 14345 : params.suppressParameter<bool>("fixed_normal"); 41 14345 : params.suppressParameter<Point>("normal"); 42 14345 : params.suppressParameter<Real>("normal_tol"); 43 14345 : params.suppressParameter<std::vector<BoundaryName>>("new_boundary"); 44 : 45 14345 : params.addClassDescription("Adds sidesets to the entire mesh based on unique normals."); 46 14345 : return params; 47 0 : } 48 : 49 40 : AllSideSetsByNormalsGenerator::AllSideSetsByNormalsGenerator(const InputParameters & parameters) 50 : : SideSetsGeneratorBase(parameters), 51 40 : _boundary_to_normal_map( 52 40 : declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals")) 53 : { 54 40 : } 55 : 56 : std::unique_ptr<MeshBase> 57 40 : AllSideSetsByNormalsGenerator::generate() 58 : { 59 40 : std::unique_ptr<MeshBase> mesh = std::move(_input); 60 40 : if (!mesh->is_replicated()) 61 0 : mooseError("AllSideSetsByNormalsGenerator is not implemented for distributed meshes"); 62 40 : setup(*mesh); 63 : 64 : // Get the current list of boundaries so we can generate new ones that won't conflict 65 40 : _mesh_boundary_ids = mesh->get_boundary_info().get_boundary_ids(); 66 : 67 40 : _visited.clear(); 68 : 69 : // We'll need to loop over all of the elements to find ones that match this normal. 70 : // We can't rely on flood catching them all here... 71 164136 : for (const auto & elem : mesh->element_ptr_range()) 72 491888 : for (const auto side : make_range(elem->n_sides())) 73 : { 74 409840 : const std::vector<Point> & normals = _fe_face->get_normals(); 75 409840 : _fe_face->reinit(elem, side); 76 : 77 : { 78 : // See if we've seen this normal before (linear search) 79 409840 : const std::map<BoundaryID, RealVectorValue>::value_type * item = nullptr; 80 1996960 : for (const auto & id_pair : _boundary_to_normal_map) 81 1996688 : if (normalsWithinTol(id_pair.second, normals[0], 1e-5)) 82 : { 83 409568 : item = &id_pair; 84 409568 : break; 85 : } 86 : 87 409840 : if (item) 88 409568 : flood(elem, normals[0], item->first, *mesh); 89 : else 90 : { 91 272 : boundary_id_type id = getNextBoundaryID(); 92 272 : _boundary_to_normal_map[id] = normals[0]; 93 272 : flood(elem, normals[0], id, *mesh); 94 : } 95 : } 96 40 : } 97 : 98 40 : finalize(); 99 : 100 40 : mesh->set_isnt_prepared(); 101 80 : return dynamic_pointer_cast<MeshBase>(mesh); 102 40 : } 103 : 104 : boundary_id_type 105 272 : AllSideSetsByNormalsGenerator::getNextBoundaryID() 106 : { 107 272 : std::set<boundary_id_type>::iterator it; 108 272 : boundary_id_type next_id = 1; 109 : 110 3160 : while ((it = _mesh_boundary_ids.find(next_id)) != _mesh_boundary_ids.end()) 111 2888 : ++next_id; 112 : 113 272 : _mesh_boundary_ids.insert(next_id); 114 : 115 272 : return next_id; 116 : }