ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
homogeneous_material_generator.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
12#include "detray/builders/surface_factory_interface.hpp"
13#include "detray/core/concepts.hpp"
14#include "detray/definitions/algebra.hpp"
15#include "detray/definitions/detail/qualifiers.hpp"
16#include "detray/definitions/indexing.hpp"
17#include "detray/material/material.hpp"
18#include "detray/material/material_rod.hpp"
19#include "detray/material/material_slab.hpp"
20#include "detray/material/predefined_materials.hpp"
21#include "detray/utils/logging.hpp"
22#include "detray/utils/ranges.hpp"
23#include "detray/utils/type_registry.hpp"
24
25// System include(s)
26#include <sstream>
27#include <stdexcept>
28
29namespace detray {
30
32template <concepts::scalar scalar_t>
42
50 return *this;
51 }
52
56 const material<scalar_t> &m) {
58 return *this;
59 }
60
65 return *this;
66 }
67
70 constexpr hom_material_config &thickness(const scalar_t t) {
71 m_thickness = t;
72 return *this;
73 }
74
75
79 constexpr const material<scalar_t> &passive_material() const {
80 return m_passive_material;
81 }
82
83 constexpr const material<scalar_t> &sensitive_material() const {
85 }
86
87 constexpr const material<scalar_t> &portal_material() const {
88 return m_portal_material;
89 }
90
91 constexpr scalar_t thickness() const { return m_thickness; }
93};
94
98template <concepts::detector detector_t>
100 : public factory_decorator<detector_t> {
102
103 public:
107 DETRAY_HOST
109 std::unique_ptr<surface_factory_interface<detector_t>> factory,
111 : factory_decorator<detector_t>(std::move(factory)), m_cfg{cfg} {
114 "No homogeneous surface material in detector type");
115 }
116
126 DETRAY_HOST
127 auto operator()(typename detector_t::volume_type &volume,
128 typename detector_t::surface_lookup_container &surfaces,
129 typename detector_t::transform_container &transforms,
130 typename detector_t::mask_container &masks,
131 typename detector_t::geometry_context ctx = {})
132 -> dindex_range override {
133 const dindex_range idx_range =
134 (*this->get_factory())(volume, surfaces, transforms, masks, ctx);
135
136 m_surface_range = idx_range;
137
138 return idx_range;
139 }
140
149 DETRAY_HOST
150 auto operator()(typename detector_t::surface_lookup_container &surfaces,
151 typename detector_t::material_container &materials) {
152 DETRAY_VERBOSE_HOST("Generate homogeneous material...");
153
154 using material_id = typename detector_t::material::id;
155 using link_t = typename detector_t::surface_type::material_link;
156
157 assert(surfaces.size() >= (m_surface_range[1] - m_surface_range[0]));
158
159 DETRAY_VERBOSE_HOST("-> Material surface range: "
160 << m_surface_range[0] << " - " << m_surface_range[1]);
161
162 // Add the material to the surfaces that the data links against
163 for (auto &sf : detray::ranges::subrange(surfaces, m_surface_range)) {
164 const material<scalar_t> *mat_ptr{nullptr};
165
166 // Get the correct material for this surface type
167 constexpr vacuum<scalar_t> vac{};
168 switch (sf.id()) {
169 case surface_id::e_passive: {
170 const auto &mat = m_cfg.passive_material();
171 mat_ptr = (mat != vac) ? &mat : nullptr;
172 break;
173 }
174 case surface_id::e_sensitive: {
175 const auto &mat = m_cfg.sensitive_material();
176 mat_ptr = (mat != vac) ? &mat : nullptr;
177 break;
178 }
179 case surface_id::e_portal: {
180 const auto &mat = m_cfg.portal_material();
181 mat_ptr = (mat != vac) ? &mat : nullptr;
182 break;
183 }
184 case surface_id::e_unknown: {
185 std::stringstream err_stream{};
186 err_stream << "-> Encountered surface of unknown type during "
187 "material generation: "
188 << sf << std::endl;
189
190 DETRAY_FATAL_HOST(err_stream.str());
191 throw std::runtime_error(err_stream.str());
192 break;
193 }
194 default: {
195 break;
196 }
197 }
198
199 // Found suitable material for this surface?
200 if (mat_ptr == nullptr) {
201 continue;
202 }
203
204 // Handle line shaped surfaces differently
205 bool is_line{false};
206 link_t mat_link;
207
209 using mask_id = typename detector_t::masks::id;
210
211 // If the current surface is a line, generate a material rod
212 const mask_id sf_mask_id = sf.mask().id();
213 if (sf_mask_id == mask_id::e_straw_tube ||
214 sf_mask_id == mask_id::e_drift_cell) {
215 is_line = true;
216
217 auto &mat_coll =
218 materials.template get<material_id::e_material_rod>();
219 mat_coll.emplace_back(*mat_ptr, m_cfg.thickness());
220
221 mat_link = {material_id::e_material_rod,
222 static_cast<dindex>(mat_coll.size() - 1u)};
223 }
224 }
225
226 // For all surfaces that are not lines, generate a material slab
228 if (!is_line) {
229 auto &mat_coll =
230 materials.template get<material_id::e_material_slab>();
231 mat_coll.emplace_back(*mat_ptr, m_cfg.thickness());
232
233 mat_link = {material_id::e_material_slab,
234 static_cast<dindex>(mat_coll.size() - 1u)};
235 }
236 }
237
238 // Set the initial surface material link (will be updated when
239 // added to the detector)
240 sf.material() = mat_link;
241
242 DETRAY_DEBUG_HOST("-> Added material to surface: " << sf);
243 }
244 }
245
246 private:
250 dindex_range m_surface_range{};
251};
252
253} // namespace detray
const surface_factory_interface< detector_t > * get_factory() const
Definition surface_factory_interface.hpp:215
factory_decorator(std::unique_ptr< surface_factory_interface< detector_t > > factory)
Wrap a concrete surface factory and forward interface calls to it.
Definition surface_factory_interface.hpp:203
auto operator()(typename detector_t::surface_lookup_container &surfaces, typename detector_t::material_container &materials)
Create material slabs or rods for all surfaces that the underlying surface factory builds.
Definition homogeneous_material_generator.hpp:150
auto operator()(typename detector_t::volume_type &volume, typename detector_t::surface_lookup_container &surfaces, typename detector_t::transform_container &transforms, typename detector_t::mask_container &masks, typename detector_t::geometry_context ctx={}) -> dindex_range override
Call the underlying surface factory and record the surface range that was produced.
Definition homogeneous_material_generator.hpp:127
homogeneous_material_generator(std::unique_ptr< surface_factory_interface< detector_t > > factory, const hom_material_config< scalar_t > cfg)
Construct from configuration cfg.
Definition homogeneous_material_generator.hpp:108
How to generate surfaces with their corresponding masks and transforms.
Definition surface_factory_interface.hpp:120
Check for the the presence of material rods in a detector definition.
Definition concepts.hpp:146
Check for the the presence of material slabs in a detector definition.
Definition concepts.hpp:141
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
detail::index_range< dindex > dindex_range
Index ranges and sequences.
Definition indexing.hpp:24
unsigned int dindex
Default index type.
Definition indexing.hpp:18
const auto & get(const detray::tuple< Ts... > &t) noexcept
Get a tuple element by index from a const tuple.
Definition tuple.hpp:152
Configuration for the homogeneous material generator.
Definition homogeneous_material_generator.hpp:33
constexpr hom_material_config & portal_material(const material< scalar_t > &m)
Set the material assigned to portal surfaces.
Definition homogeneous_material_generator.hpp:63
scalar_t m_thickness
Minimal envelope for the portals (used in autofitting).
Definition homogeneous_material_generator.hpp:41
constexpr const material< scalar_t > & passive_material() const
Getters.
Definition homogeneous_material_generator.hpp:79
material< scalar_t > m_portal_material
Type of material to put on the portal surfaces.
Definition homogeneous_material_generator.hpp:39
material< scalar_t > m_sensitive_material
Type of material to put on the sensitive surfaces.
Definition homogeneous_material_generator.hpp:37
constexpr hom_material_config & passive_material(const material< scalar_t > &m)
SettersSet the material assigned to passive surfaces.
Definition homogeneous_material_generator.hpp:48
material< scalar_t > m_passive_material
Type of material to put on the passive surfaces.
Definition homogeneous_material_generator.hpp:35
constexpr scalar_t thickness() const
Definition homogeneous_material_generator.hpp:91
constexpr const material< scalar_t > & sensitive_material() const
Definition homogeneous_material_generator.hpp:83
constexpr hom_material_config & thickness(const scalar_t t)
Set the thickness used when creating portal material.
Definition homogeneous_material_generator.hpp:70
constexpr hom_material_config & sensitive_material(const material< scalar_t > &m)
Set the material assigned to sensitive surfaces.
Definition homogeneous_material_generator.hpp:55
constexpr const material< scalar_t > & portal_material() const
Definition homogeneous_material_generator.hpp:87
Material composition properties and density data used by interactions.
Definition material.hpp:36
interface type to construct a subrange_view with CTAD
Definition subrange.hpp:90
Predefined silicon material with tabulated bulk properties.
Definition predefined_materials.hpp:116
static constexpr scalar_t mm
Native length unit, the millimetre.
Definition units.hpp:27
Elements Declaration.
Definition predefined_materials.hpp:34