Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:23:51

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file orange/univ/detail/SenseCalculator.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Assert.hh"
0010 #include "corecel/cont/Range.hh"
0011 #include "corecel/cont/Span.hh"
0012 #include "orange/OrangeTypes.hh"
0013 #include "orange/SenseUtils.hh"
0014 #include "orange/surf/LocalSurfaceVisitor.hh"
0015 
0016 #include "LazySenseCalculator.hh"
0017 #include "Types.hh"
0018 #include "../VolumeView.hh"
0019 
0020 namespace celeritas
0021 {
0022 namespace detail
0023 {
0024 //---------------------------------------------------------------------------//
0025 /*!
0026  * Calculate senses with a fixed particle position.
0027  *
0028  * This is an implementation detail used in initialization *and* complex
0029  * intersection. Senses are eagerly calculated for all faces in the volume at
0030  * construction.
0031  */
0032 class SenseCalculator
0033 {
0034   public:
0035     // Construct from persistent, current, and temporary data
0036     inline CELER_FUNCTION SenseCalculator(LocalSurfaceVisitor const& visit,
0037                                           VolumeView const& vol,
0038                                           Real3 const& pos,
0039                                           Span<SenseValue> storage,
0040                                           OnFace& face);
0041 
0042     // Calculate senses for the given volume, possibly on a face
0043     inline CELER_FUNCTION Sense operator()(FaceId face_id);
0044 
0045     //! Flip the sense of a face
0046     CELER_FUNCTION void flip_sense(FaceId face_id)
0047     {
0048         sense_storage_[face_id.get()] = celeritas::flip_sense((*this)(face_id));
0049     }
0050 
0051   private:
0052     //! Temporary senses
0053     Span<SenseValue> sense_storage_;
0054 };
0055 
0056 //---------------------------------------------------------------------------//
0057 // INLINE DEFINITIONS
0058 //---------------------------------------------------------------------------//
0059 /*!
0060  * Construct from persistent, current, and temporary data.
0061  */
0062 CELER_FUNCTION
0063 SenseCalculator::SenseCalculator(LocalSurfaceVisitor const& visit,
0064                                  VolumeView const& vol,
0065                                  Real3 const& pos,
0066                                  Span<SenseValue> storage,
0067                                  OnFace& face)
0068     : sense_storage_{storage.first(vol.num_faces())}
0069 {
0070     CELER_EXPECT(vol.num_faces() <= storage.size());
0071     LazySenseCalculator lazy_sense_calculator(visit, vol, pos, face);
0072     // Fill the temp logic vector with values for all surfaces in the volume
0073     for (FaceId cur_face : range(FaceId{vol.num_faces()}))
0074     {
0075         sense_storage_[cur_face.unchecked_get()]
0076             = lazy_sense_calculator(cur_face);
0077     }
0078 
0079     CELER_ENSURE(!face || face.id() < sense_storage_.size());
0080 }
0081 
0082 //---------------------------------------------------------------------------//
0083 /*!
0084  * Calculate senses for the given volume.
0085  *
0086  * If the point is exactly on one of the volume's surfaces, the \c face
0087  * reference passed during instance construction will be set.
0088  */
0089 CELER_FUNCTION Sense SenseCalculator::operator()(FaceId face_id)
0090 {
0091     CELER_EXPECT(face_id < sense_storage_.size());
0092 
0093     return sense_storage_[face_id.unchecked_get()];
0094 }
0095 
0096 //---------------------------------------------------------------------------//
0097 }  // namespace detail
0098 }  // namespace celeritas