Back to home page

EIC code displayed by LXR

 
 

    


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

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/detail/MatScintSpecInserter.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Assert.hh"
0011 #include "corecel/Types.hh"
0012 #include "corecel/data/CollectionBuilder.hh"
0013 #include "corecel/data/DedupeCollectionBuilder.hh"
0014 #include "corecel/math/SoftEqual.hh"
0015 #include "celeritas/io/ImportOpticalMaterial.hh"
0016 
0017 #include "../ScintillationData.hh"
0018 
0019 namespace celeritas
0020 {
0021 namespace optical
0022 {
0023 namespace detail
0024 {
0025 //---------------------------------------------------------------------------//
0026 /*!
0027  * Build scintillation spectrum data.
0028  */
0029 class MatScintSpecInserter
0030 {
0031   public:
0032     //!@{
0033     //! \name Type aliases
0034     using Data = HostVal<ScintillationData>;
0035     //!@}
0036 
0037   public:
0038     // Construct with data to insert into
0039     explicit inline MatScintSpecInserter(Data* data);
0040 
0041     // Add scintillation data for a single material
0042     auto operator()(ImportMaterialScintSpectrum const& mat);
0043 
0044   private:
0045     using MatId = OpticalMaterialId;
0046 
0047     CollectionBuilder<MatScintSpectrumRecord, MemSpace::host, MatId> materials_;
0048     DedupeCollectionBuilder<real_type> reals_;
0049     CollectionBuilder<ScintRecord> scint_records_;
0050 };
0051 
0052 //---------------------------------------------------------------------------//
0053 // INLINE DEFINITIONS
0054 //---------------------------------------------------------------------------//
0055 /*!
0056  * Construct with defaults.
0057  */
0058 MatScintSpecInserter::MatScintSpecInserter(Data* data)
0059     : materials_{&data->materials}
0060     , reals_{&data->reals}
0061     , scint_records_{&data->scint_records}
0062 {
0063     CELER_EXPECT(data);
0064 }
0065 
0066 //---------------------------------------------------------------------------//
0067 /*!
0068  * Add scintillation data for a single material.
0069  */
0070 auto MatScintSpecInserter::operator()(ImportMaterialScintSpectrum const& mat)
0071 {
0072     CELER_EXPECT(mat);
0073 
0074     CELER_VALIDATE(mat.yield_per_energy > 0,
0075                    << "invalid yield=" << mat.yield_per_energy
0076                    << " for scintillation (should be positive)");
0077 
0078     double total_yield{0};
0079     std::vector<double> yield_pdf;
0080     auto const begin_components = scint_records_.size_id();
0081     for (ImportScintComponent const& comp : mat.components)
0082     {
0083         CELER_VALIDATE(comp.lambda_mean > 0,
0084                        << "invalid lambda_mean=" << comp.lambda_mean
0085                        << " for scintillation component (should be positive)");
0086         CELER_VALIDATE(comp.lambda_sigma > 0,
0087                        << "invalid lambda_sigma=" << comp.lambda_sigma
0088                        << " (should be positive)");
0089         CELER_VALIDATE(comp.rise_time >= 0,
0090                        << "invalid rise_time=" << comp.rise_time
0091                        << " (should be nonnegative)");
0092         CELER_VALIDATE(comp.fall_time > 0,
0093                        << "invalid fall_time=" << comp.fall_time
0094                        << " (should be positive)");
0095         CELER_VALIDATE(comp.yield_frac > 0,
0096                        << "invalid yield=" << comp.yield_frac);
0097 
0098         ScintRecord scint;
0099         scint.lambda_mean = comp.lambda_mean;
0100         scint.lambda_sigma = comp.lambda_sigma;
0101         scint.rise_time = comp.rise_time;
0102         scint.fall_time = comp.fall_time;
0103         scint_records_.push_back(scint);
0104 
0105         yield_pdf.push_back(comp.yield_frac);
0106         total_yield += comp.yield_frac;
0107     }
0108 
0109     // Normalize yield PDF by total yield
0110     for (auto& y : yield_pdf)
0111     {
0112         y /= total_yield;
0113     }
0114 
0115     MatScintSpectrumRecord spectrum;
0116     spectrum.yield_per_energy = mat.yield_per_energy;
0117     spectrum.components = {begin_components, scint_records_.size_id()};
0118     spectrum.yield_pdf = reals_.insert_back(yield_pdf.begin(), yield_pdf.end());
0119 
0120     CELER_ENSURE(spectrum.components.size() == mat.components.size());
0121     return materials_.push_back(std::move(spectrum));
0122 }
0123 
0124 //---------------------------------------------------------------------------//
0125 }  // namespace detail
0126 }  // namespace optical
0127 }  // namespace celeritas