LCOV - code coverage report
Current view: top level - src/positions - NodePositions.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 31 33 93.9 %
Date: 2025-07-17 01:28:37 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       14313 : NodePositions::validParams()
      18             : {
      19       14313 :   InputParameters params = Positions::validParams();
      20       14313 :   params.addClassDescription("Positions of element nodes.");
      21       14313 :   params += BlockRestrictable::validParams();
      22             : 
      23             :   // Element nodes must be sorted to remove duplicates.
      24       14313 :   params.suppressParameter<bool>("auto_sort");
      25       14313 :   params.set<bool>("auto_sort") = true;
      26             :   // Gathered locally, should be broadcast on every process
      27       14313 :   params.set<bool>("auto_broadcast") = true;
      28             : 
      29       14313 :   return params;
      30           0 : }
      31             : 
      32          24 : NodePositions::NodePositions(const InputParameters & parameters)
      33          24 :   : Positions(parameters), BlockRestrictable(this), _mesh(_fe_problem.mesh())
      34             : {
      35             :   // Mesh is ready at construction
      36          24 :   initialize();
      37             :   // Trigger synchronization as the initialization is distributed
      38          24 :   finalize();
      39          24 : }
      40             : 
      41             : void
      42          24 : NodePositions::initialize()
      43             : {
      44          24 :   clearPositions();
      45             : 
      46        1140 :   for (const auto & [node_id, elems_ids] : _fe_problem.mesh().nodeToElemMap())
      47             :   {
      48        1116 :     if (!_mesh.queryNodePtr(node_id))
      49           0 :       continue;
      50             : 
      51             :     // Check the elements associated with the node to see if they're in the block
      52             :     // we're block-restricting. If so, add the node to the positions vector and move
      53             :     // on to the next node (to minimize duplicates).
      54        1984 :     for (const auto elem_id : elems_ids)
      55             :     {
      56        1662 :       const auto e = _mesh.queryElemPtr(elem_id);
      57        1662 :       if (e && hasBlocks(e->subdomain_id()))
      58             :       {
      59         794 :         _positions.emplace_back(_mesh.nodeRef(node_id));
      60         794 :         break;
      61             :       }
      62             :     }
      63             :   }
      64             : 
      65          24 :   _initialized = true;
      66          24 : }
      67             : 
      68             : void
      69          24 : NodePositions::finalize()
      70             : {
      71             :   // Gather up the positions vector on all ranks
      72             :   mooseAssert(initialized(false), "Positions vector has not been initialized.");
      73          24 :   if (_need_broadcast)
      74             :     // The consumer/producer reporter interface can keep track of whether a reduction is needed
      75             :     // (for example if a consumer needs replicated data, but the producer is distributed) however,
      76             :     // we have currently made the decision that positions should ALWAYS be replicated
      77          24 :     _communicator.allgather(_positions, /* identical buffer lengths = */ false);
      78             : 
      79             :   // We always need to sort the positions as nodes on the boundary between different mesh partitions
      80             :   // are duplicated. We sort by X, then Y, then Z, and prune the positions list.
      81          24 :   std::sort(_positions.begin(), _positions.end());
      82          24 :   _positions.erase(std::unique(_positions.begin(), _positions.end()), _positions.end());
      83             : 
      84             :   // Make a KDTree with the positions
      85          24 :   _positions_kd_tree = std::make_unique<KDTree>(_positions, 1);
      86             : 
      87             :   // For now at least, we expect positions to be the same on all ranks
      88             :   mooseAssert(comm().verify(_positions), "Positions should be the same across all MPI processes.");
      89          24 : }

Generated by: LCOV version 1.14