Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:23:56

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 // Project include(s).
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 // System include(s)
0020 #include <memory>
0021 #include <stdexcept>
0022 #include <vector>
0023 
0024 namespace detray {
0025 
0026 /// @brief Build a volume containing surfaces with material.
0027 ///
0028 /// Decorator class to a volume builder that adds the material data to the
0029 /// surfaces while building the volume.
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   /// @param vol_builder volume builder that should be decorated with material
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   /// Overwrite, to add material in addition to surfaces (only if surfaces are
0050   /// present in the factory, otherwise only add material)
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     // If the factory also holds surface data, call base volume builder
0059     volume_decorator<detector_t>::add_surfaces(sf_factory, ctx);
0060 
0061     // Add material
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   /// Add the volume and the material to the detector @param det
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     // Update the surface material links and shift them according to the
0099     // number of material slabs/rods that were in the detector previously
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     // Add material to the detector
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     // Call the underlying volume builder(s) and give the volume to the
0149     // next decorator
0150     return volume_decorator<detector_t>::build(det, ctx);
0151   }
0152 
0153  private:
0154   // Material container for this volume
0155   typename detector_t::material_container m_materials{};
0156 };
0157 
0158 }  // namespace detray