LCOV - code coverage report
Current view: top level - src/dirackernels - DiracKernelInfo.C (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 43 45 95.6 %
Date: 2025-07-17 01:28:37 Functions: 8 9 88.9 %
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 "DiracKernelInfo.h"
      11             : #include "MooseMesh.h"
      12             : 
      13             : // LibMesh
      14             : #include "libmesh/point_locator_base.h"
      15             : #include "libmesh/elem.h"
      16             : #include "libmesh/enum_point_locator_type.h"
      17             : #include "libmesh/point.h"
      18             : 
      19             : using namespace libMesh;
      20             : 
      21       60987 : DiracKernelInfo::DiracKernelInfo()
      22       60987 :   : _point_locator(), _point_equal_distance_sq(libMesh::TOLERANCE * libMesh::TOLERANCE)
      23             : {
      24       60987 : }
      25             : 
      26       56616 : DiracKernelInfo::~DiracKernelInfo() {}
      27             : 
      28             : void
      29      710602 : DiracKernelInfo::addPoint(const Elem * elem, const Point & p)
      30             : {
      31      710602 :   _elements.insert(elem);
      32             : 
      33      710602 :   std::pair<std::vector<Point>, std::vector<unsigned int>> & multi_point_list = _points[elem];
      34             : 
      35      710602 :   const unsigned int npoint = multi_point_list.first.size();
      36             :   mooseAssert(npoint == multi_point_list.second.size(),
      37             :               "Different sizes for location and multiplicity data");
      38             : 
      39      730042 :   for (unsigned int i = 0; i < npoint; ++i)
      40       63215 :     if (pointsFuzzyEqual(multi_point_list.first[i], p))
      41             :     {
      42             :       // a point at the same (within a tolerance) location as p exists, increase its multiplicity
      43       43775 :       multi_point_list.second[i]++;
      44       43775 :       return;
      45             :     }
      46             : 
      47             :   // no prior point found at this location, add it with a multiplicity of one
      48      666827 :   multi_point_list.first.push_back(p);
      49      666827 :   multi_point_list.second.push_back(1);
      50             : }
      51             : 
      52             : void
      53     3715306 : DiracKernelInfo::clearPoints()
      54             : {
      55     3715306 :   _elements.clear();
      56     3715306 :   _points.clear();
      57     3715306 : }
      58             : 
      59             : bool
      60      315754 : DiracKernelInfo::hasPoint(const Elem * elem, const Point & p)
      61             : {
      62      315754 :   std::vector<Point> & point_list = _points[elem].first;
      63             : 
      64      324394 :   for (const auto & pt : point_list)
      65      324394 :     if (pointsFuzzyEqual(pt, p))
      66      315754 :       return true;
      67             : 
      68             :   // If we haven't found it, we don't have it.
      69           0 :   return false;
      70             : }
      71             : 
      72             : void
      73      156844 : DiracKernelInfo::updatePointLocator(const MooseMesh & mesh)
      74             : {
      75             :   // Note: we could update the PointLocator *every* time we call this
      76             :   // function, but that may introduce an unacceptable overhead in
      77             :   // problems which don't need a PointLocator at all.  This issue will
      78             :   // most likely become a moot point when we eventually add a shared
      79             :   // "CachingPointLocator" to MOOSE.
      80             :   // _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
      81             : 
      82             :   // Construct the PointLocator object if *any* processors have Dirac
      83             :   // points.  Note: building a PointLocator object is a parallel_only()
      84             :   // function, so this is an all-or-nothing thing.
      85      156844 :   unsigned pl_needs_rebuild = _elements.size();
      86      156844 :   mesh.comm().max(pl_needs_rebuild);
      87             : 
      88      156844 :   if (pl_needs_rebuild)
      89             :   {
      90             :     // PointLocatorBase::build() is a parallel_only function!  So we
      91             :     // can't skip building it just becuase our local _elements is
      92             :     // empty, it might be non-empty on some other processor!
      93        2379 :     _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
      94             : 
      95             :     // We may be querying for points which are not in the semilocal
      96             :     // part of a distributed mesh.
      97        2379 :     _point_locator->enable_out_of_mesh_mode();
      98             :   }
      99             :   else
     100             :   {
     101             :     // There are no elements with Dirac points, but we have been
     102             :     // requested to update the PointLocator so we have to assume the
     103             :     // old one is invalid.  Therefore we reset it to NULL... however
     104             :     // adding this line causes the code to hang because it triggers
     105             :     // the PointLocator to be rebuilt in a non-parallel-only segment
     106             :     // of the code later... so it's commented out for now even though
     107             :     // it's probably the right behavior.
     108             :     // _point_locator.reset(NULL);
     109             :   }
     110      156844 : }
     111             : 
     112             : const Elem *
     113       41247 : DiracKernelInfo::findPoint(const Point & p,
     114             :                            const MooseMesh & mesh,
     115             :                            const std::set<SubdomainID> & blocks)
     116             : {
     117             :   // If the PointLocator has never been created, do so now.  NOTE - WE
     118             :   // CAN'T DO THIS if findPoint() is only called on some processors,
     119             :   // PointLocatorBase::build() is a 'parallel_only' method!
     120       41247 :   if (_point_locator.get() == NULL)
     121             :   {
     122         543 :     _point_locator = PointLocatorBase::build(TREE_LOCAL_ELEMENTS, mesh);
     123         543 :     _point_locator->enable_out_of_mesh_mode();
     124             :   }
     125             : 
     126             :   // Check that the PointLocator is ready to start locating points.
     127             :   // So far I do not have any tests that trip this...
     128       41247 :   if (_point_locator->initialized() == false)
     129           0 :     mooseError("Error, PointLocator is not initialized!");
     130             : 
     131             :   // Note: The PointLocator object returns NULL when the Point is not
     132             :   // found within the Mesh.  This is not considered to be an error as
     133             :   // far as the DiracKernels are concerned: sometimes the Mesh moves
     134             :   // out from the Dirac point entirely and in that case the Point just
     135             :   // gets "deactivated".
     136       41247 :   const Elem * elem = (*_point_locator)(p, &blocks);
     137             : 
     138             :   // The processors may not agree on which Elem the point is in.  This
     139             :   // can happen if a Dirac point lies on the processor boundary, and
     140             :   // two or more neighboring processors think the point is in the Elem
     141             :   // on *their* side.
     142       41247 :   dof_id_type elem_id = elem ? elem->id() : DofObject::invalid_id;
     143             : 
     144             :   // We are going to let the element with the smallest ID "win", all other
     145             :   // procs will return NULL.
     146       41247 :   dof_id_type min_elem_id = elem_id;
     147       41247 :   mesh.comm().min(min_elem_id);
     148             : 
     149       41247 :   return min_elem_id == elem_id ? elem : NULL;
     150             : }
     151             : 
     152             : bool
     153      387609 : DiracKernelInfo::pointsFuzzyEqual(const Point & a, const Point & b)
     154             : {
     155      387609 :   const Real dist_sq = (a - b).norm_sq();
     156      387609 :   return dist_sq < _point_equal_distance_sq;
     157             : }

Generated by: LCOV version 1.14