LCOV - code coverage report
Current view: top level - src/utils - MeshAlignmentOneToMany.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #30301 (3b550b) with base 2ad78d Lines: 46 46 100.0 %
Date: 2025-07-30 13:02:48 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.14