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 7.1)


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