LCOV - code coverage report
Current view: top level - src/positions - NodePositions.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 1f9d31 Lines: 45 47 95.7 %
Date: 2025-09-02 20:01:20 Functions: 4 4 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 "NodePositions.h"
      11             : 
      12             : #include "libmesh/parallel_algebra.h"
      13             : 
      14             : registerMooseObject("MooseApp", NodePositions);
      15             : 
      16             : InputParameters
      17       14369 : NodePositions::validParams()
      18             : {
      19       14369 :   InputParameters params = Positions::validParams();
      20       14369 :   params.addClassDescription("Positions of element nodes.");
      21       14369 :   params += BlockRestrictable::validParams();
      22       14369 :   params += BoundaryRestrictable::validParams();
      23             : 
      24             :   // Element nodes must be sorted to remove duplicates.
      25       28738 :   params.suppressParameter<bool>("auto_sort");
      26       28738 :   params.set<bool>("auto_sort") = true;
      27             :   // Gathered locally, should be broadcast on every process
      28       14369 :   params.set<bool>("auto_broadcast") = true;
      29             : 
      30       14369 :   return params;
      31           0 : }
      32             : 
      33          52 : NodePositions::NodePositions(const InputParameters & parameters)
      34             :   : Positions(parameters),
      35             :     BlockRestrictable(this),
      36             :     BoundaryRestrictable(this, true),
      37          52 :     _mesh(_subproblem.mesh())
      38             : {
      39             :   // Mesh is ready at construction
      40          52 :   initialize();
      41             :   // Trigger synchronization as the initialization is distributed
      42          52 :   finalize();
      43          52 : }
      44             : 
      45             : void
      46          52 : NodePositions::initialize()
      47             : {
      48          52 :   clearPositions();
      49             : 
      50             :   // Only needed for boundary restriction
      51          52 :   const BoundaryInfo * binfo = nullptr;
      52          52 :   if (boundaryRestricted())
      53          26 :     binfo = &_mesh.getMesh().get_boundary_info();
      54             : 
      55        2476 :   for (const auto & [node_id, elems_ids] : _mesh.nodeToElemMap())
      56             :   {
      57        2424 :     const auto * const node = _mesh.queryNodePtr(node_id);
      58        2424 :     if (!node)
      59         757 :       continue;
      60             : 
      61             :     // Check that node is part of boundary restriction
      62        2424 :     if (binfo)
      63             :     {
      64        1212 :       if (!binfo->get_nodeset_map().count(node))
      65           0 :         continue;
      66             :       else
      67             :       {
      68        2794 :         for (const auto [_, nodeset_id] : as_range(binfo->get_nodeset_map().equal_range(node)))
      69        2037 :           if (hasBoundary(nodeset_id))
      70         455 :             goto inRestriction;
      71             :       }
      72         757 :       continue;
      73         757 :     }
      74        1212 :   inRestriction:
      75             :     // Check the elements associated with the node to see if they're in the block
      76             :     // we're block-restricting. If so, add the node to the positions vector and move
      77             :     // on to the next node (to minimize duplicates).
      78        3083 :     for (const auto elem_id : elems_ids)
      79             :     {
      80        2558 :       const auto e = _mesh.queryElemPtr(elem_id);
      81        2558 :       if (e && hasBlocks(e->subdomain_id()))
      82             :       {
      83        1142 :         _positions.emplace_back(_mesh.nodeRef(node_id));
      84        1142 :         break;
      85             :       }
      86             :     }
      87             :   }
      88             : 
      89          52 :   _initialized = true;
      90          52 : }
      91             : 
      92             : void
      93          52 : NodePositions::finalize()
      94             : {
      95             :   // Gather up the positions vector on all ranks
      96             :   mooseAssert(initialized(false), "Positions vector has not been initialized.");
      97          52 :   if (_need_broadcast)
      98             :     // The consumer/producer reporter interface can keep track of whether a reduction is needed
      99             :     // (for example if a consumer needs replicated data, but the producer is distributed) however,
     100             :     // we have currently made the decision that positions should ALWAYS be replicated
     101          52 :     _communicator.allgather(_positions, /* identical buffer lengths = */ false);
     102             : 
     103             :   // We always need to sort the positions as nodes on the boundary between different mesh partitions
     104             :   // are duplicated. We sort by X, then Y, then Z, and prune the positions list.
     105          52 :   std::sort(_positions.begin(), _positions.end());
     106          52 :   _positions.erase(std::unique(_positions.begin(), _positions.end()), _positions.end());
     107             : 
     108             :   // Make a KDTree with the positions
     109          52 :   _positions_kd_tree = std::make_unique<KDTree>(_positions, 1);
     110             : 
     111             :   // For now at least, we expect positions to be the same on all ranks
     112             :   mooseAssert(comm().verify(_positions), "Positions should be the same across all MPI processes.");
     113          52 : }

Generated by: LCOV version 1.14