Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:27

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file celeritas/optical/OffloadData.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Macros.hh"
0011 #include "corecel/Types.hh"
0012 #include "corecel/data/Collection.hh"
0013 #include "corecel/data/CollectionBuilder.hh"
0014 #include "celeritas/Quantities.hh"
0015 #include "celeritas/Types.hh"
0016 
0017 #include "CerenkovData.hh"
0018 #include "GeneratorDistributionData.hh"
0019 #include "ScintillationData.hh"
0020 
0021 namespace celeritas
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Current sizes of the buffers of distribution data.
0026  *
0027  * These sizes are updated by value on the host at each step.
0028  */
0029 struct OffloadBufferSize
0030 {
0031     size_type cerenkov{0};
0032     size_type scintillation{0};
0033     size_type num_photons{0};
0034 };
0035 
0036 //---------------------------------------------------------------------------//
0037 /*!
0038  * Setup options for optical generation.
0039  *
0040  * At least one of cerenkov and scintillation must be enabled.
0041  */
0042 struct OffloadOptions
0043 {
0044     bool cerenkov{false};  //!< Whether Cerenkov is enabled
0045     bool scintillation{false};  //!< Whether scintillation is enabled
0046     size_type capacity{0};  //!< Distribution data buffer capacity
0047 
0048     //! True if valid
0049     explicit CELER_FUNCTION operator bool() const
0050     {
0051         return (cerenkov || scintillation) && capacity > 0;
0052     }
0053 };
0054 
0055 //---------------------------------------------------------------------------//
0056 /*!
0057  * Immutable problem data for generating optical photon distributions.
0058  */
0059 template<Ownership W, MemSpace M>
0060 struct OffloadParamsData
0061 {
0062     //// DATA ////
0063 
0064     OffloadOptions setup;
0065 
0066     //// METHODS ////
0067 
0068     //! True if all params are assigned
0069     explicit CELER_FUNCTION operator bool() const
0070     {
0071         return static_cast<bool>(setup);
0072     }
0073 
0074     //! Assign from another set of data
0075     template<Ownership W2, MemSpace M2>
0076     OffloadParamsData& operator=(OffloadParamsData<W2, M2> const& other)
0077     {
0078         CELER_EXPECT(other);
0079         setup = other.setup;
0080         return *this;
0081     }
0082 };
0083 
0084 //---------------------------------------------------------------------------//
0085 /*!
0086  * Pre-step data needed to generate optical photon distributions.
0087  *
0088  * If the optical material is not set, the other properties are invalid.
0089  */
0090 struct OffloadPreStepData
0091 {
0092     units::LightSpeed speed;
0093     Real3 pos{};
0094     real_type time{};
0095     OpticalMaterialId material;
0096 
0097     //! Check whether the data are assigned
0098     explicit CELER_FUNCTION operator bool() const
0099     {
0100         return material && speed > zero_quantity();
0101     }
0102 };
0103 
0104 //---------------------------------------------------------------------------//
0105 /*!
0106  * Optical photon distribution data.
0107  *
0108  * The distributions are stored in separate Cerenkov and scintillation buffers
0109  * indexed by the current buffer size plus the track slot ID. The data is
0110  * compacted at the end of each step by removing all invalid distributions. The
0111  * order of the distributions in the buffers is guaranteed to be reproducible.
0112  */
0113 template<Ownership W, MemSpace M>
0114 struct OffloadStateData
0115 {
0116     //// TYPES ////
0117 
0118     template<class T>
0119     using StateItems = StateCollection<T, W, M>;
0120     template<class T>
0121     using Items = Collection<T, W, M>;
0122 
0123     //// DATA ////
0124 
0125     // Pre-step data for generating optical photon distributions
0126     StateItems<OffloadPreStepData> step;
0127 
0128     // Buffers of distribution data for generating optical photons
0129     Items<optical::GeneratorDistributionData> cerenkov;
0130     Items<optical::GeneratorDistributionData> scintillation;
0131 
0132     // Determines which distribution a thread will generate a primary from
0133     Items<size_type> offsets;
0134 
0135     //// METHODS ////
0136 
0137     //! Number of states
0138     CELER_FUNCTION size_type size() const { return step.size(); }
0139 
0140     //! Whether all data are assigned and valid
0141     explicit CELER_FUNCTION operator bool() const
0142     {
0143         return !step.empty() && !offsets.empty()
0144                && !(cerenkov.empty() && scintillation.empty());
0145     }
0146 
0147     //! Assign from another set of data
0148     template<Ownership W2, MemSpace M2>
0149     OffloadStateData& operator=(OffloadStateData<W2, M2>& other)
0150     {
0151         CELER_EXPECT(other);
0152         step = other.step;
0153         cerenkov = other.cerenkov;
0154         scintillation = other.scintillation;
0155         offsets = other.offsets;
0156         return *this;
0157     }
0158 };
0159 
0160 //---------------------------------------------------------------------------//
0161 /*!
0162  * Resize optical states.
0163  */
0164 template<MemSpace M>
0165 void resize(OffloadStateData<Ownership::value, M>* state,
0166             HostCRef<OffloadParamsData> const& params,
0167             StreamId,
0168             size_type size)
0169 {
0170     CELER_EXPECT(params);
0171     CELER_EXPECT(size > 0);
0172 
0173     resize(&state->step, size);
0174     OffloadOptions const& setup = params.setup;
0175     if (setup.cerenkov)
0176     {
0177         resize(&state->cerenkov, setup.capacity);
0178     }
0179     if (setup.scintillation)
0180     {
0181         resize(&state->scintillation, setup.capacity);
0182     }
0183     resize(&state->offsets, setup.capacity);
0184 
0185     CELER_ENSURE(*state);
0186 }
0187 
0188 //---------------------------------------------------------------------------//
0189 }  // namespace celeritas