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 "ExtraElementIntegerDivision.h" 11 : #include "MooseMesh.h" 12 : 13 : #include "libmesh/mesh_base.h" 14 : #include "libmesh/elem.h" 15 : 16 : registerMooseObject("MooseApp", ExtraElementIntegerDivision); 17 : 18 : InputParameters 19 14340 : ExtraElementIntegerDivision::validParams() 20 : { 21 14340 : InputParameters params = MeshDivision::validParams(); 22 14340 : params.addClassDescription( 23 : "Divide the mesh by increasing extra element IDs. The division will be contiguously " 24 : "numbered even if the extra element ids are not"); 25 14340 : params.addRequiredParam<ExtraElementIDName>("extra_id_name", 26 : "The name of the extra element ID in the mesh"); 27 14340 : return params; 28 0 : } 29 : 30 39 : ExtraElementIntegerDivision::ExtraElementIntegerDivision(const InputParameters & parameters) 31 39 : : MeshDivision(parameters), _extra_id_name(getParam<ExtraElementIDName>("extra_id_name")) 32 : { 33 39 : if (!_mesh.getMesh().has_elem_integer(_extra_id_name)) 34 0 : paramError("extra_id_name", "The source element ID does not exist on the input mesh"); 35 39 : _extra_id = _mesh.getMesh().get_elem_integer_index(_extra_id_name); 36 : 37 39 : ExtraElementIntegerDivision::initialize(); 38 39 : _mesh_fully_indexed = true; 39 39 : } 40 : 41 : void 42 39 : ExtraElementIntegerDivision::initialize() 43 : { 44 : // The ExtraElementID may not be contiguously numbered so we gather them all first 45 39 : std::set<libMesh::dof_id_type> extra_ids; 46 107559 : for (const auto & elem : _mesh.getMesh().active_local_element_ptr_range()) 47 107559 : extra_ids.insert(elem->get_extra_integer(_extra_id)); 48 39 : _mesh.comm().set_union(extra_ids); 49 39 : setNumDivisions(extra_ids.size()); 50 : 51 39 : unsigned int i = 0; 52 507 : for (const auto extra_id : extra_ids) 53 468 : _extra_ids_to_division_index[extra_id] = i++; 54 39 : } 55 : 56 : unsigned int 57 86016 : ExtraElementIntegerDivision::divisionIndex(const Elem & elem) const 58 : { 59 86016 : return libmesh_map_find(_extra_ids_to_division_index, elem.get_extra_integer(_extra_id)); 60 : } 61 : 62 : unsigned int 63 0 : ExtraElementIntegerDivision::divisionIndex(const Point & pt) const 64 : { 65 0 : const auto & pl = _mesh.getMesh().sub_point_locator(); 66 : // There could be more than one elem if we are on the edge between two elements 67 0 : std::set<const Elem *> candidates; 68 0 : (*pl)(pt, candidates); 69 : 70 : // By convention we will use the element with the lowest extra element id 71 : // There could be other conventions: use lowest element if for example 72 0 : const Elem * elem = nullptr; 73 0 : libMesh::dof_id_type min_extra_id = std::numeric_limits<int>::max(); 74 0 : for (const auto elem_ptr : candidates) 75 0 : if (elem_ptr->get_extra_integer(_extra_id) < min_extra_id) 76 : { 77 0 : elem = elem_ptr; 78 0 : min_extra_id = elem_ptr->get_extra_integer(_extra_id); 79 : } 80 : 81 0 : return libmesh_map_find(_extra_ids_to_division_index, elem->get_extra_integer(_extra_id)); 82 0 : }