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 "MeshAlignmentOneToMany.h" 11 : #include "KDTree.h" 12 : #include "MooseUtils.h" 13 : 14 178 : MeshAlignmentOneToMany::MeshAlignmentOneToMany(const MooseMesh & mesh) 15 178 : : MeshAlignmentBase(mesh), _max_coupling_size(0) 16 : { 17 178 : } 18 : 19 : void 20 166 : MeshAlignmentOneToMany::buildMapping() 21 : { 22 : // Build the element mapping 23 166 : if (_primary_elem_points.size() > 0 && _secondary_elem_points.size() > 0) 24 : { 25 : // find the primary elements that are nearest to the secondary elements 26 164 : KDTree kd_tree(_primary_elem_points, _mesh.getMaxLeafSize()); 27 9456 : for (std::size_t i_secondary = 0; i_secondary < _secondary_elem_points.size(); i_secondary++) 28 : { 29 : unsigned int patch_size = 1; 30 9292 : std::vector<std::size_t> return_index(patch_size); 31 9292 : kd_tree.neighborSearch(_secondary_elem_points[i_secondary], patch_size, return_index); 32 9292 : const std::size_t i_primary = return_index[0]; 33 : 34 9292 : const auto primary_elem_id = _primary_elem_ids[i_primary]; 35 9292 : const auto secondary_elem_id = _secondary_elem_ids[i_secondary]; 36 : 37 9292 : _secondary_elem_id_to_primary_elem_id[secondary_elem_id] = primary_elem_id; 38 : 39 : auto it = _primary_elem_id_to_secondary_elem_ids.find(primary_elem_id); 40 9292 : if (it == _primary_elem_id_to_secondary_elem_ids.end()) 41 3612 : _primary_elem_id_to_secondary_elem_ids.insert({primary_elem_id, {secondary_elem_id}}); 42 : else 43 7486 : it->second.push_back(secondary_elem_id); 44 : } 45 : 46 : // Determine max coupling size 47 2034 : for (const auto primary_elem_id : _primary_elem_ids) 48 1870 : if (hasCoupledSecondaryElemIDs(primary_elem_id)) 49 : { 50 1806 : const auto & secondary_elem_ids = getCoupledSecondaryElemIDs(primary_elem_id); 51 1824 : _max_coupling_size = std::max(secondary_elem_ids.size(), _max_coupling_size); 52 : } 53 : } 54 166 : } 55 : 56 : void 57 119 : MeshAlignmentOneToMany::checkAlignment(const Point & axis_point, 58 : const RealVectorValue & axis_direction) 59 : { 60 119 : if (_primary_elem_points.size() > 0 && _secondary_elem_points.size() > 0) 61 : { 62 : // Check if meshes are aligned: all secondary boundary faces paired to a 63 : // primary element/face must have the same axial coordinate. 64 119 : _meshes_are_aligned = true; 65 1309 : for (const auto i_primary : index_range(_primary_elem_ids)) 66 : { 67 1190 : const auto primary_elem_id = _primary_elem_ids[i_primary]; 68 1190 : const auto primary_elem_point = _primary_elem_points[i_primary]; 69 : const auto primary_ax_coord = axis_direction * (primary_elem_point - axis_point); 70 : 71 1190 : if (hasCoupledSecondaryElemIDs(primary_elem_id)) 72 : { 73 1172 : const auto & secondary_elem_ids = getCoupledSecondaryElemIDs(primary_elem_id); 74 8212 : for (const auto secondary_elem_id : secondary_elem_ids) 75 : { 76 : auto it = 77 7040 : std::find(_secondary_elem_ids.begin(), _secondary_elem_ids.end(), secondary_elem_id); 78 : const auto i_secondary = std::distance(_secondary_elem_ids.begin(), it); 79 7040 : const auto secondary_elem_point = _secondary_elem_points[i_secondary]; 80 : const auto secondary_ax_coord = axis_direction * (secondary_elem_point - axis_point); 81 7040 : if (!MooseUtils::absoluteFuzzyEqual(secondary_ax_coord, primary_ax_coord)) 82 200 : _meshes_are_aligned = false; 83 : } 84 : } 85 : else 86 18 : _meshes_are_aligned = false; 87 : } 88 : } 89 119 : } 90 : 91 : bool 92 5900 : MeshAlignmentOneToMany::hasCoupledPrimaryElemID(const dof_id_type & secondary_elem_id) const 93 : { 94 : return _secondary_elem_id_to_primary_elem_id.find(secondary_elem_id) != 95 5900 : _secondary_elem_id_to_primary_elem_id.end(); 96 : } 97 : 98 : dof_id_type 99 100301 : MeshAlignmentOneToMany::getCoupledPrimaryElemID(const dof_id_type & secondary_elem_id) const 100 : { 101 : mooseAssert(hasCoupledPrimaryElemID(secondary_elem_id), 102 : "The element ID has no coupled elements."); 103 100301 : return _secondary_elem_id_to_primary_elem_id.find(secondary_elem_id)->second; 104 : } 105 : 106 : bool 107 3740 : MeshAlignmentOneToMany::hasCoupledSecondaryElemIDs(const dof_id_type & primary_elem_id) const 108 : { 109 : return _primary_elem_id_to_secondary_elem_ids.find(primary_elem_id) != 110 3740 : _primary_elem_id_to_secondary_elem_ids.end(); 111 : } 112 : 113 : const std::vector<dof_id_type> & 114 68150 : MeshAlignmentOneToMany::getCoupledSecondaryElemIDs(const dof_id_type & primary_elem_id) const 115 : { 116 : mooseAssert(hasCoupledSecondaryElemIDs(primary_elem_id), 117 : "The element ID has no coupled elements."); 118 68150 : return _primary_elem_id_to_secondary_elem_ids.find(primary_elem_id)->second; 119 : } 120 : 121 : unsigned int 122 1351601 : MeshAlignmentOneToMany::getCoupledPrimaryElemQpIndex(const dof_id_type & secondary_elem_id, 123 : const unsigned int & secondary_qp) const 124 : { 125 : auto it = _secondary_elem_id_to_qp_indices.find(secondary_elem_id); 126 : mooseAssert(it != _secondary_elem_id_to_qp_indices.end(), 127 : "The element ID has no coupled quadrature point indices."); 128 : mooseAssert(secondary_qp < it->second.size(), "The quadrature index does not exist in the map."); 129 1351601 : return it->second[secondary_qp]; 130 : }