File indexing completed on 2025-01-18 09:11:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Direction.hpp"
0013 #include "Acts/Definitions/Tolerance.hpp"
0014 #include "Acts/Geometry/BoundarySurfaceFace.hpp"
0015 #include "Acts/Geometry/Volume.hpp"
0016 #include "Acts/Geometry/VolumeBounds.hpp"
0017 #include "Acts/Surfaces/CylinderBounds.hpp"
0018 #include "Acts/Surfaces/CylinderSurface.hpp"
0019 #include "Acts/Surfaces/DiscSurface.hpp"
0020 #include "Acts/Surfaces/RadialBounds.hpp"
0021 #include "Acts/Surfaces/Surface.hpp"
0022 #include "Acts/Utilities/BoundingBox.hpp"
0023
0024 #include <memory>
0025 #include <ostream>
0026 #include <stdexcept>
0027 #include <utility>
0028
0029 namespace Acts {
0030
0031 std::vector<double> CutoutCylinderVolumeBounds::values() const {
0032 return {m_values.begin(), m_values.end()};
0033 }
0034
0035 void CutoutCylinderVolumeBounds::checkConsistency() noexcept(false) {
0036 if (get(eMinR) < 0. || get(eMedR) <= 0. || get(eMaxR) <= 0. ||
0037 get(eMinR) >= get(eMedR) || get(eMinR) >= get(eMaxR) ||
0038 get(eMedR) >= get(eMaxR)) {
0039 throw std::invalid_argument(
0040 "CutoutCylinderVolumeBounds: invalid radial input.");
0041 }
0042 if (get(eHalfLengthZ) <= 0 || get(eHalfLengthZcutout) <= 0. ||
0043 get(eHalfLengthZcutout) > get(eHalfLengthZ)) {
0044 throw std::invalid_argument(
0045 "CutoutCylinderVolumeBounds: invalid longitudinal input.");
0046 }
0047 }
0048
0049 bool CutoutCylinderVolumeBounds::inside(const Vector3& gpos, double tol) const {
0050
0051 using VectorHelpers::perp;
0052 using VectorHelpers::phi;
0053 double ros = perp(gpos);
0054
0055 bool insideR = (ros >= get(eMinR) - tol) && (ros <= get(eMaxR) + tol);
0056 bool insideZ = std::abs(gpos.z()) <= get(eHalfLengthZ) + tol;
0057
0058 if (!insideR || !insideZ) {
0059 return false;
0060 }
0061
0062
0063
0064 bool insideRInner = ros <= get(eMedR) - tol;
0065 bool insideZInner = std::abs(gpos.z()) < get(eHalfLengthZcutout) - tol;
0066
0067 return !insideRInner || !insideZInner;
0068 }
0069
0070 std::vector<OrientedSurface> CutoutCylinderVolumeBounds::orientedSurfaces(
0071 const Transform3& transform) const {
0072 std::vector<OrientedSurface> oSurfaces;
0073
0074 if (get(eMinR) == 0.) {
0075 oSurfaces.resize(6);
0076 } else {
0077 oSurfaces.resize(8);
0078 }
0079
0080
0081 auto outer =
0082 Surface::makeShared<CylinderSurface>(transform, m_outerCylinderBounds);
0083 oSurfaces.at(tubeOuterCover) =
0084 OrientedSurface{std::move(outer), Direction::OppositeNormal()};
0085
0086
0087 auto cutoutInner =
0088 Surface::makeShared<CylinderSurface>(transform, m_cutoutCylinderBounds);
0089 oSurfaces.at(tubeInnerCover) =
0090 OrientedSurface{std::move(cutoutInner), Direction::AlongNormal()};
0091
0092
0093 double hlChoke = (get(eHalfLengthZ) - get(eHalfLengthZcutout)) * 0.5;
0094 double zChoke = get(eHalfLengthZcutout) + hlChoke;
0095
0096 if (m_innerCylinderBounds != nullptr) {
0097 auto posChokeTrf = transform * Translation3(Vector3(0, 0, zChoke));
0098 auto posInner = Surface::makeShared<CylinderSurface>(posChokeTrf,
0099 m_innerCylinderBounds);
0100 oSurfaces.at(index7) =
0101 OrientedSurface{std::move(posInner), Direction::AlongNormal()};
0102
0103 auto negChokeTrf = transform * Translation3(Vector3(0, 0, -zChoke));
0104 auto negInner = Surface::makeShared<CylinderSurface>(negChokeTrf,
0105 m_innerCylinderBounds);
0106 oSurfaces.at(index6) =
0107 OrientedSurface{std::move(negInner), Direction::AlongNormal()};
0108 }
0109
0110
0111 auto posOutDiscTrf =
0112 transform * Translation3(Vector3(0, 0, get(eHalfLengthZ)));
0113 auto posOutDisc =
0114 Surface::makeShared<DiscSurface>(posOutDiscTrf, m_outerDiscBounds);
0115 oSurfaces.at(positiveFaceXY) =
0116 OrientedSurface{std::move(posOutDisc), Direction::OppositeNormal()};
0117
0118 auto negOutDiscTrf =
0119 transform * Translation3(Vector3(0, 0, -get(eHalfLengthZ)));
0120 auto negOutDisc =
0121 Surface::makeShared<DiscSurface>(negOutDiscTrf, m_outerDiscBounds);
0122 oSurfaces.at(negativeFaceXY) =
0123 OrientedSurface{std::move(negOutDisc), Direction::AlongNormal()};
0124
0125
0126 auto posInDiscTrf =
0127 transform * Translation3(Vector3(0, 0, get(eHalfLengthZcutout)));
0128 auto posInDisc =
0129 Surface::makeShared<DiscSurface>(posInDiscTrf, m_innerDiscBounds);
0130 oSurfaces.at(index5) =
0131 OrientedSurface{std::move(posInDisc), Direction::AlongNormal()};
0132
0133 auto negInDiscTrf =
0134 transform * Translation3(Vector3(0, 0, -get(eHalfLengthZcutout)));
0135 auto negInDisc =
0136 Surface::makeShared<DiscSurface>(negInDiscTrf, m_innerDiscBounds);
0137 oSurfaces.at(index4) =
0138 OrientedSurface{std::move(negInDisc), Direction::OppositeNormal()};
0139
0140 return oSurfaces;
0141 }
0142
0143 Volume::BoundingBox CutoutCylinderVolumeBounds::boundingBox(
0144 const Transform3* trf, const Vector3& envelope,
0145 const Volume* entity) const {
0146 Vector3 vmin, vmax;
0147
0148
0149
0150
0151 vmax = {get(eMaxR), get(eMaxR), get(eHalfLengthZ)};
0152 vmin = {-get(eMaxR), -get(eMaxR), -get(eHalfLengthZ)};
0153
0154 Volume::BoundingBox box(entity, vmin - envelope, vmax + envelope);
0155
0156 return trf == nullptr ? box : box.transformed(*trf);
0157 }
0158
0159 std::ostream& CutoutCylinderVolumeBounds::toStream(std::ostream& sl) const {
0160 sl << "CutoutCylinderVolumeBounds(\n";
0161 sl << "rmin = " << get(eMinR) << " rmed = " << get(eMedR)
0162 << " rmax = " << get(eMaxR) << "\n";
0163 sl << "dz1 = " << get(eHalfLengthZ) << " dz2 = " << get(eHalfLengthZcutout);
0164 return sl;
0165 }
0166
0167 void CutoutCylinderVolumeBounds::buildSurfaceBounds() {
0168 if (get(eMinR) > s_epsilon) {
0169 double hlChoke = (get(eHalfLengthZ) - get(eHalfLengthZcutout)) * 0.5;
0170 m_innerCylinderBounds =
0171 std::make_shared<CylinderBounds>(get(eMinR), hlChoke);
0172 }
0173
0174 m_cutoutCylinderBounds =
0175 std::make_shared<CylinderBounds>(get(eMedR), get(eHalfLengthZcutout));
0176
0177 m_outerCylinderBounds =
0178 std::make_shared<CylinderBounds>(get(eMaxR), get(eHalfLengthZ));
0179
0180 m_innerDiscBounds = std::make_shared<RadialBounds>(get(eMinR), get(eMedR));
0181
0182 m_outerDiscBounds = std::make_shared<RadialBounds>(get(eMinR), get(eMaxR));
0183 }
0184
0185 }