Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4TwistedTubs.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /geometry/solids/specific/src/G4TwistedTubs.cc (Version 11.3.0) and /geometry/solids/specific/src/G4TwistedTubs.cc (Version 11.1)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4TwistedTubs implementation                    26 // G4TwistedTubs implementation
 27 //                                                 27 //
 28 // 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepbu     28 // 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepburn.s.chiba-u.ac.jp), created.
 29 // 13-Nov-2003 - O.Link (Oliver.Link@cern.ch),     29 // 13-Nov-2003 - O.Link (Oliver.Link@cern.ch), Integration in Geant4
 30 //               from original version in Jupi     30 //               from original version in Jupiter-2.5.02 application.
 31 // -------------------------------------------     31 // --------------------------------------------------------------------
 32                                                    32 
 33 #include "G4TwistedTubs.hh"                        33 #include "G4TwistedTubs.hh"
 34                                                    34 
 35 #include "G4GeomTools.hh"                          35 #include "G4GeomTools.hh"
 36 #include "G4PhysicalConstants.hh"                  36 #include "G4PhysicalConstants.hh"
 37 #include "G4SystemOfUnits.hh"                      37 #include "G4SystemOfUnits.hh"
 38 #include "G4GeometryTolerance.hh"                  38 #include "G4GeometryTolerance.hh"
 39 #include "G4VoxelLimits.hh"                        39 #include "G4VoxelLimits.hh"
 40 #include "G4AffineTransform.hh"                    40 #include "G4AffineTransform.hh"
 41 #include "G4BoundingEnvelope.hh"                   41 #include "G4BoundingEnvelope.hh"
 42 #include "G4ClippablePolygon.hh"                   42 #include "G4ClippablePolygon.hh"
 43 #include "G4VPVParameterisation.hh"                43 #include "G4VPVParameterisation.hh"
 44 #include "meshdefs.hh"                             44 #include "meshdefs.hh"
 45                                                    45 
 46 #include "G4VGraphicsScene.hh"                     46 #include "G4VGraphicsScene.hh"
 47 #include "G4Polyhedron.hh"                         47 #include "G4Polyhedron.hh"
 48 #include "G4VisExtent.hh"                          48 #include "G4VisExtent.hh"
 49                                                    49 
 50 #include "Randomize.hh"                            50 #include "Randomize.hh"
 51                                                    51 
 52 #include "G4AutoLock.hh"                           52 #include "G4AutoLock.hh"
 53                                                    53 
 54 namespace                                          54 namespace
 55 {                                                  55 {
 56   G4Mutex polyhedronMutex = G4MUTEX_INITIALIZE     56   G4Mutex polyhedronMutex = G4MUTEX_INITIALIZER;
 57 }                                                  57 }
 58                                                    58 
 59                                                << 
 60 //============================================     59 //=====================================================================
 61 //* constructors -----------------------------     60 //* constructors ------------------------------------------------------
 62                                                    61 
 63 G4TwistedTubs::G4TwistedTubs(const G4String& p     62 G4TwistedTubs::G4TwistedTubs(const G4String& pname,
 64                                    G4double  t     63                                    G4double  twistedangle,
 65                                    G4double  e     64                                    G4double  endinnerrad,
 66                                    G4double  e     65                                    G4double  endouterrad,
 67                                    G4double  h     66                                    G4double  halfzlen,
 68                                    G4double  d     67                                    G4double  dphi)
 69    : G4VSolid(pname), fDPhi(dphi),                 68    : G4VSolid(pname), fDPhi(dphi), 
 70      fLowerEndcap(nullptr), fUpperEndcap(nullp <<  69      fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
 71      fFormerTwisted(nullptr), fInnerHype(nullp <<  70      fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
 72 {                                                  71 {
 73    if (endinnerrad < DBL_MIN)                      72    if (endinnerrad < DBL_MIN)
 74    {                                               73    {
 75       G4Exception("G4TwistedTubs::G4TwistedTub     74       G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
 76                   FatalErrorInArgument, "Inval     75                   FatalErrorInArgument, "Invalid end-inner-radius!");
 77    }                                               76    }
 78                                                    77             
 79    G4double sinhalftwist = std::sin(0.5 * twis     78    G4double sinhalftwist = std::sin(0.5 * twistedangle);
 80                                                    79 
 81    G4double endinnerradX = endinnerrad * sinha     80    G4double endinnerradX = endinnerrad * sinhalftwist;
 82    G4double innerrad     = std::sqrt( endinner     81    G4double innerrad     = std::sqrt( endinnerrad * endinnerrad
 83                                  - endinnerrad     82                                  - endinnerradX * endinnerradX );
 84                                                    83 
 85    G4double endouterradX = endouterrad * sinha     84    G4double endouterradX = endouterrad * sinhalftwist;
 86    G4double outerrad     = std::sqrt( endouter     85    G4double outerrad     = std::sqrt( endouterrad * endouterrad
 87                                  - endouterrad     86                                  - endouterradX * endouterradX );
 88                                                    87    
 89    // temporary treatment!!                        88    // temporary treatment!!
 90    SetFields(twistedangle, innerrad, outerrad,     89    SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
 91    CreateSurfaces();                               90    CreateSurfaces();
 92 }                                                  91 }
 93                                                    92 
 94 G4TwistedTubs::G4TwistedTubs(const G4String& p     93 G4TwistedTubs::G4TwistedTubs(const G4String& pname,     
 95                                    G4double  t     94                                    G4double  twistedangle,    
 96                                    G4double  e     95                                    G4double  endinnerrad,  
 97                                    G4double  e     96                                    G4double  endouterrad,  
 98                                    G4double  h     97                                    G4double  halfzlen,
 99                                    G4int     n     98                                    G4int     nseg,
100                                    G4double  t     99                                    G4double  totphi)
101    : G4VSolid(pname),                             100    : G4VSolid(pname),
102      fLowerEndcap(nullptr), fUpperEndcap(nullp << 101      fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
103      fFormerTwisted(nullptr), fInnerHype(nullp << 102      fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
104 {                                                 103 {
105                                                   104 
106    if (nseg == 0)                              << 105    if (!nseg)
107    {                                              106    {
108       std::ostringstream message;                 107       std::ostringstream message;
109       message << "Invalid number of segments."    108       message << "Invalid number of segments." << G4endl
110               << "        nseg = " << nseg;       109               << "        nseg = " << nseg;
111       G4Exception("G4TwistedTubs::G4TwistedTub    110       G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
112                   FatalErrorInArgument, messag    111                   FatalErrorInArgument, message);
113    }                                              112    }
114    if (totphi == DBL_MIN || endinnerrad < DBL_    113    if (totphi == DBL_MIN || endinnerrad < DBL_MIN)
115    {                                              114    {
116       G4Exception("G4TwistedTubs::G4TwistedTub    115       G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
117                 FatalErrorInArgument, "Invalid    116                 FatalErrorInArgument, "Invalid total-phi or end-inner-radius!");
118    }                                              117    }
119                                                   118          
120    G4double sinhalftwist = std::sin(0.5 * twis    119    G4double sinhalftwist = std::sin(0.5 * twistedangle);
121                                                   120 
122    G4double endinnerradX = endinnerrad * sinha    121    G4double endinnerradX = endinnerrad * sinhalftwist;
123    G4double innerrad     = std::sqrt( endinner    122    G4double innerrad     = std::sqrt( endinnerrad * endinnerrad
124                                  - endinnerrad    123                                  - endinnerradX * endinnerradX );
125                                                   124 
126    G4double endouterradX = endouterrad * sinha    125    G4double endouterradX = endouterrad * sinhalftwist;
127    G4double outerrad     = std::sqrt( endouter    126    G4double outerrad     = std::sqrt( endouterrad * endouterrad
128                                  - endouterrad    127                                  - endouterradX * endouterradX );
129                                                   128    
130    // temporary treatment!!                       129    // temporary treatment!!
131    fDPhi = totphi / nseg;                         130    fDPhi = totphi / nseg;
132    SetFields(twistedangle, innerrad, outerrad,    131    SetFields(twistedangle, innerrad, outerrad, -halfzlen, halfzlen);
133    CreateSurfaces();                              132    CreateSurfaces();
134 }                                                 133 }
135                                                   134 
136 G4TwistedTubs::G4TwistedTubs(const G4String& p    135 G4TwistedTubs::G4TwistedTubs(const G4String& pname,
137                                    G4double  t    136                                    G4double  twistedangle,
138                                    G4double  i    137                                    G4double  innerrad,
139                                    G4double  o    138                                    G4double  outerrad,
140                                    G4double  n    139                                    G4double  negativeEndz,
141                                    G4double  p    140                                    G4double  positiveEndz,
142                                    G4double  d    141                                    G4double  dphi)
143    : G4VSolid(pname), fDPhi(dphi),                142    : G4VSolid(pname), fDPhi(dphi),
144      fLowerEndcap(nullptr), fUpperEndcap(nullp << 143      fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
145      fFormerTwisted(nullptr), fInnerHype(nullp << 144      fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
146 {                                                 145 {
147    if (innerrad < DBL_MIN)                        146    if (innerrad < DBL_MIN)
148    {                                              147    {
149       G4Exception("G4TwistedTubs::G4TwistedTub    148       G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
150                   FatalErrorInArgument, "Inval    149                   FatalErrorInArgument, "Invalid end-inner-radius!");
151    }                                              150    }
152                                                   151                  
153    SetFields(twistedangle, innerrad, outerrad,    152    SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
154    CreateSurfaces();                              153    CreateSurfaces();
155 }                                                 154 }
156                                                   155 
157 G4TwistedTubs::G4TwistedTubs(const G4String& p    156 G4TwistedTubs::G4TwistedTubs(const G4String& pname,     
158                                    G4double  t    157                                    G4double  twistedangle,    
159                                    G4double  i    158                                    G4double  innerrad,  
160                                    G4double  o    159                                    G4double  outerrad,  
161                                    G4double  n    160                                    G4double  negativeEndz,
162                                    G4double  p    161                                    G4double  positiveEndz,
163                                    G4int     n    162                                    G4int     nseg,
164                                    G4double  t    163                                    G4double  totphi)
165    : G4VSolid(pname),                             164    : G4VSolid(pname),
166      fLowerEndcap(nullptr), fUpperEndcap(nullp << 165      fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0),
167      fFormerTwisted(nullptr), fInnerHype(nullp << 166      fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
168 {                                                 167 {
169    if (nseg == 0)                              << 168    if (!nseg)
170    {                                              169    {
171       std::ostringstream message;                 170       std::ostringstream message;
172       message << "Invalid number of segments."    171       message << "Invalid number of segments." << G4endl
173               << "        nseg = " << nseg;       172               << "        nseg = " << nseg;
174       G4Exception("G4TwistedTubs::G4TwistedTub    173       G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
175                   FatalErrorInArgument, messag    174                   FatalErrorInArgument, message);
176    }                                              175    }
177    if (totphi == DBL_MIN || innerrad < DBL_MIN    176    if (totphi == DBL_MIN || innerrad < DBL_MIN)
178    {                                              177    {
179       G4Exception("G4TwistedTubs::G4TwistedTub    178       G4Exception("G4TwistedTubs::G4TwistedTubs()", "GeomSolids0002",
180                 FatalErrorInArgument, "Invalid    179                 FatalErrorInArgument, "Invalid total-phi or end-inner-radius!");
181    }                                              180    }
182                                                   181             
183    fDPhi = totphi / nseg;                         182    fDPhi = totphi / nseg;
184    SetFields(twistedangle, innerrad, outerrad,    183    SetFields(twistedangle, innerrad, outerrad, negativeEndz, positiveEndz);
185    CreateSurfaces();                              184    CreateSurfaces();
186 }                                                 185 }
187                                                   186 
188 //============================================    187 //=====================================================================
189 //* Fake default constructor -----------------    188 //* Fake default constructor ------------------------------------------
190                                                   189 
191 G4TwistedTubs::G4TwistedTubs( __void__& a )       190 G4TwistedTubs::G4TwistedTubs( __void__& a )
192   : G4VSolid(a),                               << 191   : G4VSolid(a), fPhiTwist(0.), fInnerRadius(0.), fOuterRadius(0.), fDPhi(0.),
193     fLowerEndcap(nullptr), fUpperEndcap(nullpt << 192     fZHalfLength(0.), fInnerStereo(0.), fOuterStereo(0.), fTanInnerStereo(0.),
194     fLatterTwisted(nullptr), fFormerTwisted(nu << 193     fTanOuterStereo(0.), fKappa(0.), fInnerRadius2(0.), fOuterRadius2(0.),
195     fInnerHype(nullptr), fOuterHype(nullptr)   << 194     fTanInnerStereo2(0.), fTanOuterStereo2(0.), fLowerEndcap(0), fUpperEndcap(0),
                                                   >> 195     fLatterTwisted(0), fFormerTwisted(0), fInnerHype(0), fOuterHype(0)
196 {                                                 196 {
197 }                                                 197 }
198                                                   198 
199 //============================================    199 //=====================================================================
200 //* destructor -------------------------------    200 //* destructor --------------------------------------------------------
201                                                   201 
202 G4TwistedTubs::~G4TwistedTubs()                   202 G4TwistedTubs::~G4TwistedTubs()
203 {                                                 203 {
204    delete fLowerEndcap;                        << 204    if (fLowerEndcap)   { delete fLowerEndcap;   }
205    delete fUpperEndcap;                        << 205    if (fUpperEndcap)   { delete fUpperEndcap;   }
206    delete fLatterTwisted;                      << 206    if (fLatterTwisted) { delete fLatterTwisted; }
207    delete fFormerTwisted;                      << 207    if (fFormerTwisted) { delete fFormerTwisted; }
208    delete fInnerHype;                          << 208    if (fInnerHype)     { delete fInnerHype;     }
209    delete fOuterHype;                          << 209    if (fOuterHype)     { delete fOuterHype;     }
210    delete fpPolyhedron; fpPolyhedron = nullptr << 210    if (fpPolyhedron)   { delete fpPolyhedron; fpPolyhedron = nullptr; }
211 }                                                 211 }
212                                                   212 
213 //============================================    213 //=====================================================================
214 //* Copy constructor -------------------------    214 //* Copy constructor --------------------------------------------------
215                                                   215 
216 G4TwistedTubs::G4TwistedTubs(const G4TwistedTu    216 G4TwistedTubs::G4TwistedTubs(const G4TwistedTubs& rhs)
217   : G4VSolid(rhs), fPhiTwist(rhs.fPhiTwist),      217   : G4VSolid(rhs), fPhiTwist(rhs.fPhiTwist),
218     fInnerRadius(rhs.fInnerRadius), fOuterRadi    218     fInnerRadius(rhs.fInnerRadius), fOuterRadius(rhs.fOuterRadius),
219     fDPhi(rhs.fDPhi), fZHalfLength(rhs.fZHalfL    219     fDPhi(rhs.fDPhi), fZHalfLength(rhs.fZHalfLength),
220     fInnerStereo(rhs.fInnerStereo), fOuterSter    220     fInnerStereo(rhs.fInnerStereo), fOuterStereo(rhs.fOuterStereo),
221     fTanInnerStereo(rhs.fTanInnerStereo), fTan    221     fTanInnerStereo(rhs.fTanInnerStereo), fTanOuterStereo(rhs.fTanOuterStereo),
222     fKappa(rhs.fKappa), fInnerRadius2(rhs.fInn    222     fKappa(rhs.fKappa), fInnerRadius2(rhs.fInnerRadius2), 
223     fOuterRadius2(rhs.fOuterRadius2), fTanInne    223     fOuterRadius2(rhs.fOuterRadius2), fTanInnerStereo2(rhs.fTanInnerStereo2),
224     fTanOuterStereo2(rhs.fTanOuterStereo2),       224     fTanOuterStereo2(rhs.fTanOuterStereo2),
225     fLowerEndcap(nullptr), fUpperEndcap(nullpt << 225     fLowerEndcap(0), fUpperEndcap(0), fLatterTwisted(0), fFormerTwisted(0),
226     fInnerHype(nullptr), fOuterHype(nullptr),  << 226     fInnerHype(0), fOuterHype(0),
227     fCubicVolume(rhs.fCubicVolume), fSurfaceAr << 227     fCubicVolume(rhs.fCubicVolume), fSurfaceArea(rhs.fSurfaceArea),
                                                   >> 228     fLastInside(rhs.fLastInside), fLastNormal(rhs.fLastNormal),
                                                   >> 229     fLastDistanceToIn(rhs.fLastDistanceToIn),
                                                   >> 230     fLastDistanceToOut(rhs.fLastDistanceToOut),
                                                   >> 231     fLastDistanceToInWithV(rhs.fLastDistanceToInWithV),
                                                   >> 232     fLastDistanceToOutWithV(rhs.fLastDistanceToOutWithV)
228 {                                                 233 {
229   for (auto i=0; i<2; ++i)                        234   for (auto i=0; i<2; ++i)
230   {                                               235   {
231     fEndZ[i] = rhs.fEndZ[i];                      236     fEndZ[i] = rhs.fEndZ[i];
232     fEndInnerRadius[i] = rhs.fEndInnerRadius[i    237     fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
233     fEndOuterRadius[i] = rhs.fEndOuterRadius[i    238     fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
234     fEndPhi[i] = rhs.fEndPhi[i];                  239     fEndPhi[i] = rhs.fEndPhi[i];
235     fEndZ2[i] = rhs.fEndZ2[i];                    240     fEndZ2[i] = rhs.fEndZ2[i];
236   }                                               241   }
237   CreateSurfaces();                               242   CreateSurfaces();
238 }                                                 243 }
239                                                   244 
240                                                   245 
241 //============================================    246 //=====================================================================
242 //* Assignment operator ----------------------    247 //* Assignment operator -----------------------------------------------
243                                                   248 
244 G4TwistedTubs& G4TwistedTubs::operator = (cons    249 G4TwistedTubs& G4TwistedTubs::operator = (const G4TwistedTubs& rhs) 
245 {                                                 250 {
246    // Check assignment to self                    251    // Check assignment to self
247    //                                             252    //
248    if (this == &rhs)  { return *this; }           253    if (this == &rhs)  { return *this; }
249                                                   254 
250    // Copy base class data                        255    // Copy base class data
251    //                                             256    //
252    G4VSolid::operator=(rhs);                      257    G4VSolid::operator=(rhs);
253                                                   258 
254    // Copy data                                   259    // Copy data
255    //                                             260    //
256    fPhiTwist= rhs.fPhiTwist;                      261    fPhiTwist= rhs.fPhiTwist;
257    fInnerRadius= rhs.fInnerRadius; fOuterRadiu    262    fInnerRadius= rhs.fInnerRadius; fOuterRadius= rhs.fOuterRadius;
258    fDPhi= rhs.fDPhi; fZHalfLength= rhs.fZHalfL    263    fDPhi= rhs.fDPhi; fZHalfLength= rhs.fZHalfLength;
259    fInnerStereo= rhs.fInnerStereo; fOuterStere    264    fInnerStereo= rhs.fInnerStereo; fOuterStereo= rhs.fOuterStereo;
260    fTanInnerStereo= rhs.fTanInnerStereo; fTanO    265    fTanInnerStereo= rhs.fTanInnerStereo; fTanOuterStereo= rhs.fTanOuterStereo;
261    fKappa= rhs.fKappa; fInnerRadius2= rhs.fInn    266    fKappa= rhs.fKappa; fInnerRadius2= rhs.fInnerRadius2; 
262    fOuterRadius2= rhs.fOuterRadius2; fTanInner    267    fOuterRadius2= rhs.fOuterRadius2; fTanInnerStereo2= rhs.fTanInnerStereo2;
263    fTanOuterStereo2= rhs.fTanOuterStereo2;        268    fTanOuterStereo2= rhs.fTanOuterStereo2;
264    fLowerEndcap= fUpperEndcap= fLatterTwisted= << 269    fLowerEndcap= fUpperEndcap= fLatterTwisted= fFormerTwisted= 0;
265    fInnerHype= fOuterHype= nullptr;            << 270    fInnerHype= fOuterHype= 0;
266    fCubicVolume= rhs.fCubicVolume; fSurfaceAre    271    fCubicVolume= rhs.fCubicVolume; fSurfaceArea= rhs.fSurfaceArea;
                                                   >> 272    fLastInside= rhs.fLastInside; fLastNormal= rhs.fLastNormal;
                                                   >> 273    fLastDistanceToIn= rhs.fLastDistanceToIn;
                                                   >> 274    fLastDistanceToOut= rhs.fLastDistanceToOut;
                                                   >> 275    fLastDistanceToInWithV= rhs.fLastDistanceToInWithV;
                                                   >> 276    fLastDistanceToOutWithV= rhs.fLastDistanceToOutWithV;
267                                                   277  
268    for (auto i=0; i<2; ++i)                       278    for (auto i=0; i<2; ++i)
269    {                                              279    {
270      fEndZ[i] = rhs.fEndZ[i];                     280      fEndZ[i] = rhs.fEndZ[i];
271      fEndInnerRadius[i] = rhs.fEndInnerRadius[    281      fEndInnerRadius[i] = rhs.fEndInnerRadius[i];
272      fEndOuterRadius[i] = rhs.fEndOuterRadius[    282      fEndOuterRadius[i] = rhs.fEndOuterRadius[i];
273      fEndPhi[i] = rhs.fEndPhi[i];                 283      fEndPhi[i] = rhs.fEndPhi[i];
274      fEndZ2[i] = rhs.fEndZ2[i];                   284      fEndZ2[i] = rhs.fEndZ2[i];
275    }                                              285    }
276                                                   286  
277    CreateSurfaces();                              287    CreateSurfaces();
278    fRebuildPolyhedron = false;                    288    fRebuildPolyhedron = false;
279    delete fpPolyhedron; fpPolyhedron = nullptr    289    delete fpPolyhedron; fpPolyhedron = nullptr;
280                                                   290 
281    return *this;                                  291    return *this;
282 }                                                 292 }
283                                                   293 
284 //============================================    294 //=====================================================================
285 //* ComputeDimensions ------------------------    295 //* ComputeDimensions -------------------------------------------------
286                                                   296 
287 void G4TwistedTubs::ComputeDimensions(G4VPVPar    297 void G4TwistedTubs::ComputeDimensions(G4VPVParameterisation* /* p */ ,
288                                       const G4    298                                       const G4int            /* n  */ ,
289                                       const G4    299                                       const G4VPhysicalVolume* /* pRep */ )
290 {                                                 300 {
291   G4Exception("G4TwistedTubs::ComputeDimension    301   G4Exception("G4TwistedTubs::ComputeDimensions()",
292               "GeomSolids0001", FatalException    302               "GeomSolids0001", FatalException,
293               "G4TwistedTubs does not support     303               "G4TwistedTubs does not support Parameterisation.");
294 }                                                 304 }
295                                                   305 
296 //============================================    306 //=====================================================================
297 //* BoundingLimits ---------------------------    307 //* BoundingLimits ----------------------------------------------------
298                                                   308 
299 void G4TwistedTubs::BoundingLimits(G4ThreeVect    309 void G4TwistedTubs::BoundingLimits(G4ThreeVector& pMin,
300                                    G4ThreeVect    310                                    G4ThreeVector& pMax) const
301 {                                                 311 {
302   // Find bounding tube                           312   // Find bounding tube
303   G4double rmin = GetInnerRadius();               313   G4double rmin = GetInnerRadius();
304   G4double rmax = GetEndOuterRadius();            314   G4double rmax = GetEndOuterRadius();
305                                                   315 
306   G4double zmin = std::min(GetEndZ(0), GetEndZ    316   G4double zmin = std::min(GetEndZ(0), GetEndZ(1));
307   G4double zmax = std::max(GetEndZ(0), GetEndZ    317   G4double zmax = std::max(GetEndZ(0), GetEndZ(1));
308                                                   318 
309   G4double dphi = 0.5*GetDPhi();                  319   G4double dphi = 0.5*GetDPhi();
310   G4double sphi = std::min(GetEndPhi(0), GetEn    320   G4double sphi = std::min(GetEndPhi(0), GetEndPhi(1)) - dphi;
311   G4double ephi = std::max(GetEndPhi(0), GetEn    321   G4double ephi = std::max(GetEndPhi(0), GetEndPhi(1)) + dphi;
312   G4double totalphi = ephi - sphi;                322   G4double totalphi = ephi - sphi;
313                                                   323 
314   // Find bounding box                            324   // Find bounding box
315   if (dphi <= 0 || totalphi >= CLHEP::twopi)      325   if (dphi <= 0 || totalphi >= CLHEP::twopi)
316   {                                               326   {
317     pMin.set(-rmax,-rmax, zmin);                  327     pMin.set(-rmax,-rmax, zmin);
318     pMax.set( rmax, rmax, zmax);                  328     pMax.set( rmax, rmax, zmax);
319   }                                               329   }
320   else                                            330   else
321   {                                               331   {
322     G4TwoVector vmin,vmax;                        332     G4TwoVector vmin,vmax;
323     G4GeomTools::DiskExtent(rmin, rmax, sphi,     333     G4GeomTools::DiskExtent(rmin, rmax, sphi, totalphi, vmin, vmax);
324     pMin.set(vmin.x(), vmin.y(), zmin);           334     pMin.set(vmin.x(), vmin.y(), zmin);
325     pMax.set(vmax.x(), vmax.y(), zmax);           335     pMax.set(vmax.x(), vmax.y(), zmax);
326   }                                               336   }
327                                                   337 
328   // Check correctness of the bounding box        338   // Check correctness of the bounding box
329   //                                              339   //
330   if (pMin.x() >= pMax.x() || pMin.y() >= pMax    340   if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
331   {                                               341   {
332     std::ostringstream message;                   342     std::ostringstream message;
333     message << "Bad bounding box (min >= max)     343     message << "Bad bounding box (min >= max) for solid: "
334             << GetName() << " !"                  344             << GetName() << " !"
335             << "\npMin = " << pMin                345             << "\npMin = " << pMin
336             << "\npMax = " << pMax;               346             << "\npMax = " << pMax;
337     G4Exception("G4TwistedTubs::BoundingLimits    347     G4Exception("G4TwistedTubs::BoundingLimits()", "GeomMgt0001",
338                 JustWarning, message);            348                 JustWarning, message);
339     DumpInfo();                                   349     DumpInfo();
340   }                                               350   }
341 }                                                 351 }
342                                                   352 
343 //============================================    353 //=====================================================================
344 //* CalculateExtent --------------------------    354 //* CalculateExtent ---------------------------------------------------
345                                                   355 
346 G4bool                                            356 G4bool
347 G4TwistedTubs::CalculateExtent(const EAxis pAx    357 G4TwistedTubs::CalculateExtent(const EAxis pAxis,
348                                const G4VoxelLi    358                                const G4VoxelLimits& pVoxelLimit,
349                                const G4AffineT    359                                const G4AffineTransform& pTransform,
350                                      G4double&    360                                      G4double& pMin, G4double& pMax) const
351 {                                                 361 {
352   G4ThreeVector bmin, bmax;                       362   G4ThreeVector bmin, bmax;
353                                                   363 
354   // Get bounding box                             364   // Get bounding box
355   BoundingLimits(bmin,bmax);                      365   BoundingLimits(bmin,bmax);
356                                                   366 
357   // Find extent                                  367   // Find extent
358   G4BoundingEnvelope bbox(bmin,bmax);             368   G4BoundingEnvelope bbox(bmin,bmax);
359   return bbox.CalculateExtent(pAxis,pVoxelLimi    369   return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
360 }                                                 370 }
361                                                   371 
362                                                   372 
363 //============================================    373 //=====================================================================
364 //* Inside -----------------------------------    374 //* Inside ------------------------------------------------------------
365                                                   375 
366 EInside G4TwistedTubs::Inside(const G4ThreeVec    376 EInside G4TwistedTubs::Inside(const G4ThreeVector& p) const
367 {                                                 377 {
368                                                   378 
369    const G4double halftol                         379    const G4double halftol
370      = 0.5 * G4GeometryTolerance::GetInstance(    380      = 0.5 * G4GeometryTolerance::GetInstance()->GetRadialTolerance();
371    // static G4int timerid = -1;                  381    // static G4int timerid = -1;
372    // G4Timer timer(timerid, "G4TwistedTubs",     382    // G4Timer timer(timerid, "G4TwistedTubs", "Inside");
373    // timer.Start();                              383    // timer.Start();
374                                                   384 
                                                   >> 385    G4ThreeVector *tmpp;
                                                   >> 386    EInside       *tmpinside;
                                                   >> 387    if (fLastInside.p == p)
                                                   >> 388    {
                                                   >> 389      return fLastInside.inside;
                                                   >> 390    }
                                                   >> 391    else
                                                   >> 392    {
                                                   >> 393       tmpp      = const_cast<G4ThreeVector*>(&(fLastInside.p));
                                                   >> 394       tmpinside = const_cast<EInside*>(&(fLastInside.inside));
                                                   >> 395       tmpp->set(p.x(), p.y(), p.z());
                                                   >> 396    }
375                                                   397    
376    EInside  outerhypearea = ((G4TwistTubsHypeS    398    EInside  outerhypearea = ((G4TwistTubsHypeSide *)fOuterHype)->Inside(p);
377    G4double innerhyperho  = ((G4TwistTubsHypeS    399    G4double innerhyperho  = ((G4TwistTubsHypeSide *)fInnerHype)->GetRhoAtPZ(p);
378    G4double distanceToOut = p.getRho() - inner    400    G4double distanceToOut = p.getRho() - innerhyperho; // +ve: inside
379    EInside       tmpinside;                    << 401 
380    if ((outerhypearea == kOutside) || (distanc    402    if ((outerhypearea == kOutside) || (distanceToOut < -halftol))
381    {                                              403    {
382       tmpinside = kOutside;                    << 404       *tmpinside = kOutside;
383    }                                              405    }
384    else if (outerhypearea == kSurface)            406    else if (outerhypearea == kSurface)
385    {                                              407    {
386       tmpinside = kSurface;                    << 408       *tmpinside = kSurface;
387    }                                              409    }
388    else                                           410    else
389    {                                              411    {
390       if (distanceToOut <= halftol)               412       if (distanceToOut <= halftol)
391       {                                           413       {
392          tmpinside = kSurface;                 << 414          *tmpinside = kSurface;
393       }                                           415       }
394       else                                        416       else
395       {                                           417       {
396          tmpinside = kInside;                  << 418          *tmpinside = kInside;
397       }                                           419       }
398    }                                              420    }
399                                                   421 
400    return tmpinside;                           << 422    return fLastInside.inside;
401 }                                                 423 }
402                                                   424 
403 //============================================    425 //=====================================================================
404 //* SurfaceNormal ----------------------------    426 //* SurfaceNormal -----------------------------------------------------
405                                                   427 
406 G4ThreeVector G4TwistedTubs::SurfaceNormal(con    428 G4ThreeVector G4TwistedTubs::SurfaceNormal(const G4ThreeVector& p) const
407 {                                                 429 {
408    //                                             430    //
409    // return the normal unit vector to the Hyp    431    // return the normal unit vector to the Hyperbolical Surface at a point 
410    // p on (or nearly on) the surface             432    // p on (or nearly on) the surface
411    //                                             433    //
412    // Which of the three or four surfaces are     434    // Which of the three or four surfaces are we closest to?
413    //                                             435    //
414                                                   436 
                                                   >> 437    if (fLastNormal.p == p)
                                                   >> 438    {
                                                   >> 439       return fLastNormal.vec;
                                                   >> 440    }    
                                                   >> 441    G4ThreeVector *tmpp          =
                                                   >> 442      const_cast<G4ThreeVector*>(&(fLastNormal.p));
                                                   >> 443    G4ThreeVector *tmpnormal     =
                                                   >> 444      const_cast<G4ThreeVector*>(&(fLastNormal.vec));
                                                   >> 445    G4VTwistSurface **tmpsurface =
                                                   >> 446      const_cast<G4VTwistSurface**>(fLastNormal.surface);
                                                   >> 447    tmpp->set(p.x(), p.y(), p.z());
415                                                   448 
416    G4double      distance = kInfinity;            449    G4double      distance = kInfinity;
417                                                   450 
418    G4VTwistSurface *surfaces[6];                  451    G4VTwistSurface *surfaces[6];
419    surfaces[0] = fLatterTwisted;                  452    surfaces[0] = fLatterTwisted;
420    surfaces[1] = fFormerTwisted;                  453    surfaces[1] = fFormerTwisted;
421    surfaces[2] = fInnerHype;                      454    surfaces[2] = fInnerHype;
422    surfaces[3] = fOuterHype;                      455    surfaces[3] = fOuterHype;
423    surfaces[4] = fLowerEndcap;                    456    surfaces[4] = fLowerEndcap;
424    surfaces[5] = fUpperEndcap;                    457    surfaces[5] = fUpperEndcap;
425                                                   458 
426    G4ThreeVector xx;                              459    G4ThreeVector xx;
427    G4ThreeVector bestxx;                          460    G4ThreeVector bestxx;
428    G4int besti = -1;                              461    G4int besti = -1;
429    for (auto i=0; i<6; ++i)                       462    for (auto i=0; i<6; ++i)
430    {                                              463    {
431       G4double tmpdistance = surfaces[i]->Dist    464       G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
432       if (tmpdistance < distance)                 465       if (tmpdistance < distance)
433       {                                           466       {
434          distance = tmpdistance;                  467          distance = tmpdistance;
435          bestxx = xx;                             468          bestxx = xx;
436          besti = i;                               469          besti = i; 
437       }                                           470       }
438    }                                              471    }
439                                                   472 
440   return surfaces[besti]->GetNormal(bestxx, tr << 473    tmpsurface[0] = surfaces[besti];
                                                   >> 474    *tmpnormal = tmpsurface[0]->GetNormal(bestxx, true);
                                                   >> 475    
                                                   >> 476    return fLastNormal.vec;
441 }                                                 477 }
442                                                   478 
443 //============================================    479 //=====================================================================
444 //* DistanceToIn (p, v) ----------------------    480 //* DistanceToIn (p, v) -----------------------------------------------
445                                                   481 
446 G4double G4TwistedTubs::DistanceToIn (const G4    482 G4double G4TwistedTubs::DistanceToIn (const G4ThreeVector& p,
447                                       const G4    483                                       const G4ThreeVector& v ) const
448 {                                                 484 {
449                                                   485 
450    // DistanceToIn (p, v):                        486    // DistanceToIn (p, v):
451    // Calculate distance to surface of shape f    487    // Calculate distance to surface of shape from `outside' 
452    // along with the v, allowing for tolerance    488    // along with the v, allowing for tolerance.
453    // The function returns kInfinity if no int    489    // The function returns kInfinity if no intersection or
454    // just grazing within tolerance.              490    // just grazing within tolerance.
455                                                   491 
456    //                                             492    //
                                                   >> 493    // checking last value
                                                   >> 494    //
                                                   >> 495    
                                                   >> 496    G4ThreeVector* tmpp;
                                                   >> 497    G4ThreeVector* tmpv;
                                                   >> 498    G4double* tmpdist;
                                                   >> 499    if ((fLastDistanceToInWithV.p == p) && (fLastDistanceToInWithV.vec == v))
                                                   >> 500    {
                                                   >> 501      return fLastDistanceToIn.value;
                                                   >> 502    }
                                                   >> 503    else
                                                   >> 504    {
                                                   >> 505       tmpp    = const_cast<G4ThreeVector*>(&(fLastDistanceToInWithV.p));
                                                   >> 506       tmpv    = const_cast<G4ThreeVector*>(&(fLastDistanceToInWithV.vec));
                                                   >> 507       tmpdist = const_cast<G4double*>(&(fLastDistanceToInWithV.value));
                                                   >> 508       tmpp->set(p.x(), p.y(), p.z());
                                                   >> 509       tmpv->set(v.x(), v.y(), v.z());
                                                   >> 510    }
                                                   >> 511 
                                                   >> 512    //
457    // Calculate DistanceToIn(p,v)                 513    // Calculate DistanceToIn(p,v)
458    //                                             514    //
459                                                   515    
460    EInside currentside = Inside(p);               516    EInside currentside = Inside(p);
461                                                   517 
462    if (currentside == kInside)                    518    if (currentside == kInside)
463    {                                              519    {
464    }                                              520    }
465    else                                           521    else
466    {                                              522    {
467      if (currentside == kSurface)                 523      if (currentside == kSurface)
468      {                                            524      {
469        // particle is just on a boundary.         525        // particle is just on a boundary.
470        // If the particle is entering to the v    526        // If the particle is entering to the volume, return 0.
471        //                                         527        //
472        G4ThreeVector normal = SurfaceNormal(p)    528        G4ThreeVector normal = SurfaceNormal(p);
473        if (normal*v < 0)                          529        if (normal*v < 0)
474        {                                          530        {
475          return 0;                             << 531          *tmpdist = 0.;
                                                   >> 532          return fLastDistanceToInWithV.value;
476        }                                          533        } 
477      }                                            534      }
478    }                                              535    }
479                                                   536       
480    // now, we can take smallest positive dista    537    // now, we can take smallest positive distance.
481                                                   538    
482    // Initialize                                  539    // Initialize
483    //                                             540    //
484    G4double      distance = kInfinity;            541    G4double      distance = kInfinity;   
485                                                   542 
486    // find intersections and choose nearest on    543    // find intersections and choose nearest one.
487    //                                             544    //
488    G4VTwistSurface* surfaces[6];                  545    G4VTwistSurface* surfaces[6];
489    surfaces[0] = fLowerEndcap;                    546    surfaces[0] = fLowerEndcap;
490    surfaces[1] = fUpperEndcap;                    547    surfaces[1] = fUpperEndcap;
491    surfaces[2] = fLatterTwisted;                  548    surfaces[2] = fLatterTwisted;
492    surfaces[3] = fFormerTwisted;                  549    surfaces[3] = fFormerTwisted;
493    surfaces[4] = fInnerHype;                      550    surfaces[4] = fInnerHype;
494    surfaces[5] = fOuterHype;                      551    surfaces[5] = fOuterHype;
495                                                   552    
496    G4ThreeVector xx;                              553    G4ThreeVector xx;
497    G4ThreeVector bestxx;                          554    G4ThreeVector bestxx;
498    for (const auto & surface : surfaces)       << 555    for (auto i=0; i<6; ++i)
499    {                                              556    {
500       G4double tmpdistance = surface->Distance << 557       G4double tmpdistance = surfaces[i]->DistanceToIn(p, v, xx);
501       if (tmpdistance < distance)                 558       if (tmpdistance < distance)
502       {                                           559       {
503          distance = tmpdistance;                  560          distance = tmpdistance;
504          bestxx = xx;                             561          bestxx = xx;
505       }                                           562       }
506    }                                              563    }
507    return distance;                            << 564    *tmpdist = distance;
                                                   >> 565 
                                                   >> 566    return fLastDistanceToInWithV.value;
508 }                                                 567 }
509                                                   568  
510 //============================================    569 //=====================================================================
511 //* DistanceToIn (p) -------------------------    570 //* DistanceToIn (p) --------------------------------------------------
512                                                   571 
513 G4double G4TwistedTubs::DistanceToIn (const G4    572 G4double G4TwistedTubs::DistanceToIn (const G4ThreeVector& p) const
514 {                                                 573 {
515    // DistanceToIn(p):                            574    // DistanceToIn(p):
516    // Calculate distance to surface of shape f    575    // Calculate distance to surface of shape from `outside',
517    // allowing for tolerance                      576    // allowing for tolerance
                                                   >> 577    
                                                   >> 578    //
                                                   >> 579    // checking last value
                                                   >> 580    //
                                                   >> 581    
                                                   >> 582    G4ThreeVector* tmpp;
                                                   >> 583    G4double* tmpdist;
                                                   >> 584    if (fLastDistanceToIn.p == p)
                                                   >> 585    {
                                                   >> 586      return fLastDistanceToIn.value;
                                                   >> 587    }
                                                   >> 588    else
                                                   >> 589    {
                                                   >> 590       tmpp    = const_cast<G4ThreeVector*>(&(fLastDistanceToIn.p));
                                                   >> 591       tmpdist = const_cast<G4double*>(&(fLastDistanceToIn.value));
                                                   >> 592       tmpp->set(p.x(), p.y(), p.z());
                                                   >> 593    }
518                                                   594 
519    //                                             595    //
520    // Calculate DistanceToIn(p)                   596    // Calculate DistanceToIn(p) 
521    //                                             597    //
522                                                   598    
523    EInside currentside = Inside(p);               599    EInside currentside = Inside(p);
524                                                   600 
525    switch (currentside)                           601    switch (currentside)
526    {                                              602    {
527       case (kInside) :                            603       case (kInside) :
528       {}                                          604       {}
529       case (kSurface) :                           605       case (kSurface) :
530       {                                           606       {
531          return 0;                             << 607          *tmpdist = 0.;
                                                   >> 608          return fLastDistanceToIn.value;
532       }                                           609       }
533       case (kOutside) :                           610       case (kOutside) :
534       {                                           611       {
535          // Initialize                            612          // Initialize
536          G4double distance = kInfinity;           613          G4double distance = kInfinity;   
537                                                   614 
538          // find intersections and choose near    615          // find intersections and choose nearest one.
539          G4VTwistSurface *surfaces[6];            616          G4VTwistSurface *surfaces[6];
540          surfaces[0] = fLowerEndcap;              617          surfaces[0] = fLowerEndcap;
541          surfaces[1] = fUpperEndcap;              618          surfaces[1] = fUpperEndcap;
542          surfaces[2] = fLatterTwisted;            619          surfaces[2] = fLatterTwisted;
543          surfaces[3] = fFormerTwisted;            620          surfaces[3] = fFormerTwisted;
544          surfaces[4] = fInnerHype;                621          surfaces[4] = fInnerHype;
545          surfaces[5] = fOuterHype;                622          surfaces[5] = fOuterHype;
546                                                   623 
547          G4ThreeVector xx;                        624          G4ThreeVector xx;
548          G4ThreeVector bestxx;                    625          G4ThreeVector bestxx;
549          for (const auto & surface : surfaces) << 626          for (auto i=0; i<6; ++i)
550          {                                        627          {
551             G4double tmpdistance = surface->Di << 628             G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
552             if (tmpdistance < distance)           629             if (tmpdistance < distance)
553             {                                     630             {
554                distance = tmpdistance;            631                distance = tmpdistance;
555                bestxx = xx;                       632                bestxx = xx;
556             }                                     633             }
557          }                                        634          }
558          return distance;                      << 635          *tmpdist = distance;
                                                   >> 636          return fLastDistanceToIn.value;
559       }                                           637       }
560       default :                                   638       default :
561       {                                           639       {
562          G4Exception("G4TwistedTubs::DistanceT    640          G4Exception("G4TwistedTubs::DistanceToIn(p)", "GeomSolids0003",
563                      FatalException, "Unknown     641                      FatalException, "Unknown point location!");
564       }                                           642       }
565    } // switch end                                643    } // switch end
566                                                   644 
567    return kInfinity;                              645    return kInfinity;
568 }                                                 646 }
569                                                   647 
570 //============================================    648 //=====================================================================
571 //* DistanceToOut (p, v) ---------------------    649 //* DistanceToOut (p, v) ----------------------------------------------
572                                                   650 
573 G4double G4TwistedTubs::DistanceToOut( const G    651 G4double G4TwistedTubs::DistanceToOut( const G4ThreeVector& p,
574                                        const G    652                                        const G4ThreeVector& v,
575                                        const G    653                                        const G4bool calcNorm,
576                                        G4bool     654                                        G4bool *validNorm,
577                                        G4Three    655                                        G4ThreeVector *norm ) const
578 {                                                 656 {
579    // DistanceToOut (p, v):                       657    // DistanceToOut (p, v):
580    // Calculate distance to surface of shape f    658    // Calculate distance to surface of shape from `inside'
581    // along with the v, allowing for tolerance    659    // along with the v, allowing for tolerance.
582    // The function returns kInfinity if no int    660    // The function returns kInfinity if no intersection or
583    // just grazing within tolerance.              661    // just grazing within tolerance.
584                                                   662 
585    //                                             663    //
                                                   >> 664    // checking last value
                                                   >> 665    //
                                                   >> 666    
                                                   >> 667    G4ThreeVector* tmpp;
                                                   >> 668    G4ThreeVector* tmpv;
                                                   >> 669    G4double* tmpdist;
                                                   >> 670    if ((fLastDistanceToOutWithV.p == p) && (fLastDistanceToOutWithV.vec == v) )
                                                   >> 671    {
                                                   >> 672      return fLastDistanceToOutWithV.value;
                                                   >> 673    }
                                                   >> 674    else
                                                   >> 675    {
                                                   >> 676       tmpp    = const_cast<G4ThreeVector*>(&(fLastDistanceToOutWithV.p));
                                                   >> 677       tmpv    = const_cast<G4ThreeVector*>(&(fLastDistanceToOutWithV.vec));
                                                   >> 678       tmpdist = const_cast<G4double*>(&(fLastDistanceToOutWithV.value));
                                                   >> 679       tmpp->set(p.x(), p.y(), p.z());
                                                   >> 680       tmpv->set(v.x(), v.y(), v.z());
                                                   >> 681    }
                                                   >> 682 
                                                   >> 683    //
586    // Calculate DistanceToOut(p,v)                684    // Calculate DistanceToOut(p,v)
587    //                                             685    //
588                                                   686    
589    EInside currentside = Inside(p);               687    EInside currentside = Inside(p);
                                                   >> 688 
590    if (currentside == kOutside)                   689    if (currentside == kOutside)
591    {                                              690    {
592    }                                              691    }
593    else                                           692    else
594    {                                              693    {
595      if (currentside == kSurface)                 694      if (currentside == kSurface)
596      {                                            695      {
597        // particle is just on a boundary.         696        // particle is just on a boundary.
598        // If the particle is exiting from the     697        // If the particle is exiting from the volume, return 0.
599        //                                         698        //
600        G4ThreeVector normal = SurfaceNormal(p)    699        G4ThreeVector normal = SurfaceNormal(p);
                                                   >> 700        G4VTwistSurface *blockedsurface = fLastNormal.surface[0];
601        if (normal*v > 0)                          701        if (normal*v > 0)
602        {                                          702        {
603          if (calcNorm)                            703          if (calcNorm)
604          {                                        704          {
605            *norm = normal;                     << 705            *norm = (blockedsurface->GetNormal(p, true));
606            *validNorm = true;                  << 706            *validNorm = blockedsurface->IsValidNorm();
607          }                                        707          }
608          return 0;                             << 708          *tmpdist = 0.;
                                                   >> 709          return fLastDistanceToOutWithV.value;
609        }                                          710        }
610      }                                            711      }
611    }                                              712    }
612                                                   713       
613    // now, we can take smallest positive dista    714    // now, we can take smallest positive distance.
614                                                   715    
615    // Initialize                                  716    // Initialize
616    //                                             717    //
617    G4double distance = kInfinity;                 718    G4double distance = kInfinity;
618                                                   719        
619    // find intersections and choose nearest on    720    // find intersections and choose nearest one.
620    //                                             721    //
621    G4VTwistSurface* surfaces[6];                  722    G4VTwistSurface* surfaces[6];
622    surfaces[0] = fLatterTwisted;                  723    surfaces[0] = fLatterTwisted;
623    surfaces[1] = fFormerTwisted;                  724    surfaces[1] = fFormerTwisted;
624    surfaces[2] = fInnerHype;                      725    surfaces[2] = fInnerHype;
625    surfaces[3] = fOuterHype;                      726    surfaces[3] = fOuterHype;
626    surfaces[4] = fLowerEndcap;                    727    surfaces[4] = fLowerEndcap;
627    surfaces[5] = fUpperEndcap;                    728    surfaces[5] = fUpperEndcap;
628                                                   729    
629    G4int besti = -1;                              730    G4int besti = -1;
630    G4ThreeVector xx;                              731    G4ThreeVector xx;
631    G4ThreeVector bestxx;                          732    G4ThreeVector bestxx;
632    for (auto i=0; i<6; ++i)                       733    for (auto i=0; i<6; ++i)
633    {                                              734    {
634       G4double tmpdistance = surfaces[i]->Dist    735       G4double tmpdistance = surfaces[i]->DistanceToOut(p, v, xx);
635       if (tmpdistance < distance)                 736       if (tmpdistance < distance)
636       {                                           737       {
637          distance = tmpdistance;                  738          distance = tmpdistance;
638          bestxx = xx;                             739          bestxx = xx; 
639          besti = i;                               740          besti = i;
640       }                                           741       }
641    }                                              742    }
642                                                   743 
643    if (calcNorm)                                  744    if (calcNorm)
644    {                                              745    {
645       if (besti != -1)                            746       if (besti != -1)
646       {                                           747       {
647          *norm = (surfaces[besti]->GetNormal(p    748          *norm = (surfaces[besti]->GetNormal(p, true));
648          *validNorm = surfaces[besti]->IsValid    749          *validNorm = surfaces[besti]->IsValidNorm();
649       }                                           750       }
650    }                                              751    }
651                                                   752 
652    return distance;                            << 753    *tmpdist = distance;
                                                   >> 754 
                                                   >> 755    return fLastDistanceToOutWithV.value;
653 }                                                 756 }
654                                                   757 
655                                                   758 
656 //============================================    759 //=====================================================================
657 //* DistanceToOut (p) ------------------------    760 //* DistanceToOut (p) ----------------------------------------------
658                                                   761 
659 G4double G4TwistedTubs::DistanceToOut( const G    762 G4double G4TwistedTubs::DistanceToOut( const G4ThreeVector& p ) const
660 {                                                 763 {
661    // DistanceToOut(p):                           764    // DistanceToOut(p):
662    // Calculate distance to surface of shape f    765    // Calculate distance to surface of shape from `inside', 
663    // allowing for tolerance                      766    // allowing for tolerance
664                                                   767 
665    //                                             768    //
                                                   >> 769    // checking last value
                                                   >> 770    //
                                                   >> 771    
                                                   >> 772    G4ThreeVector* tmpp;
                                                   >> 773    G4double* tmpdist;
                                                   >> 774    if (fLastDistanceToOut.p == p)
                                                   >> 775    {
                                                   >> 776       return fLastDistanceToOut.value;
                                                   >> 777    }
                                                   >> 778    else
                                                   >> 779    {
                                                   >> 780       tmpp    = const_cast<G4ThreeVector*>(&(fLastDistanceToOut.p));
                                                   >> 781       tmpdist = const_cast<G4double*>(&(fLastDistanceToOut.value));
                                                   >> 782       tmpp->set(p.x(), p.y(), p.z());
                                                   >> 783    }
                                                   >> 784    
                                                   >> 785    //
666    // Calculate DistanceToOut(p)                  786    // Calculate DistanceToOut(p)
667    //                                             787    //
668                                                   788    
669    EInside currentside = Inside(p);               789    EInside currentside = Inside(p);
670                                                   790 
671    switch (currentside)                           791    switch (currentside)
672    {                                              792    {
673       case (kOutside) :                           793       case (kOutside) :
674       {                                           794       {
675       }                                           795       }
676       case (kSurface) :                           796       case (kSurface) :
677       {                                           797       {
678          return 0;                             << 798         *tmpdist = 0.;
                                                   >> 799          return fLastDistanceToOut.value;
679       }                                           800       }
680       case (kInside) :                            801       case (kInside) :
681       {                                           802       {
682          // Initialize                            803          // Initialize
683          G4double      distance = kInfinity;      804          G4double      distance = kInfinity;
684                                                   805    
685          // find intersections and choose near    806          // find intersections and choose nearest one.
686          G4VTwistSurface* surfaces[6];            807          G4VTwistSurface* surfaces[6];
687          surfaces[0] = fLatterTwisted;            808          surfaces[0] = fLatterTwisted;
688          surfaces[1] = fFormerTwisted;            809          surfaces[1] = fFormerTwisted;
689          surfaces[2] = fInnerHype;                810          surfaces[2] = fInnerHype;
690          surfaces[3] = fOuterHype;                811          surfaces[3] = fOuterHype;
691          surfaces[4] = fLowerEndcap;              812          surfaces[4] = fLowerEndcap;
692          surfaces[5] = fUpperEndcap;              813          surfaces[5] = fUpperEndcap;
693                                                   814 
694          G4ThreeVector xx;                        815          G4ThreeVector xx;
695          G4ThreeVector bestxx;                    816          G4ThreeVector bestxx;
696          for (const auto & surface : surfaces) << 817          for (auto i=0; i<6; ++i)
697          {                                        818          {
698             G4double tmpdistance = surface->Di << 819             G4double tmpdistance = surfaces[i]->DistanceTo(p, xx);
699             if (tmpdistance < distance)           820             if (tmpdistance < distance)
700             {                                     821             {
701                distance = tmpdistance;            822                distance = tmpdistance;
702                bestxx = xx;                       823                bestxx = xx;
703             }                                     824             }
704          }                                        825          }
705          return distance;                      << 826          *tmpdist = distance;
                                                   >> 827    
                                                   >> 828          return fLastDistanceToOut.value;
706       }                                           829       }
707       default :                                   830       default :
708       {                                           831       {
709          G4Exception("G4TwistedTubs::DistanceT    832          G4Exception("G4TwistedTubs::DistanceToOut(p)", "GeomSolids0003",
710                      FatalException, "Unknown     833                      FatalException, "Unknown point location!");
711       }                                           834       }
712    } // switch end                                835    } // switch end
713                                                   836 
714    return 0.;                                     837    return 0.;
715 }                                                 838 }
716                                                   839 
717 //============================================    840 //=====================================================================
718 //* StreamInfo -------------------------------    841 //* StreamInfo --------------------------------------------------------
719                                                   842 
720 std::ostream& G4TwistedTubs::StreamInfo(std::o    843 std::ostream& G4TwistedTubs::StreamInfo(std::ostream& os) const
721 {                                                 844 {
722   //                                              845   //
723   // Stream object contents to an output strea    846   // Stream object contents to an output stream
724   //                                              847   //
725   G4long oldprc = os.precision(16);               848   G4long oldprc = os.precision(16);
726   os << "-------------------------------------    849   os << "-----------------------------------------------------------\n"
727      << "    *** Dump for solid - " << GetName    850      << "    *** Dump for solid - " << GetName() << " ***\n"
728      << "    =================================    851      << "    ===================================================\n"
729      << " Solid type: G4TwistedTubs\n"            852      << " Solid type: G4TwistedTubs\n"
730      << " Parameters: \n"                         853      << " Parameters: \n"
731      << "    -ve end Z              : " << fEn    854      << "    -ve end Z              : " << fEndZ[0]/mm << " mm \n"
732      << "    +ve end Z              : " << fEn    855      << "    +ve end Z              : " << fEndZ[1]/mm << " mm \n"
733      << "    inner end radius(-ve z): " << fEn    856      << "    inner end radius(-ve z): " << fEndInnerRadius[0]/mm << " mm \n"
734      << "    inner end radius(+ve z): " << fEn    857      << "    inner end radius(+ve z): " << fEndInnerRadius[1]/mm << " mm \n"
735      << "    outer end radius(-ve z): " << fEn    858      << "    outer end radius(-ve z): " << fEndOuterRadius[0]/mm << " mm \n"
736      << "    outer end radius(+ve z): " << fEn    859      << "    outer end radius(+ve z): " << fEndOuterRadius[1]/mm << " mm \n"
737      << "    inner radius (z=0)     : " << fIn    860      << "    inner radius (z=0)     : " << fInnerRadius/mm << " mm \n"
738      << "    outer radius (z=0)     : " << fOu    861      << "    outer radius (z=0)     : " << fOuterRadius/mm << " mm \n"
739      << "    twisted angle          : " << fPh    862      << "    twisted angle          : " << fPhiTwist/degree << " degrees \n"
740      << "    inner stereo angle     : " << fIn    863      << "    inner stereo angle     : " << fInnerStereo/degree << " degrees \n"
741      << "    outer stereo angle     : " << fOu    864      << "    outer stereo angle     : " << fOuterStereo/degree << " degrees \n"
742      << "    phi-width of a piece   : " << fDP    865      << "    phi-width of a piece   : " << fDPhi/degree << " degrees \n"
743      << "-------------------------------------    866      << "-----------------------------------------------------------\n";
744   os.precision(oldprc);                           867   os.precision(oldprc);
745                                                   868 
746   return os;                                      869   return os;
747 }                                                 870 }
748                                                   871 
749                                                   872 
750 //============================================    873 //=====================================================================
751 //* DiscribeYourselfTo -----------------------    874 //* DiscribeYourselfTo ------------------------------------------------
752                                                   875 
753 void G4TwistedTubs::DescribeYourselfTo (G4VGra    876 void G4TwistedTubs::DescribeYourselfTo (G4VGraphicsScene& scene) const 
754 {                                                 877 {
755   scene.AddSolid (*this);                         878   scene.AddSolid (*this);
756 }                                                 879 }
757                                                   880 
758 //============================================    881 //=====================================================================
759 //* GetExtent --------------------------------    882 //* GetExtent ---------------------------------------------------------
760                                                   883 
761 G4VisExtent G4TwistedTubs::GetExtent() const      884 G4VisExtent G4TwistedTubs::GetExtent() const
762 {                                                 885 {
763   // Define the sides of the box into which th    886   // Define the sides of the box into which the G4Tubs instance would fit.
764   //                                              887   //
765   G4ThreeVector pmin,pmax;                        888   G4ThreeVector pmin,pmax;
766   BoundingLimits(pmin,pmax);                      889   BoundingLimits(pmin,pmax);
767   return { pmin.x(),pmax.x(),                  << 890   return G4VisExtent(pmin.x(),pmax.x(),
768            pmin.y(),pmax.y(),                  << 891                      pmin.y(),pmax.y(),
769            pmin.z(),pmax.z() };                << 892                      pmin.z(),pmax.z());
770 }                                                 893 }
771                                                   894 
772 //============================================    895 //=====================================================================
773 //* CreatePolyhedron -------------------------    896 //* CreatePolyhedron --------------------------------------------------
774                                                   897 
775 G4Polyhedron* G4TwistedTubs::CreatePolyhedron     898 G4Polyhedron* G4TwistedTubs::CreatePolyhedron () const 
776 {                                                 899 {
777   // number of meshes                             900   // number of meshes
778   //                                              901   //
779   G4double absPhiTwist = std::abs(fPhiTwist);     902   G4double absPhiTwist = std::abs(fPhiTwist);
780   G4double dA = std::max(fDPhi,absPhiTwist);      903   G4double dA = std::max(fDPhi,absPhiTwist);
781   const G4int k =                                 904   const G4int k =
782     G4int(G4Polyhedron::GetNumberOfRotationSte    905     G4int(G4Polyhedron::GetNumberOfRotationSteps() * dA / twopi) + 2;
783   const G4int n =                                 906   const G4int n =
784     G4int(G4Polyhedron::GetNumberOfRotationSte    907     G4int(G4Polyhedron::GetNumberOfRotationSteps() * absPhiTwist / twopi) + 2;
785                                                   908 
786   const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;    909   const G4int nnodes = 4*(k-1)*(n-2) + 2*k*k ;
787   const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)    910   const G4int nfaces = 4*(k-1)*(n-1) + 2*(k-1)*(k-1) ;
788                                                   911 
789   auto ph = new G4Polyhedron;                  << 912   G4Polyhedron* ph = new G4Polyhedron;
790   typedef G4double G4double3[3];                  913   typedef G4double G4double3[3];
791   typedef G4int G4int4[4];                        914   typedef G4int G4int4[4];
792   auto xyz = new G4double3[nnodes];  // number << 915   G4double3* xyz = new G4double3[nnodes];  // number of nodes 
793   auto faces = new G4int4[nfaces] ;  // number << 916   G4int4*  faces = new G4int4[nfaces] ;    // number of faces
794   fLowerEndcap->GetFacets(k,k,xyz,faces,0) ;      917   fLowerEndcap->GetFacets(k,k,xyz,faces,0) ;
795   fUpperEndcap->GetFacets(k,k,xyz,faces,1) ;      918   fUpperEndcap->GetFacets(k,k,xyz,faces,1) ;
796   fInnerHype->GetFacets(k,n,xyz,faces,2) ;        919   fInnerHype->GetFacets(k,n,xyz,faces,2) ;
797   fFormerTwisted->GetFacets(k,n,xyz,faces,3) ;    920   fFormerTwisted->GetFacets(k,n,xyz,faces,3) ;
798   fOuterHype->GetFacets(k,n,xyz,faces,4) ;        921   fOuterHype->GetFacets(k,n,xyz,faces,4) ;
799   fLatterTwisted->GetFacets(k,n,xyz,faces,5) ;    922   fLatterTwisted->GetFacets(k,n,xyz,faces,5) ;
800                                                   923 
801   ph->createPolyhedron(nnodes,nfaces,xyz,faces    924   ph->createPolyhedron(nnodes,nfaces,xyz,faces);
802                                                   925 
803   delete[] xyz;                                   926   delete[] xyz;
804   delete[] faces;                                 927   delete[] faces;
805                                                   928 
806   return ph;                                      929   return ph;
807 }                                                 930 }
808                                                   931 
809 //============================================    932 //=====================================================================
810 //* GetPolyhedron ----------------------------    933 //* GetPolyhedron -----------------------------------------------------
811                                                   934 
812 G4Polyhedron* G4TwistedTubs::GetPolyhedron ()     935 G4Polyhedron* G4TwistedTubs::GetPolyhedron () const
813 {                                                 936 {
814   if (fpPolyhedron == nullptr ||                  937   if (fpPolyhedron == nullptr ||
815       fRebuildPolyhedron ||                       938       fRebuildPolyhedron ||
816       fpPolyhedron->GetNumberOfRotationStepsAt    939       fpPolyhedron->GetNumberOfRotationStepsAtTimeOfCreation() !=
817       fpPolyhedron->GetNumberOfRotationSteps()    940       fpPolyhedron->GetNumberOfRotationSteps())
818   {                                               941   {
819     G4AutoLock l(&polyhedronMutex);               942     G4AutoLock l(&polyhedronMutex);
820     delete fpPolyhedron;                          943     delete fpPolyhedron;
821     fpPolyhedron = CreatePolyhedron();            944     fpPolyhedron = CreatePolyhedron();
822     fRebuildPolyhedron = false;                   945     fRebuildPolyhedron = false;
823     l.unlock();                                   946     l.unlock();
824   }                                               947   }
825   return fpPolyhedron;                            948   return fpPolyhedron;
826 }                                                 949 }
827                                                   950 
828 //============================================    951 //=====================================================================
829 //* CreateSurfaces ---------------------------    952 //* CreateSurfaces ----------------------------------------------------
830                                                   953 
831 void G4TwistedTubs::CreateSurfaces()              954 void G4TwistedTubs::CreateSurfaces() 
832 {                                                 955 {
833    // create 6 surfaces of TwistedTub             956    // create 6 surfaces of TwistedTub
834                                                   957 
835    G4ThreeVector x0(0, 0, fEndZ[0]);              958    G4ThreeVector x0(0, 0, fEndZ[0]);
836    G4ThreeVector n (0, 0, -1);                    959    G4ThreeVector n (0, 0, -1);
837                                                   960 
838    fLowerEndcap = new G4TwistTubsFlatSide("Low    961    fLowerEndcap = new G4TwistTubsFlatSide("LowerEndcap",
839                                     fEndInnerR    962                                     fEndInnerRadius, fEndOuterRadius,
840                                     fDPhi, fEn    963                                     fDPhi, fEndPhi, fEndZ, -1) ;
841                                                   964 
842    fUpperEndcap = new G4TwistTubsFlatSide("Upp    965    fUpperEndcap = new G4TwistTubsFlatSide("UpperEndcap",  
843                                     fEndInnerR    966                                     fEndInnerRadius, fEndOuterRadius,
844                                     fDPhi, fEn    967                                     fDPhi, fEndPhi, fEndZ, 1) ;
845                                                   968 
846    G4RotationMatrix    rotHalfDPhi;               969    G4RotationMatrix    rotHalfDPhi;
847    rotHalfDPhi.rotateZ(0.5*fDPhi);                970    rotHalfDPhi.rotateZ(0.5*fDPhi);
848                                                   971 
849    fLatterTwisted = new G4TwistTubsSide("Latte    972    fLatterTwisted = new G4TwistTubsSide("LatterTwisted",
850                                          fEndI    973                                          fEndInnerRadius, fEndOuterRadius,
851                                          fDPhi    974                                          fDPhi, fEndPhi, fEndZ, 
852                                          fInne    975                                          fInnerRadius, fOuterRadius, fKappa,
853                                          1 ) ;    976                                          1 ) ; 
854    fFormerTwisted = new G4TwistTubsSide("Forme    977    fFormerTwisted = new G4TwistTubsSide("FormerTwisted", 
855                                          fEndI    978                                          fEndInnerRadius, fEndOuterRadius,
856                                          fDPhi    979                                          fDPhi, fEndPhi, fEndZ, 
857                                          fInne    980                                          fInnerRadius, fOuterRadius, fKappa,
858                                          -1 )     981                                          -1 ) ; 
859                                                   982 
860    fInnerHype = new G4TwistTubsHypeSide("Inner    983    fInnerHype = new G4TwistTubsHypeSide("InnerHype",
861                                         fEndIn    984                                         fEndInnerRadius, fEndOuterRadius,
862                                         fDPhi,    985                                         fDPhi, fEndPhi, fEndZ, 
863                                         fInner    986                                         fInnerRadius, fOuterRadius,fKappa,
864                                         fTanIn    987                                         fTanInnerStereo, fTanOuterStereo, -1) ;
865    fOuterHype = new G4TwistTubsHypeSide("Outer    988    fOuterHype = new G4TwistTubsHypeSide("OuterHype", 
866                                         fEndIn    989                                         fEndInnerRadius, fEndOuterRadius,
867                                         fDPhi,    990                                         fDPhi, fEndPhi, fEndZ, 
868                                         fInner    991                                         fInnerRadius, fOuterRadius,fKappa,
869                                         fTanIn    992                                         fTanInnerStereo, fTanOuterStereo, 1) ;
870                                                   993 
871                                                   994 
872    // set neighbour surfaces                      995    // set neighbour surfaces
873    //                                             996    //
874    fLowerEndcap->SetNeighbours(fInnerHype, fLa    997    fLowerEndcap->SetNeighbours(fInnerHype, fLatterTwisted,
875                                fOuterHype, fFo    998                                fOuterHype, fFormerTwisted);
876    fUpperEndcap->SetNeighbours(fInnerHype, fLa    999    fUpperEndcap->SetNeighbours(fInnerHype, fLatterTwisted,
877                                fOuterHype, fFo    1000                                fOuterHype, fFormerTwisted);
878    fLatterTwisted->SetNeighbours(fInnerHype, f    1001    fLatterTwisted->SetNeighbours(fInnerHype, fLowerEndcap,
879                                  fOuterHype, f    1002                                  fOuterHype, fUpperEndcap);
880    fFormerTwisted->SetNeighbours(fInnerHype, f    1003    fFormerTwisted->SetNeighbours(fInnerHype, fLowerEndcap,
881                                  fOuterHype, f    1004                                  fOuterHype, fUpperEndcap);
882    fInnerHype->SetNeighbours(fLatterTwisted, f    1005    fInnerHype->SetNeighbours(fLatterTwisted, fLowerEndcap,
883                              fFormerTwisted, f    1006                              fFormerTwisted, fUpperEndcap);
884    fOuterHype->SetNeighbours(fLatterTwisted, f    1007    fOuterHype->SetNeighbours(fLatterTwisted, fLowerEndcap,
885                              fFormerTwisted, f    1008                              fFormerTwisted, fUpperEndcap);
886 }                                                 1009 }
887                                                   1010 
888                                                   1011 
889 //============================================    1012 //=====================================================================
890 //* GetEntityType ----------------------------    1013 //* GetEntityType -----------------------------------------------------
891                                                   1014 
892 G4GeometryType G4TwistedTubs::GetEntityType()     1015 G4GeometryType G4TwistedTubs::GetEntityType() const
893 {                                                 1016 {
894   return {"G4TwistedTubs"};                    << 1017   return G4String("G4TwistedTubs");
895 }                                                 1018 }
896                                                   1019 
897 //============================================    1020 //=====================================================================
898 //* Clone ------------------------------------    1021 //* Clone -------------------------------------------------------------
899                                                   1022 
900 G4VSolid* G4TwistedTubs::Clone() const            1023 G4VSolid* G4TwistedTubs::Clone() const
901 {                                                 1024 {
902   return new G4TwistedTubs(*this);                1025   return new G4TwistedTubs(*this);
903 }                                                 1026 }
904                                                   1027 
905 //============================================    1028 //=====================================================================
906 //* GetCubicVolume ---------------------------    1029 //* GetCubicVolume ----------------------------------------------------
907                                                   1030 
908 G4double G4TwistedTubs::GetCubicVolume()          1031 G4double G4TwistedTubs::GetCubicVolume()
909 {                                                 1032 {
910   if (fCubicVolume == 0.)                         1033   if (fCubicVolume == 0.)
911   {                                               1034   {
912     G4double DPhi  = GetDPhi();                   1035     G4double DPhi  = GetDPhi();
913     G4double Z0    = GetEndZ(0);                  1036     G4double Z0    = GetEndZ(0);
914     G4double Z1    = GetEndZ(1);                  1037     G4double Z1    = GetEndZ(1);
915     G4double Ain   = GetInnerRadius();            1038     G4double Ain   = GetInnerRadius();
916     G4double Aout  = GetOuterRadius();            1039     G4double Aout  = GetOuterRadius();
917     G4double R0in  = GetEndInnerRadius(0);        1040     G4double R0in  = GetEndInnerRadius(0);
918     G4double R1in  = GetEndInnerRadius(1);        1041     G4double R1in  = GetEndInnerRadius(1);
919     G4double R0out = GetEndOuterRadius(0);        1042     G4double R0out = GetEndOuterRadius(0);
920     G4double R1out = GetEndOuterRadius(1);        1043     G4double R1out = GetEndOuterRadius(1);
921                                                   1044 
922     // V_hyperboloid = pi*h*(2*a*a + R*R)/3       1045     // V_hyperboloid = pi*h*(2*a*a + R*R)/3
923     fCubicVolume = (2.*(Z1 - Z0)*(Aout + Ain)*    1046     fCubicVolume = (2.*(Z1 - Z0)*(Aout + Ain)*(Aout - Ain)
924                     + Z1*(R1out + R1in)*(R1out    1047                     + Z1*(R1out + R1in)*(R1out - R1in)
925                     - Z0*(R0out + R0in)*(R0out    1048                     - Z0*(R0out + R0in)*(R0out - R0in))*DPhi/6.;
926   }                                               1049   }
927   return fCubicVolume;                            1050   return fCubicVolume;
928 }                                                 1051 }
929                                                   1052 
930 //============================================    1053 //=====================================================================
931 //* GetLateralArea ---------------------------    1054 //* GetLateralArea ----------------------------------------------------
932                                                   1055 
933 G4double                                          1056 G4double
934 G4TwistedTubs::GetLateralArea(G4double a, G4do    1057 G4TwistedTubs::GetLateralArea(G4double a, G4double r, G4double z) const
935 {                                                 1058 {
936   if (z == 0) return 0.;                          1059   if (z == 0) return 0.;
937   G4double h = std::abs(z);                       1060   G4double h = std::abs(z);
938   G4double area = h*a;                            1061   G4double area = h*a;
939   if (std::abs(a - r) > kCarTolerance)            1062   if (std::abs(a - r) > kCarTolerance)
940   {                                               1063   {
941     G4double aa = a*a;                            1064     G4double aa = a*a;
942     G4double hh = h*h;                            1065     G4double hh = h*h;
943     G4double rr = r*r;                            1066     G4double rr = r*r;
944     G4double cc = aa*hh/(rr - aa);                1067     G4double cc = aa*hh/(rr - aa);
945     G4double k  = std::sqrt(aa + cc)/cc;          1068     G4double k  = std::sqrt(aa + cc)/cc;
946     G4double kh = k*h;                            1069     G4double kh = k*h;
947     area = 0.5*a*(h*std::sqrt(1. + kh*kh) + st    1070     area = 0.5*a*(h*std::sqrt(1. + kh*kh) + std::asinh(kh)/k);
948   }                                               1071   }
949   return GetDPhi()*area;                          1072   return GetDPhi()*area;
950 }                                                 1073 }
951                                                   1074 
952 //============================================    1075 //=====================================================================
953 //* GetPhiCutArea ----------------------------    1076 //* GetPhiCutArea -----------------------------------------------------
954                                                   1077 
955 G4double                                          1078 G4double
956 G4TwistedTubs::GetPhiCutArea(G4double a, G4dou    1079 G4TwistedTubs::GetPhiCutArea(G4double a, G4double r, G4double z) const
957 {                                                 1080 {
958   if (GetDPhi() >= CLHEP::twopi || r <= 0 || z    1081   if (GetDPhi() >= CLHEP::twopi || r <= 0 || z == 0) return 0.;
959   G4double h = std::abs(z);                       1082   G4double h = std::abs(z);
960   G4double area = h*a;                            1083   G4double area = h*a;
961   if (GetPhiTwist() > kCarTolerance)              1084   if (GetPhiTwist() > kCarTolerance)
962   {                                               1085   {
963     G4double sinw = std::sin(0.5*GetPhiTwist()    1086     G4double sinw = std::sin(0.5*GetPhiTwist())*h/GetZHalfLength();
964     G4double p = sinw*r/h;                        1087     G4double p = sinw*r/h;
965     G4double q = sinw*r/a;                        1088     G4double q = sinw*r/a;
966     G4double pp = p*p;                            1089     G4double pp = p*p;
967     G4double qq = q*q;                            1090     G4double qq = q*q;
968     G4double pq = p*q;                            1091     G4double pq = p*q;
969     G4double sqroot = std::sqrt(pp + qq + 1);     1092     G4double sqroot = std::sqrt(pp + qq + 1);
970     area = (pq*sqroot +                           1093     area = (pq*sqroot +
971             0.5*p*(pp + 3.)*std::atanh(q/sqroo    1094             0.5*p*(pp + 3.)*std::atanh(q/sqroot) +
972             0.5*q*(qq + 3.)*std::atanh(p/sqroo    1095             0.5*q*(qq + 3.)*std::atanh(p/sqroot) +
973             std::atan(sqroot/(pq)) - CLHEP::ha    1096             std::atan(sqroot/(pq)) - CLHEP::halfpi)*h*a/(3.*pq);
974   }                                               1097   }
975   return area;                                    1098   return area;
976 }                                                 1099 }
977                                                   1100 
978 //============================================    1101 //=====================================================================
979 //* GetSurfaceArea ---------------------------    1102 //* GetSurfaceArea ----------------------------------------------------
980                                                   1103 
981 G4double G4TwistedTubs::GetSurfaceArea()          1104 G4double G4TwistedTubs::GetSurfaceArea()
982 {                                                 1105 {
983   if (fSurfaceArea == 0.)                         1106   if (fSurfaceArea == 0.)
984   {                                               1107   {
985     G4double dphi = GetDPhi();                    1108     G4double dphi = GetDPhi();
986     G4double Ainn = GetInnerRadius();             1109     G4double Ainn = GetInnerRadius();
987     G4double Aout = GetOuterRadius();             1110     G4double Aout = GetOuterRadius();
988     G4double Rinn0 = GetEndInnerRadius(0);        1111     G4double Rinn0 = GetEndInnerRadius(0);
989     G4double Rout0 = GetEndOuterRadius(0);        1112     G4double Rout0 = GetEndOuterRadius(0);
990     G4double Rinn1 = GetEndInnerRadius(1);        1113     G4double Rinn1 = GetEndInnerRadius(1);
991     G4double Rout1 = GetEndOuterRadius(1);        1114     G4double Rout1 = GetEndOuterRadius(1);
992     G4double z0 = GetEndZ(0);                     1115     G4double z0 = GetEndZ(0);
993     G4double z1 = GetEndZ(1);                     1116     G4double z1 = GetEndZ(1);
994                                                   1117 
995     G4double base0 = 0.5*dphi*(Rout0*Rout0 - R    1118     G4double base0 = 0.5*dphi*(Rout0*Rout0 - Rinn0*Rinn0); // lower base
996     G4double inner0 = GetLateralArea(Ainn, Rin    1119     G4double inner0 = GetLateralArea(Ainn, Rinn0, z0); // lower inner surface
997     G4double outer0 = GetLateralArea(Aout, Rou    1120     G4double outer0 = GetLateralArea(Aout, Rout0, z0); // lower outer surface
998     G4double cut0 =                               1121     G4double cut0 =                                    // lower phi cut
999       GetPhiCutArea(Aout, Rout0, z0) - GetPhiC    1122       GetPhiCutArea(Aout, Rout0, z0) - GetPhiCutArea(Ainn, Rinn0, z0);
1000                                                  1123 
1001     G4double base1 = base0;                      1124     G4double base1 = base0;
1002     G4double inner1 = inner0;                    1125     G4double inner1 = inner0;
1003     G4double outer1 = outer0;                    1126     G4double outer1 = outer0;
1004     G4double cut1 = cut0;                        1127     G4double cut1 = cut0;
1005     if (std::abs(z0) != std::abs(z1))            1128     if (std::abs(z0) != std::abs(z1))
1006     {                                            1129     {
1007       base1 = 0.5*dphi*(Rout1*Rout1 - Rinn1*R    1130       base1 = 0.5*dphi*(Rout1*Rout1 - Rinn1*Rinn1); // upper base
1008       inner1 = GetLateralArea(Ainn, Rinn1, z1    1131       inner1 = GetLateralArea(Ainn, Rinn1, z1); // upper inner surface
1009       outer1 = GetLateralArea(Aout, Rout1, z1    1132       outer1 = GetLateralArea(Aout, Rout1, z1); // upper outer surface
1010       cut1 =                                     1133       cut1 =                                    // upper phi cut
1011       GetPhiCutArea(Aout, Rout1, z1) - GetPhi    1134       GetPhiCutArea(Aout, Rout1, z1) - GetPhiCutArea(Ainn, Rinn1, z1);
1012     }                                            1135     }
1013     fSurfaceArea = base0 + base1 +               1136     fSurfaceArea = base0 + base1 +
1014       ((z0*z1 < 0) ?                             1137       ((z0*z1 < 0) ?
1015       (inner0 + inner1 + outer0 + outer1 + 2.    1138       (inner0 + inner1 + outer0 + outer1 + 2.*(cut0 + cut1)) :
1016       std::abs(inner0 - inner1 + outer0 - out    1139       std::abs(inner0 - inner1 + outer0 - outer1 + 2.*(cut0 - cut1)));
1017   }                                              1140   }
1018   return fSurfaceArea;                           1141   return fSurfaceArea;
1019 }                                                1142 }
1020                                                  1143 
1021 //===========================================    1144 //=====================================================================
1022 //* GetPointOnSurface -----------------------    1145 //* GetPointOnSurface -------------------------------------------------
1023                                                  1146 
1024 G4ThreeVector G4TwistedTubs::GetPointOnSurfac    1147 G4ThreeVector G4TwistedTubs::GetPointOnSurface() const
1025 {                                                1148 {
1026                                                  1149 
1027   G4double z = G4RandFlat::shoot(fEndZ[0],fEn    1150   G4double z = G4RandFlat::shoot(fEndZ[0],fEndZ[1]);
1028   G4double phi , phimin, phimax ;                1151   G4double phi , phimin, phimax ;
1029   G4double x   , xmin,   xmax ;                  1152   G4double x   , xmin,   xmax ;
1030   G4double r   , rmin,   rmax ;                  1153   G4double r   , rmin,   rmax ;
1031                                                  1154 
1032   G4double a1 = fOuterHype->GetSurfaceArea()     1155   G4double a1 = fOuterHype->GetSurfaceArea() ;
1033   G4double a2 = fInnerHype->GetSurfaceArea()     1156   G4double a2 = fInnerHype->GetSurfaceArea() ;
1034   G4double a3 = fLatterTwisted->GetSurfaceAre    1157   G4double a3 = fLatterTwisted->GetSurfaceArea() ;
1035   G4double a4 = fFormerTwisted->GetSurfaceAre    1158   G4double a4 = fFormerTwisted->GetSurfaceArea() ;
1036   G4double a5 = fLowerEndcap->GetSurfaceArea(    1159   G4double a5 = fLowerEndcap->GetSurfaceArea()  ;
1037   G4double a6 = fUpperEndcap->GetSurfaceArea(    1160   G4double a6 = fUpperEndcap->GetSurfaceArea() ;
1038                                                  1161 
1039   G4double chose = G4RandFlat::shoot(0.,a1 +     1162   G4double chose = G4RandFlat::shoot(0.,a1 + a2 + a3 + a4 + a5 + a6) ;
1040                                                  1163 
1041   if(chose < a1)                                 1164   if(chose < a1)
1042   {                                              1165   {
1043                                                  1166 
1044     phimin = fOuterHype->GetBoundaryMin(z) ;     1167     phimin = fOuterHype->GetBoundaryMin(z) ;
1045     phimax = fOuterHype->GetBoundaryMax(z) ;     1168     phimax = fOuterHype->GetBoundaryMax(z) ;
1046     phi = G4RandFlat::shoot(phimin,phimax) ;     1169     phi = G4RandFlat::shoot(phimin,phimax) ;
1047                                                  1170 
1048     return fOuterHype->SurfacePoint(phi,z,tru    1171     return fOuterHype->SurfacePoint(phi,z,true) ;
1049                                                  1172 
1050   }                                              1173   }
1051   else if ( (chose >= a1) && (chose < a1 + a2    1174   else if ( (chose >= a1) && (chose < a1 + a2 ) )
1052   {                                              1175   {
1053                                                  1176 
1054     phimin = fInnerHype->GetBoundaryMin(z) ;     1177     phimin = fInnerHype->GetBoundaryMin(z) ;
1055     phimax = fInnerHype->GetBoundaryMax(z) ;     1178     phimax = fInnerHype->GetBoundaryMax(z) ;
1056     phi = G4RandFlat::shoot(phimin,phimax) ;     1179     phi = G4RandFlat::shoot(phimin,phimax) ;
1057                                                  1180 
1058     return fInnerHype->SurfacePoint(phi,z,tru    1181     return fInnerHype->SurfacePoint(phi,z,true) ;
1059                                                  1182 
1060   }                                              1183   }
1061   else if ( (chose >= a1 + a2 ) && (chose < a    1184   else if ( (chose >= a1 + a2 ) && (chose < a1 + a2 + a3 ) ) 
1062   {                                              1185   {
1063                                                  1186 
1064     xmin = fLatterTwisted->GetBoundaryMin(z)     1187     xmin = fLatterTwisted->GetBoundaryMin(z) ; 
1065     xmax = fLatterTwisted->GetBoundaryMax(z)     1188     xmax = fLatterTwisted->GetBoundaryMax(z) ;
1066     x = G4RandFlat::shoot(xmin,xmax) ;           1189     x = G4RandFlat::shoot(xmin,xmax) ;
1067                                                  1190     
1068     return fLatterTwisted->SurfacePoint(x,z,t    1191     return fLatterTwisted->SurfacePoint(x,z,true) ;
1069                                                  1192 
1070   }                                              1193   }
1071   else if ( (chose >= a1 + a2 + a3  ) && (cho    1194   else if ( (chose >= a1 + a2 + a3  ) && (chose < a1 + a2 + a3 + a4  ) )
1072   {                                              1195   {
1073                                                  1196 
1074     xmin = fFormerTwisted->GetBoundaryMin(z)     1197     xmin = fFormerTwisted->GetBoundaryMin(z) ; 
1075     xmax = fFormerTwisted->GetBoundaryMax(z)     1198     xmax = fFormerTwisted->GetBoundaryMax(z) ;
1076     x = G4RandFlat::shoot(xmin,xmax) ;           1199     x = G4RandFlat::shoot(xmin,xmax) ;
1077                                                  1200 
1078     return fFormerTwisted->SurfacePoint(x,z,t    1201     return fFormerTwisted->SurfacePoint(x,z,true) ;
1079    }                                             1202    }
1080   else if( (chose >= a1 + a2 + a3 + a4  )&&(c    1203   else if( (chose >= a1 + a2 + a3 + a4  )&&(chose < a1 + a2 + a3 + a4 + a5 ) )
1081   {                                              1204   {
1082     rmin = GetEndInnerRadius(0) ;                1205     rmin = GetEndInnerRadius(0) ;
1083     rmax = GetEndOuterRadius(0) ;                1206     rmax = GetEndOuterRadius(0) ;
1084     r = std::sqrt(G4RandFlat::shoot()*(sqr(rm    1207     r = std::sqrt(G4RandFlat::shoot()*(sqr(rmax)-sqr(rmin))+sqr(rmin));
1085                                                  1208 
1086     phimin = fLowerEndcap->GetBoundaryMin(r)     1209     phimin = fLowerEndcap->GetBoundaryMin(r) ; 
1087     phimax = fLowerEndcap->GetBoundaryMax(r)     1210     phimax = fLowerEndcap->GetBoundaryMax(r) ;
1088     phi    = G4RandFlat::shoot(phimin,phimax)    1211     phi    = G4RandFlat::shoot(phimin,phimax) ;
1089                                                  1212 
1090     return fLowerEndcap->SurfacePoint(phi,r,t    1213     return fLowerEndcap->SurfacePoint(phi,r,true) ;
1091   }                                              1214   }
1092   else                                           1215   else
1093   {                                              1216   {
1094     rmin = GetEndInnerRadius(1) ;                1217     rmin = GetEndInnerRadius(1) ;
1095     rmax = GetEndOuterRadius(1) ;                1218     rmax = GetEndOuterRadius(1) ;
1096     r = rmin + (rmax-rmin)*std::sqrt(G4RandFl    1219     r = rmin + (rmax-rmin)*std::sqrt(G4RandFlat::shoot());
1097                                                  1220 
1098     phimin = fUpperEndcap->GetBoundaryMin(r)     1221     phimin = fUpperEndcap->GetBoundaryMin(r) ; 
1099     phimax = fUpperEndcap->GetBoundaryMax(r)     1222     phimax = fUpperEndcap->GetBoundaryMax(r) ;
1100     phi    = G4RandFlat::shoot(phimin,phimax)    1223     phi    = G4RandFlat::shoot(phimin,phimax) ;
1101                                                  1224 
1102     return fUpperEndcap->SurfacePoint(phi,r,t    1225     return fUpperEndcap->SurfacePoint(phi,r,true) ;
1103   }                                              1226   }
1104 }                                                1227 }
1105                                                  1228