File indexing completed on 2026-05-27 07:23:56
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/builders/homogeneous_material_factory.hpp"
0013 #include "detray/builders/homogeneous_material_generator.hpp"
0014 #include "detray/builders/volume_builder.hpp"
0015 #include "detray/builders/volume_builder_interface.hpp"
0016 #include "detray/core/concepts.hpp"
0017 #include "detray/utils/logging.hpp"
0018
0019
0020 #include <memory>
0021 #include <stdexcept>
0022 #include <vector>
0023
0024 namespace detray {
0025
0026
0027
0028
0029
0030 template <typename detector_t>
0031 class homogeneous_material_builder final : public volume_decorator<detector_t> {
0032 public:
0033 using material_id = typename detector_t::material::id;
0034 using scalar_type = dscalar<typename detector_t::algebra_type>;
0035
0036
0037 DETRAY_HOST
0038 explicit homogeneous_material_builder(
0039 std::unique_ptr<volume_builder_interface<detector_t>> vol_builder)
0040 : volume_decorator<detector_t>(std::move(vol_builder)) {
0041 DETRAY_VERBOSE_HOST(
0042 "Add hom. material builder to volume: " << this->name());
0043
0044 static_assert(concepts::has_material_slabs<detector_t> ||
0045 concepts::has_material_rods<detector_t>,
0046 "No homogeneous surface material in detector type");
0047 }
0048
0049
0050
0051
0052 DETRAY_HOST
0053 void add_surfaces(
0054 std::shared_ptr<surface_factory_interface<detector_t>> sf_factory,
0055 typename detector_t::geometry_context ctx = {}) override {
0056 DETRAY_VERBOSE_HOST("Add [material] surface factory:");
0057
0058
0059 volume_decorator<detector_t>::add_surfaces(sf_factory, ctx);
0060
0061
0062 auto mat_factory =
0063 std::dynamic_pointer_cast<homogeneous_material_factory<detector_t>>(
0064 sf_factory);
0065 if (mat_factory) {
0066 DETRAY_VERBOSE_HOST("-> found decoration: " << DETRAY_TYPENAME(
0067 homogeneous_material_factory<detector_t>));
0068 (*mat_factory)(this->surfaces(), m_materials);
0069 return;
0070 }
0071 auto mat_generator =
0072 std::dynamic_pointer_cast<homogeneous_material_generator<detector_t>>(
0073 sf_factory);
0074 if (mat_generator) {
0075 DETRAY_VERBOSE_HOST("-> found decoration: " << DETRAY_TYPENAME(
0076 homogeneous_material_generator<detector_t>));
0077 (*mat_generator)(this->surfaces(), m_materials);
0078 return;
0079 }
0080
0081 if (!mat_factory && !mat_generator) {
0082 DETRAY_VERBOSE_HOST("No material found in this surface factory");
0083 DETRAY_VERBOSE_HOST("-> Built non-material surfaces");
0084 }
0085 }
0086
0087
0088
0089 DETRAY_HOST
0090 auto build(detector_t &det, typename detector_t::geometry_context ctx = {}) ->
0091 typename detector_t::volume_type * override {
0092 DETRAY_VERBOSE_HOST("Build homogeneous material...");
0093
0094 const auto &material = det.material_store();
0095
0096 DETRAY_DEBUG_HOST("-> n_surfaces=" << this->surfaces().size());
0097
0098
0099
0100 for (auto &sf : this->surfaces()) {
0101 DETRAY_DEBUG_HOST("-> sf=" << sf);
0102 DETRAY_DEBUG_HOST(" -> material_id=" << sf.material().id());
0103 if constexpr (concepts::has_material_slabs<detector_t>) {
0104 if (sf.material().id() == material_id::e_material_slab) {
0105 dindex offset =
0106 material.template size<material_id::e_material_slab>();
0107 DETRAY_DEBUG_HOST("-> update material slab offset: " << offset);
0108 sf.update_material(offset);
0109 DETRAY_DEBUG_HOST("-> material now: " << sf.material());
0110 }
0111
0112 DETRAY_DEBUG_HOST(
0113 "-> Appending "
0114 << m_materials.template size<material_id::e_material_slab>()
0115 << " slabs into detector materials");
0116 }
0117 if constexpr (concepts::has_material_rods<detector_t>) {
0118 if (sf.material().id() == material_id::e_material_rod) {
0119 DETRAY_DEBUG_HOST(
0120 "-> update material rod offset: "
0121 << material.template size<material_id::e_material_rod>());
0122 sf.update_material(
0123 material.template size<material_id::e_material_rod>());
0124 }
0125
0126 DETRAY_DEBUG_HOST(
0127 "-> Appending "
0128 << m_materials.template size<material_id::e_material_rod>()
0129 << " rods into detector materials");
0130 }
0131 }
0132
0133
0134
0135 if constexpr (types::contains<typename detector_t::material,
0136 material_rod<scalar_type>>) {
0137 DETRAY_DEBUG_HOST(
0138 "-> Appending "
0139 << m_materials.template size<material_id::e_material_rod>()
0140 << " rods into detector materials");
0141 }
0142 det._materials.append(std::move(m_materials));
0143 m_materials.clear_all();
0144
0145 DETRAY_VERBOSE_HOST(
0146 "Successfully built homogeneous material for volume: " << this->name());
0147
0148
0149
0150 return volume_decorator<detector_t>::build(det, ctx);
0151 }
0152
0153 private:
0154
0155 typename detector_t::material_container m_materials{};
0156 };
0157
0158 }