File indexing completed on 2026-05-27 07:23:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/material/material.hpp"
0013 #include "detray/utils/grid/concepts.hpp"
0014
0015 namespace detray::concepts {
0016
0017
0018 template <class M>
0019 concept material_params = requires(const M m) {
0020 typename M::ratio;
0021
0022 { m.X0() } -> std::same_as<typename M::scalar_type>;
0023
0024 { m.L0() } -> std::same_as<typename M::scalar_type>;
0025
0026 { m.Ar() } -> std::same_as<typename M::scalar_type>;
0027
0028 { m.Z() } -> std::same_as<typename M::scalar_type>;
0029
0030 { m.mass_density() } -> std::same_as<typename M::scalar_type>;
0031
0032 { m.molar_density() } -> std::same_as<typename M::scalar_type>;
0033
0034 { m.state() } -> std::same_as<detray::material_state>;
0035
0036 { m.molar_electron_density() } -> std::same_as<typename M::scalar_type>;
0037
0038 {
0039 m.density_effect_data()
0040 } -> std::same_as<
0041 const detray::detail::density_effect_data<typename M::scalar_type>&>;
0042
0043 { m.mean_excitation_energy() } -> std::same_as<typename M::scalar_type>;
0044 };
0045
0046
0047 template <class M>
0048 concept material_slab = requires(const M slab) {
0049 typename M::material_type;
0050
0051 requires concepts::material_params<typename M::material_type>;
0052
0053 { slab.thickness() } -> std::same_as<typename M::scalar_type>;
0054
0055 { slab.thickness_in_X0() } -> std::same_as<typename M::scalar_type>;
0056
0057 { slab.thickness_in_L0() } -> std::same_as<typename M::scalar_type>;
0058
0059 {
0060 slab.path_segment(typename M::scalar_type(), typename M::scalar_type())
0061 } -> std::same_as<typename M::scalar_type>;
0062
0063 {
0064 slab.path_segment_in_X0(typename M::scalar_type(),
0065 typename M::scalar_type())
0066 } -> std::same_as<typename M::scalar_type>;
0067
0068 {
0069 slab.path_segment_in_L0(typename M::scalar_type(),
0070 typename M::scalar_type())
0071 } -> std::same_as<typename M::scalar_type>;
0072 };
0073
0074
0075 template <class M>
0076 concept material_rod = requires(const M rod) {
0077 typename M::material_type;
0078
0079 requires concepts::material_params<typename M::material_type>;
0080
0081 { rod.thickness() } -> std::same_as<typename M::scalar_type>;
0082
0083 { rod.radius() } -> std::same_as<typename M::scalar_type>;
0084
0085 {
0086 rod.path_segment(typename M::scalar_type(), typename M::scalar_type())
0087 } -> std::same_as<typename M::scalar_type>;
0088
0089 {
0090 rod.path_segment_in_X0(typename M::scalar_type(), typename M::scalar_type())
0091 } -> std::same_as<typename M::scalar_type>;
0092
0093 {
0094 rod.path_segment_in_L0(typename M::scalar_type(), typename M::scalar_type())
0095 } -> std::same_as<typename M::scalar_type>;
0096 };
0097
0098
0099 template <class M>
0100 concept homogeneous_material =
0101 concepts::material_slab<M> || concepts::material_rod<M> ||
0102 concepts::material_params<M>;
0103
0104
0105 template <class M>
0106 concept material_map =
0107 concepts::grid<M> && concepts::material_slab<typename M::value_type>;
0108
0109
0110 template <class M>
0111 concept surface_material =
0112 (concepts::material_map<M> && (M::dim == 2)) ||
0113 concepts::material_slab<M> || concepts::material_rod<M>;
0114
0115
0116 template <class M>
0117 concept volume_material = (concepts::material_map<M> && (M::dim == 3)) ||
0118 concepts::material_params<M>;
0119
0120 }