12#include "detray/builders/bin_fillers.hpp"
13#include "detray/builders/detail/material_deduplication.hpp"
14#include "detray/builders/material_map_factory.hpp"
15#include "detray/builders/material_map_generator.hpp"
16#include "detray/builders/surface_factory_interface.hpp"
17#include "detray/builders/volume_builder_interface.hpp"
18#include "detray/core/concepts.hpp"
19#include "detray/geometry/concepts.hpp"
20#include "detray/geometry/surface.hpp"
21#include "detray/material/material_map.hpp"
35template <
typename material_t>
45 typename mat_map_factory_t =
48 using material_t =
typename detector_t::material;
59 typename fill_by_bin::template bin_data<DIM, value_type>;
67 DETRAY_VERBOSE_HOST(
"Add material map builder to volume: " << this->
name());
84 typename detector_t::geometry_context ctx = {})
override {
85 DETRAY_VERBOSE_HOST(
"Add [material] surface factory:");
92 auto mat_factory = std::dynamic_pointer_cast<sf_factory_t>(sf_factory);
95 "-> found decoration: " << DETRAY_TYPENAME(sf_factory_t));
96 (*mat_factory)(this->
surfaces(), m_bin_data, m_n_bins, m_axis_spans);
99 std::dynamic_pointer_cast<material_map_generator<detector_t>>(
102 DETRAY_VERBOSE_HOST(
"-> found decoration: " << DETRAY_TYPENAME(
103 material_map_generator<detector_t>));
104 (*mat_generator)(this->
surfaces(), this->
masks(), m_bin_data, m_n_bins);
108 if (!mat_factory && !mat_generator) {
109 DETRAY_VERBOSE_HOST(
"No material found in this surface factory");
110 DETRAY_VERBOSE_HOST(
"-> Built non-material surfaces");
122 typename detector_t::geometry_context ctx = {}) ->
123 typename detector_t::volume_type*
override {
124 DETRAY_VERBOSE_HOST(
"Build material maps...");
128 add_material_maps(opt, det);
131 "-> Let underlying builders construct the volume using correct "
132 "material links...");
135 "Successfully built material maps for volume: " << this->
name());
145 bool surface_has_map(
const dindex sf_idx)
const {
146 return m_bin_data.contains(sf_idx);
156 void add_material_maps(
const volume_builder_options& opt, detector_t& det) {
157 DETRAY_VERBOSE_HOST(
"Build material maps for surfaces...");
162 for (
dindex sf_idx = 0u; sf_idx < n_surfaces; ++sf_idx) {
163 if (!surface_has_map(sf_idx)) {
167 auto& sf_desc = this->
surfaces().at(sf_idx);
169 DETRAY_DEBUG_HOST(
"-> surface #" << sf_idx <<
" sf_desc = " << sf_desc);
174 if (
auto axis_spans_itr = m_axis_spans.find(sf_idx);
175 axis_spans_itr != m_axis_spans.end()) {
176 axis_spans = axis_spans_itr->second;
181 auto [mat_id, mat_idx] =
182 this->
masks().template visit<detail::add_sf_material_map<material_t>>(
183 sf_desc.mask(), m_factory, m_bin_data.at(sf_idx),
184 m_n_bins.at(sf_idx), axis_spans, det._materials,
188 if (mat_id != sf_desc.material().id() || mat_idx ==
dindex_invalid) {
189 std::stringstream err_msg;
190 err_msg <<
"-> material id mismatch for surface " << sf_idx
191 <<
": expected " << sf_desc.material().id() <<
", got "
194 DETRAY_FATAL_HOST(err_msg.str());
195 throw std::runtime_error(err_msg.str());
198 sf_desc.material().set_index(mat_idx);
200 DETRAY_DEBUG_HOST(
"--> material link = " << sf_desc.material());
205 std::map<dindex, std::vector<bin_data_type>> m_bin_data;
207 std::map<dindex, darray<std::size_t, DIM>> m_n_bins{};
209 std::map<dindex, darray<std::vector<scalar_type>, DIM>> m_axis_spans{};
211 mat_map_factory_t m_factory{};
222template <
typename material_t>
234 template <
typename mask_coll_t,
typename index_range_t,
235 typename mat_factory_t,
typename bin_data_t, std::size_t DIM,
237 DETRAY_HOST
inline std::pair<typename material_t::id, dindex>
operator()(
238 [[maybe_unused]]
const mask_coll_t& mask_coll,
239 [[maybe_unused]]
const index_range_t& index,
240 [[maybe_unused]]
const mat_factory_t& mat_factory,
241 [[maybe_unused]] std::vector<bin_data_t>& bin_data,
243 [[maybe_unused]]
const darray<std::vector<scalar_t>, DIM>& axis_spans,
244 [[maybe_unused]] material_store_t& mat_store,
245 [[maybe_unused]]
const bool deduplicate =
false)
const {
246 using mask_t =
typename mask_coll_t::value_type;
254 using index_t =
typename index_range_t::index_type;
257 sf_mask = mask_coll.at(index.lower());
259 if (index.size() > 1u) {
260 const index_range_t other_masks{
261 index.lower() + 1u,
static_cast<index_t
>(index.size() - 1u)};
264 for (
const auto& sub_mask :
266 sf_mask = sf_mask + sub_mask;
270 sf_mask = mask_coll.at(index);
273 auto mat_grid = mat_factory.new_grid(sf_mask, n_bins, {}, {}, axis_spans);
276 using non_owning_t =
typename decltype(mat_grid)::template type<false>;
279 if constexpr (types::contains<material_t, non_owning_t>) {
280 DETRAY_VERBOSE_HOST(
"Filling material grid...");
283 for (
const auto& bin : bin_data) {
284 mat_grid.template populate<replace<>>(bin.local_bin_idx,
288 constexpr auto gid{types::id<material_t, non_owning_t>};
292 const auto& grid_coll = mat_store.template get<gid>();
293 for (
dindex i = 0u; i < grid_coll.size(); ++i) {
294 if (is_identical_grid(mat_grid, grid_coll[i])) {
296 "Found identical material grid:" << gid <<
" at index " << i);
303 mat_store.template push_back<gid>(mat_grid);
304 DETRAY_VERBOSE_HOST(
"Built material grid:" << gid <<
":\n"
308 return {gid,
static_cast<dindex>(mat_store.template size<gid>() - 1u)};
detector_t detector_type
Detector type whose geometry and material stores are populated.
Definition material_map_builder.hpp:54
typename fill_by_bin::template bin_data< DIM, value_type > bin_data_type
Bin payload containing a local bin index and its material values.
Definition material_map_builder.hpp:58
material_slab< scalar_type > value_type
Material slab type stored in each bin.
Definition material_map_builder.hpp:56
auto build(detector_t &det, const volume_builder_options &opt, typename detector_t::geometry_context ctx={}) -> typename detector_t::volume_type *override
Add the volume and the material maps to the detector det.
Definition material_map_builder.hpp:121
void add_surfaces(std::shared_ptr< surface_factory_interface< detector_t > > sf_factory, typename detector_t::geometry_context ctx={}) override
Overwrite, to add material maps in addition to surfaces.
Definition material_map_builder.hpp:82
dscalar< typename detector_t::algebra_type > scalar_type
Scalar type used by material map bins.
Definition material_map_builder.hpp:52
auto data() const -> const std::map< dindex, std::vector< bin_data_type > > &
Definition material_map_builder.hpp:73
material_map_builder(std::unique_ptr< volume_builder_interface< detector_t > > vol_builder)
Definition material_map_builder.hpp:64
Factory class for material maps.
Definition material_map_factory.hpp:39
How to generate surfaces with their corresponding masks and transforms.
Definition surface_factory_interface.hpp:120
Interface for volume builders (and volume builder decorators).
Definition volume_builder_interface.hpp:66
std::string_view name() override
Returns the wrapped volume's name.
Definition volume_builder_interface.hpp:222
volume_decorator(std::unique_ptr< volume_builder_interface< detector_t > > vol_builder)
Wraps a volume builder.
Definition volume_builder_interface.hpp:178
detector_t::surface_lookup_container & surfaces() override
Returns mutable access to the wrapped builder's surface lookup container.
Definition volume_builder_interface.hpp:283
detector_t::mask_container & masks() override
Returns mutable access to the wrapped builder's masks.
Definition volume_builder_interface.hpp:293
void add_surfaces(std::shared_ptr< surface_factory_interface< detector_t > > sf_factory, typename detector_t::geometry_context ctx={}) override
Adds surfaces through the wrapped builder's factory interface.
Definition volume_builder_interface.hpp:267
auto build(detector_t &det, const volume_builder_options &opt, typename detector_t::geometry_context={}) -> typename detector_t::volume_type *override
Builds the wrapped volume in the detector.
Definition volume_builder_interface.hpp:229
Check if a type can be used as a detector.
Definition concepts.hpp:47
Concept that checks if a type models an interval of some value that can be obtained with 'get'.
Definition concepts.hpp:41
Definition concepts.hpp:197
Scalar concept: Elements of vectors/matrices (can be simd vectors).
Definition concepts.hpp:40
Detray include(s).
Definition array_operators.hpp:18
get_scalar_t< A, T > dscalar
Scalar type for algebra A and value type T.
Definition algebra.hpp:64
unsigned int dindex
Default index type.
Definition indexing.hpp:18
constexpr dindex dindex_invalid
Global invalid index definition.
Definition indexing.hpp:21
std::array< value_t, kDIM > darray
Fixed-size array container.
Definition containers.hpp:30
grid_factory< bins::single< material_slab< dscalar< algebra_t > > >, simple_serializer, algebra_t > material_grid_factory
How to build material maps of various shapes.
Definition material_map.hpp:36
A functor to add a material map to a surface.
Definition material_map_builder.hpp:223
std::pair< typename material_t::id, dindex > operator()(const mask_coll_t &mask_coll, const index_range_t &index, const mat_factory_t &mat_factory, std::vector< bin_data_t > &bin_data, const darray< std::size_t, DIM > &n_bins, const darray< std::vector< scalar_t >, DIM > &axis_spans, material_store_t &mat_store, const bool deduplicate=false) const
Build a material grid for a surface mask and store its link.
Definition material_map_builder.hpp:237
Slab structure to be mapped on the mask (plane, cylinder).
Definition material_slab.hpp:25
interface type to construct a subrange_view with CTAD
Definition subrange.hpp:90
Options for the volume builder classes.
Definition volume_builder_interface.hpp:29