Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-20 09:12:07

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 // G4TwistedTubs
0027 //
0028 // Class description:
0029 //
0030 // G4TwistedTubs is a sector of a twisted hollow cylinder.
0031 // A twisted cylinder which is placed along with z-axis and is
0032 // separated into phi-segments should become a hyperboloid, and
0033 // its each segmented piece should be tilted with a stereo angle.
0034 // G4TwistedTubs is a G4VSolid.
0035 //
0036 // Details of the implementation: "Development of a Geant4 solid
0037 // for stereo mini-jet cells in a cylindrical drift chamber",
0038 // Computer Physics Communications 153 (2003) pp.373-391
0039 
0040 // Author: Kotoyo Hoshina (Chiba University), 01.08.2002 - created.
0041 //         Oliver Link (CERN), 13.11.2003 - Integration in Geant4
0042 //                from original version in Jupiter-2.5.02 application.
0043 // --------------------------------------------------------------------
0044 #ifndef G4TWISTEDTUBS_HH
0045 #define G4TWISTEDTUBS_HH
0046 
0047 #include "G4VSolid.hh"
0048 #include "G4TwistTubsFlatSide.hh"
0049 #include "G4TwistTubsSide.hh"
0050 #include "G4TwistTubsHypeSide.hh"
0051 
0052 class G4SolidExtentList;
0053 class G4ClippablePolygon;
0054 
0055 /**
0056  * @brief G4TwistedTubs is a sector of a twisted hollow cylinder.
0057  * A twisted cylinder which is placed along with Z axis and is separated into
0058  * phi-segments should become a hyperboloid, and its each segmented piece
0059  * should be tilted with a stereo angle.
0060  */
0061 
0062 class G4TwistedTubs : public G4VSolid
0063 {
0064   public:
0065  
0066     /**
0067      * Constructs a twisted tube, given radii and twist angle.
0068      *  @param[in] pName The solid name.
0069      *  @param[in] twistedangle The twisted angle.
0070      *  @param[in] endinnerrad Inner radius at endcap.
0071      *  @param[in] endouterrad Outer radius at endcap.
0072      *  @param[in] halfzlen Half Z length.
0073      *  @param[in] dphi Phi angle of a segment.
0074      */
0075     G4TwistedTubs(const G4String& pname,        // Name of instance
0076                         G4double  twistedangle, // Twisted angle
0077                         G4double  endinnerrad,  // Inner radius at endcap
0078                         G4double  endouterrad,  // Outer radius at endcap
0079                         G4double  halfzlen,     // half z length
0080                         G4double  dphi);        // Phi angle of a segment
0081                       
0082     /**
0083      * Constructs a twisted tube, given radii, twist angle and number of segments.
0084      *  @param[in] pName The solid name.
0085      *  @param[in] twistedangle The twisted angle.
0086      *  @param[in] endinnerrad Inner radius at endcap.
0087      *  @param[in] endouterrad Outer radius at endcap.
0088      *  @param[in] halfzlen Half Z length.
0089      *  @param[in] nseg Number of segments in Phi.
0090      *  @param[in] totphi Total angle of all segments.
0091      */
0092     G4TwistedTubs(const G4String& pname,        // Name of instance
0093                         G4double  twistedangle, // Stereo angle
0094                         G4double  endinnerrad,  // Inner radius at endcap
0095                         G4double  endouterrad,  // Outer radius at endcap
0096                         G4double  halfzlen,     // half z length 
0097                         G4int     nseg,         // Number of segments in totalPhi
0098                         G4double  totphi);      // Total angle of all segments
0099                       
0100     /**
0101      * Constructs a twisted tube, given radii, twist angle and EndZ values.
0102      *  @param[in] pName The solid name.
0103      *  @param[in] twistedangle The twisted angle.
0104      *  @param[in] innerrad Inner radius at z=0.
0105      *  @param[in] outerrad Outer radius at z=0.
0106      *  @param[in] negativeEndz -ve Z endplate.
0107      *  @param[in] positiveEndz +ve Z endplate.
0108      *  @param[in] dphi Phi angle of a segment.
0109      */
0110     G4TwistedTubs(const G4String& pname,        // Name of instance
0111                         G4double  twistedangle, // Twisted angle
0112                         G4double  innerrad,     // Inner radius at z=0
0113                         G4double  outerrad,     // Outer radius at z=0
0114                         G4double  negativeEndz, // -ve z endplate
0115                         G4double  positiveEndz, // +ve z endplate
0116                         G4double  dphi);        // Phi angle of a segment
0117 
0118     /**
0119      * Constructs a twisted tube, given radii, twist angle, EndZ values
0120      * and number of segments.
0121      *  @param[in] pName The solid name.
0122      *  @param[in] twistedangle The twisted angle.
0123      *  @param[in] innerrad Inner radius at z=0.
0124      *  @param[in] outerrad Outer radius at z=0.
0125      *  @param[in] negativeEndz -ve Z endplate.
0126      *  @param[in] positiveEndz +ve Z endplate.
0127      *  @param[in] nseg Number of segments in Phi.
0128      *  @param[in] totphi Total angle of all segments.
0129      */
0130     G4TwistedTubs(const G4String& pname,        // Name of instance
0131                         G4double  twistedangle, // Stereo angle
0132                         G4double  innerrad,     // Inner radius at z=0 
0133                         G4double  outerrad,     // Outer radius at z=0 
0134                         G4double  negativeEndz, // -ve z endplate
0135                         G4double  positiveEndz, // +ve z endplate
0136                         G4int     nseg,         // Number of segments in totalPhi
0137                         G4double  totphi);      // Total angle of all segments
0138 
0139     /**
0140      * Destructor.
0141      */
0142     ~G4TwistedTubs() override;
0143              
0144     /**
0145      * Thows a fatal exception. Parameterisations are not allowed on this shape.
0146      */
0147     void ComputeDimensions(G4VPVParameterisation*    /* p  */ ,
0148                            const G4int               /* n  */ ,
0149                            const G4VPhysicalVolume*  /* prep */ ) override;
0150 
0151     /**
0152      * Computes the bounding limits of the solid.
0153      *  @param[out] pMin The minimum bounding limit point.
0154      *  @param[out] pMax The maximum bounding limit point.
0155      */
0156     void BoundingLimits(G4ThreeVector& pMin, G4ThreeVector& pMax) const override;
0157 
0158     /**
0159      * Calculates the minimum and maximum extent of the solid, when under the
0160      * specified transform, and within the specified limits.
0161      *  @param[in] pAxis The axis along which compute the extent.
0162      *  @param[in] pVoxelLimit The limiting space dictated by voxels.
0163      *  @param[in] pTransform The internal transformation applied to the solid.
0164      *  @param[out] pMin The minimum extent value.
0165      *  @param[out] pMax The maximum extent value.
0166      *  @returns True if the solid is intersected by the extent region.
0167      */
0168     G4bool CalculateExtent(const EAxis               pAxis,
0169                            const G4VoxelLimits&     pVoxelLimit,
0170                            const G4AffineTransform& pTransform,
0171                                  G4double&          pMin,
0172                                  G4double&          pMax ) const override;
0173 
0174     /**
0175      * Concrete implementations of the expected query interfaces for
0176      * solids, as defined in the base class G4VSolid.
0177      */
0178     G4double DistanceToIn (const G4ThreeVector& p,
0179                            const G4ThreeVector& v ) const override;
0180     G4double DistanceToIn (const G4ThreeVector& p ) const override;
0181     G4double DistanceToOut(const G4ThreeVector& p, 
0182                            const G4ThreeVector& v,
0183                            const G4bool calcnorm = false,
0184                                  G4bool* validnorm = nullptr, 
0185                                  G4ThreeVector* n = nullptr ) const override;
0186     G4double DistanceToOut(const G4ThreeVector& p) const override;
0187     EInside Inside (const G4ThreeVector& p) const override;
0188     G4ThreeVector SurfaceNormal(const G4ThreeVector& p) const override;
0189 
0190     /**
0191      * Methods for creating graphical representations (i.e. for visualisation).
0192      */
0193     void DescribeYourselfTo (G4VGraphicsScene& scene) const override;
0194     G4Polyhedron* CreatePolyhedron () const override;
0195     G4Polyhedron* GetPolyhedron () const override;
0196     G4VisExtent GetExtent () const override;
0197 
0198     /**
0199      * Streams the object contents to an output stream.
0200      */
0201     std::ostream &StreamInfo(std::ostream& os) const override;
0202 
0203     /**
0204      * Accessors.
0205      */
0206     inline G4double GetDPhi        () const { return fDPhi       ; }
0207     inline G4double GetPhiTwist    () const { return fPhiTwist   ; }
0208     inline G4double GetInnerRadius () const { return fInnerRadius; }
0209     inline G4double GetOuterRadius () const { return fOuterRadius; }
0210     inline G4double GetInnerStereo () const { return fInnerStereo; }
0211     inline G4double GetOuterStereo () const { return fOuterStereo; }
0212     inline G4double GetZHalfLength () const { return fZHalfLength; }
0213     inline G4double GetKappa       () const { return fKappa      ; }
0214     //
0215     inline G4double GetTanInnerStereo () const { return fTanInnerStereo  ; }
0216     inline G4double GetTanInnerStereo2() const { return fTanInnerStereo2 ; }
0217     inline G4double GetTanOuterStereo () const { return fTanOuterStereo  ; }
0218     inline G4double GetTanOuterStereo2() const { return fTanOuterStereo2 ; }
0219     //
0220     inline G4double GetEndZ           (G4int i) const { return fEndZ[i]  ; }
0221     inline G4double GetEndPhi         (G4int i) const { return fEndPhi[i]; }
0222     inline G4double GetEndInnerRadius (G4int i) const
0223                     { return fEndInnerRadius[i]; }
0224     inline G4double GetEndOuterRadius (G4int i) const
0225                     { return fEndOuterRadius[i]; }
0226     inline G4double GetEndInnerRadius () const 
0227                     { return (fEndInnerRadius[0] > fEndInnerRadius[1] ?
0228                       fEndInnerRadius[0] : fEndInnerRadius[1]); }
0229     inline G4double GetEndOuterRadius () const
0230                     { return (fEndOuterRadius[0] > fEndOuterRadius[1] ?
0231                       fEndOuterRadius[0] : fEndOuterRadius[1]); }
0232   
0233     /**
0234      * Returns the type ID, "G4TwistedTubs" of the solid.
0235      */
0236     G4GeometryType  GetEntityType() const override;
0237 
0238     /**
0239      * Makes a clone of the object for use in multi-treading.
0240      *  @returns A pointer to the new cloned allocated solid.
0241      */
0242     G4VSolid* Clone() const override;
0243 
0244     /**
0245      * Returning an estimation of the solid volume (capacity) and surface area,
0246      * in internal units. Caches the computed value once computed the first time.
0247      */
0248     G4double GetCubicVolume() override;
0249     G4double GetSurfaceArea() override;
0250 
0251     /**
0252      * Returns a random point located and uniformly distributed on the
0253      * surface of the solid.
0254      */
0255     G4ThreeVector GetPointOnSurface() const override ;
0256 
0257     /**
0258      * Fake default constructor for usage restricted to direct object
0259      * persistency for clients requiring preallocation of memory for
0260      * persistifiable objects.
0261      */
0262     G4TwistedTubs(__void__&);
0263 
0264     /**
0265      * Copy constructor and assignment operator.
0266      */
0267     G4TwistedTubs(const G4TwistedTubs& rhs);
0268     G4TwistedTubs& operator=(const G4TwistedTubs& rhs); 
0269 
0270 #ifdef G4TWISTDEBUG
0271     inline G4VTwistSurface* GetOuterHype() const { return fOuterHype; }
0272 #endif
0273   
0274   private:
0275  
0276     /**
0277      * Initialiser of data.
0278      */
0279     inline void SetFields(G4double phitwist, G4double innerrad,
0280                           G4double outerrad,
0281                           G4double negativeEndz, G4double positiveEndz);
0282 
0283     /**
0284      * Generates the surfaces. Used in constructors.
0285      */
0286     void CreateSurfaces();
0287 
0288     /**
0289      * Utilities for area computation.
0290      */
0291     G4double GetLateralArea(G4double a, G4double r, G4double z) const;
0292     G4double GetPhiCutArea(G4double a, G4double r, G4double z) const;
0293 
0294   private:
0295  
0296     G4double fPhiTwist;       // Twist angle from -fZHalfLength to fZHalfLength
0297     G4double fInnerRadius;    // Inner-hype radius at z=0
0298     G4double fOuterRadius;    // Outer-hype radius at z=0
0299     G4double fEndZ[2];        // z at endcaps, [0] = -ve z, [1] = +ve z
0300     G4double fDPhi;           // Phi-width of a segment fDPhi > 0
0301     G4double fZHalfLength;    // Half length along z-axis
0302  
0303     G4double fInnerStereo;       // Inner-hype stereo angle
0304     G4double fOuterStereo;       // Outer-hype stereo angle
0305     G4double fTanInnerStereo;    // std::tan(innerStereoAngle)
0306     G4double fTanOuterStereo;    // std::tan(outerStereoAngle)
0307     G4double fKappa;             // std::tan(fPhiTwist/2)/fZHalfLen;
0308     G4double fEndInnerRadius[2]; // Inner-hype radii endcaps [0] -ve z, [1] +ve z
0309     G4double fEndOuterRadius[2]; // Outer-hype radii endcaps [0] -ve z, [1] +ve z
0310     G4double fEndPhi[2];         // Phi endcaps, [0] = -ve z, [1] = +ve z
0311   
0312     G4double fInnerRadius2;      // fInnerRadius * fInnerRadius
0313     G4double fOuterRadius2;      // fOuterRadius * fOuterRadius
0314     G4double fTanInnerStereo2;   // fInnerRadius * fInnerRadius
0315     G4double fTanOuterStereo2;   // fInnerRadius * fInnerRadius
0316     G4double fEndZ2[2];          // fEndZ * fEndZ
0317   
0318     G4VTwistSurface* fLowerEndcap;    // Surface of -ve z
0319     G4VTwistSurface* fUpperEndcap;    // Surface of +ve z
0320     G4VTwistSurface* fLatterTwisted;  // Surface of -ve phi
0321     G4VTwistSurface* fFormerTwisted;  // Surface of +ve phi
0322     G4VTwistSurface* fInnerHype;      // Surface of -ve r
0323     G4VTwistSurface* fOuterHype;      // Surface of +ve r
0324 
0325     G4double fCubicVolume = 0.0;      // Cached value for cubic volume
0326     G4double fSurfaceArea = 0.0;      // Cached value for surface area
0327 
0328     mutable G4bool fRebuildPolyhedron = false;
0329     mutable G4Polyhedron* fpPolyhedron = nullptr; // polyhedron for vis
0330 
0331 };
0332 
0333 //=====================================================================
0334 
0335 //---------------------
0336 // inline functions
0337 //---------------------
0338 
0339 inline
0340 void G4TwistedTubs::SetFields(G4double phitwist, G4double innerrad, 
0341                               G4double outerrad, G4double negativeEndz, 
0342                               G4double positiveEndz)
0343 {
0344    fCubicVolume  = 0.;
0345    fPhiTwist     = phitwist;
0346    fEndZ[0]      = negativeEndz;
0347    fEndZ[1]      = positiveEndz;
0348    fEndZ2[0]     = fEndZ[0] * fEndZ[0];
0349    fEndZ2[1]     = fEndZ[1] * fEndZ[1];
0350    fInnerRadius  = innerrad;
0351    fOuterRadius  = outerrad;
0352    fInnerRadius2 = fInnerRadius * fInnerRadius;
0353    fOuterRadius2 = fOuterRadius * fOuterRadius;
0354    
0355    if (std::fabs(fEndZ[0]) >= std::fabs(fEndZ[1]))
0356    {
0357       fZHalfLength = std::fabs(fEndZ[0]);
0358    }
0359    else
0360    {
0361       fZHalfLength = std::fabs(fEndZ[1]);
0362    }
0363 
0364    G4double parity         = (fPhiTwist > 0 ? 1 : -1); 
0365    G4double tanHalfTwist   = std::tan(0.5 * fPhiTwist);
0366    G4double innerNumerator = std::fabs(fInnerRadius * tanHalfTwist) * parity;
0367    G4double outerNumerator = std::fabs(fOuterRadius * tanHalfTwist) * parity;
0368 
0369    fTanInnerStereo    = innerNumerator / fZHalfLength; 
0370    fTanOuterStereo    = outerNumerator / fZHalfLength; 
0371    fTanInnerStereo2   = fTanInnerStereo * fTanInnerStereo;
0372    fTanOuterStereo2   = fTanOuterStereo * fTanOuterStereo;
0373    fInnerStereo       = std::atan2(innerNumerator,  fZHalfLength); 
0374    fOuterStereo       = std::atan2(outerNumerator,  fZHalfLength); 
0375    fEndInnerRadius[0] = std::sqrt(fInnerRadius2 + fEndZ2[0] * fTanInnerStereo2);
0376    fEndInnerRadius[1] = std::sqrt(fInnerRadius2 + fEndZ2[1] * fTanInnerStereo2);
0377    fEndOuterRadius[0] = std::sqrt(fOuterRadius2 + fEndZ2[0] * fTanOuterStereo2);
0378    fEndOuterRadius[1] = std::sqrt(fOuterRadius2 + fEndZ2[1] * fTanOuterStereo2);
0379 
0380    fKappa          = tanHalfTwist / fZHalfLength;
0381    fEndPhi[0]      = std::atan2(fEndZ[0] * tanHalfTwist, fZHalfLength);
0382    fEndPhi[1]      = std::atan2(fEndZ[1] * tanHalfTwist, fZHalfLength);
0383 
0384 #ifdef G4TWISTDEBUG
0385    G4cout << "/********* G4TwistedTubs::SetFields() Field Parameters ***************** " << G4endl;
0386    G4cout << "/*   fPhiTwist                  : " << fPhiTwist << G4endl;
0387    G4cout << "/*   fEndZ(0, 1)                : " << fEndZ[0] << " , " << fEndZ[1] << G4endl; 
0388    G4cout << "/*   fEndPhi(0, 1)              : " << fEndPhi[0] << " , " << fEndPhi[1] << G4endl; 
0389    G4cout << "/*   fInnerRadius, fOuterRadius : " << fInnerRadius << " , " << fOuterRadius << G4endl; 
0390    G4cout << "/*   fEndInnerRadius(0, 1)      : " << fEndInnerRadius[0] << " , " 
0391           << fEndInnerRadius[1] << G4endl; 
0392    G4cout << "/*   fEndOuterRadius(0, 1)      : " << fEndOuterRadius[0] << " , " 
0393           << fEndOuterRadius[1] << G4endl; 
0394    G4cout << "/*   fInnerStereo, fOuterStereo : " << fInnerStereo << " , " << fOuterStereo << G4endl; 
0395    G4cout << "/*   tanHalfTwist, fKappa       : " << tanHalfTwist << " , " << fKappa << G4endl; 
0396    G4cout << "/*********************************************************************** " << G4endl;
0397 #endif
0398 }
0399 
0400 #endif