12#include "detray/builders/surface_factory.hpp"
13#include "detray/core/concepts.hpp"
14#include "detray/definitions/algebra.hpp"
15#include "detray/definitions/indexing.hpp"
16#include "detray/geometry/shapes/unmasked.hpp"
17#include "detray/material/material.hpp"
18#include "detray/utils/logging.hpp"
19#include "detray/utils/ranges.hpp"
34template <concepts::scalar scalar_t>
43 const std::size_t sf_idx = detail::invalid_value<std::size_t>())
44 : m_sf_index{sf_idx} {}
56 const std::size_t sf_idx = detail::invalid_value<std::size_t>())
57 : m_sf_index{sf_idx}, m_mat{mat}, m_thickness{thickness} {}
70 const scalar_t thickness,
const std::vector<scalar_t> &material_paramters,
72 const std::size_t sf_idx = detail::invalid_value<std::size_t>())
75 material_paramters.at(0), material_paramters.at(1),
76 material_paramters.at(2), material_paramters.at(3),
77 material_paramters.at(4), state}},
78 m_thickness{thickness} {}
83 -> std::tuple<std::size_t &, std::vector<material<scalar_t>> &,
84 std::vector<scalar_t> &> {
85 return std::tie(m_sf_index, m_mat, m_thickness);
96 m_thickness.push_back(thickness);
102 m_mat.reserve(m_mat.size() + other.m_mat.size());
103 std::ranges::move(other.m_mat, std::back_inserter(m_mat));
105 m_thickness.reserve(m_thickness.size() + other.m_thickness.size());
106 std::ranges::move(other.m_thickness, std::back_inserter(m_thickness));
118 const std::vector<scalar_t> &material_paramters,
122 material_paramters.at(2), material_paramters.at(3),
123 material_paramters.at(4), state});
124 m_thickness.push_back(thickness);
128 DETRAY_HOST
friend std::ostream &
operator<<(std::ostream &os,
130 os <<
"material_data{\nsf_index: ";
131 if (detail::is_invalid_value(mat_data.m_sf_index)) {
134 os << mat_data.m_sf_index;
136 os <<
", materials: [\n";
137 for (std::size_t i = 0; i < mat_data.m_mat.size(); ++i) {
141 os << mat_data.m_mat.at(i);
143 os <<
"],\nthickness: [\n";
144 for (std::size_t i = 0; i < mat_data.m_thickness.size(); ++i) {
148 os << mat_data.m_thickness.at(i);
156 std::size_t m_sf_index{detail::invalid_value<std::size_t>()};
158 std::vector<material<scalar_t>> m_mat{};
160 std::vector<scalar_t> m_thickness{};
171template <concepts::detector detector_t>
174 using mask_id =
typename detector_t::masks::id;
175 using material_id =
typename detector_t::material::id;
184 using base_factory::operator();
192 std::make_unique<placeholder_factory_t>())
193 : base_factory(std::move(sf_factory)) {
196 "No homogeneous surface material in detector type");
203 const dindex n_surfaces{
static_cast<dindex>(m_links.size())};
206 assert(m_indices.empty() || (m_indices.size() == n_surfaces));
207 assert(m_links.size() == n_surfaces);
208 assert(m_materials.size() == n_surfaces);
209 assert(m_thickness.size() == n_surfaces);
216 auto links() const -> const std::vector<material_id> & {
return m_links; }
237 std::size_t index = detail::invalid_value<std::size_t>()) {
238 DETRAY_DEBUG_HOST(
"homogeneous_material_factory::add_material single");
240 auto [sf_index, mat,
thickness] = std::move(mat_data).get_data();
242 DETRAY_DEBUG_HOST(
"- sf_index=" << sf_index);
243 DETRAY_DEBUG_HOST(
"- mat=" << mat.at(0));
244 DETRAY_DEBUG_HOST(
"- thickness=" <<
thickness.at(0));
247 assert(mat.size() == 1u);
250 m_links.push_back(std::make_pair(
id,
static_cast<dindex>(index)));
251 m_indices.push_back(sf_index);
252 m_materials.push_back(mat.at(0));
263 DETRAY_DEBUG_HOST(
"homogeneous_material_factory::add_material multiple");
265 m_links.reserve(m_links.size() + mat_data_vec.size());
266 m_materials.reserve(m_materials.size() + mat_data_vec.size());
267 m_thickness.reserve(m_thickness.size() + mat_data_vec.size());
270 for (
auto &mat_data : mat_data_vec) {
300 auto operator()(
typename detector_t::surface_lookup_container &surfaces,
301 typename detector_t::material_container &
materials) {
302 DETRAY_VERBOSE_HOST(
"Add homogeneous material...");
304 using link_t =
typename detector_t::surface_type::material_link;
305 DETRAY_DEBUG_HOST(
"-> Accumulated " << m_materials.size() <<
" materials");
307 if (m_materials.empty()) {
311 DETRAY_DEBUG_HOST(
"-> n_materials=" <<
n_materials());
312 DETRAY_DEBUG_HOST(
"-> links:");
313 for ([[maybe_unused]]
const auto &[i, link] :
315 DETRAY_DEBUG_HOST(
"-> #" << i <<
": " << link.first <<
" "
320 const std::size_t
n_materials{this->n_materials()};
325 if (m_indices.empty() ||
326 std::ranges::find(m_indices, detail::invalid_value<std::size_t>()) !=
328 DETRAY_DEBUG_HOST(
"Indices were empty or invalid, recalculating");
330 std::iota(std::begin(m_indices), std::end(m_indices),
333 DETRAY_DEBUG_HOST(
"-> Indices: " << DETRAY_LOG_VECTOR(m_indices));
343 auto &sf_desc = surfaces.at(
static_cast<dindex>(sf_idx));
345 if (sf_desc.material().id() < detector_t::material::id::e_none) {
346 DETRAY_WARN_HOST(
"Surface descriptor already has a material link:"
347 << sf_desc.material().id()
348 <<
" skipping configured homogeneous assignment");
355 DETRAY_DEBUG_HOST(
"-> Adding: i=" << i <<
", sf_index=" << sf_idx
356 <<
", sf=" << sf_desc);
357 DETRAY_DEBUG_HOST(
" mat=" << mat <<
" thickness=" << t);
362 if (m_links.at(i).first == material_id::e_material_slab) {
368 m_links.at(i).second);
372 if (m_links.at(i).first == material_id::e_material_rod) {
378 m_links.at(i).second);
381 DETRAY_DEBUG_HOST(
"-> After insert: mat_idx=" << mat_idx);
382 link_t new_link{m_links.at(i).first, mat_idx};
384 DETRAY_DEBUG_HOST(
"-> Existing link: " << sf_desc.material());
385 DETRAY_DEBUG_HOST(
"-> Setting new link: " << new_link);
389 sf_desc.material() = new_link;
391 DETRAY_DEBUG_HOST(
"-> Added material to surface: " << sf_desc);
397 std::vector<std::pair<material_id, dindex>> m_links{};
399 std::vector<std::size_t> m_indices{};
401 std::vector<scalar_type> m_thickness{};
403 std::vector<material<scalar_type>> m_materials{};
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 links() const -> const std::vector< material_id > &
Definition homogeneous_material_factory.hpp:216
void add_material(material_id id, material_data< scalar_type > &&mat_data, std::size_t index=detail::invalid_value< std::size_t >())
Add all necessary components to the factory for a single material slab or rod (determined by the id).
Definition homogeneous_material_factory.hpp:236
dscalar< typename detector_t::algebra_type > scalar_type
Scalar type used by the detector's material definitions.
Definition homogeneous_material_factory.hpp:182
homogeneous_material_factory(std::unique_ptr< surface_factory_interface< detector_t > > sf_factory=std::make_unique< placeholder_factory_t >())
Factory with surfaces potentially already filled or empty placeholder that will not be used.
Definition homogeneous_material_factory.hpp:190
auto n_materials() const -> dindex
Definition homogeneous_material_factory.hpp:202
auto operator()(typename detector_t::surface_lookup_container &surfaces, typename detector_t::material_container &materials)
Add material to the containers of a volume builder.
Definition homogeneous_material_factory.hpp:300
void add_material(material_id id, std::vector< material_data< scalar_type > > &&mat_data_vec)
Add all necessary components to the factory for multiple material slabs or rods (determined by the id...
Definition homogeneous_material_factory.hpp:261
auto thickness() const -> const std::vector< scalar_type > &
Definition homogeneous_material_factory.hpp:226
auto clear() -> void override
Clear old data.
Definition homogeneous_material_factory.hpp:277
auto materials() const -> const std::vector< material< scalar_type > > &
Definition homogeneous_material_factory.hpp:220
Bind components for material together.
Definition homogeneous_material_factory.hpp:35
void append(material_data &&other)
Append new material from.
Definition homogeneous_material_factory.hpp:101
constexpr material_data(const scalar_t thickness, const std::vector< scalar_t > &material_paramters, const material_state state=material_state::e_solid, const std::size_t sf_idx=detail::invalid_value< std::size_t >())
Construct from all parameters:
Definition homogeneous_material_factory.hpp:69
friend std::ostream & operator<<(std::ostream &os, const material_data &mat_data)
Output stream operator for material_data.
Definition homogeneous_material_factory.hpp:128
void append(const scalar_t thickness, const std::vector< scalar_t > &material_paramters, const material_state state=material_state::e_solid)
Append new material.
Definition homogeneous_material_factory.hpp:117
constexpr material_data(const std::size_t sf_idx=detail::invalid_value< std::size_t >())
Construct empty data for a given surface.
Definition homogeneous_material_factory.hpp:42
constexpr auto get_data() -> std::tuple< std::size_t &, std::vector< material< scalar_t > > &, std::vector< scalar_t > & >
Definition homogeneous_material_factory.hpp:82
void append(const scalar_t thickness, const material< scalar_t > &mat)
Append new material.
Definition homogeneous_material_factory.hpp:94
constexpr material_data(const scalar_t thickness, const material< scalar_t > &mat, const std::size_t sf_idx=detail::invalid_value< std::size_t >())
Construct from a predefined material.
Definition homogeneous_material_factory.hpp:54
How to generate surfaces with their corresponding masks and transforms.
Definition surface_factory_interface.hpp:120
dindex insert_in_container(container_t &cont, const typename container_t::value_type value, const dindex idx, Args &&...args) const
Insert a value in a container at a specific index.
Definition surface_factory_interface.hpp:173
Generates a number of surfaces for a volume (can be portals, passives or sensitives) and fills them i...
Definition surface_factory.hpp:43
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
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
material_state
Material State.
Definition material.hpp:27
Rod structure to be mapped on the line mask.
Definition material_rod.hpp:26
Slab structure to be mapped on the mask (plane, cylinder).
Definition material_slab.hpp:25
Material composition properties and density data used by interactions.
Definition material.hpp:36
Range adaptor that creates an enumerate view, optionally starting at a selected index.
Definition enumerate.hpp:266