diff --git a/src/celeritas/CMakeLists.txt b/src/celeritas/CMakeLists.txt index fbbf5b23f1..0079b78be7 100644 --- a/src/celeritas/CMakeLists.txt +++ b/src/celeritas/CMakeLists.txt @@ -42,9 +42,10 @@ list(APPEND SOURCES global/Stepper.cc global/detail/ActionSequence.cc global/detail/PinnedAllocator.cc + grid/GenericGridBuilder.cc grid/ValueGridBuilder.cc - grid/ValueGridData.cc grid/ValueGridInserter.cc + grid/ValueGridType.cc grid/VectorUtils.cc io/AtomicRelaxationReader.cc io/ImportData.cc diff --git a/src/celeritas/Types.cc b/src/celeritas/Types.cc index ca54a0208a..d3e318fef0 100644 --- a/src/celeritas/Types.cc +++ b/src/celeritas/Types.cc @@ -42,6 +42,16 @@ UnitSystem to_unit_system(std::string const& s) return from_string(s); } +//---------------------------------------------------------------------------// +/*! + * Get a string corresponding to an interpolation. + */ +char const* to_cstring(Interp value) +{ + static EnumStringMapper const to_cstring_impl{"linear", "log"}; + return to_cstring_impl(value); +} + //---------------------------------------------------------------------------// /*! * Get a string corresponding to a state of matter. diff --git a/src/celeritas/Types.hh b/src/celeritas/Types.hh index cdbb468878..ee64c848dd 100644 --- a/src/celeritas/Types.hh +++ b/src/celeritas/Types.hh @@ -94,7 +94,8 @@ enum class UnitSystem enum class Interp { linear, - log + log, + size_ }; //---------------------------------------------------------------------------// @@ -195,6 +196,9 @@ struct StepLimit // Get a string corresponding to a unit system char const* to_cstring(UnitSystem); +// Get a string corresponding to an interpolation +char const* to_cstring(Interp); + // Get a unit system corresponding to a string UnitSystem to_unit_system(std::string const& s); diff --git a/src/celeritas/em/data/LivermorePEData.hh b/src/celeritas/em/data/LivermorePEData.hh index 208995bc95..af3314f648 100644 --- a/src/celeritas/em/data/LivermorePEData.hh +++ b/src/celeritas/em/data/LivermorePEData.hh @@ -100,16 +100,18 @@ struct LivermorePEXsData //// MEMBER DATA //// - Items reals; Items shells; ElementItems elements; + // Backend data + Items reals; + //// MEMBER FUNCTIONS //// //! Whether all data are assigned and valid explicit CELER_FUNCTION operator bool() const { - return !reals.empty() && !shells.empty() && !elements.empty(); + return !shells.empty() && !elements.empty() && !reals.empty(); } //! Assign from another set of data @@ -117,9 +119,9 @@ struct LivermorePEXsData LivermorePEXsData& operator=(LivermorePEXsData const& other) { CELER_EXPECT(other); - reals = other.reals; shells = other.shells; elements = other.elements; + reals = other.reals; return *this; } }; diff --git a/src/celeritas/em/model/LivermorePEModel.cc b/src/celeritas/em/model/LivermorePEModel.cc index 4a8ccf485e..6878a3fbfd 100644 --- a/src/celeritas/em/model/LivermorePEModel.cc +++ b/src/celeritas/em/model/LivermorePEModel.cc @@ -13,8 +13,6 @@ #include "celeritas_config.h" #include "corecel/cont/Range.hh" -#include "corecel/data/Collection.hh" -#include "corecel/data/CollectionBuilder.hh" #include "celeritas/em/data/LivermorePEData.hh" #include "celeritas/em/executor/LivermorePEExecutor.hh" #include "celeritas/global/ActionLauncher.hh" @@ -23,7 +21,6 @@ #include "celeritas/global/TrackExecutor.hh" #include "celeritas/grid/XsGridData.hh" #include "celeritas/io/ImportLivermorePE.hh" -#include "celeritas/io/ImportPhysicsVector.hh" #include "celeritas/mat/ElementView.hh" #include "celeritas/mat/MaterialParams.hh" #include "celeritas/phys/InteractionApplier.hh" @@ -31,6 +28,8 @@ #include "celeritas/phys/ParticleParams.hh" #include "celeritas/phys/ParticleView.hh" +#include "detail/LivermoreXsInserter.hh" + namespace celeritas { //---------------------------------------------------------------------------// @@ -63,11 +62,11 @@ LivermorePEModel::LivermorePEModel(ActionId id, particles.get(host_data.ids.electron).mass()); // Load Livermore cross section data - make_builder(&host_data.xs.elements).reserve(materials.num_elements()); + detail::LivermoreXsInserter insert_element(&host_data.xs); for (auto el_id : range(ElementId{materials.num_elements()})) { AtomicNumber z = materials.get(el_id).atomic_number(); - this->append_element(load_data(z), &host_data.xs); + insert_element(load_data(z)); } CELER_ASSERT(host_data.xs.elements.size() == materials.num_elements()); @@ -134,79 +133,5 @@ ActionId LivermorePEModel::action_id() const return this->host_ref().ids.action; } -//---------------------------------------------------------------------------// -/*! - * Construct cross section data for a single element. - */ -void LivermorePEModel::append_element(ImportLivermorePE const& inp, - HostXsData* xs) const -{ - CELER_EXPECT(!inp.shells.empty()); - if constexpr (CELERITAS_DEBUG) - { - CELER_EXPECT(inp.thresh_lo <= inp.thresh_hi); - for (auto const& shell : inp.shells) - { - CELER_EXPECT(shell.param_lo.size() == 6); - CELER_EXPECT(shell.param_hi.size() == 6); - CELER_EXPECT(shell.binding_energy <= inp.thresh_lo); - } - } - - auto reals = make_builder(&xs->reals); - - LivermoreElement el; - - // Add tabulated total cross sections - el.xs_lo.grid = reals.insert_back(inp.xs_lo.x.begin(), inp.xs_lo.x.end()); - el.xs_lo.value = reals.insert_back(inp.xs_lo.y.begin(), inp.xs_lo.y.end()); - el.xs_lo.grid_interp = Interp::linear; - el.xs_lo.value_interp = Interp::linear; - el.xs_hi.grid = reals.insert_back(inp.xs_hi.x.begin(), inp.xs_hi.x.end()); - el.xs_hi.value = reals.insert_back(inp.xs_hi.y.begin(), inp.xs_hi.y.end()); - el.xs_hi.grid_interp = Interp::linear; - el.xs_hi.value_interp = Interp::linear; // TODO: spline - - // Add energy thresholds for using low and high xs parameterization - el.thresh_lo = MevEnergy(inp.thresh_lo); - el.thresh_hi = MevEnergy(inp.thresh_hi); - - // Allocate subshell data - std::vector shells(inp.shells.size()); - - // Add subshell data - for (auto i : range(inp.shells.size())) - { - // Ionization energy - shells[i].binding_energy = MevEnergy(inp.shells[i].binding_energy); - - // Tabulated subshell cross section - shells[i].xs.grid = reals.insert_back(inp.shells[i].energy.begin(), - inp.shells[i].energy.end()); - shells[i].xs.value = reals.insert_back(inp.shells[i].xs.begin(), - inp.shells[i].xs.end()); - shells[i].xs.grid_interp = Interp::linear; - shells[i].xs.value_interp = Interp::linear; - - // Subshell cross section fit parameters - std::copy(inp.shells[i].param_lo.begin(), - inp.shells[i].param_lo.end(), - shells[i].param[0].begin()); - std::copy(inp.shells[i].param_hi.begin(), - inp.shells[i].param_hi.end(), - shells[i].param[1].begin()); - - CELER_ASSERT(shells[i]); - } - el.shells - = make_builder(&xs->shells).insert_back(shells.begin(), shells.end()); - - // Add the elemental data - CELER_ASSERT(el); - make_builder(&xs->elements).push_back(el); - - CELER_ENSURE(el.shells.size() == inp.shells.size()); -} - //---------------------------------------------------------------------------// } // namespace celeritas diff --git a/src/celeritas/em/model/LivermorePEModel.hh b/src/celeritas/em/model/LivermorePEModel.hh index 040660ff74..b8d0edccee 100644 --- a/src/celeritas/em/model/LivermorePEModel.hh +++ b/src/celeritas/em/model/LivermorePEModel.hh @@ -29,7 +29,6 @@ class LivermorePEModel final : public Model { public: //!@{ - using MevEnergy = units::MevEnergy; using ReadData = std::function; using HostRef = LivermorePEHostRef; using DeviceRef = LivermorePEDeviceRef; @@ -75,10 +74,6 @@ class LivermorePEModel final : public Model private: // Host/device storage and reference CollectionMirror data_; - - using HostXsData = HostVal; - void - append_element(ImportLivermorePE const& inp, HostXsData* xs_data) const; }; //---------------------------------------------------------------------------// diff --git a/src/celeritas/em/model/detail/LivermoreXsInserter.hh b/src/celeritas/em/model/detail/LivermoreXsInserter.hh new file mode 100644 index 0000000000..39eb121e60 --- /dev/null +++ b/src/celeritas/em/model/detail/LivermoreXsInserter.hh @@ -0,0 +1,127 @@ +//----------------------------------*-C++-*----------------------------------// +// Copyright 2024 UT-Battelle, LLC, and other Celeritas developers. +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/em/model/detail/LivermoreXsInserter.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/data/CollectionBuilder.hh" +#include "celeritas/em/data/LivermorePEData.hh" +#include "celeritas/grid/GenericGridBuilder.hh" +#include "celeritas/io/ImportLivermorePE.hh" +#include "celeritas/io/ImportPhysicsVector.hh" + +namespace celeritas +{ +namespace detail +{ +//---------------------------------------------------------------------------// +/*! + * Construct Livermore Photoelectric cross section data from imported data. + */ +class LivermoreXsInserter +{ + public: + //!@{ + //! \name Type aliases + using Data = HostVal; + //!@} + + public: + // Construct with pointer to host data + explicit inline LivermoreXsInserter(Data* data); + + // Construct cross section data for a single element + inline void operator()(ImportLivermorePE const& inp); + + private: + GenericGridBuilder build_grid_; + + CollectionBuilder shells_; + CollectionBuilder elements_; +}; + +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + * Construct with data. + */ +LivermoreXsInserter::LivermoreXsInserter(Data* data) + : build_grid_{&data->reals} + , shells_{&data->shells} + , elements_{&data->elements} +{ + CELER_EXPECT(data); +} + +//---------------------------------------------------------------------------// +/*! + * Construct cross section data for a single element. + */ +void LivermoreXsInserter::operator()(ImportLivermorePE const& inp) +{ + CELER_EXPECT(!inp.shells.empty()); + if constexpr (CELERITAS_DEBUG) + { + CELER_EXPECT(inp.thresh_lo <= inp.thresh_hi); + for (auto const& shell : inp.shells) + { + CELER_EXPECT(shell.param_lo.size() == 6); + CELER_EXPECT(shell.param_hi.size() == 6); + CELER_EXPECT(shell.binding_energy <= inp.thresh_lo); + } + } + using units::MevEnergy; + + LivermoreElement el; + + // Add tabulated total cross sections + if (inp.xs_lo) + { + // Z < 3 have no low-energy cross sections + el.xs_lo = build_grid_(inp.xs_lo); + } + el.xs_hi = build_grid_(inp.xs_hi); + + // Add energy thresholds for using low and high xs parameterization + el.thresh_lo = MevEnergy(inp.thresh_lo); + el.thresh_hi = MevEnergy(inp.thresh_hi); + + // Allocate subshell data + std::vector shells(inp.shells.size()); + + // Add subshell data + for (auto i : range(inp.shells.size())) + { + // Ionization energy + shells[i].binding_energy = MevEnergy(inp.shells[i].binding_energy); + + // Tabulated subshell cross section + shells[i].xs = build_grid_(make_span(inp.shells[i].energy), + make_span(inp.shells[i].xs)); + + // Subshell cross section fit parameters + std::copy(inp.shells[i].param_lo.begin(), + inp.shells[i].param_lo.end(), + shells[i].param[0].begin()); + std::copy(inp.shells[i].param_hi.begin(), + inp.shells[i].param_hi.end(), + shells[i].param[1].begin()); + + CELER_ASSERT(shells[i]); + } + el.shells = shells_.insert_back(shells.begin(), shells.end()); + + // Add the elemental data + CELER_ASSERT(el); + elements_.push_back(el); + + CELER_ENSURE(el.shells.size() == inp.shells.size()); +} + +//---------------------------------------------------------------------------// +} // namespace detail +} // namespace celeritas diff --git a/src/celeritas/em/msc/detail/UrbanMscHelper.hh b/src/celeritas/em/msc/detail/UrbanMscHelper.hh index 963349979b..808c7c2f76 100644 --- a/src/celeritas/em/msc/detail/UrbanMscHelper.hh +++ b/src/celeritas/em/msc/detail/UrbanMscHelper.hh @@ -17,7 +17,7 @@ #include "celeritas/grid/EnergyLossCalculator.hh" #include "celeritas/grid/InverseRangeCalculator.hh" #include "celeritas/grid/RangeCalculator.hh" -#include "celeritas/grid/ValueGridData.hh" +#include "celeritas/grid/ValueGridType.hh" #include "celeritas/grid/XsCalculator.hh" #include "celeritas/phys/ParticleTrackView.hh" #include "celeritas/phys/PhysicsTrackView.hh" diff --git a/src/celeritas/em/process/EPlusAnnihilationProcess.cc b/src/celeritas/em/process/EPlusAnnihilationProcess.cc index c7cfabab42..16f387fc9d 100644 --- a/src/celeritas/em/process/EPlusAnnihilationProcess.cc +++ b/src/celeritas/em/process/EPlusAnnihilationProcess.cc @@ -14,7 +14,7 @@ #include "corecel/cont/Range.hh" #include "celeritas/em/model/EPlusGGModel.hh" #include "celeritas/grid/ValueGridBuilder.hh" -#include "celeritas/grid/ValueGridData.hh" +#include "celeritas/grid/ValueGridType.hh" #include "celeritas/phys/Model.hh" #include "celeritas/phys/PDGNumber.hh" diff --git a/src/celeritas/grid/GenericCalculator.hh b/src/celeritas/grid/GenericCalculator.hh index c1ebdb5e66..4240f7385b 100644 --- a/src/celeritas/grid/GenericCalculator.hh +++ b/src/celeritas/grid/GenericCalculator.hh @@ -22,6 +22,8 @@ namespace celeritas //---------------------------------------------------------------------------// /*! * Find and interpolate values on a nonuniform grid. + * + * Out-of-bounds values are snapped to the closest grid points. */ class GenericCalculator { diff --git a/src/celeritas/grid/GenericGridBuilder.cc b/src/celeritas/grid/GenericGridBuilder.cc new file mode 100644 index 0000000000..a1ba2ba4d3 --- /dev/null +++ b/src/celeritas/grid/GenericGridBuilder.cc @@ -0,0 +1,74 @@ +//----------------------------------*-C++-*----------------------------------// +// Copyright 2024 UT-Battelle, LLC, and other Celeritas developers. +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/grid/GenericGridBuilder.cc +//---------------------------------------------------------------------------// +#include "GenericGridBuilder.hh" + +#include "celeritas/io/ImportPhysicsVector.hh" + +namespace celeritas +{ +//---------------------------------------------------------------------------// +/*! + * Construct with pointers to data that will be modified. + */ +GenericGridBuilder::GenericGridBuilder(Items* reals) : reals_{reals} +{ + CELER_EXPECT(reals); +} + +//---------------------------------------------------------------------------// +/*! + * Add a grid of generic data with linear interpolation. + */ +auto GenericGridBuilder::operator()(SpanConstFlt grid, SpanConstFlt values) + -> Grid +{ + return this->insert_impl(grid, values); +} + +//---------------------------------------------------------------------------// +/*! + * Add a grid of generic data with linear interpolation. + */ +auto GenericGridBuilder::operator()(SpanConstDbl grid, SpanConstDbl values) + -> Grid +{ + return this->insert_impl(grid, values); +} + +//---------------------------------------------------------------------------// +/*! + * Add a grid from an imported physics vector. + */ +auto GenericGridBuilder::operator()(ImportPhysicsVector const& pvec) -> Grid +{ + CELER_EXPECT(pvec.vector_type == ImportPhysicsVectorType::free); + return this->insert_impl(make_span(pvec.x), make_span(pvec.y)); +} + +//---------------------------------------------------------------------------// +/*! + * Add a grid from container references. + */ +template +auto GenericGridBuilder::insert_impl(Span grid, Span values) + -> Grid +{ + CELER_EXPECT(grid.size() >= 2); + CELER_EXPECT(grid.front() <= grid.back()); + CELER_EXPECT(values.size() == grid.size()); + + Grid result; + result.grid = reals_.insert_back(grid.begin(), grid.end()); + result.value = reals_.insert_back(values.begin(), values.end()); + + CELER_ENSURE(result); + return result; +} + +//---------------------------------------------------------------------------// +} // namespace celeritas diff --git a/src/celeritas/grid/GenericGridBuilder.hh b/src/celeritas/grid/GenericGridBuilder.hh new file mode 100644 index 0000000000..de01e52d25 --- /dev/null +++ b/src/celeritas/grid/GenericGridBuilder.hh @@ -0,0 +1,59 @@ +//----------------------------------*-C++-*----------------------------------// +// Copyright 2024 UT-Battelle, LLC, and other Celeritas developers. +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/grid/GenericGridBuilder.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/data/Collection.hh" +#include "corecel/data/CollectionBuilder.hh" +#include "corecel/data/DedupeCollectionBuilder.hh" + +#include "GenericGridData.hh" + +namespace celeritas +{ +struct ImportPhysicsVector; +//---------------------------------------------------------------------------// +/*! + * Construct a generic grid. + * + * This uses a deduplicating inserter for real values to improve cacheing. + */ +class GenericGridBuilder +{ + public: + //!@{ + //! \name Type aliases + template + using Items = Collection; + using Grid = GenericGridData; + using SpanConstFlt = Span; + using SpanConstDbl = Span; + //!@} + + public: + // Construct with pointers to data that will be modified + explicit GenericGridBuilder(Items* reals); + + // Add a grid of generic data with linear interpolation + Grid operator()(SpanConstFlt grid, SpanConstFlt values); + + // Add a grid of generic data with linear interpolation + Grid operator()(SpanConstDbl grid, SpanConstDbl values); + + // Add a grid from an imported physics vector + Grid operator()(ImportPhysicsVector const&); + + private: + DedupeCollectionBuilder reals_; + + // Insert with floating point conversion if needed + template + Grid insert_impl(Span grid, Span values); +}; + +//---------------------------------------------------------------------------// +} // namespace celeritas diff --git a/src/celeritas/grid/GenericGridData.hh b/src/celeritas/grid/GenericGridData.hh index 9d817bc0ff..d651aeaf84 100644 --- a/src/celeritas/grid/GenericGridData.hh +++ b/src/celeritas/grid/GenericGridData.hh @@ -15,19 +15,19 @@ namespace celeritas { //---------------------------------------------------------------------------// /*! - * A generic grid of 1D data with arbitrary interpolation. + * A grid of increasing, sorted 1D data with linear-linear interpolation. + * + * \todo Rename to GenericGridRecord */ struct GenericGridData { ItemRange grid; //!< x grid ItemRange value; //!< f(x) value - Interp grid_interp; //!< Interpolation along x - Interp value_interp; //!< Interpolation along f(x) - //! Whether the interface is initialized and valid + //! Whether the record is initialized and valid explicit CELER_FUNCTION operator bool() const { - return (value.size() >= 2) && grid.size() == value.size(); + return grid.size() >= 2 && value.size() == grid.size(); } }; diff --git a/src/celeritas/grid/ValueGridBuilder.cc b/src/celeritas/grid/ValueGridBuilder.cc index ecba3236fa..1307134891 100644 --- a/src/celeritas/grid/ValueGridBuilder.cc +++ b/src/celeritas/grid/ValueGridBuilder.cc @@ -253,49 +253,6 @@ auto ValueGridLogBuilder::value() const -> SpanConstDbl return make_span(value_); } -//---------------------------------------------------------------------------// -// GENERIC BUILDER -//---------------------------------------------------------------------------// -/*! - * Construct from raw data. - */ -ValueGridGenericBuilder::ValueGridGenericBuilder(VecDbl grid, - VecDbl value, - Interp grid_interp, - Interp value_interp) - : grid_(std::move(grid)) - , value_(std::move(value)) - , grid_interp_(grid_interp) - , value_interp_(value_interp) -{ - CELER_EXPECT(grid_.size() >= 2 - && is_monotonic_increasing(make_span(grid_))); - CELER_EXPECT(value_.size() == grid_.size()); -} - -//---------------------------------------------------------------------------// -/*! - * Construct from raw data with linear interpolation. - */ -ValueGridGenericBuilder::ValueGridGenericBuilder(VecDbl grid, VecDbl value) - : ValueGridGenericBuilder( - std::move(grid), std::move(value), Interp::linear, Interp::linear) -{ -} - -//---------------------------------------------------------------------------// -/*! - * Construct grid data in the given mutable insert. - */ -auto ValueGridGenericBuilder::build(ValueGridInserter insert) const - -> ValueGridId -{ - insert({make_span(grid_), grid_interp_}, - {make_span(value_), value_interp_}); - CELER_NOT_IMPLEMENTED("generic grids"); - return {}; -} - //---------------------------------------------------------------------------// // ON-THE-FLY //---------------------------------------------------------------------------// diff --git a/src/celeritas/grid/ValueGridBuilder.hh b/src/celeritas/grid/ValueGridBuilder.hh index 2c4f6e2e30..1c4c80af92 100644 --- a/src/celeritas/grid/ValueGridBuilder.hh +++ b/src/celeritas/grid/ValueGridBuilder.hh @@ -134,39 +134,6 @@ class ValueGridLogBuilder : public ValueGridBuilder VecDbl value_; }; -//---------------------------------------------------------------------------// -/*! - * Build a physics vector for quantities that are nonuniform in energy. - */ -class ValueGridGenericBuilder final : public ValueGridBuilder -{ - public: - //!@{ - //! \name Type aliases - using VecDbl = std::vector; - using Id = ItemId; - //!@} - - public: - // Construct - ValueGridGenericBuilder(VecDbl grid, - VecDbl value, - Interp grid_interp, - Interp value_interp); - - // Construct with linear interpolation - ValueGridGenericBuilder(VecDbl grid, VecDbl value); - - // Construct in the given store - ValueGridId build(ValueGridInserter) const final; - - private: - VecDbl grid_; - VecDbl value_; - Interp grid_interp_; - Interp value_interp_; -}; - //---------------------------------------------------------------------------// /*! * Special cases for indicating *only* on-the-fly cross sections. diff --git a/src/celeritas/grid/ValueGridInserter.cc b/src/celeritas/grid/ValueGridInserter.cc index 0ab5508f1c..41414f74a1 100644 --- a/src/celeritas/grid/ValueGridInserter.cc +++ b/src/celeritas/grid/ValueGridInserter.cc @@ -54,15 +54,5 @@ auto ValueGridInserter::operator()(UniformGridData const& log_grid, return (*this)(log_grid, XsGridData::no_scaling(), values); } -//---------------------------------------------------------------------------// -/*! - * Add a grid of host pointer data. - */ -auto ValueGridInserter::operator()(InterpolatedGrid, InterpolatedGrid) - -> GenericIndex -{ - CELER_NOT_IMPLEMENTED("generic grids"); -} - //---------------------------------------------------------------------------// } // namespace celeritas diff --git a/src/celeritas/grid/ValueGridInserter.hh b/src/celeritas/grid/ValueGridInserter.hh index 0d2a5af08f..856bbcd19a 100644 --- a/src/celeritas/grid/ValueGridInserter.hh +++ b/src/celeritas/grid/ValueGridInserter.hh @@ -17,7 +17,6 @@ #include "corecel/grid/UniformGridData.hh" #include "celeritas/Types.hh" -#include "GenericGridData.hh" #include "XsGridData.hh" namespace celeritas @@ -48,9 +47,7 @@ class ValueGridInserter using XsGridCollection = Collection; using SpanConstDbl = Span; - using InterpolatedGrid = std::pair; using XsIndex = ItemId; - using GenericIndex = ItemId; //!@} public: @@ -65,9 +62,6 @@ class ValueGridInserter // Add a grid of uniform log-grid data XsIndex operator()(UniformGridData const& log_grid, SpanConstDbl values); - // Add a grid of generic data - GenericIndex operator()(InterpolatedGrid grid, InterpolatedGrid values); - private: CollectionBuilder> values_; CollectionBuilder> xs_grids_; diff --git a/src/celeritas/grid/ValueGridData.cc b/src/celeritas/grid/ValueGridType.cc similarity index 69% rename from src/celeritas/grid/ValueGridData.cc rename to src/celeritas/grid/ValueGridType.cc index f3b3a2c22b..96a8be6ce3 100644 --- a/src/celeritas/grid/ValueGridData.cc +++ b/src/celeritas/grid/ValueGridType.cc @@ -3,21 +3,24 @@ // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: (Apache-2.0 OR MIT) //---------------------------------------------------------------------------// -//! \file celeritas/grid/ValueGridData.cc +//! \file celeritas/grid/ValueGridType.cc //---------------------------------------------------------------------------// -#include "ValueGridData.hh" +#include "ValueGridType.hh" #include "corecel/Assert.hh" +#include "corecel/io/EnumStringMapper.hh" namespace celeritas { //---------------------------------------------------------------------------// +/*! + * Get the string representation of a grid. + */ char const* to_cstring(ValueGridType value) { - static char const* const strings[] = {"macro_xs", "energy_loss", "range"}; - CELER_EXPECT(static_cast(value) * sizeof(char const*) - < sizeof(strings)); - return strings[static_cast(value)]; + static EnumStringMapper const to_cstring_impl{ + "macro_xs", "energy_loss", "range"}; + return to_cstring_impl(value); } //---------------------------------------------------------------------------// diff --git a/src/celeritas/grid/ValueGridData.hh b/src/celeritas/grid/ValueGridType.hh similarity index 91% rename from src/celeritas/grid/ValueGridData.hh rename to src/celeritas/grid/ValueGridType.hh index 805990f95a..57ab46949d 100644 --- a/src/celeritas/grid/ValueGridData.hh +++ b/src/celeritas/grid/ValueGridType.hh @@ -3,7 +3,7 @@ // See the top-level COPYRIGHT file for details. // SPDX-License-Identifier: (Apache-2.0 OR MIT) //---------------------------------------------------------------------------// -//! \file celeritas/grid/ValueGridData.hh +//! \file celeritas/grid/ValueGridType.hh //---------------------------------------------------------------------------// #pragma once @@ -19,12 +19,13 @@ enum class ValueGridType macro_xs, //!< Interaction cross sections energy_loss, //!< Energy loss per unit length range, //!< Particle range - size_ //!< Sentinel value + size_ }; template using ValueGridArray = EnumArray; +// Get the string representation of a grid char const* to_cstring(ValueGridType grid); //---------------------------------------------------------------------------// diff --git a/src/celeritas/io/LivermorePEReader.cc b/src/celeritas/io/LivermorePEReader.cc index fb2c0a2ded..fe223e248a 100644 --- a/src/celeritas/io/LivermorePEReader.cc +++ b/src/celeritas/io/LivermorePEReader.cc @@ -76,11 +76,13 @@ LivermorePEReader::operator()(AtomicNumber atomic_number) const // Read tabulated energies and cross sections double energy_min = 0.; double energy_max = 0.; - size_type size = 0; + int size = -1; infile >> energy_min >> energy_max >> size >> size; + CELER_VALIDATE(size >= 0, + << "invalid cross section size in '" << filename << "'"); result.xs_hi.x.resize(size); result.xs_hi.y.resize(size); - for (size_type i = 0; i < size; ++i) + for (int i = 0; i < size; ++i) { CELER_ASSERT(infile); infile >> result.xs_hi.x[i] >> result.xs_hi.y[i]; @@ -95,25 +97,34 @@ LivermorePEReader::operator()(AtomicNumber atomic_number) const << "failed to open '" << filename << "' (should contain cross section data)"); - // Set the physics vector type and the data type - result.xs_lo.vector_type = ImportPhysicsVectorType::free; - // Check that the file is not empty - if (!(infile.peek() == std::ifstream::traits_type::eof())) + if (infile.peek() != std::ifstream::traits_type::eof()) { // Read tabulated energies and cross sections - double energy_min = 0.; - double energy_max = 0.; - size_type size = 0; + double energy_min = 0; + double energy_max = 0; + int size = -1; infile >> energy_min >> energy_max >> size >> size; + CELER_VALIDATE(size >= 0, + << "invalid cross section size in '" << filename + << "'"); result.xs_lo.x.resize(size); result.xs_lo.y.resize(size); - for (size_type i = 0; i < size; ++i) + result.xs_lo.vector_type = ImportPhysicsVectorType::free; + for (int i = 0; i < size; ++i) { CELER_ASSERT(infile); infile >> result.xs_lo.x[i] >> result.xs_lo.y[i]; } } + else if (atomic_number <= AtomicNumber{2}) + { + // Total cross sections below the K-shell energy aren't present for + // elements with only one subshell, but if another element is + // missing them we have a problem + CELER_LOG(warning) << "No low-energy cross sections found in '" + << filename << "'"; + } } // Read subshell cross section fit parameters in low energy interval diff --git a/src/celeritas/neutron/data/NeutronElasticData.hh b/src/celeritas/neutron/data/NeutronElasticData.hh index d0b43da516..4ca5828667 100644 --- a/src/celeritas/neutron/data/NeutronElasticData.hh +++ b/src/celeritas/neutron/data/NeutronElasticData.hh @@ -83,12 +83,16 @@ struct NeutronElasticData units::MevMass neutron_mass; //! Microscopic (element) cross section data (G4PARTICLEXS/neutron/elZ) - Items reals; ElementItems micro_xs; //! A-dependent coefficients for the momentum transfer of the CHIPS model IsotopeItems coeffs; + // Backend data + Items reals; + + //// MEMBER FUNCTIONS //// + //! Model's minimum and maximum energy limit [MeV] static CELER_CONSTEXPR_FUNCTION units::MevEnergy min_valid_energy() { @@ -103,8 +107,8 @@ struct NeutronElasticData //! Whether the data are assigned explicit CELER_FUNCTION operator bool() const { - return ids && neutron_mass > zero_quantity() && !reals.empty() - && !micro_xs.empty() && !coeffs.empty(); + return ids && neutron_mass > zero_quantity() && !micro_xs.empty() + && !coeffs.empty() && !reals.empty(); } //! Assign from another set of data @@ -114,9 +118,9 @@ struct NeutronElasticData CELER_EXPECT(other); ids = other.ids; neutron_mass = other.neutron_mass; - reals = other.reals; micro_xs = other.micro_xs; coeffs = other.coeffs; + reals = other.reals; return *this; } }; diff --git a/src/celeritas/neutron/model/ChipsNeutronElasticModel.cc b/src/celeritas/neutron/model/ChipsNeutronElasticModel.cc index 7d19124c2e..ca794f4922 100644 --- a/src/celeritas/neutron/model/ChipsNeutronElasticModel.cc +++ b/src/celeritas/neutron/model/ChipsNeutronElasticModel.cc @@ -12,6 +12,7 @@ #include "celeritas/global/CoreParams.hh" #include "celeritas/global/CoreState.hh" #include "celeritas/global/TrackExecutor.hh" +#include "celeritas/grid/GenericGridBuilder.hh" #include "celeritas/io/ImportPhysicsTable.hh" #include "celeritas/io/ImportPhysicsVector.hh" #include "celeritas/mat/MaterialParams.hh" @@ -50,11 +51,12 @@ ChipsNeutronElasticModel::ChipsNeutronElasticModel( data.neutron_mass = particles.get(data.ids.neutron).mass(); // Load neutron elastic cross section data - make_builder(&data.micro_xs).reserve(materials.num_elements()); + CollectionBuilder micro_xs{&data.micro_xs}; + GenericGridBuilder build_grid{&data.reals}; for (auto el_id : range(ElementId{materials.num_elements()})) { AtomicNumber z = materials.get(el_id).atomic_number(); - this->append_xs(load_data(z), &data); + micro_xs.push_back(build_grid(load_data(z))); } CELER_ASSERT(data.micro_xs.size() == materials.num_elements()); @@ -129,27 +131,6 @@ ActionId ChipsNeutronElasticModel::action_id() const return this->host_ref().ids.action; } -//---------------------------------------------------------------------------// -/*! - * Construct interaction cross section data for a single element. - */ -void ChipsNeutronElasticModel::append_xs(ImportPhysicsVector const& inp, - HostXsData* data) const -{ - auto reals = make_builder(&data->reals); - GenericGridData micro_xs; - - // Add the tabulated interaction cross section from input - micro_xs.grid = reals.insert_back(inp.x.begin(), inp.x.end()); - micro_xs.value = reals.insert_back(inp.y.begin(), inp.y.end()); - micro_xs.grid_interp = Interp::linear; - micro_xs.value_interp = Interp::linear; - - // Add micro xs data - CELER_ASSERT(micro_xs); - make_builder(&data->micro_xs).push_back(micro_xs); -} - //---------------------------------------------------------------------------// /*! * Construct A-dependent coefficients of the CHIPS differential cross section diff --git a/src/celeritas/neutron/model/ChipsNeutronElasticModel.hh b/src/celeritas/neutron/model/ChipsNeutronElasticModel.hh index a40bc09e78..1c1c804362 100644 --- a/src/celeritas/neutron/model/ChipsNeutronElasticModel.hh +++ b/src/celeritas/neutron/model/ChipsNeutronElasticModel.hh @@ -86,7 +86,6 @@ class ChipsNeutronElasticModel final : public Model using HostXsData = HostVal; //// HELPER FUNCTIONS //// - void append_xs(ImportPhysicsVector const& inp, HostXsData* xs_data) const; void append_coeffs(AtomicMassNumber A, HostXsData* xs_data) const; }; diff --git a/src/celeritas/neutron/xs/NeutronElasticMicroXsCalculator.hh b/src/celeritas/neutron/xs/NeutronElasticMicroXsCalculator.hh index 6592cac3dd..c9fc17e685 100644 --- a/src/celeritas/neutron/xs/NeutronElasticMicroXsCalculator.hh +++ b/src/celeritas/neutron/xs/NeutronElasticMicroXsCalculator.hh @@ -69,11 +69,8 @@ auto NeutronElasticMicroXsCalculator::operator()(ElementId el_id) const { CELER_EXPECT(el_id < shared_.micro_xs.size()); - // Get element cross section data - GenericGridData grid = shared_.micro_xs[el_id]; - // Calculate micro cross section at the given energy - GenericCalculator calc_xs(grid, shared_.reals); + GenericCalculator calc_xs(shared_.micro_xs[el_id], shared_.reals); real_type result = calc_xs(inc_energy_); return BarnXs{result}; diff --git a/src/celeritas/optical/CerenkovData.hh b/src/celeritas/optical/CerenkovData.hh index a8ff80a108..e98fdf2014 100644 --- a/src/celeritas/optical/CerenkovData.hh +++ b/src/celeritas/optical/CerenkovData.hh @@ -29,15 +29,17 @@ struct CerenkovData //// MEMBER DATA //// - Items reals; OpticalMaterialItems angle_integral; + // Backend data + Items reals; + //// MEMBER FUNCTIONS //// //! Whether all data are assigned and valid explicit CELER_FUNCTION operator bool() const { - return !reals.empty() && !angle_integral.empty(); + return !angle_integral.empty() && !reals.empty(); } //! Assign from another set of data @@ -45,8 +47,8 @@ struct CerenkovData CerenkovData& operator=(CerenkovData const& other) { CELER_EXPECT(other); - reals = other.reals; angle_integral = other.angle_integral; + reals = other.reals; return *this; } }; diff --git a/src/celeritas/optical/CerenkovDndxCalculator.hh b/src/celeritas/optical/CerenkovDndxCalculator.hh index 424f90bddf..0e70a9ed89 100644 --- a/src/celeritas/optical/CerenkovDndxCalculator.hh +++ b/src/celeritas/optical/CerenkovDndxCalculator.hh @@ -14,7 +14,6 @@ #include "corecel/Types.hh" #include "celeritas/Quantities.hh" #include "celeritas/grid/GenericCalculator.hh" -#include "celeritas/grid/GenericGridData.hh" #include "celeritas/grid/VectorUtils.hh" #include "CerenkovData.hh" diff --git a/src/celeritas/optical/CerenkovGenerator.hh b/src/celeritas/optical/CerenkovGenerator.hh index a87c5dc056..8c4bab5439 100644 --- a/src/celeritas/optical/CerenkovGenerator.hh +++ b/src/celeritas/optical/CerenkovGenerator.hh @@ -16,7 +16,6 @@ #include "corecel/math/ArrayOperators.hh" #include "corecel/math/ArrayUtils.hh" #include "celeritas/grid/GenericCalculator.hh" -#include "celeritas/grid/GenericGridData.hh" #include "celeritas/random/distribution/BernoulliDistribution.hh" #include "celeritas/random/distribution/GenerateCanonical.hh" #include "celeritas/random/distribution/UniformRealDistribution.hh" diff --git a/src/celeritas/optical/CerenkovParams.cc b/src/celeritas/optical/CerenkovParams.cc index 531c28df02..664176e3a5 100644 --- a/src/celeritas/optical/CerenkovParams.cc +++ b/src/celeritas/optical/CerenkovParams.cc @@ -16,6 +16,7 @@ #include "corecel/math/Algorithms.hh" #include "celeritas/Quantities.hh" #include "celeritas/Types.hh" +#include "celeritas/grid/GenericGridBuilder.hh" #include "celeritas/grid/GenericGridData.hh" #include "OpticalPropertyParams.hh" @@ -28,25 +29,27 @@ namespace celeritas */ CerenkovParams::CerenkovParams(SPConstProperties properties) { - HostVal data; + CELER_EXPECT(properties); auto const& host_ref = properties->host_ref(); - DedupeCollectionBuilder reals(&data.reals); + + HostVal data; + GenericGridBuilder build_angle_integral(&data.reals); CollectionBuilder angle_integral(&data.angle_integral); + for (auto mat_id : range(OpticalMaterialId(host_ref.refractive_index.size()))) { - GenericGridData ai_grid; auto const& ri_grid = host_ref.refractive_index[mat_id]; if (!ri_grid) { // No refractive index data stored for this material - angle_integral.push_back(ai_grid); + angle_integral.push_back({}); continue; } // Calculate the Cerenkov angle integral - auto const refractive_index = host_ref.reals[ri_grid.value]; - auto const energy = host_ref.reals[ri_grid.grid]; + auto const&& refractive_index = host_ref.reals[ri_grid.value]; + auto const&& energy = host_ref.reals[ri_grid.grid]; std::vector integral(energy.size()); for (size_type i = 1; i < energy.size(); ++i) { @@ -55,10 +58,11 @@ CerenkovParams::CerenkovParams(SPConstProperties properties) * (1 / ipow<2>(refractive_index[i - 1]) + 1 / ipow<2>(refractive_index[i])); } - ai_grid.grid = reals.insert_back(energy.begin(), energy.end()); - ai_grid.value = reals.insert_back(integral.begin(), integral.end()); - angle_integral.push_back(ai_grid); + angle_integral.push_back( + build_angle_integral(make_span(energy), make_span(integral))); } + CELER_ASSERT(angle_integral.size() == host_ref.refractive_index.size()); + data_ = CollectionMirror{std::move(data)}; CELER_ENSURE(data_ || host_ref.refractive_index.empty()); } diff --git a/src/celeritas/optical/OpticalPropertyData.hh b/src/celeritas/optical/OpticalPropertyData.hh index 2264741834..a6c39baa26 100644 --- a/src/celeritas/optical/OpticalPropertyData.hh +++ b/src/celeritas/optical/OpticalPropertyData.hh @@ -31,15 +31,17 @@ struct OpticalPropertyData //// MEMBER DATA //// - Items reals; OpticalMaterialItems refractive_index; + // Backend data + Items reals; + //// MEMBER FUNCTIONS //// //! Whether all data are assigned and valid explicit CELER_FUNCTION operator bool() const { - return !reals.empty() && !refractive_index.empty(); + return !refractive_index.empty() && !reals.empty(); } //! Assign from another set of data @@ -47,8 +49,8 @@ struct OpticalPropertyData OpticalPropertyData& operator=(OpticalPropertyData const& other) { CELER_EXPECT(other); - reals = other.reals; refractive_index = other.refractive_index; + reals = other.reals; return *this; } }; diff --git a/src/celeritas/optical/OpticalPropertyParams.cc b/src/celeritas/optical/OpticalPropertyParams.cc index 66879d3b20..d1ec7ba289 100644 --- a/src/celeritas/optical/OpticalPropertyParams.cc +++ b/src/celeritas/optical/OpticalPropertyParams.cc @@ -16,6 +16,7 @@ #include "corecel/math/Algorithms.hh" #include "celeritas/Quantities.hh" #include "celeritas/Types.hh" +#include "celeritas/grid/GenericGridBuilder.hh" #include "celeritas/grid/GenericGridData.hh" #include "celeritas/grid/VectorUtils.hh" #include "celeritas/io/ImportData.hh" @@ -55,17 +56,16 @@ OpticalPropertyParams::from_import(ImportData const& data) OpticalPropertyParams::OpticalPropertyParams(Input const& inp) { HostVal data; - DedupeCollectionBuilder reals(&data.reals); - CollectionBuilder refractive_index(&data.refractive_index); + CollectionBuilder refractive_index{&data.refractive_index}; + GenericGridBuilder build_grid(&data.reals); for (auto const& mat : inp.data) { // Store refractive index tabulated as a function of photon energy auto const& ri_vec = mat.refractive_index; - GenericGridData grid; if (ri_vec.x.empty()) { // No refractive index data for this material - refractive_index.push_back(grid); + refractive_index.push_back({}); continue; } @@ -78,11 +78,10 @@ OpticalPropertyParams::OpticalPropertyParams(Input const& inp) << "refractive index values are not monotonically " "increasing"); - grid.grid = reals.insert_back(ri_vec.x.begin(), ri_vec.x.end()); - grid.value = reals.insert_back(ri_vec.y.begin(), ri_vec.y.end()); - CELER_ASSERT(grid); - refractive_index.push_back(grid); + refractive_index.push_back(build_grid(ri_vec)); } + CELER_ASSERT(refractive_index.size() == inp.data.size()); + data_ = CollectionMirror{std::move(data)}; CELER_ENSURE(data_ || inp.data.empty()); } diff --git a/src/celeritas/phys/ImportedProcessAdapter.cc b/src/celeritas/phys/ImportedProcessAdapter.cc index 9e4a220836..97a531fbe6 100644 --- a/src/celeritas/phys/ImportedProcessAdapter.cc +++ b/src/celeritas/phys/ImportedProcessAdapter.cc @@ -17,7 +17,7 @@ #include "corecel/cont/Range.hh" #include "celeritas/Types.hh" #include "celeritas/grid/ValueGridBuilder.hh" -#include "celeritas/grid/ValueGridData.hh" +#include "celeritas/grid/ValueGridType.hh" #include "celeritas/io/ImportData.hh" #include "celeritas/io/ImportPhysicsTable.hh" diff --git a/src/celeritas/phys/Model.hh b/src/celeritas/phys/Model.hh index 124d235995..1b8735ffcc 100644 --- a/src/celeritas/phys/Model.hh +++ b/src/celeritas/phys/Model.hh @@ -16,7 +16,7 @@ #include "celeritas/Types.hh" #include "celeritas/global/ActionInterface.hh" // IWYU pragma: export #include "celeritas/grid/ValueGridBuilder.hh" -#include "celeritas/grid/ValueGridData.hh" +#include "celeritas/grid/ValueGridType.hh" #include "Applicability.hh" // IWYU pragma: export diff --git a/src/celeritas/phys/ParticleData.hh b/src/celeritas/phys/ParticleData.hh index 6b78eb6fb2..3160431131 100644 --- a/src/celeritas/phys/ParticleData.hh +++ b/src/celeritas/phys/ParticleData.hh @@ -44,15 +44,14 @@ struct ParticleParamsData //// TYPES //// template - using Items = celeritas::Collection; + using Items = Collection; //// DATA //// Items mass; //!< Rest mass [MeV / c^2] Items charge; //!< Charge in units of [e] Items decay_constant; //!< Decay constant [1/s] - Items matter; //!< Antiparticle (negative PDG - //!< number) + Items matter; //!< Antiparticle flag (negative PDG number) //// METHODS //// @@ -63,8 +62,8 @@ struct ParticleParamsData && !matter.empty(); } - //! Params size - CELER_FUNCTION typename Items::size_type size() const + //! Number of particles + CELER_FUNCTION ParticleId::size_type size() const { return decay_constant.size(); } diff --git a/src/celeritas/phys/ParticleParams.cc b/src/celeritas/phys/ParticleParams.cc index 8a60885780..501c13dc77 100644 --- a/src/celeritas/phys/ParticleParams.cc +++ b/src/celeritas/phys/ParticleParams.cc @@ -21,6 +21,8 @@ #include "ParticleData.hh" // IWYU pragma: associated #include "ParticleView.hh" +#include "detail/ParticleInserter.hh" + namespace celeritas { //---------------------------------------------------------------------------// @@ -83,40 +85,19 @@ ParticleParams::ParticleParams(Input const& input) // Build elements and materials on host. HostVal host_data; - auto mass = make_builder(&host_data.mass); - auto charge = make_builder(&host_data.charge); - auto decay_constant = make_builder(&host_data.decay_constant); - auto matter = make_builder(&host_data.matter); - mass.reserve(input.size()); - charge.reserve(input.size()); - decay_constant.reserve(input.size()); - matter.reserve(input.size()); - + detail::ParticleInserter insert_particle(&host_data); for (auto const& particle : input) { CELER_EXPECT(!particle.name.empty()); - CELER_EXPECT(particle.mass >= zero_quantity()); - CELER_EXPECT(particle.decay_constant >= 0); + + ParticleId id = insert_particle(particle); // Add host metadata - ParticleId id(name_to_id_.size()); - bool inserted; - std::tie(std::ignore, inserted) - = name_to_id_.insert({particle.name, id}); + md_.push_back({particle.name, particle.pdg_code}); + bool inserted = name_to_id_.insert({particle.name, id}).second; CELER_ASSERT(inserted); - std::tie(std::ignore, inserted) - = pdg_to_id_.insert({particle.pdg_code, id}); + inserted = pdg_to_id_.insert({particle.pdg_code, id}).second; CELER_ASSERT(inserted); - - // Save the metadata on the host - md_.push_back({particle.name, particle.pdg_code}); - - // Save the definitions on the host - mass.push_back(particle.mass); - charge.push_back(particle.charge); - decay_constant.push_back(particle.decay_constant); - matter.push_back(particle.pdg_code.get() < 0 ? MatterType::antiparticle - : MatterType::particle); } // Move to mirrored data, copying to device diff --git a/src/celeritas/phys/PhysicsData.hh b/src/celeritas/phys/PhysicsData.hh index 534f1fb1c4..d81d482927 100644 --- a/src/celeritas/phys/PhysicsData.hh +++ b/src/celeritas/phys/PhysicsData.hh @@ -16,7 +16,7 @@ #include "celeritas/em/data/AtomicRelaxationData.hh" #include "celeritas/em/data/EPlusGGData.hh" #include "celeritas/em/data/LivermorePEData.hh" -#include "celeritas/grid/ValueGridData.hh" +#include "celeritas/grid/ValueGridType.hh" #include "celeritas/grid/XsGridData.hh" #include "celeritas/neutron/data/NeutronElasticData.hh" diff --git a/src/celeritas/phys/PhysicsParams.cc b/src/celeritas/phys/PhysicsParams.cc index 1169072a52..7eed74b7c4 100644 --- a/src/celeritas/phys/PhysicsParams.cc +++ b/src/celeritas/phys/PhysicsParams.cc @@ -36,8 +36,8 @@ #include "celeritas/global/ActionInterface.hh" #include "celeritas/global/ActionRegistry.hh" #include "celeritas/grid/ValueGridBuilder.hh" -#include "celeritas/grid/ValueGridData.hh" #include "celeritas/grid/ValueGridInserter.hh" +#include "celeritas/grid/ValueGridType.hh" #include "celeritas/grid/XsCalculator.hh" #include "celeritas/grid/XsGridData.hh" #include "celeritas/mat/MaterialData.hh" diff --git a/src/celeritas/phys/PhysicsStepUtils.hh b/src/celeritas/phys/PhysicsStepUtils.hh index b0cf12469a..d77d7a7c78 100644 --- a/src/celeritas/phys/PhysicsStepUtils.hh +++ b/src/celeritas/phys/PhysicsStepUtils.hh @@ -17,7 +17,7 @@ #include "celeritas/grid/EnergyLossCalculator.hh" #include "celeritas/grid/InverseRangeCalculator.hh" #include "celeritas/grid/RangeCalculator.hh" -#include "celeritas/grid/ValueGridData.hh" +#include "celeritas/grid/ValueGridType.hh" #include "celeritas/grid/XsCalculator.hh" #include "celeritas/mat/MaterialTrackView.hh" #include "celeritas/random/Selector.hh" diff --git a/src/celeritas/phys/Process.hh b/src/celeritas/phys/Process.hh index 8eb9cc1b1a..ef7fab5d6c 100644 --- a/src/celeritas/phys/Process.hh +++ b/src/celeritas/phys/Process.hh @@ -13,7 +13,7 @@ #include "corecel/cont/Range.hh" #include "celeritas/Types.hh" -#include "celeritas/grid/ValueGridData.hh" +#include "celeritas/grid/ValueGridType.hh" namespace celeritas { diff --git a/src/celeritas/phys/detail/ParticleInserter.hh b/src/celeritas/phys/detail/ParticleInserter.hh new file mode 100644 index 0000000000..a4cb90f9e2 --- /dev/null +++ b/src/celeritas/phys/detail/ParticleInserter.hh @@ -0,0 +1,85 @@ +//----------------------------------*-C++-*----------------------------------// +// Copyright 2024 UT-Battelle, LLC, and other Celeritas developers. +// See the top-level COPYRIGHT file for details. +// SPDX-License-Identifier: (Apache-2.0 OR MIT) +//---------------------------------------------------------------------------// +//! \file celeritas/phys/detail/ParticleInserter.hh +//---------------------------------------------------------------------------// +#pragma once + +#include "corecel/data/CollectionBuilder.hh" +#include "celeritas/Units.hh" +#include "celeritas/phys/ParticleData.hh" +#include "celeritas/phys/ParticleParams.hh" + +namespace celeritas +{ +namespace detail +{ +//---------------------------------------------------------------------------// +/*! + * Build particle parameters from user input. + */ +class ParticleInserter +{ + public: + //!@{ + //! \name Type aliases + using Data = HostVal; + using Input = ParticleParams::ParticleInput; + using Id = ParticleId; + //!@} + + public: + // Construct from host data to be built + explicit inline ParticleInserter(Data* data); + + // Add a particle type + inline Id operator()(Input const& inp); + + private: + template + using Builder = CollectionBuilder; + + Builder mass_; + Builder charge_; + Builder decay_constant_; + Builder matter_; +}; + +//---------------------------------------------------------------------------// +// INLINE DEFINITIONS +//---------------------------------------------------------------------------// +/*! + * Construct from host data to be built. + */ +ParticleInserter::ParticleInserter(Data* data) + : mass_{&data->mass} + , charge_{&data->charge} + , decay_constant_{&data->decay_constant} + , matter_{&data->matter} +{ +} + +//---------------------------------------------------------------------------// +/*! + * Add a particle. + */ +auto ParticleInserter::operator()(Input const& inp) -> Id +{ + CELER_VALIDATE(inp.mass >= zero_quantity(), + << "invalid particle mass " << inp.mass.value()); + CELER_VALIDATE(inp.decay_constant >= 0, + << "invalid particle decay constant " << inp.decay_constant); + + auto result = mass_.push_back(inp.mass); + charge_.push_back(inp.charge); + decay_constant_.push_back(inp.decay_constant); + matter_.push_back(inp.pdg_code.get() < 0 ? MatterType::antiparticle + : MatterType::particle); + return result; +} + +//---------------------------------------------------------------------------// +} // namespace detail +} // namespace celeritas diff --git a/test/celeritas/grid/GenericCalculator.test.cc b/test/celeritas/grid/GenericCalculator.test.cc index 618c10fa03..6fd6b500b7 100644 --- a/test/celeritas/grid/GenericCalculator.test.cc +++ b/test/celeritas/grid/GenericCalculator.test.cc @@ -12,8 +12,9 @@ #include "corecel/cont/Range.hh" #include "corecel/data/CollectionBuilder.hh" +#include "corecel/data/Ref.hh" +#include "celeritas/grid/GenericGridBuilder.hh" -#include "CalculatorTestBase.hh" #include "celeritas_test.hh" namespace celeritas @@ -24,27 +25,24 @@ namespace test // TEST HARNESS //---------------------------------------------------------------------------// -class GenericCalculatorTest : public CalculatorTestBase +class GenericCalculatorTest : public Test { protected: + template + using Items = Collection; + void SetUp() override { - std::vector grid{1.0, 2.0, 1e2, 1e4}; - std::vector value{4.0, 8.0, 8.0, 2.0}; - - storage_ = {}; - data_.grid - = make_builder(&storage_).insert_back(grid.begin(), grid.end()); - data_.value - = make_builder(&storage_).insert_back(value.begin(), value.end()); - ref_ = storage_; + std::vector const grid = {1.0, 2.0, 1e2, 1e4}; + std::vector const value = {4.0, 8.0, 8.0, 2.0}; - CELER_ENSURE(data_); + GenericGridBuilder build_grid(&reals_); + grid_ = build_grid(make_span(grid), make_span(value)); + CELER_ENSURE(grid_); } - GenericGridData data_; - Values storage_; - Data ref_; + GenericGridData grid_; + Items reals_; }; //---------------------------------------------------------------------------// @@ -53,7 +51,9 @@ class GenericCalculatorTest : public CalculatorTestBase TEST_F(GenericCalculatorTest, all) { - GenericCalculator calc(data_, ref_); + Collection ref; + ref = reals_; + GenericCalculator calc(grid_, ref); // Test accessing tabulated data EXPECT_EQ(4.0, calc[0]); diff --git a/test/celeritas/grid/ValueGridBuilder.test.cc b/test/celeritas/grid/ValueGridBuilder.test.cc index 6cf31f628b..c6f86dee94 100644 --- a/test/celeritas/grid/ValueGridBuilder.test.cc +++ b/test/celeritas/grid/ValueGridBuilder.test.cc @@ -123,30 +123,6 @@ TEST_F(ValueGridBuilderTest, log_grid) } } -TEST_F(ValueGridBuilderTest, DISABLED_generic_grid) -{ - using Builder_t = ValueGridGenericBuilder; - - VecBuilder entries; - { - entries.push_back( - make_shared(VeDbl{.1, .2, .3}, VeDbl{1, 2, 3})); - entries.push_back(make_shared( - VeDbl{1e-2, 1e-1, 1}, VeDbl{1, 2, 3}, Interp::log, Interp::linear)); - } - - // Build - this->build(entries); - - // Test results using the physics calculator - ASSERT_EQ(2, grid_storage.size()); - { - XsCalculator calc_xs(grid_storage[XsIndex{0}], real_ref); - EXPECT_SOFT_EQ(0.1, calc_xs(Energy{1e1})); - EXPECT_SOFT_EQ(0.2, calc_xs(Energy{1e2})); - EXPECT_SOFT_EQ(0.3, calc_xs(Energy{1e3})); - } -} //---------------------------------------------------------------------------// } // namespace test } // namespace celeritas diff --git a/test/celeritas/neutron/NeutronElastic.test.cc b/test/celeritas/neutron/NeutronElastic.test.cc index 8710030d5e..bba6036e0f 100644 --- a/test/celeritas/neutron/NeutronElastic.test.cc +++ b/test/celeritas/neutron/NeutronElastic.test.cc @@ -70,9 +70,8 @@ TEST_F(NeutronElasticTest, micro_xs) ElementId el_id{1}; // Check the size of the element cross section data (G4PARTICLEXS4.0) - NeutronElasticRef shared = model_->host_ref(); - GenericGridData grid = shared.micro_xs[el_id]; - EXPECT_EQ(grid.grid.size(), 181); + NeutronElasticRef const& shared = model_->host_ref(); + EXPECT_EQ(shared.micro_xs[el_id].grid.size(), 181); // Microscopic cross section (\f$ mm^{2} \f$) in [1e-05:1e+4] (MeV) std::vector const expected_micro_xs = {7.7754820698300016, diff --git a/test/celeritas/optical/Cerenkov.test.cc b/test/celeritas/optical/Cerenkov.test.cc index b44d724b42..8b88dd4a77 100644 --- a/test/celeritas/optical/Cerenkov.test.cc +++ b/test/celeritas/optical/Cerenkov.test.cc @@ -17,7 +17,6 @@ #include "corecel/math/Quantity.hh" #include "celeritas/Constants.hh" #include "celeritas/Units.hh" -#include "celeritas/grid/GenericGridData.hh" #include "celeritas/grid/VectorUtils.hh" #include "celeritas/io/ImportOpticalMaterial.hh" #include "celeritas/optical/CerenkovDndxCalculator.hh" @@ -124,16 +123,17 @@ class CerenkovTest : public OpticalTestBase { // Build optical properties: only one material (water) ImportOpticalProperty water; - auto wavelength = get_wavelength(); - for (auto wl : wavelength) + for (double wl : get_wavelength()) { water.refractive_index.x.push_back( convert_to_energy(wl * micrometer)); } water.refractive_index.y = {get_refractive_index().begin(), get_refractive_index().end()}; + water.refractive_index.vector_type = ImportPhysicsVectorType::free; + OpticalPropertyParams::Input input; - input.data.push_back(water); + input.data.push_back(std::move(water)); properties = std::make_shared(std::move(input)); // Build Cerenkov data diff --git a/test/celeritas/optical/ScintillationGenerator.test.cc b/test/celeritas/optical/ScintillationGenerator.test.cc index 4aab914c52..4af37f4e51 100644 --- a/test/celeritas/optical/ScintillationGenerator.test.cc +++ b/test/celeritas/optical/ScintillationGenerator.test.cc @@ -8,8 +8,6 @@ #include "celeritas/optical/ScintillationGenerator.hh" #include "corecel/data/Collection.hh" -#include "corecel/data/CollectionBuilder.hh" -#include "corecel/data/CollectionMirror.hh" #include "celeritas/Quantities.hh" #include "celeritas/optical/OpticalDistributionData.hh" #include "celeritas/optical/OpticalPrimary.hh"