Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4TwistedTubs 27 // 28 // Class description: 29 // 30 // G4TwistedTubs is a sector of a twisted hollow cylinder. 31 // A twisted cylinder which is placed along with z-axis and is 32 // separated into phi-segments should become a hyperboloid, and 33 // its each segmented piece should be tilted with a stereo angle. 34 // G4TwistedTubs is a G4VSolid. 35 // 36 // Details of the implementation: "Development of a Geant4 solid 37 // for stereo mini-jet cells in a cylindrical drift chamber", 38 // Computer Physics Communications 153 (2003) pp.373–391 39 40 // 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepburn.s.chiba-u.ac.jp), created. 41 // 13-Nov-2003 - O.Link (Oliver.Link@cern.ch), Integration in Geant4 42 // from original version in Jupiter-2.5.02 application. 43 // -------------------------------------------------------------------- 44 #ifndef G4TWISTEDTUBS_HH 45 #define G4TWISTEDTUBS_HH 46 47 #include "G4VSolid.hh" 48 #include "G4TwistTubsFlatSide.hh" 49 #include "G4TwistTubsSide.hh" 50 #include "G4TwistTubsHypeSide.hh" 51 52 class G4SolidExtentList; 53 class G4ClippablePolygon; 54 55 class G4TwistedTubs : public G4VSolid 56 { 57 public: 58 59 G4TwistedTubs(const G4String& pname, // Name of instance 60 G4double twistedangle, // Twisted angle 61 G4double endinnerrad, // Inner radius at endcap 62 G4double endouterrad, // Outer radius at endcap 63 G4double halfzlen, // half z length 64 G4double dphi); // Phi angle of a segment 65 66 G4TwistedTubs(const G4String& pname, // Name of instance 67 G4double twistedangle, // Stereo angle 68 G4double endinnerrad, // Inner radius at endcap 69 G4double endouterrad, // Outer radius at endcap 70 G4double halfzlen, // half z length 71 G4int nseg, // Number of segments in totalPhi 72 G4double totphi); // Total angle of all segments 73 74 G4TwistedTubs(const G4String& pname, // Name of instance 75 G4double twistedangle, // Twisted angle 76 G4double innerrad, // Inner radius at z=0 77 G4double outerrad, // Outer radius at z=0 78 G4double negativeEndz, // -ve z endplate 79 G4double positiveEndz, // +ve z endplate 80 G4double dphi); // Phi angle of a segment 81 82 G4TwistedTubs(const G4String& pname, // Name of instance 83 G4double twistedangle, // Stereo angle 84 G4double innerrad, // Inner radius at z=0 85 G4double outerrad, // Outer radius at z=0 86 G4double negativeEndz, // -ve z endplate 87 G4double positiveEndz, // +ve z endplate 88 G4int nseg, // Number of segments in totalPhi 89 G4double totphi); // Total angle of all segments 90 91 ~G4TwistedTubs() override; 92 93 void ComputeDimensions(G4VPVParameterisation* /* p */ , 94 const G4int /* n */ , 95 const G4VPhysicalVolume* /* prep */ ) override; 96 97 void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const override; 98 99 G4bool CalculateExtent(const EAxis pAxis, 100 const G4VoxelLimits& pVoxelLimit, 101 const G4AffineTransform& pTransform, 102 G4double& pMin, 103 G4double& pMax ) const override; 104 105 G4double DistanceToIn (const G4ThreeVector& p, 106 const G4ThreeVector& v ) const override; 107 108 G4double DistanceToIn (const G4ThreeVector& p ) const override; 109 110 G4double DistanceToOut(const G4ThreeVector& p, 111 const G4ThreeVector& v, 112 const G4bool calcnorm = false, 113 G4bool* validnorm = nullptr, 114 G4ThreeVector* n = nullptr ) const override; 115 116 G4double DistanceToOut(const G4ThreeVector& p) const override; 117 118 EInside Inside (const G4ThreeVector& p) const override; 119 120 G4ThreeVector SurfaceNormal(const G4ThreeVector& p) const override; 121 122 void DescribeYourselfTo (G4VGraphicsScene& scene) const override; 123 G4Polyhedron* CreatePolyhedron () const override; 124 G4Polyhedron* GetPolyhedron () const override; 125 126 std::ostream &StreamInfo(std::ostream& os) const override; 127 128 // accessors 129 130 inline G4double GetDPhi () const { return fDPhi ; } 131 inline G4double GetPhiTwist () const { return fPhiTwist ; } 132 inline G4double GetInnerRadius () const { return fInnerRadius; } 133 inline G4double GetOuterRadius () const { return fOuterRadius; } 134 inline G4double GetInnerStereo () const { return fInnerStereo; } 135 inline G4double GetOuterStereo () const { return fOuterStereo; } 136 inline G4double GetZHalfLength () const { return fZHalfLength; } 137 inline G4double GetKappa () const { return fKappa ; } 138 139 inline G4double GetTanInnerStereo () const { return fTanInnerStereo ; } 140 inline G4double GetTanInnerStereo2() const { return fTanInnerStereo2 ; } 141 inline G4double GetTanOuterStereo () const { return fTanOuterStereo ; } 142 inline G4double GetTanOuterStereo2() const { return fTanOuterStereo2 ; } 143 144 inline G4double GetEndZ (G4int i) const { return fEndZ[i] ; } 145 inline G4double GetEndPhi (G4int i) const { return fEndPhi[i]; } 146 inline G4double GetEndInnerRadius (G4int i) const 147 { return fEndInnerRadius[i]; } 148 inline G4double GetEndOuterRadius (G4int i) const 149 { return fEndOuterRadius[i]; } 150 inline G4double GetEndInnerRadius () const 151 { return (fEndInnerRadius[0] > fEndInnerRadius[1] ? 152 fEndInnerRadius[0] : fEndInnerRadius[1]); } 153 inline G4double GetEndOuterRadius () const 154 { return (fEndOuterRadius[0] > fEndOuterRadius[1] ? 155 fEndOuterRadius[0] : fEndOuterRadius[1]); } 156 157 G4VisExtent GetExtent () const override; 158 G4GeometryType GetEntityType() const override; 159 G4VSolid* Clone() const override; 160 161 G4double GetCubicVolume() override; 162 // Returns an estimation of the geometrical cubic volume of the 163 // solid. Caches the computed value once computed the first time. 164 G4double GetSurfaceArea() override; 165 // Returns the geometrical surface area of the solid. 166 // Caches the computed value once computed the first time. 167 168 G4ThreeVector GetPointOnSurface() const override ; 169 170 G4TwistedTubs(__void__&); 171 // Fake default constructor for usage restricted to direct object 172 // persistency for clients requiring preallocation of memory for 173 // persistifiable objects. 174 175 G4TwistedTubs(const G4TwistedTubs& rhs); 176 G4TwistedTubs& operator=(const G4TwistedTubs& rhs); 177 // Copy constructor and assignment operator. 178 179 #ifdef G4TWISTDEBUG 180 G4VTwistSurface* GetOuterHype() const { return fOuterHype; } 181 #endif 182 183 private: 184 185 inline void SetFields(G4double phitwist, G4double innerrad, 186 G4double outerrad, 187 G4double negativeEndz, G4double positiveEndz); 188 void CreateSurfaces(); 189 G4double GetLateralArea(G4double a, G4double r, G4double z) const; 190 G4double GetPhiCutArea(G4double a, G4double r, G4double z) const; 191 192 private: 193 194 G4double fPhiTwist; // Twist angle from -fZHalfLength to fZHalfLength 195 G4double fInnerRadius; // Inner-hype radius at z=0 196 G4double fOuterRadius; // Outer-hype radius at z=0 197 G4double fEndZ[2]; // z at endcaps, [0] = -ve z, [1] = +ve z 198 G4double fDPhi; // Phi-width of a segment fDPhi > 0 199 G4double fZHalfLength; // Half length along z-axis 200 201 G4double fInnerStereo; // Inner-hype stereo angle 202 G4double fOuterStereo; // Outer-hype stereo angle 203 G4double fTanInnerStereo; // std::tan(innerStereoAngle) 204 G4double fTanOuterStereo; // std::tan(outerStereoAngle) 205 G4double fKappa; // std::tan(fPhiTwist/2)/fZHalfLen; 206 G4double fEndInnerRadius[2]; // Inner-hype radii endcaps [0] -ve z, [1] +ve z 207 G4double fEndOuterRadius[2]; // Outer-hype radii endcaps [0] -ve z, [1] +ve z 208 G4double fEndPhi[2]; // Phi endcaps, [0] = -ve z, [1] = +ve z 209 210 G4double fInnerRadius2; // fInnerRadius * fInnerRadius 211 G4double fOuterRadius2; // fOuterRadius * fOuterRadius 212 G4double fTanInnerStereo2; // fInnerRadius * fInnerRadius 213 G4double fTanOuterStereo2; // fInnerRadius * fInnerRadius 214 G4double fEndZ2[2]; // fEndZ * fEndZ 215 216 G4VTwistSurface* fLowerEndcap; // Surface of -ve z 217 G4VTwistSurface* fUpperEndcap; // Surface of +ve z 218 G4VTwistSurface* fLatterTwisted; // Surface of -ve phi 219 G4VTwistSurface* fFormerTwisted; // Surface of +ve phi 220 G4VTwistSurface* fInnerHype; // Surface of -ve r 221 G4VTwistSurface* fOuterHype; // Surface of +ve r 222 223 G4double fCubicVolume = 0.0; // Cached value for cubic volume 224 G4double fSurfaceArea = 0.0; // Cached value for surface area 225 226 mutable G4bool fRebuildPolyhedron = false; 227 mutable G4Polyhedron* fpPolyhedron = nullptr; // polyhedron for vis 228 229 }; 230 231 //===================================================================== 232 233 //--------------------- 234 // inline functions 235 //--------------------- 236 237 inline 238 void G4TwistedTubs::SetFields(G4double phitwist, G4double innerrad, 239 G4double outerrad, G4double negativeEndz, 240 G4double positiveEndz) 241 { 242 fCubicVolume = 0.; 243 fPhiTwist = phitwist; 244 fEndZ[0] = negativeEndz; 245 fEndZ[1] = positiveEndz; 246 fEndZ2[0] = fEndZ[0] * fEndZ[0]; 247 fEndZ2[1] = fEndZ[1] * fEndZ[1]; 248 fInnerRadius = innerrad; 249 fOuterRadius = outerrad; 250 fInnerRadius2 = fInnerRadius * fInnerRadius; 251 fOuterRadius2 = fOuterRadius * fOuterRadius; 252 253 if (std::fabs(fEndZ[0]) >= std::fabs(fEndZ[1])) 254 { 255 fZHalfLength = std::fabs(fEndZ[0]); 256 } 257 else 258 { 259 fZHalfLength = std::fabs(fEndZ[1]); 260 } 261 262 G4double parity = (fPhiTwist > 0 ? 1 : -1); 263 G4double tanHalfTwist = std::tan(0.5 * fPhiTwist); 264 G4double innerNumerator = std::fabs(fInnerRadius * tanHalfTwist) * parity; 265 G4double outerNumerator = std::fabs(fOuterRadius * tanHalfTwist) * parity; 266 267 fTanInnerStereo = innerNumerator / fZHalfLength; 268 fTanOuterStereo = outerNumerator / fZHalfLength; 269 fTanInnerStereo2 = fTanInnerStereo * fTanInnerStereo; 270 fTanOuterStereo2 = fTanOuterStereo * fTanOuterStereo; 271 fInnerStereo = std::atan2(innerNumerator, fZHalfLength); 272 fOuterStereo = std::atan2(outerNumerator, fZHalfLength); 273 fEndInnerRadius[0] = std::sqrt(fInnerRadius2 + fEndZ2[0] * fTanInnerStereo2); 274 fEndInnerRadius[1] = std::sqrt(fInnerRadius2 + fEndZ2[1] * fTanInnerStereo2); 275 fEndOuterRadius[0] = std::sqrt(fOuterRadius2 + fEndZ2[0] * fTanOuterStereo2); 276 fEndOuterRadius[1] = std::sqrt(fOuterRadius2 + fEndZ2[1] * fTanOuterStereo2); 277 278 fKappa = tanHalfTwist / fZHalfLength; 279 fEndPhi[0] = std::atan2(fEndZ[0] * tanHalfTwist, fZHalfLength); 280 fEndPhi[1] = std::atan2(fEndZ[1] * tanHalfTwist, fZHalfLength); 281 282 #ifdef G4TWISTDEBUG 283 G4cout << "/********* G4TwistedTubs::SetFields() Field Parameters ***************** " << G4endl; 284 G4cout << "/* fPhiTwist : " << fPhiTwist << G4endl; 285 G4cout << "/* fEndZ(0, 1) : " << fEndZ[0] << " , " << fEndZ[1] << G4endl; 286 G4cout << "/* fEndPhi(0, 1) : " << fEndPhi[0] << " , " << fEndPhi[1] << G4endl; 287 G4cout << "/* fInnerRadius, fOuterRadius : " << fInnerRadius << " , " << fOuterRadius << G4endl; 288 G4cout << "/* fEndInnerRadius(0, 1) : " << fEndInnerRadius[0] << " , " 289 << fEndInnerRadius[1] << G4endl; 290 G4cout << "/* fEndOuterRadius(0, 1) : " << fEndOuterRadius[0] << " , " 291 << fEndOuterRadius[1] << G4endl; 292 G4cout << "/* fInnerStereo, fOuterStereo : " << fInnerStereo << " , " << fOuterStereo << G4endl; 293 G4cout << "/* tanHalfTwist, fKappa : " << tanHalfTwist << " , " << fKappa << G4endl; 294 G4cout << "/*********************************************************************** " << G4endl; 295 #endif 296 } 297 298 #endif 299