LCOV - code coverage report
Current view: top level - include/userobjects - RayTracingStudy.h (source / functions) Hit Total Coverage
Test: idaholab/moose ray_tracing: #31405 (292dce) with base fef103 Lines: 59 59 100.0 %
Date: 2025-09-04 07:56:07 Functions: 13 13 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             : #pragma once
      11             : 
      12             : #include "GeneralUserObject.h"
      13             : 
      14             : // Local Includes
      15             : #include "ElemIndexHelper.h"
      16             : #include "ParallelRayStudy.h"
      17             : #include "RayTracingAttributes.h"
      18             : #include "TraceData.h"
      19             : #include "TraceRayBndElement.h"
      20             : 
      21             : // MOOSE Includes
      22             : #include "TheWarehouse.h"
      23             : 
      24             : // libMesh includes
      25             : #include "libmesh/mesh.h"
      26             : #include "libmesh/elem_side_builder.h"
      27             : 
      28             : // Forward Declarations
      29             : class RayBoundaryConditionBase;
      30             : class RayKernelBase;
      31             : class TraceRay;
      32             : class RayTracingObject;
      33             : 
      34             : /**
      35             :  * Base class for Ray tracing studies that will generate Rays and then propagate
      36             :  * all of them to termination.
      37             :  *
      38             :  * Subclasses _must_ override generateRays()
      39             :  */
      40             : class RayTracingStudy : public GeneralUserObject
      41             : {
      42             : public:
      43             :   RayTracingStudy(const InputParameters & parameters);
      44             : 
      45             :   /**
      46             :    * Key that is used for restricting access to acquireRayInternal().
      47             :    *
      48             :    * In general, we restrict access to the construction of Rays to only protected
      49             :    * methods within RayTracingStudy. However, there are a few classes/functions
      50             :    * that have a legimate reason to construct Rays. Here, the friends are said
      51             :    * classes/functions.
      52             :    */
      53             :   class AcquireRayInternalKey
      54             :   {
      55             :     friend class Parallel::Packing<std::shared_ptr<Ray>>;
      56             :     friend void dataLoad(std::istream & stream, std::shared_ptr<Ray> & ray, void * context);
      57             :     AcquireRayInternalKey() {}
      58             :     AcquireRayInternalKey(const AcquireRayInternalKey &) {}
      59             :   };
      60             : 
      61             :   /**
      62             :    * Key that is used for restricting access to moveRayToBufferDuringTrace() and
      63             :    * acquireRayDuringTrace().
      64             :    */
      65             :   class AcquireMoveDuringTraceKey
      66             :   {
      67             :     friend class RayBoundaryConditionBase;
      68             :     friend class RayKernelBase;
      69             :     AcquireMoveDuringTraceKey() {}
      70             :     AcquireMoveDuringTraceKey(const AcquireMoveDuringTraceKey &) {}
      71             :   };
      72             : 
      73             :   static InputParameters validParams();
      74             : 
      75             :   virtual void initialSetup() override;
      76             :   virtual void residualSetup() override;
      77             :   virtual void jacobianSetup() override;
      78             :   virtual void meshChanged() override;
      79             :   virtual void timestepSetup() override;
      80        8208 :   virtual void initialize() override {}
      81        8108 :   virtual void finalize() override {}
      82             : 
      83             :   /**
      84             :    * Executes the study (generates and propagates Rays)
      85             :    */
      86             :   virtual void execute() override;
      87             : 
      88             :   /**
      89             :    * Setup for on subdomain change or subdomain AND ray change during ray tracing
      90             :    * @param subdomain The subdomain changed to
      91             :    * @param tid Thread id
      92             :    * @param ray_id ID of the ray initiating the change
      93             :    */
      94             :   virtual void
      95             :   segmentSubdomainSetup(const SubdomainID subdomain, const THREAD_ID tid, const RayID ray_id);
      96             : 
      97             :   /**
      98             :    * Reinitialize objects for a Ray segment for ray tracing
      99             :    * @param elem The elem the segment is in
     100             :    * @param start Start point of the segment
     101             :    * @param end End point of the segment
     102             :    * @param length The length of the start -> end segment
     103             :    * @param tid Thread id
     104             :    */
     105             :   virtual void reinitSegment(
     106             :       const Elem * elem, const Point & start, const Point & end, const Real length, THREAD_ID tid);
     107             : 
     108             :   /**
     109             :    * Called at the end of a Ray segment
     110             :    * @param tid Thread id
     111             :    * @param ray The ray
     112             :    */
     113             :   virtual void postOnSegment(const THREAD_ID tid, const std::shared_ptr<Ray> & ray);
     114             : 
     115             :   /**
     116             :    * Called at the beginning of a trace for a ray
     117             :    * @param tid Thread id
     118             :    * @param ray The ray
     119             :    */
     120     5380196 :   virtual void preTrace(const THREAD_ID /* tid */, const std::shared_ptr<Ray> & /* ray */) {}
     121             : 
     122             :   /**
     123             :    * Method for executing the study so that it can be called out of the standard UO execute()
     124             :    */
     125             :   void executeStudy();
     126             : 
     127             :   /**
     128             :    * Total number of processor crossings for Rays that finished on this processor
     129             :    */
     130             :   unsigned long long int endingProcessorCrossings() const { return _ending_processor_crossings; }
     131             :   /**
     132             :    * Max number of total processor crossings for Rays that finished on this processor
     133             :    */
     134             :   unsigned int endingMaxProcessorCrossings() const { return _ending_max_processor_crossings; }
     135             :   /**
     136             :    * Total number of processor crossings
     137             :    */
     138          14 :   unsigned long long int totalProcessorCrossings() const { return _total_processor_crossings; }
     139             :   /**
     140             :    * Max number of processor crossings for all Rays
     141             :    */
     142          14 :   unsigned int maxProcessorCrossings() const { return _max_processor_crossings; }
     143             : 
     144             :   /**
     145             :    * Total number of Ray/element intersections for Rays that finished on this processor
     146             :    */
     147             :   unsigned long long int endingIntersections() const { return _ending_intersections; }
     148             :   /**
     149             :    * Max number of intersections for Rays that finished on this processor
     150             :    */
     151             :   unsigned int endingMaxIntersections() const { return _ending_max_intersections; }
     152             :   /**
     153             :    * Total number of Ray/element intersections
     154             :    */
     155             :   unsigned long long int totalIntersections() const { return _total_intersections; }
     156             :   /**
     157             :    * Max number of intersections for a Ray
     158             :    */
     159             :   unsigned int maxIntersections() const { return _max_intersections; }
     160             :   /**
     161             :    * Max number of trajectory changes for a Ray
     162             :    */
     163             :   unsigned int maxTrajectoryChanges() const { return _max_trajectory_changes; }
     164             : 
     165             :   /**
     166             :    * Total amount of distance traveled by the rays that end on this processor
     167             :    */
     168             :   Real endingDistance() const { return _ending_distance; }
     169             :   /**
     170             :    * Total distance traveled by all Rays
     171             :    */
     172        2266 :   Real totalDistance() const { return _total_distance; }
     173             : 
     174             :   unsigned long long int localTraceRayResult(const int result) const
     175             :   {
     176         196 :     return _local_trace_ray_results[result];
     177             :   }
     178             : 
     179             :   const ParallelRayStudy & parallelRayStudy() const { return *_parallel_ray_study; }
     180             : 
     181             :   /**
     182             :    * Max distance any Ray can travel
     183             :    */
     184    35293907 :   Real rayMaxDistance() const { return _ray_max_distance; }
     185             : 
     186             :   /**
     187             :    * Duration for execute() in seconds
     188             :    */
     189             :   Real executionTime() { return std::chrono::duration<Real>(_execution_time).count(); }
     190             :   /**
     191             :    * Duration for execute() in nanoseconds
     192             :    */
     193             :   Real executionTimeNano()
     194             :   {
     195             :     return std::chrono::duration<Real, std::nano>(_execution_time).count();
     196             :   }
     197             :   /**
     198             :    * Duration for creation of all Rays in seconds
     199             :    */
     200             :   Real generationTime() const { return std::chrono::duration<Real>(_generation_time).count(); }
     201             :   /**
     202             :    * Duration for creation of all Rays in seconds
     203             :    */
     204             :   Real propagationTime() const { return std::chrono::duration<Real>(_propagation_time).count(); }
     205             : 
     206             :   /**
     207             :    * Whether or not to tolerate failure
     208             :    */
     209           9 :   bool tolerateFailure() const { return _tolerate_failure; }
     210             : 
     211             :   /**
     212             :    * Whether or not to bank Rays on completion
     213             :    */
     214         810 :   bool bankRaysOnCompletion() const { return _bank_rays_on_completion; }
     215             : 
     216             :   /**
     217             :    * Whether or not to use Ray dependent subdomain setup
     218             :    */
     219     5370064 :   bool rayDependentSubdomainSetup() const { return _ray_dependent_subdomain_setup; }
     220             : 
     221             :   /**
     222             :    * Register a value to be filled in the data on a Ray with a given name.
     223             :    * @param name The name to register
     224             :    * \return The Ray data index for the registered value
     225             :    *
     226             :    * Note that this does not actually allocate the storage. It is simply a registration system to
     227             :    * keep track of the values stored in the Ray data.
     228             :    */
     229             :   RayDataIndex registerRayData(const std::string & name);
     230             :   /**
     231             :    * Register values to be filled in the data on a Ray with a given name.
     232             :    * @param names The names to register
     233             :    * \return The Ray data indices for the registered value
     234             :    *
     235             :    * Note that this does not actually allocate the storage. It is simply a registration system to
     236             :    * keep track of the values stored in the Ray data.
     237             :    */
     238             :   std::vector<RayDataIndex> registerRayData(const std::vector<std::string> & names);
     239             :   /**
     240             :    * Gets the index associated with a registered value in the Ray data
     241             :    * @param name The value name to get the index of
     242             :    * @param graceful Whether or not to exit gracefully if none is found (return
     243             :    * INVALID_RAY_DATA_INDEX)
     244             :    * \return The index for the value
     245             :    */
     246             :   RayDataIndex getRayDataIndex(const std::string & name, const bool graceful = false) const;
     247             :   /**
     248             :    * Gets the indices associated with registered values in the Ray data
     249             :    * @param names The value names to get the indices of
     250             :    * @param graceful Whether or not to exit gracefully if none is found (index is filled with
     251             :    * INVALID_RAY_DATA_INDEX)
     252             :    * \return The indices for the values
     253             :    */
     254             :   std::vector<RayDataIndex> getRayDataIndices(const std::vector<std::string> & names,
     255             :                                               const bool graceful = false) const;
     256             :   /**
     257             :    * Gets the name associated with a registered value in the Ray data
     258             :    * @param index The index to get the name of
     259             :    * \return The name associated with index
     260             :    */
     261             :   const std::string & getRayDataName(const RayDataIndex index) const;
     262             :   /**
     263             :    * Gets the names associated with registered values in the Ray data
     264             :    * @param indices The indices to get the names of
     265             :    * \return The associated names
     266             :    */
     267             :   std::vector<std::string> getRayDataNames(const std::vector<RayDataIndex> & indices) const;
     268             : 
     269             :   /**
     270             :    * The registered size of values in the Ray data.
     271             :    */
     272             :   std::size_t rayDataSize() const { return _ray_data_names.size(); }
     273             :   /**
     274             :    * Whether or not any Ray data are registered
     275             :    */
     276             :   bool hasRayData() const { return _ray_data_names.size(); }
     277             :   /**
     278             :    * The Ray data names
     279             :    */
     280         190 :   const std::vector<std::string> & rayDataNames() const { return _ray_data_names; }
     281             : 
     282             :   /**
     283             :    * Register a value to be filled in the aux data on a Ray with a given name.
     284             :    * @param name The name to register
     285             :    * \returns The Ray aux data index for the registered value
     286             :    *
     287             :    * Note that this does not actually allocate the storage. It is simply a registration system to
     288             :    * keep track of the values stored in the Ray aux data.
     289             :    */
     290             :   RayDataIndex registerRayAuxData(const std::string & name);
     291             :   /**
     292             :    * Register values to be filled in the aux data on a Ray with a given name.
     293             :    * @param names The names to register
     294             :    * \returns The Ray aux data indices for the registered values
     295             :    *
     296             :    * Note that this does not actually allocate the storage. It is simply a registration system to
     297             :    * keep track of the values stored in the Ray aux data.
     298             :    */
     299             :   std::vector<RayDataIndex> registerRayAuxData(const std::vector<std::string> & names);
     300             :   /**
     301             :    * Gets the index associated with a registered value in the Ray aux data
     302             :    * @param name The value name to get the index of
     303             :    * @param graceful Whether or not to exit gracefully if none is found (return
     304             :    * INVALID_RAY_DATA_INDEX)
     305             :    * \returns The index for the value
     306             :    */
     307             :   RayDataIndex getRayAuxDataIndex(const std::string & name, const bool graceful = false) const;
     308             :   /**
     309             :    * Gets the indices associated with registered values in the Ray aux data
     310             :    * @param names The value names to get the indices of
     311             :    * @param graceful Whether or not to exit gracefully if none is found (index is filled with
     312             :    * INVALID_RAY_DATA_INDEX)
     313             :    * \return The indices for the values
     314             :    */
     315             :   std::vector<RayDataIndex> getRayAuxDataIndices(const std::vector<std::string> & names,
     316             :                                                  const bool graceful = false) const;
     317             :   /**
     318             :    * Gets the name associated with a registered value in the Ray aux data
     319             :    * @param index The index to get the name of
     320             :    * \return The name associated with index
     321             :    */
     322             :   const std::string & getRayAuxDataName(const RayDataIndex index) const;
     323             :   /**
     324             :    * Gets the names associated with registered values in the Ray aux data
     325             :    * @param indices The indices to get the names of
     326             :    * \return The associated names
     327             :    */
     328             :   std::vector<std::string> getRayAuxDataNames(const std::vector<RayDataIndex> & indices) const;
     329             :   /**
     330             :    * The registered size of values in the Ray aux data.
     331             :    */
     332             :   std::size_t rayAuxDataSize() const { return _ray_aux_data_names.size(); }
     333             :   /**
     334             :    * Whether or not any Ray aux data are registered
     335             :    */
     336             :   bool hasRayAuxData() const { return _ray_aux_data_names.size(); }
     337             :   /**
     338             :    * The Ray aux data names
     339             :    */
     340          82 :   const std::vector<std::string> & rayAuxDataNames() const { return _ray_aux_data_names; }
     341             : 
     342             :   /**
     343             :    * Whether or not there are currently any active RayKernel objects
     344             :    */
     345             :   bool hasRayKernels(const THREAD_ID tid);
     346             :   /**
     347             :    * Fills the active RayKernels associated with this study and a block into result
     348             :    */
     349             :   void getRayKernels(std::vector<RayKernelBase *> & result, SubdomainID id, THREAD_ID tid);
     350             :   /**
     351             :    * Fills the active RayKernels associated with this study into result
     352             :    */
     353             :   template <typename T>
     354       28717 :   void getRayKernels(std::vector<T *> & result, THREAD_ID tid)
     355             :   {
     356       28717 :     _fe_problem.theWarehouse()
     357             :         .query()
     358       57434 :         .condition<AttribRayTracingStudy>(this)
     359       28717 :         .condition<AttribSystem>("RayKernel")
     360       28717 :         .condition<AttribThread>(tid)
     361             :         .queryInto(result);
     362       28717 :   }
     363             :   /**
     364             :    * Fills the active RayKernels associeted with this study, block, and potentially Ray into result
     365             :    */
     366             :   void
     367             :   getRayKernels(std::vector<RayKernelBase *> & result, SubdomainID id, THREAD_ID tid, RayID ray_id);
     368             :   /**
     369             :    * Fills the active RayBCs associated with this study and a boundary into result
     370             :    */
     371             :   void getRayBCs(std::vector<RayBoundaryConditionBase *> & result, BoundaryID id, THREAD_ID tid);
     372             :   /**
     373             :    * Fills the active RayBCs associated with this study and boundaries result
     374             :    */
     375             :   template <typename T>
     376       86375 :   void getRayBCs(std::vector<T *> & result, const std::vector<BoundaryID> & ids, THREAD_ID tid)
     377             :   {
     378       86375 :     _fe_problem.theWarehouse()
     379             :         .query()
     380      172750 :         .condition<AttribRayTracingStudy>(this)
     381       86375 :         .condition<AttribSystem>("RayBoundaryCondition")
     382       86375 :         .condition<AttribBoundaries>(ids)
     383       86375 :         .condition<AttribThread>(tid)
     384             :         .queryInto(result);
     385       86375 :   }
     386             :   /**
     387             :    * Fills the active RayBCs associated with this study into result
     388             :    */
     389             :   template <typename T>
     390        3705 :   void getRayBCs(std::vector<T *> & result, THREAD_ID tid)
     391             :   {
     392        3705 :     _fe_problem.theWarehouse()
     393             :         .query()
     394        7410 :         .condition<AttribRayTracingStudy>(this)
     395        3705 :         .condition<AttribSystem>("RayBoundaryCondition")
     396        3705 :         .condition<AttribThread>(tid)
     397             :         .queryInto(result);
     398        3705 :   }
     399             :   /**
     400             :    * Fills the active RayBCs associated with thie study, boundary elements, and potentially Ray into
     401             :    * result.
     402             :    *
     403             :    * This is purposely virtual because it allows derived studies to optimize the retrieval of RayBCs
     404             :    * during the trace in TraceRay.
     405             :    */
     406             :   virtual void getRayBCs(std::vector<RayBoundaryConditionBase *> & result,
     407             :                          const std::vector<TraceRayBndElement> & bnd_elems,
     408             :                          THREAD_ID tid,
     409             :                          RayID ray_id);
     410             : 
     411             :   /**
     412             :    * Gets the current RayKernels for a thread, which are set in segmentSubdomainSetup()
     413             :    */
     414             :   const std::vector<RayKernelBase *> & currentRayKernels(THREAD_ID tid) const
     415             :   {
     416   111920756 :     return _threaded_current_ray_kernels[tid];
     417             :   }
     418             : 
     419             :   /**
     420             :    * Get the nodal bounding box for the domain
     421             :    */
     422     4118378 :   const BoundingBox & boundingBox() const { return _b_box; }
     423             :   /**
     424             :    * Get the loose nodal bounding box for the domain
     425             :    *
     426             :    * BoundingBox::contains_point does not have a tolerance, so we need to stretch the
     427             :    * box a little bit for some contains_point checks.
     428             :    */
     429    13528053 :   const BoundingBox & looseBoundingBox() const { return _loose_b_box; }
     430             :   /**
     431             :    * Get the inflated maximum length across the domain
     432             :    */
     433   177110859 :   Real domainMaxLength() const { return _domain_max_length; }
     434             :   /**
     435             :    * Get the current total volume of the domain
     436             :    */
     437       12485 :   Real totalVolume() const { return _total_volume; }
     438             :   /**
     439             :    * Whether or not the domain is rectangular (if it is prefectly encompassed by its bounding box)
     440             :    */
     441             :   bool isRectangularDomain() const;
     442             : 
     443             :   /**
     444             :    * Whether or not the local mesh has internal sidesets that have RayBCs on them
     445             :    *
     446             :    * NOTE: if useInternalSidesets() == false, this will be false even if the mesh does
     447             :    * have internal sidesets
     448             :    */
     449             :   bool hasInternalSidesets() const { return _internal_sidesets.size(); }
     450             :   /**
     451             :    * Get the internal sidesets (that have RayBC(s)) for each side for a given element
     452             :    *
     453             :    * This will be empty if the elem does not have any internal sidesets that have RayBC(s)
     454             :    */
     455             :   const std::vector<std::vector<BoundaryID>> & getInternalSidesets(const Elem * elem) const;
     456             :   /**
     457             :    * Gets the internal sidesets (that have RayBCs) within the local domain
     458             :    */
     459             :   const std::set<BoundaryID> & getInternalSidesets() const { return _internal_sidesets; }
     460             :   /**
     461             :    * Whether or not the side \s on elem \p elem is non-planar
     462             :    *
     463             :    * This is cached because checking whether or not a face is planar is costly
     464             :    */
     465    14380501 :   bool sideIsNonPlanar(const Elem * elem, const unsigned short s) const
     466             :   {
     467    14380501 :     return _has_non_planar_sides && _non_planar_sides[_elem_index_helper.getIndex(elem)][s] == 1;
     468             :   }
     469             :   /**
     470             :    * Whether or not the mesh has active elements of the same level
     471             :    *
     472             :    * Use this over sameLevelActiveElems(), which is for internally setting
     473             :    * _has_same_level_active_elems
     474             :    */
     475    63749280 :   bool hasSameLevelActiveElems() const { return _has_same_level_active_elems; }
     476             : 
     477             :   /**
     478             :    * INTERNAL methods for acquiring a Ray during a trace in RayKernels and RayBCs.
     479             :    *
     480             :    * You should not use these APIs directly. If you wish to acquire a Ray during generation
     481             :    * during generateRays()), use the protected RayTracingStudy::acquire{}Ray() methods.
     482             :    * If you wish to acquire a Ray during propagation in RayKernels and RayBC, use the
     483             :    * protected RayKernelBase::acquireRay() and RayBoundaryConditionBase::acquireRay(),
     484             :    * respectively.
     485             :    */
     486             :   ///@{
     487             :   std::shared_ptr<Ray> acquireRayDuringTrace(const THREAD_ID tid,
     488             :                                              const AcquireMoveDuringTraceKey &);
     489     3925497 :   std::shared_ptr<Ray> acquireRayInternal(const RayID id,
     490             :                                           const std::size_t data_size,
     491             :                                           const std::size_t aux_data_size,
     492             :                                           const bool reset,
     493             :                                           const AcquireRayInternalKey &)
     494             :   {
     495     3925497 :     return _parallel_ray_study->acquireParallelData(
     496     7850994 :         0, this, id, data_size, aux_data_size, reset, Ray::ConstructRayKey());
     497             :   }
     498             :   ///@}
     499             : 
     500             :   /**
     501             :    * INTERNAL method for moving a Ray into the buffer during tracing.
     502             :    *
     503             :    * You should not and cannot use this API. It is protected by the
     504             :    * AcquireMoveDuringTraceKey, which is only constructable by
     505             :    * RayKernelBase and RayBoundaryConditionBase.
     506             :    */
     507             :   void moveRayToBufferDuringTrace(std::shared_ptr<Ray> & ray,
     508             :                                   const THREAD_ID tid,
     509             :                                   const AcquireMoveDuringTraceKey &);
     510             :   /**
     511             :    * Access to the libMesh MeshBase.
     512             :    *
     513             :    * This is needed for unpack routines for a Ray, which has a context of this study.
     514             :    */
     515     5202717 :   MeshBase & meshBase() const { return _mesh; }
     516             : 
     517             :   /**
     518             :    * @returns A reference to the MooseMesh associated with this study.
     519             :    */
     520        3614 :   MooseMesh & mesh() { return _mesh; }
     521             : 
     522             :   /**
     523             :    * Get the outward normal for a given element side.
     524             :    */
     525             :   virtual const Point &
     526             :   getSideNormal(const Elem * elem, const unsigned short side, const THREAD_ID tid);
     527             :   /**
     528             :    * Gets the outward normals for a given element.
     529             :    * Returns a pointer to the normal for the zeroth side.
     530             :    */
     531           2 :   virtual const Point * getElemNormals(const Elem * /* elem */, const THREAD_ID /* tid */)
     532             :   {
     533           2 :     mooseError("Unimplemented element normal caching in ", type(), "::getElemNormals()");
     534             :   }
     535             : 
     536             :   /**
     537             :    * Gets the data value for a banked ray with a given ID
     538             :    *
     539             :    * This will return the value replicated across all processors
     540             :    */
     541             :   RayData getBankedRayData(const RayID ray_id, const RayDataIndex index) const;
     542             :   /**
     543             :    * Gets the data value for a banked ray with a given ID
     544             :    *
     545             :    * This will return the value replicated across all processors
     546             :    */
     547             :   RayData getBankedRayAuxData(const RayID ray_id, const RayDataIndex index) const;
     548             : 
     549             :   /**
     550             :    * Gets the ID of a registered ray
     551             :    * @param name The name of said ray
     552             :    * @param graceful Whether or not to exit gracefully if none is found (with invalid_id)
     553             :    */
     554             :   RayID registeredRayID(const std::string & name, const bool graceful = false) const;
     555             :   /**
     556             :    * Gets the name of a registered ray
     557             :    * @param ray_id The ID of said ray
     558             :    */
     559             :   const std::string & registeredRayName(const RayID ray_id) const;
     560             : 
     561             :   /**
     562             :    * Whether or not ray registration is being used
     563             :    */
     564        4501 :   bool useRayRegistration() const { return _use_ray_registration; }
     565             : 
     566             :   /**
     567             :    * Whether or not to store the Ray data on the cached Ray traces
     568             :    */
     569       72358 :   bool dataOnCacheTraces() const { return _data_on_cache_traces; }
     570             :   /**
     571             :    * Whether or not to store the Ray aux data on the cached Ray traces
     572             :    */
     573       72268 :   bool auxDataOnCacheTraces() const { return _aux_data_on_cache_traces; }
     574             :   /**
     575             :    *  Whether or not to cache individual element segments when _cache_traces = true
     576             :    */
     577       62181 :   bool segmentsOnCacheTraces() const { return _segments_on_cache_traces; }
     578             : 
     579             :   /**
     580             :    * Virtual that allows for selection in if a Ray should be cached or not (only used when
     581             :    * _cache_traces).
     582             :    */
     583     5380196 :   virtual bool shouldCacheTrace(const std::shared_ptr<Ray> & /* ray */) const
     584             :   {
     585     5380196 :     return _always_cache_traces;
     586             :   }
     587             : 
     588             :   /**
     589             :    * Initialize a Ray in the threaded cached trace map to be filled with segments
     590             :    */
     591             :   TraceData & initThreadedCachedTrace(const std::shared_ptr<Ray> & ray, THREAD_ID tid);
     592             :   /**
     593             :    * Get the cached trace data structure
     594             :    */
     595             :   const std::vector<TraceData> & getCachedTraces() const { return _cached_traces; }
     596             : 
     597             :   /**
     598             :    * Get the cached hmax for all elements in a subdomain
     599             :    *
     600             :    * Used for scaling tolerances in ray tracing.
     601             :    */
     602             :   Real subdomainHmax(const SubdomainID subdomain_id) const;
     603             : 
     604             :   /**
     605             :    * Entry point for acting on a ray when it is completed (shouldContinue() == false)
     606             :    */
     607             :   virtual void onCompleteRay(const std::shared_ptr<Ray> & ray);
     608             : 
     609             :   /**
     610             :    * Verifies that the Rays in the given range have unique Ray IDs.
     611             :    *
     612             :    * @param begin The beginning of the range of Rays to check
     613             :    * @param end The end of the range of Rays to check
     614             :    * @param global If true, this will complete the verification across all processors
     615             :    * @param error_suffix Entry point for additional information in the error message
     616             :    */
     617             :   void verifyUniqueRayIDs(const std::vector<std::shared_ptr<Ray>>::const_iterator begin,
     618             :                           const std::vector<std::shared_ptr<Ray>>::const_iterator end,
     619             :                           const bool global,
     620             :                           const std::string & error_suffix) const;
     621             : 
     622             :   /**
     623             :    * Verifies that the Rays in the given range are unique. That is, that there are not multiple
     624             :    * shared_ptrs that point to the same Ray
     625             :    *
     626             :    * @param begin The beginning of the range of Rays to check
     627             :    * @param end The end of the range of Rays to check
     628             :    * @param error_suffix Entry point for additional information in the error message
     629             :    */
     630             :   void verifyUniqueRays(const std::vector<std::shared_ptr<Ray>>::const_iterator begin,
     631             :                         const std::vector<std::shared_ptr<Ray>>::const_iterator end,
     632             :                         const std::string & error_suffix);
     633             : 
     634             :   /**
     635             :    * Whether or not the study is propagating (tracing Rays)
     636             :    */
     637             :   bool currentlyPropagating() const { return _parallel_ray_study->currentlyExecuting(); }
     638             :   /**
     639             :    * Whether or not the study is generating
     640             :    */
     641             :   bool currentlyGenerating() const { return _parallel_ray_study->currentlyPreExecuting(); }
     642             : 
     643             :   /**
     644             :    * Gets the threaded TraceRay object for \p tid.
     645             :    */
     646             :   ///@{
     647          44 :   TraceRay & traceRay(const THREAD_ID tid) { return *_threaded_trace_ray[tid]; }
     648        8443 :   const TraceRay & traceRay(const THREAD_ID tid) const { return *_threaded_trace_ray[tid]; }
     649             :   ///@}
     650             : 
     651             :   /**
     652             :    * Whether or not to verify if Rays have valid information before being traced
     653             :    */
     654    18926369 :   bool verifyRays() const { return _verify_rays; }
     655             :   /**
     656             :    * Whether or not trace verification is enabled in devel/dbg modes
     657             :    */
     658             : #ifndef NDEBUG
     659             :   bool verifyTraceIntersections() const { return _verify_trace_intersections; }
     660             : #endif
     661             : 
     662             :   /**
     663             :    * Whether or not \p side is incoming on element \p elem in direction \p direction.
     664             :    */
     665             :   bool sideIsIncoming(const Elem * const elem,
     666             :                       const unsigned short side,
     667             :                       const Point & direction,
     668             :                       const THREAD_ID tid);
     669             : 
     670             :   /**
     671             :    * Whether or not to produce a warning when interacting with a non-planar mesh.
     672             :    */
     673             :   bool warnNonPlanar() const { return _warn_non_planar; }
     674             : 
     675             :   /**
     676             :    * The underlying parallel study: used for the context for calling the packed range routines.
     677             :    */
     678             :   ParallelStudy<std::shared_ptr<Ray>, Ray> * parallelStudy() { return _parallel_ray_study.get(); }
     679             : 
     680             :   /**
     681             :    * Get an element's side pointer without excessive memory allocation
     682             :    *
     683             :    * @param elem The element to build a side for
     684             :    * @param s The side to build
     685             :    * @param tid The thread id
     686             :    * @return A pointer to the side element
     687             :    */
     688             :   const libMesh::Elem &
     689             :   elemSide(const libMesh::Elem & elem, const unsigned int s, const THREAD_ID tid = 0)
     690             :   {
     691     3092126 :     return _threaded_elem_side_builders[tid](elem, s);
     692             :   }
     693             : 
     694             : protected:
     695             :   /**
     696             :    * Subclasses should override this to determine how to generate Rays.
     697             :    * This will be called within execute() and makes up the "generation phase"
     698             :    * of the algorithm.
     699             :    */
     700             :   virtual void generateRays() = 0;
     701             : 
     702             :   /**
     703             :    * Entry point before study execution
     704             :    */
     705        8023 :   virtual void preExecuteStudy() {}
     706             :   /**
     707             :    * Entry point after study execution
     708             :    */
     709        7567 :   virtual void postExecuteStudy() {}
     710             : 
     711             :   /**
     712             :    * Helper function for computing the total domain volume
     713             :    */
     714             :   Real computeTotalVolume();
     715             : 
     716             :   /**
     717             :    * Gets the writeable current RayKernels for a thread
     718             :    *
     719             :    * Allows for other ray studies to fill the current ray kernels in a custom manner
     720             :    */
     721             :   std::vector<RayKernelBase *> & currentRayKernelsWrite(THREAD_ID tid)
     722             :   {
     723             :     return _threaded_current_ray_kernels[tid];
     724             :   }
     725             : 
     726             :   /**
     727             :    * Reserve \p size entires in the Ray buffer.
     728             :    *
     729             :    * This can only be used within generateRays() and should be used when possible
     730             :    * to reserve entires in the buffer before adding Rays via moveRay(s)ToBuffer.
     731             :    */
     732             :   void reserveRayBuffer(const std::size_t size);
     733             : 
     734             :   /**
     735             :    * Determine whether or not the mesh currently has active elements that are
     736             :    * all the same level
     737             :    */
     738             :   bool sameLevelActiveElems() const;
     739             : 
     740             :   /**
     741             :    * Builds quadrature points for a given segment using the _segment_qrule
     742             :    * @param start Start point of the segment
     743             :    * @param end End point of the segment
     744             :    * @param length The lengh of the start -> end segment
     745             :    * @param points Points to fill into (should be sized ahead of time)
     746             :    * @param weights Weights to fill into (should be sized ahead of time)
     747             :    */
     748             :   virtual void buildSegmentQuadrature(const Point & start,
     749             :                                       const Point & end,
     750             :                                       const Real length,
     751             :                                       std::vector<Point> & points,
     752             :                                       std::vector<Real> & weights) const;
     753             : 
     754             :   /**
     755             :    * Get the Ray bank. This is the bank of Rays that have completed on this processor
     756             :    * after an execution of the study.
     757             :    *
     758             :    * This is only available when the private parameter _bank_rays_on_completion
     759             :    * is set to true.
     760             :    */
     761             :   const std::vector<std::shared_ptr<Ray>> & rayBank() const;
     762             : 
     763             :   /**
     764             :    * Gets the Ray with the ID \p ray_id from the Ray bank.
     765             :    *
     766             :    * If the Ray with \p ray_id is not found across all processors, this will error.
     767             :    *
     768             :    * This will ONLY return a valid Ray (not a null shared_ptr) on the processor that
     769             :    * has the Ray.
     770             :    */
     771             :   std::shared_ptr<Ray> getBankedRay(const RayID ray_id) const;
     772             : 
     773             :   /**
     774             :    * Resets the generation of unique RayIDs via generateUniqueRayID() to the beginning
     775             :    * of the range.
     776             :    */
     777             :   void resetUniqueRayIDs();
     778             :   /**
     779             :    * Resets the generation of unique replicated RayIDs accessed via generateReplicatedRayID().
     780             :    */
     781             :   void resetReplicatedRayIDs();
     782             : 
     783             :   /**
     784             :    * Gets all of the currently active RayTracingObjects
     785             :    */
     786             :   std::vector<RayTracingObject *> getRayTracingObjects();
     787             : 
     788             :   /**
     789             :    * Generates a unique RayID to be used for a Ray.
     790             :    *
     791             :    * This is used internally when acquiring new Rays.
     792             :    */
     793             :   virtual RayID generateUniqueRayID(const THREAD_ID tid);
     794             :   /**
     795             :    * Generates a Ray ID that is replicated across all processors.
     796             :    */
     797             :   RayID generateReplicatedRayID();
     798             : 
     799             :   /**
     800             :    * User APIs for constructing Rays within the RayTracingStudy.
     801             :    *
     802             :    * Rays can ONLY be constructed by users within the RayTracingStudy via the following methods.
     803             :    */
     804             :   ///@{
     805             :   /**
     806             :    * Acquire a Ray from the pool of Rays within generateRays().
     807             :    *
     808             :    * A unique ID is generated and assigned to the acquired Ray. The data and aux
     809             :    * data sizes are set according to the sizes required by the RayTracingStudy.
     810             :    */
     811             :   std::shared_ptr<Ray> acquireRay();
     812             :   /**
     813             :    * Acquire a Ray from the pool of Rays within generateRays(), without resizing
     814             :    * the data (sizes the data to zero).
     815             :    *
     816             :    * A unique ID is generated and assigned to the acquired Ray.
     817             :    */
     818             :   std::shared_ptr<Ray> acquireUnsizedRay();
     819             :   /**
     820             :    * Acquire a Ray from the pool of Rays within generateRays() in a replicated fashion.
     821             :    *
     822             :    * That is, this method must be called on all processors at the same time and the ID of the
     823             :    * resulting Ray is the same across all processors.
     824             :    *
     825             :    * The data and aux data sizes are set according to the sizes required by the RayTracingStudy.
     826             :    */
     827             :   std::shared_ptr<Ray> acquireReplicatedRay();
     828             :   /**
     829             :    * Acquires a Ray that that is copied from another Ray within generateRays().
     830             :    *
     831             :    * All of the information is copied except for the counters (intersections, processor crossings,
     832             :    * etc), which are reset.
     833             :    */
     834             :   std::shared_ptr<Ray> acquireCopiedRay(const Ray & ray);
     835             :   /**
     836             :    * Acquires a Ray with a given name within generateRays(). Used when ray registration is enabled,
     837             :    * that is, the private paramater '_use_ray_registration' == true.
     838             :    *
     839             :    * This method must be called on all processors at the same time with the same name.
     840             :    * This method can only be called on thread 0, which is why there is no thread argument.
     841             :    */
     842             :   std::shared_ptr<Ray> acquireRegisteredRay(const std::string & name);
     843             :   ///@}
     844             : 
     845             :   /**
     846             :    * Moves a ray to the buffer to be traced during generateRays().
     847             :    *
     848             :    * This moves the Ray into the buffer (with std::move), therefore \p ray will be nullptr after
     849             :    * this call.
     850             :    */
     851             :   void moveRayToBuffer(std::shared_ptr<Ray> & ray);
     852             :   /**
     853             :    * Moves rays to the buffer to be traced during generateRays().
     854             :    *
     855             :    * This moves the rays into the buffer (with std::move), therefore all valid rays
     856             :    * in \p rays will be nullptr after this call.
     857             :    */
     858             :   void moveRaysToBuffer(std::vector<std::shared_ptr<Ray>> & rays);
     859             : 
     860             :   /// The Mesh
     861             :   MooseMesh & _mesh;
     862             :   /// The Communicator
     863             :   const Parallel::Communicator & _comm;
     864             :   /// The rank of this processor (this actually takes time to lookup - so just do it once)
     865             :   const processor_id_type _pid;
     866             : 
     867             :   /// Whether or not to perform coverage checks on RayKernels
     868             :   const bool _ray_kernel_coverage_check;
     869             :   /// Whether not to warn if non-planar faces are found
     870             :   const bool _warn_non_planar;
     871             :   /// Whether or not to use Ray registration
     872             :   const bool _use_ray_registration;
     873             :   /// Whether or not to use the internal sidesets in ray tracing
     874             :   const bool _use_internal_sidesets;
     875             :   /// Whether or not to tolerate a Ray Tracing failure
     876             :   const bool _tolerate_failure;
     877             :   /// Whether or not to bank rays on completion
     878             :   const bool _bank_rays_on_completion;
     879             :   /// Whether or not subdomain setup is dependent on the Ray
     880             :   const bool _ray_dependent_subdomain_setup;
     881             : 
     882             :   /// Whether or not to cache traces on every trace execution
     883             :   bool _always_cache_traces;
     884             :   /// Whether or not to store the Ray data on the cache traces
     885             :   const bool _data_on_cache_traces;
     886             :   /// Whether or not to store the Ray aux data on the cache traces
     887             :   const bool _aux_data_on_cache_traces;
     888             :   /// Whether or not to cache individual element segments when caching
     889             :   const bool _segments_on_cache_traces;
     890             :   /// Max distance a Ray can travel before being killed (can change)
     891             :   const Real _ray_max_distance;
     892             :   /// Whether or not to verify if Rays have valid information before being traced
     893             :   const bool _verify_rays;
     894             :   /// Whether or not to verify the trace intersections in devel and dbg modes
     895             : #ifndef NDEBUG
     896             :   const bool _verify_trace_intersections;
     897             : #endif
     898             : 
     899             : private:
     900             :   /**
     901             :    * Perform coverage checks (coverage of RayMaterials and RayKernels, if enabled)
     902             :    */
     903             :   void coverageChecks();
     904             : 
     905             :   /**
     906             :    * Perform checks to see if the listed dependencies in the RayTracingObjects exist
     907             :    */
     908             :   void dependencyChecks();
     909             :   /**
     910             :    * Verifies that the dependencies exist for a set of RayTracingObjects
     911             :    */
     912             :   void verifyDependenciesExist(const std::vector<RayTracingObject *> & rtos);
     913             : 
     914             :   /**
     915             :    * Check for if all of the element types in the mesh are supported by ray tracing
     916             :    */
     917             :   void traceableMeshChecks();
     918             : 
     919             :   /**
     920             :    * Does the setup for internal sidesets. This includes:
     921             :    * - Setting if the local mesh has internal sidesets that have RayBCs and on which
     922             :    *   boundary (stored in _internal_sidesets)
     923             :    * - Sets up the internal sideset mapping that maps element sides to the BoundaryIDs
     924             :    *   on said side that have internal sidesets that have RayBCs
     925             :    *   (stored in _internal_sidesets_map)
     926             :    *
     927             :    * If _use_internal_sidesets == false, this will still check to make sure that the
     928             :    * user does not have internal sidesets with RayBCs on them, and will report an error
     929             :    * if so.
     930             :    */
     931             :   void internalSidesetSetup();
     932             : 
     933             :   /**
     934             :    * Sets up the caching of whether or not each element side is non-planar, which is
     935             :    * stored in _non_planar_sides.
     936             :    *
     937             :    * This is done because this check is made within TraceRay, and determining whether
     938             :    * or not a side is non planar is quite expensive and we don't want to call it
     939             :    * mid-trace.
     940             :    */
     941             :   void nonPlanarSideSetup();
     942             : 
     943             :   /**
     944             :    * Sets up the _elem_index_helper, which is used for obtaining a contiguous index
     945             :    * for all elements that this processor knows about.
     946             :    *
     947             :    * Said index is used for quickly accessing things like internal sidesets and checking
     948             :    * if an element side is non-planar during tracing.
     949             :    */
     950             :   void localElemIndexSetup();
     951             : 
     952             :   /**
     953             :    * Sets up the maps from Ray to associated RayTracingObjects if _use_ray_registration.
     954             :    *
     955             :    * If ray registration is disabled, this makes sure no RayTracingObjects provided rays.
     956             :    */
     957             :   void registeredRaySetup();
     958             : 
     959             :   /**
     960             :    * Zero the AuxVariables that the registered AuxRayKernels contribute to.
     961             :    */
     962             :   void zeroAuxVariables();
     963             : 
     964             :   /**
     965             :    * Caches the hmax for all elements in each subdomain
     966             :    */
     967             :   void subdomainHMaxSetup();
     968             : 
     969             :   /**
     970             :    * Internal method for registering Ray data or Ray aux data with a name.
     971             :    */
     972             :   RayDataIndex registerRayDataInternal(const std::string & name, const bool aux);
     973             :   /**
     974             :    * Internal method for registering Ray data or Ray aux data with names.
     975             :    */
     976             :   std::vector<RayDataIndex> registerRayDataInternal(const std::vector<std::string> & names,
     977             :                                                     const bool aux);
     978             :   /**
     979             :    * Internal method for getting the index of Ray data or Ray aux data.
     980             :    */
     981             :   RayDataIndex
     982             :   getRayDataIndexInternal(const std::string & name, const bool aux, const bool graceful) const;
     983             :   /**
     984             :    * Internal method for getting the indicies of Ray data or Ray aux data.
     985             :    */
     986             :   std::vector<RayDataIndex> getRayDataIndicesInternal(const std::vector<std::string> & names,
     987             :                                                       const bool aux,
     988             :                                                       const bool graceful) const;
     989             : 
     990             :   /**
     991             :    * Internal method for getting the name of Ray data or Ray aux data.
     992             :    */
     993             :   const std::string & getRayDataNameInternal(const RayDataIndex index, const bool aux) const;
     994             : 
     995             :   /**
     996             :    * Internal method for getting the value (replicated across all processors) in a Ray's data
     997             :    * or aux data from the Ray banks.
     998             :    */
     999             :   RayData
    1000             :   getBankedRayDataInternal(const RayID ray_id, const RayDataIndex index, const bool aux) const;
    1001             : 
    1002             :   /**
    1003             :    * Registers a Ray with a given name.
    1004             :    *
    1005             :    * This is for internal use only and is an internal map for replicated Ray IDs -> names for
    1006             :    * easy access for studies that have a small number of rays to generate.
    1007             :    *
    1008             :    * @param name The name to register
    1009             :    * @return The allocated ID for the registered ray
    1010             :    */
    1011             :   RayID registerRay(const std::string & name);
    1012             : 
    1013             :   /// Threaded helpers for building element sides without extraneous allocation
    1014             :   std::vector<libMesh::ElemSideBuilder> _threaded_elem_side_builders;
    1015             : 
    1016             :   /// Timing
    1017             :   //@{
    1018             :   std::chrono::steady_clock::time_point _execution_start_time;
    1019             :   std::chrono::steady_clock::duration _execution_time;
    1020             :   std::chrono::steady_clock::duration _generation_time;
    1021             :   std::chrono::steady_clock::duration _propagation_time;
    1022             :   //@}
    1023             : 
    1024             :   /// The map from Ray data names to index
    1025             :   std::unordered_map<std::string, RayDataIndex> _ray_data_map;
    1026             :   /// The map from Ray aux data names to index
    1027             :   std::unordered_map<std::string, RayDataIndex> _ray_aux_data_map;
    1028             : 
    1029             :   /// The names for each Ray data entry
    1030             :   std::vector<std::string> _ray_data_names;
    1031             :   /// The names for each Ray aux data entry
    1032             :   std::vector<std::string> _ray_aux_data_names;
    1033             : 
    1034             :   /// Map from registered Ray name to ID
    1035             :   std::unordered_map<std::string, RayID> & _registered_ray_map;
    1036             :   /// Map from registered Ray ID to name
    1037             :   std::vector<std::string> & _reverse_registered_ray_map;
    1038             : 
    1039             :   /// Storage for the cached traces
    1040             :   std::vector<TraceData> _cached_traces;
    1041             :   /// The threaded storage for cached traces
    1042             :   std::vector<std::vector<TraceData>> _threaded_cached_traces;
    1043             : 
    1044             :   /// Number of currently cached objects for Jacobian/residual for each thread
    1045             :   std::vector<std::size_t> _num_cached;
    1046             : 
    1047             :   /// The BoundaryIDs on the local mesh that have internal RayBCs
    1048             :   std::set<BoundaryID> _internal_sidesets;
    1049             :   /// Internal sideset data, if internal sidesets exist (indexed with getLocalElemIndex())
    1050             :   std::vector<std::vector<std::vector<BoundaryID>>> _internal_sidesets_map;
    1051             :   /// Whether or not the local mesh has elements with non-planar sides
    1052             :   bool _has_non_planar_sides;
    1053             :   /// Non planar side data, which is for quick checking if an elem side is non-planar
    1054             :   /// We use unsigned short here to avoid a std::vector<bool>; 0 = false, otherwise true
    1055             :   std::vector<std::vector<unsigned short>> _non_planar_sides;
    1056             :   /// Whether or not the mesh has active elements of the same level
    1057             :   bool _has_same_level_active_elems;
    1058             : 
    1059             :   /// Nodal bounding box for the domain
    1060             :   libMesh::BoundingBox _b_box;
    1061             :   /// Loose nodal bounding box for the domain
    1062             :   libMesh::BoundingBox _loose_b_box;
    1063             :   /// An inflated max distance for the domain
    1064             :   Real _domain_max_length;
    1065             :   /// The total volume of the domain
    1066             :   Real _total_volume;
    1067             : 
    1068             :   /// Threaded cached subdomain query for RayKernelBase objects pertaining to this study
    1069             :   std::vector<TheWarehouse::QueryCache<AttribSubdomains>> _threaded_cache_ray_kernel;
    1070             :   /// Threaded cached boundary query for RayBC objects pertaining to this study
    1071             :   std::vector<TheWarehouse::QueryCache<AttribBoundaries>> _threaded_cache_ray_bc;
    1072             :   /// Threaded storage for all of the RayTracingObjects associated with a single Ray
    1073             :   std::vector<std::vector<std::set<const RayTracingObject *>>> _threaded_ray_object_registration;
    1074             :   /// The current RayKernel objects for each thread
    1075             :   std::vector<std::vector<RayKernelBase *>> _threaded_current_ray_kernels;
    1076             :   /// The TraceRay objects for each thread (they do the physical tracing)
    1077             :   std::vector<std::shared_ptr<TraceRay>> _threaded_trace_ray;
    1078             :   /// Face FE used for computing face normals for each thread
    1079             :   std::vector<std::unique_ptr<libMesh::FEBase>> _threaded_fe_face;
    1080             :   /// Face quadrature used for computing face normals for each thread
    1081             :   std::vector<std::unique_ptr<libMesh::QBase>> _threaded_q_face;
    1082             :   /// Threaded cache for side normals that have been computed already during tracing
    1083             :   std::vector<std::unordered_map<std::pair<const Elem *, unsigned short>, Point>>
    1084             :       _threaded_cached_normals;
    1085             :   /// Cumulative Ray bank - stored only when _bank_rays_on_completion
    1086             :   std::vector<std::shared_ptr<Ray>> _ray_bank;
    1087             :   /// Storage for the next available unique RayID, obtained via generateUniqueRayID()
    1088             :   std::vector<RayID> _threaded_next_ray_id;
    1089             :   /// Storage for the next available replicated RayID, obtained via generateReplicatedRayID()
    1090             :   RayID _replicated_next_ray_id;
    1091             : 
    1092             :   /// The study that used is to actually execute (trace) the Rays
    1093             :   const std::unique_ptr<ParallelRayStudy> _parallel_ray_study;
    1094             : 
    1095             :   /// Quadrature rule for laying points across a 1D ray segment
    1096             :   std::unique_ptr<libMesh::QBase> _segment_qrule;
    1097             : 
    1098             :   /// Total number of processor crossings for Rays that finished on this processor
    1099             :   unsigned long long int _ending_processor_crossings;
    1100             :   /// Max number of total processor crossings for Rays that finished on this processor
    1101             :   unsigned int _ending_max_processor_crossings;
    1102             :   /// Total number of processor crossings
    1103             :   unsigned long long int _total_processor_crossings;
    1104             :   /// Max number of processor crossings for all Rays
    1105             :   unsigned int _max_processor_crossings;
    1106             : 
    1107             :   /// Total number of Ray/element intersections for Rays that finished on this processor
    1108             :   unsigned long long int _ending_intersections;
    1109             :   /// Max number of intersections for Rays that finished on this processor
    1110             :   unsigned int _ending_max_intersections;
    1111             :   /// Max number of trajectory changes for Rays that finished on this processor
    1112             :   unsigned int _ending_max_trajectory_changes;
    1113             :   /// Total number of Ray/element intersections
    1114             :   unsigned long long int _total_intersections;
    1115             :   /// Max number of intersections for a single Ray
    1116             :   unsigned int _max_intersections;
    1117             :   /// Max number of trajectory changes for a single Ray
    1118             :   unsigned int _max_trajectory_changes;
    1119             : 
    1120             :   /// Total distance traveled by Rays that end on this processor
    1121             :   Real _ending_distance;
    1122             :   /// Total distance traveled by all Rays
    1123             :   Real _total_distance;
    1124             : 
    1125             :   /// Cumulative results on this processor from the threaded TraceRay objects
    1126             :   std::vector<unsigned long long int> _local_trace_ray_results;
    1127             : 
    1128             :   /// The cached hmax for all elements in a subdomain
    1129             :   std::unordered_map<SubdomainID, Real> _subdomain_hmax;
    1130             : 
    1131             :   /// Whether or not we've called initial setup - used to stop from late registration
    1132             :   bool _called_initial_setup;
    1133             : 
    1134             :   /// Helper for defining a local contiguous index for each element
    1135             :   ElemIndexHelper _elem_index_helper;
    1136             : 
    1137             :   /// Spin mutex object for locks
    1138             :   mutable Threads::spin_mutex _spin_mutex;
    1139             : };

Generated by: LCOV version 1.14