File indexing completed on 2025-02-22 10:31:26
0001
0002
0003
0004
0005
0006
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
0028
0029 class MatScintSpecInserter
0030 {
0031 public:
0032
0033
0034 using Data = HostVal<ScintillationData>;
0035
0036
0037 public:
0038
0039 explicit inline MatScintSpecInserter(Data* data);
0040
0041
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
0054
0055
0056
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
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
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 }
0126 }
0127 }