Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4TwistTrapAlphaSide.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/G4TwistTrapAlphaSide.cc (Version 11.3.0) and /geometry/solids/specific/src/G4TwistTrapAlphaSide.cc (Version 10.7.p2)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
 26 // G4TwistTrapAlphaSide implementation             26 // G4TwistTrapAlphaSide implementation
 27 //                                                 27 //
 28 // Author: 18/03/2005 - O.Link (Oliver.Link@ce     28 // Author: 18/03/2005 - O.Link (Oliver.Link@cern.ch)
 29 // -------------------------------------------     29 // --------------------------------------------------------------------
 30                                                    30 
 31 #include <cmath>                                   31 #include <cmath>
 32                                                    32 
 33 #include "G4TwistTrapAlphaSide.hh"                 33 #include "G4TwistTrapAlphaSide.hh"
 34 #include "G4PhysicalConstants.hh"                  34 #include "G4PhysicalConstants.hh"
 35 #include "G4JTPolynomialSolver.hh"                 35 #include "G4JTPolynomialSolver.hh"
 36                                                    36 
 37 //============================================     37 //=====================================================================
 38 //* constructors -----------------------------     38 //* constructors ------------------------------------------------------
 39                                                    39 
 40 G4TwistTrapAlphaSide::                             40 G4TwistTrapAlphaSide::
 41 G4TwistTrapAlphaSide(const G4String& name,         41 G4TwistTrapAlphaSide(const G4String& name,
 42                      G4double      PhiTwist,       42                      G4double      PhiTwist,  // twist angle
 43                      G4double      pDz,            43                      G4double      pDz,       // half z lenght
 44                      G4double      pTheta,         44                      G4double      pTheta,    // direction between end planes
 45                      G4double      pPhi,           45                      G4double      pPhi,      // by polar and azimutal angles
 46                      G4double      pDy1,           46                      G4double      pDy1,      // half y length at -pDz
 47                      G4double      pDx1,           47                      G4double      pDx1,      // half x length at -pDz,-pDy
 48                      G4double      pDx2,           48                      G4double      pDx2,      // half x length at -pDz,+pDy
 49                      G4double      pDy2,           49                      G4double      pDy2,      // half y length at +pDz
 50                      G4double      pDx3,           50                      G4double      pDx3,      // half x length at +pDz,-pDy
 51                      G4double      pDx4,           51                      G4double      pDx4,      // half x length at +pDz,+pDy
 52                      G4double      pAlph,          52                      G4double      pAlph,     // tilt angle at +pDz
 53                      G4double      AngleSide       53                      G4double      AngleSide  // parity
 54                                              )     54                                              )
 55   : G4VTwistSurface(name)                          55   : G4VTwistSurface(name)
 56 {                                                  56 {
 57   fAxis[0]    = kYAxis; // in local coordinate     57   fAxis[0]    = kYAxis; // in local coordinate system
 58   fAxis[1]    = kZAxis;                            58   fAxis[1]    = kZAxis;
 59   fAxisMin[0] = -kInfinity ;  // Y Axis bounda     59   fAxisMin[0] = -kInfinity ;  // Y Axis boundary
 60   fAxisMax[0] = kInfinity ;   //   depends on      60   fAxisMax[0] = kInfinity ;   //   depends on z !!
 61   fAxisMin[1] = -pDz ;      // Z Axis boundary     61   fAxisMin[1] = -pDz ;      // Z Axis boundary
 62   fAxisMax[1] = pDz ;                              62   fAxisMax[1] = pDz ;
 63                                                    63   
 64   fDx1  = pDx1 ;                                   64   fDx1  = pDx1 ;
 65   fDx2  = pDx2 ;                                   65   fDx2  = pDx2 ;
 66   fDx3  = pDx3 ;                                   66   fDx3  = pDx3 ;
 67   fDx4  = pDx4 ;                                   67   fDx4  = pDx4 ;
 68                                                    68 
 69   fDy1   = pDy1 ;                                  69   fDy1   = pDy1 ;
 70   fDy2   = pDy2 ;                                  70   fDy2   = pDy2 ;
 71                                                    71 
 72   fDz   = pDz ;                                    72   fDz   = pDz ;
 73                                                    73 
 74   fAlph = pAlph  ;                                 74   fAlph = pAlph  ;
 75   fTAlph = std::tan(fAlph) ;                       75   fTAlph = std::tan(fAlph) ;
 76                                                    76 
 77   fTheta = pTheta ;                                77   fTheta = pTheta ;
 78   fPhi   = pPhi ;                                  78   fPhi   = pPhi ;
 79                                                    79 
 80   // precalculate frequently used parameters       80   // precalculate frequently used parameters
 81   fDx4plus2  = fDx4 + fDx2 ;                       81   fDx4plus2  = fDx4 + fDx2 ;
 82   fDx4minus2 = fDx4 - fDx2 ;                       82   fDx4minus2 = fDx4 - fDx2 ;
 83   fDx3plus1  = fDx3 + fDx1 ;                       83   fDx3plus1  = fDx3 + fDx1 ; 
 84   fDx3minus1 = fDx3 - fDx1 ;                       84   fDx3minus1 = fDx3 - fDx1 ;
 85   fDy2plus1  = fDy2 + fDy1 ;                       85   fDy2plus1  = fDy2 + fDy1 ;
 86   fDy2minus1 = fDy2 - fDy1 ;                       86   fDy2minus1 = fDy2 - fDy1 ;
 87                                                    87 
 88   fa1md1 = 2*fDx2 - 2*fDx1  ;                      88   fa1md1 = 2*fDx2 - 2*fDx1  ; 
 89   fa2md2 = 2*fDx4 - 2*fDx3 ;                       89   fa2md2 = 2*fDx4 - 2*fDx3 ;
 90                                                    90 
 91   fPhiTwist = PhiTwist ;    // dphi            <<  91   fPhiTwist = PhiTwist ;     // dphi
 92   fAngleSide = AngleSide ;  // 0,90,180,270 de     92   fAngleSide = AngleSide ;  // 0,90,180,270 deg
 93                                                    93 
 94   fdeltaX = 2 * fDz * std::tan(fTheta) * std::     94   fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi);
 95     // dx in surface equation                      95     // dx in surface equation
 96   fdeltaY = 2 * fDz * std::tan(fTheta) * std::     96   fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi);
 97     // dy in surface equation                      97     // dy in surface equation
 98                                                    98   
 99   fRot.rotateZ( AngleSide ) ;                      99   fRot.rotateZ( AngleSide ) ; 
100                                                   100   
101   fTrans.set(0, 0, 0);  // No Translation         101   fTrans.set(0, 0, 0);  // No Translation
102   fIsValidNorm = false;                           102   fIsValidNorm = false;
103                                                   103   
104   SetCorners() ;                                  104   SetCorners() ;
105   SetBoundaries() ;                               105   SetBoundaries() ;
106 }                                                 106 }
107                                                   107 
108                                                   108 
109 //============================================    109 //=====================================================================
110 //* Fake default constructor -----------------    110 //* Fake default constructor ------------------------------------------
111                                                   111 
112 G4TwistTrapAlphaSide::G4TwistTrapAlphaSide( __    112 G4TwistTrapAlphaSide::G4TwistTrapAlphaSide( __void__& a )
113   : G4VTwistSurface(a)                         << 113   : G4VTwistSurface(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.), 
                                                   >> 114     fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fAlph(0.), fTAlph(0.), fPhiTwist(0.), 
                                                   >> 115     fAngleSide(0.), fDx4plus2(0.), fDx4minus2(0.), fDx3plus1(0.), fDx3minus1(0.), 
                                                   >> 116     fDy2plus1(0.), fDy2minus1(0.), fa1md1(0.), fa2md2(0.), fdeltaX(0.),
                                                   >> 117     fdeltaY(0.)
114 {                                                 118 {
115 }                                                 119 }
116                                                   120 
117                                                   121 
118 //============================================    122 //=====================================================================
119 //* destructor -------------------------------    123 //* destructor --------------------------------------------------------
120                                                   124 
121 G4TwistTrapAlphaSide::~G4TwistTrapAlphaSide()  << 125 G4TwistTrapAlphaSide::~G4TwistTrapAlphaSide()
                                                   >> 126 {
                                                   >> 127 }
122                                                   128 
123                                                   129 
124 //============================================    130 //=====================================================================
125 //* GetNormal --------------------------------    131 //* GetNormal ---------------------------------------------------------
126                                                   132 
127 G4ThreeVector                                     133 G4ThreeVector
128 G4TwistTrapAlphaSide::GetNormal(const G4ThreeV    134 G4TwistTrapAlphaSide::GetNormal(const G4ThreeVector& tmpxx, 
129                                       G4bool i    135                                       G4bool isGlobal) 
130 {                                                 136 {
131    // GetNormal returns a normal vector at a s    137    // GetNormal returns a normal vector at a surface (or very close
132    // to surface) point at tmpxx.                 138    // to surface) point at tmpxx.
133    // If isGlobal=true, it returns the normal     139    // If isGlobal=true, it returns the normal in global coordinate.
134    //                                             140    //
135                                                   141 
136    G4ThreeVector xx;                              142    G4ThreeVector xx;
137    if (isGlobal)                                  143    if (isGlobal)
138    {                                              144    {
139       xx = ComputeLocalPoint(tmpxx);              145       xx = ComputeLocalPoint(tmpxx);
140       if ((xx - fCurrentNormal.p).mag() < 0.5     146       if ((xx - fCurrentNormal.p).mag() < 0.5 * kCarTolerance)
141       {                                           147       {
142          return ComputeGlobalDirection(fCurren    148          return ComputeGlobalDirection(fCurrentNormal.normal);
143       }                                           149       }
144    }                                              150    }
145    else                                           151    else
146    {                                              152    {
147       xx = tmpxx;                                 153       xx = tmpxx;
148       if (xx == fCurrentNormal.p)                 154       if (xx == fCurrentNormal.p)
149       {                                           155       {
150          return fCurrentNormal.normal;            156          return fCurrentNormal.normal;
151       }                                           157       }
152    }                                              158    }
153                                                   159 
154    G4double phi ;                                 160    G4double phi ;
155    G4double u ;                                   161    G4double u ;
156                                                   162 
157    GetPhiUAtX(xx,phi,u) ;   // phi,u for point    163    GetPhiUAtX(xx,phi,u) ;   // phi,u for point xx close to surface 
158                                                   164 
159    G4ThreeVector normal =  NormAng(phi,u) ;  /    165    G4ThreeVector normal =  NormAng(phi,u) ;  // the normal vector at phi,u
160                                                   166 
161 #ifdef G4TWISTDEBUG                               167 #ifdef G4TWISTDEBUG
162    G4cout  << "normal vector = " << normal <<     168    G4cout  << "normal vector = " << normal << G4endl ;
163    G4cout << "phi = " << phi << " , u = " << u    169    G4cout << "phi = " << phi << " , u = " << u << G4endl ;
164 #endif                                            170 #endif
165                                                   171 
166    if (isGlobal)                                  172    if (isGlobal)
167    {                                              173    {
168       fCurrentNormal.normal = ComputeGlobalDir    174       fCurrentNormal.normal = ComputeGlobalDirection(normal.unit());
169    }                                              175    }
170    else                                           176    else
171    {                                              177    {
172       fCurrentNormal.normal = normal.unit();      178       fCurrentNormal.normal = normal.unit();
173    }                                              179    }
174                                                   180 
175    return fCurrentNormal.normal;                  181    return fCurrentNormal.normal;
176 }                                                 182 }
177                                                   183 
178 //============================================    184 //=====================================================================
179 //* DistanceToSurface ------------------------    185 //* DistanceToSurface -------------------------------------------------
180                                                   186 
181 G4int                                             187 G4int
182 G4TwistTrapAlphaSide::DistanceToSurface(const     188 G4TwistTrapAlphaSide::DistanceToSurface(const G4ThreeVector& gp,
183                                         const     189                                         const G4ThreeVector& gv,
184                                                   190                                               G4ThreeVector  gxx[],
185                                                   191                                               G4double       distance[],
186                                                   192                                               G4int          areacode[],
187                                                   193                                               G4bool         isvalid[],
188                                                   194                                               EValidate      validate)
189 {                                                 195 {
190   static const G4double pihalf = pi/2 ;           196   static const G4double pihalf = pi/2 ;
191   const G4double ctol = 0.5 * kCarTolerance;      197   const G4double ctol = 0.5 * kCarTolerance;
192                                                   198 
193   G4bool IsParallel = false ;                     199   G4bool IsParallel = false ;
194   G4bool IsConverged =  false ;                   200   G4bool IsConverged =  false ;
195                                                   201 
196   G4int nxx = 0 ;  // number of physical solut    202   G4int nxx = 0 ;  // number of physical solutions
197                                                   203 
198   fCurStatWithV.ResetfDone(validate, &gp, &gv)    204   fCurStatWithV.ResetfDone(validate, &gp, &gv);
199                                                   205 
200   if (fCurStatWithV.IsDone())                     206   if (fCurStatWithV.IsDone())
201   {                                               207   {
202     for (G4int i=0; i<fCurStatWithV.GetNXX();     208     for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
203     {                                             209     {
204       gxx[i] = fCurStatWithV.GetXX(i);            210       gxx[i] = fCurStatWithV.GetXX(i);
205       distance[i] = fCurStatWithV.GetDistance(    211       distance[i] = fCurStatWithV.GetDistance(i);
206       areacode[i] = fCurStatWithV.GetAreacode(    212       areacode[i] = fCurStatWithV.GetAreacode(i);
207       isvalid[i]  = fCurStatWithV.IsValid(i);     213       isvalid[i]  = fCurStatWithV.IsValid(i);
208     }                                             214     }
209     return fCurStatWithV.GetNXX();                215     return fCurStatWithV.GetNXX();
210   }                                               216   }
211   else  // initialise                             217   else  // initialise
212   {                                               218   {
213     for (G4int j=0; j<G4VSURFACENXX ; ++j)        219     for (G4int j=0; j<G4VSURFACENXX ; ++j)
214     {                                             220     {
215       distance[j] = kInfinity;                    221       distance[j] = kInfinity;
216       areacode[j] = sOutside;                     222       areacode[j] = sOutside;
217       isvalid[j]  = false;                        223       isvalid[j]  = false;
218       gxx[j].set(kInfinity, kInfinity, kInfini    224       gxx[j].set(kInfinity, kInfinity, kInfinity);
219     }                                             225     }
220   }                                               226   }
221                                                   227 
222   G4ThreeVector p = ComputeLocalPoint(gp);        228   G4ThreeVector p = ComputeLocalPoint(gp);
223   G4ThreeVector v = ComputeLocalDirection(gv);    229   G4ThreeVector v = ComputeLocalDirection(gv);
224                                                   230   
225 #ifdef G4TWISTDEBUG                               231 #ifdef G4TWISTDEBUG
226   G4cout << "Local point p = " << p << G4endl     232   G4cout << "Local point p = " << p << G4endl ;
227   G4cout << "Local direction v = " << v << G4e    233   G4cout << "Local direction v = " << v << G4endl ; 
228 #endif                                            234 #endif
229                                                   235 
230   G4double phi,u ;  // parameters                 236   G4double phi,u ;  // parameters
231                                                   237 
232   // temporary variables                          238   // temporary variables
233                                                   239 
234   G4double      tmpdist = kInfinity ;             240   G4double      tmpdist = kInfinity ;
235   G4ThreeVector tmpxx;                            241   G4ThreeVector tmpxx;
236   G4int         tmpareacode = sOutside ;          242   G4int         tmpareacode = sOutside ;
237   G4bool        tmpisvalid  = false ;             243   G4bool        tmpisvalid  = false ;
238                                                   244 
239   std::vector<Intersection> xbuf ;                245   std::vector<Intersection> xbuf ;
240   Intersection xbuftmp ;                          246   Intersection xbuftmp ;
241                                                   247   
242   // prepare some variables for the intersecti    248   // prepare some variables for the intersection finder
243                                                   249 
244   G4double L = 2*fDz ;                            250   G4double L = 2*fDz ;
245                                                   251 
246   G4double phixz = fPhiTwist * ( p.x() * v.z()    252   G4double phixz = fPhiTwist * ( p.x() * v.z() - p.z() * v.x() ) ;
247   G4double phiyz = fPhiTwist * ( p.y() * v.z()    253   G4double phiyz = fPhiTwist * ( p.y() * v.z() - p.z() * v.y() ) ;
248                                                   254 
249                                                   255 
250   // special case vz = 0                          256   // special case vz = 0
251                                                   257 
252   if ( v.z() == 0. )                              258   if ( v.z() == 0. )
253   {                                            << 259  {
254     if ( std::fabs(p.z()) <= L )   // intersec    260     if ( std::fabs(p.z()) <= L )   // intersection possible in z
255     {                                             261     {
256       phi = p.z() * fPhiTwist / L ;  // phi is    262       phi = p.z() * fPhiTwist / L ;  // phi is determined by the z-position 
257       u = (fDy1*(4*(-(fdeltaY*phi*v.x()) + fPh    263       u = (fDy1*(4*(-(fdeltaY*phi*v.x()) + fPhiTwist*p.y()*v.x()
258                     + fdeltaX*phi*v.y() - fPhi    264                     + fdeltaX*phi*v.y() - fPhiTwist*p.x()*v.y())
259                  + ((fDx3plus1 + fDx4plus2)*fP    265                  + ((fDx3plus1 + fDx4plus2)*fPhiTwist
260                  +  2*(fDx3minus1 + fDx4minus2    266                  +  2*(fDx3minus1 + fDx4minus2)*phi)
261                      *(v.y()*std::cos(phi) - v    267                      *(v.y()*std::cos(phi) - v.x()*std::sin(phi))))
262          /(fPhiTwist*(4*fDy1* v.x() - (fa1md1     268          /(fPhiTwist*(4*fDy1* v.x() - (fa1md1 + 4*fDy1*fTAlph)*v.y())
263                     *std::cos(phi) + fPhiTwist    269                     *std::cos(phi) + fPhiTwist*(fa1md1*v.x()
264                        + 4*fDy1*(fTAlph*v.x()     270                        + 4*fDy1*(fTAlph*v.x() + v.y()))*std::sin(phi));
265       xbuftmp.phi = phi ;                         271       xbuftmp.phi = phi ;
266       xbuftmp.u = u ;                             272       xbuftmp.u = u ;
267       xbuftmp.areacode = sOutside ;               273       xbuftmp.areacode = sOutside ;
268       xbuftmp.distance = kInfinity ;              274       xbuftmp.distance = kInfinity ;
269       xbuftmp.isvalid = false ;                   275       xbuftmp.isvalid = false ;
270                                                   276 
271       xbuf.push_back(xbuftmp) ;  // store it t    277       xbuf.push_back(xbuftmp) ;  // store it to xbuf
272     }                                             278     }
273     else   // no intersection possible            279     else   // no intersection possible
274     {                                             280     {
275       distance[0] = kInfinity;                    281       distance[0] = kInfinity;
276       gxx[0].set(kInfinity,kInfinity,kInfinity    282       gxx[0].set(kInfinity,kInfinity,kInfinity);
277       isvalid[0] = false ;                        283       isvalid[0] = false ;
278       areacode[0] = sOutside ;                    284       areacode[0] = sOutside ;
279       fCurStatWithV.SetCurrentStatus(0, gxx[0]    285       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0],
280                                      areacode[    286                                      areacode[0], isvalid[0],
281                                      0, valida    287                                      0, validate, &gp, &gv);
282       return 0;                                   288       return 0;
283     }  // end std::fabs(p.z() <= L                289     }  // end std::fabs(p.z() <= L 
284   } // end v.z() == 0                             290   } // end v.z() == 0
285   else  // general solution for non-zero vz       291   else  // general solution for non-zero vz
286   {                                               292   {
287                                                   293 
288     G4double c[8],srd[7],si[7] ;                  294     G4double c[8],srd[7],si[7] ;  
289                                                   295 
290     c[7] = 57600*                                 296     c[7] = 57600*
291       fDy1*(fa1md1*phiyz +                        297       fDy1*(fa1md1*phiyz + 
292             fDy1*(-4*phixz + 4*fTAlph*phiyz       298             fDy1*(-4*phixz + 4*fTAlph*phiyz
293                  + (fDx3plus1 + fDx4plus2)*fPh    299                  + (fDx3plus1 + fDx4plus2)*fPhiTwist*v.z())) ;
294     c[6] = -57600*                                300     c[6] = -57600*
295       fDy1*(4*fDy1*(phiyz + 2*fDz*v.x() + fTAl    301       fDy1*(4*fDy1*(phiyz + 2*fDz*v.x() + fTAlph*(phixz - 2*fDz*v.y()))
296           - 2*fDy1*(2*fdeltaX + fDx3minus1 + f    302           - 2*fDy1*(2*fdeltaX + fDx3minus1 + fDx4minus2
297                   - 2*fdeltaY*fTAlph)*v.z()       303                   - 2*fdeltaY*fTAlph)*v.z()
298           + fa1md1*(phixz - 2*fDz*v.y() + fdel    304           + fa1md1*(phixz - 2*fDz*v.y() + fdeltaY*v.z()));
299     c[5] = 4800*                                  305     c[5] = 4800*
300       fDy1*(fa1md1*(-5*phiyz - 24*fDz*v.x() +     306       fDy1*(fa1md1*(-5*phiyz - 24*fDz*v.x() + 12*fdeltaX*v.z()) + 
301             fDy1*(20*phixz - 4*(5*fTAlph*phiyz    307             fDy1*(20*phixz - 4*(5*fTAlph*phiyz + 24*fDz*fTAlph*v.x()
302                    + 24*fDz*v.y()) + (48*fdelt    308                    + 24*fDz*v.y()) + (48*fdeltaY + (fDx3plus1 + fDx4plus2)
303                                     *fPhiTwist    309                                     *fPhiTwist + 48*fdeltaX*fTAlph)*v.z()));
304     c[4] = 4800*                                  310     c[4] = 4800*
305       fDy1*(fa1md1*(phixz - 10*fDz*v.y() + 5*f    311       fDy1*(fa1md1*(phixz - 10*fDz*v.y() + 5*fdeltaY*v.z())
306           + 2*fDy1*(2*phiyz + 20*fDz*v.x()        312           + 2*fDy1*(2*phiyz + 20*fDz*v.x()
307                    + (-10*fdeltaX + fDx3minus1    313                    + (-10*fdeltaX + fDx3minus1 + fDx4minus2)*v.z()
308                    + 2*fTAlph*(phixz - 10*fDz*    314                    + 2*fTAlph*(phixz - 10*fDz*v.y() + 5*fdeltaY*v.z())));
309     c[3] = -96*                                   315     c[3] = -96*
310       fDy1*(-(fa1md1*(phiyz + 100*fDz*v.x() -     316       fDy1*(-(fa1md1*(phiyz + 100*fDz*v.x() - 50*fdeltaX*v.z()))
311           + fDy1*(4*phixz - 400*fDz*v.y()         317           + fDy1*(4*phixz - 400*fDz*v.y()
312                   + (200*fdeltaY - (fDx3plus1     318                   + (200*fdeltaY - (fDx3plus1 + fDx4plus2)*fPhiTwist)*v.z()
313                   - 4*fTAlph*(phiyz + 100*fDz*    319                   - 4*fTAlph*(phiyz + 100*fDz*v.x() - 50*fdeltaX*v.z())));
314     c[2] = 32*                                    320     c[2] = 32*
315       fDy1*(4*fDy1*(7*fTAlph*phixz + 7*phiyz -    321       fDy1*(4*fDy1*(7*fTAlph*phixz + 7*phiyz - 6*fDz*v.x() + 6*fDz*fTAlph*v.y())
316           + 6*fDy1*(2*fdeltaX+fDx3minus1+fDx4m    322           + 6*fDy1*(2*fdeltaX+fDx3minus1+fDx4minus2-2*fdeltaY*fTAlph)*v.z()
317           + fa1md1*(7*phixz + 6*fDz*v.y() - 3*    323           + fa1md1*(7*phixz + 6*fDz*v.y() - 3*fdeltaY*v.z()));
318     c[1] = -8*                                    324     c[1] = -8*
319       fDy1*(fa1md1*(-9*phiyz - 56*fDz*v.x() +     325       fDy1*(fa1md1*(-9*phiyz - 56*fDz*v.x() + 28*fdeltaX*v.z())
320           + 4*fDy1*(9*phixz - 9*fTAlph*phiyz -    326           + 4*fDy1*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.x()
321                   - 56*fDz*v.y() + 28*(fdeltaY    327                   - 56*fDz*v.y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.z()));
322     c[0] = 72*                                    328     c[0] = 72*
323       fDy1*(fa1md1*(2*fDz*v.y() - fdeltaY*v.z(    329       fDy1*(fa1md1*(2*fDz*v.y() - fdeltaY*v.z())
324           + fDy1*(-8*fDz*v.x() + 8*fDz*fTAlph*    330           + fDy1*(-8*fDz*v.x() + 8*fDz*fTAlph*v.y()
325                 + 4*fdeltaX*v.z() - 4*fdeltaY*    331                 + 4*fdeltaX*v.z() - 4*fdeltaY*fTAlph*v.z()));
326                                                   332 
327 #ifdef G4TWISTDEBUG                               333 #ifdef G4TWISTDEBUG
328     G4cout << "coef = " << c[0] << " "            334     G4cout << "coef = " << c[0] << " " 
329            <<  c[1] << " "                        335            <<  c[1] << " "  
330            <<  c[2] << " "                        336            <<  c[2] << " "  
331            <<  c[3] << " "                        337            <<  c[3] << " "  
332            <<  c[4] << " "                        338            <<  c[4] << " "  
333            <<  c[5] << " "                        339            <<  c[5] << " "  
334            <<  c[6] << " "                        340            <<  c[6] << " "  
335            <<  c[7] << G4endl ;                   341            <<  c[7] << G4endl ; 
336 #endif                                            342 #endif    
337                                                   343 
338     G4JTPolynomialSolver trapEq ;                 344     G4JTPolynomialSolver trapEq ;
339     G4int num = trapEq.FindRoots(c,7,srd,si);     345     G4int num = trapEq.FindRoots(c,7,srd,si);
340                                                   346 
341     for (G4int i = 0 ; i<num ; i++ )   // loop    347     for (G4int i = 0 ; i<num ; i++ )   // loop over all math solutions
342     {                                             348     {  
343       if ( si[i]==0.0 )  // only real solution    349       if ( si[i]==0.0 )  // only real solutions
344       {                                           350       { 
345 #ifdef G4TWISTDEBUG                               351 #ifdef G4TWISTDEBUG
346         G4cout << "Solution " << i << " : " <<    352         G4cout << "Solution " << i << " : " << srd[i] << G4endl ;
347 #endif                                            353 #endif
348         phi = std::fmod(srd[i] , pihalf)  ;       354         phi = std::fmod(srd[i] , pihalf)  ;
349         u   = (fDy1*(4*(phiyz + 2*fDz*phi*v.y(    355         u   = (fDy1*(4*(phiyz + 2*fDz*phi*v.y() - fdeltaY*phi*v.z())
350                      - ((fDx3plus1 + fDx4plus2    356                      - ((fDx3plus1 + fDx4plus2)*fPhiTwist
351                        + 2*(fDx3minus1 + fDx4m    357                        + 2*(fDx3minus1 + fDx4minus2)*phi)*v.z()*std::sin(phi)))
352              /(fPhiTwist*v.z()*(4*fDy1*std::co    358              /(fPhiTwist*v.z()*(4*fDy1*std::cos(phi)
353                              + (fa1md1 + 4*fDy    359                              + (fa1md1 + 4*fDy1*fTAlph)*std::sin(phi)));        
354         xbuftmp.phi = phi ;                       360         xbuftmp.phi = phi ;
355         xbuftmp.u = u ;                           361         xbuftmp.u = u ;
356         xbuftmp.areacode = sOutside ;             362         xbuftmp.areacode = sOutside ;
357         xbuftmp.distance = kInfinity ;            363         xbuftmp.distance = kInfinity ;
358         xbuftmp.isvalid = false ;                 364         xbuftmp.isvalid = false ;
359                                                   365         
360         xbuf.push_back(xbuftmp) ;  // store it    366         xbuf.push_back(xbuftmp) ;  // store it to xbuf
361                                                   367       
362 #ifdef G4TWISTDEBUG                               368 #ifdef G4TWISTDEBUG
363         G4cout << "solution " << i << " = " <<    369         G4cout << "solution " << i << " = " << phi << " , " << u  << G4endl ;
364 #endif                                            370 #endif
365       }  // end if real solution                  371       }  // end if real solution
366     }  // end loop i                              372     }  // end loop i    
367   }    // end general case                        373   }    // end general case
368                                                   374 
369   nxx = (G4int)xbuf.size() ;  // save the numb << 375   nxx = xbuf.size() ;  // save the number of  solutions
370                                                   376 
371   G4ThreeVector xxonsurface  ;    // point on     377   G4ThreeVector xxonsurface  ;    // point on surface
372   G4ThreeVector surfacenormal  ;  // normal ve    378   G4ThreeVector surfacenormal  ;  // normal vector  
373   G4double deltaX;  // distance between inters    379   G4double deltaX;  // distance between intersection point and point on surface
374   G4double theta;   // angle between track and    380   G4double theta;   // angle between track and surfacenormal
375   G4double factor;  // a scaling factor           381   G4double factor;  // a scaling factor
376   G4int maxint=30;  // number of iterations       382   G4int maxint=30;  // number of iterations
377                                                   383 
378   for (auto & k : xbuf)                        << 384   for ( size_t k = 0 ; k<xbuf.size() ; ++k )
379   {                                               385   {
380 #ifdef G4TWISTDEBUG                               386 #ifdef G4TWISTDEBUG
381     G4cout << "Solution " << k << " : "           387     G4cout << "Solution " << k << " : " 
382            << "reconstructed phiR = " << xbuf[    388            << "reconstructed phiR = " << xbuf[k].phi
383            << ", uR = " << xbuf[k].u << G4endl    389            << ", uR = " << xbuf[k].u << G4endl ; 
384 #endif                                            390 #endif
385                                                   391     
386     phi = k.phi ;  // get the stored values fo << 392     phi = xbuf[k].phi ;  // get the stored values for phi and u
387     u = k.u ;                                  << 393     u = xbuf[k].u ;
388                                                   394 
389     IsConverged = false ;   // no convergence     395     IsConverged = false ;   // no convergence at the beginning
390                                                   396     
391     for ( G4int i = 1 ; i<maxint ; ++i )          397     for ( G4int i = 1 ; i<maxint ; ++i )
392     {                                             398     {
393       xxonsurface = SurfacePoint(phi,u) ;         399       xxonsurface = SurfacePoint(phi,u) ;
394       surfacenormal = NormAng(phi,u) ;            400       surfacenormal = NormAng(phi,u) ;
395                                                   401 
396       tmpdist = DistanceToPlaneWithV(p, v, xxo    402       tmpdist = DistanceToPlaneWithV(p, v, xxonsurface, surfacenormal, tmpxx); 
397       deltaX = ( tmpxx - xxonsurface ).mag() ;    403       deltaX = ( tmpxx - xxonsurface ).mag() ; 
398       theta = std::fabs(std::acos(v*surfacenor    404       theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
399       if ( theta < 0.001 )                        405       if ( theta < 0.001 )
400       {                                           406       { 
401         factor = 50 ;                             407         factor = 50 ;
402         IsParallel = true ;                       408         IsParallel = true ;
403       }                                           409       }
404       else                                        410       else
405       {                                           411       {
406         factor = 1 ;                              412         factor = 1 ;
407       }                                           413       }
408                                                   414 
409 #ifdef G4TWISTDEBUG                               415 #ifdef G4TWISTDEBUG
410       G4cout << "Step i = " << i << ", distanc    416       G4cout << "Step i = " << i << ", distance = " << tmpdist
411              << ", " << deltaX << G4endl ;        417              << ", " << deltaX << G4endl ;
412       G4cout << "X = " << tmpxx << G4endl ;       418       G4cout << "X = " << tmpxx << G4endl ;
413 #endif                                            419 #endif
414                                                   420       
415       GetPhiUAtX(tmpxx, phi, u) ;                 421       GetPhiUAtX(tmpxx, phi, u) ;
416         // the new point xx is accepted and ph    422         // the new point xx is accepted and phi/u replaced
417                                                   423       
418 #ifdef G4TWISTDEBUG                               424 #ifdef G4TWISTDEBUG
419       G4cout << "approximated phi = " << phi <    425       G4cout << "approximated phi = " << phi << ", u = " << u << G4endl ; 
420 #endif                                            426 #endif
421                                                   427       
422       if ( deltaX <= factor*ctol ) { IsConverg    428       if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
423                                                   429       
424     }  // end iterative loop (i)                  430     }  // end iterative loop (i)
425                                                   431     
426     if ( std::fabs(tmpdist)<ctol ) { tmpdist =    432     if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0 ; }
427                                                   433 
428 #ifdef G4TWISTDEBUG                               434 #ifdef G4TWISTDEBUG
429     G4cout << "refined solution "  << phi << "    435     G4cout << "refined solution "  << phi << " , " << u  <<  G4endl ;
430     G4cout << "distance = " << tmpdist << G4en    436     G4cout << "distance = " << tmpdist << G4endl ;
431     G4cout << "local X = " << tmpxx << G4endl     437     G4cout << "local X = " << tmpxx << G4endl ;
432 #endif                                            438 #endif
433                                                   439     
434     tmpisvalid = false ;  // init                 440     tmpisvalid = false ;  // init 
435                                                   441 
436     if ( IsConverged )                            442     if ( IsConverged )
437     {                                             443     {
438       if (validate == kValidateWithTol)           444       if (validate == kValidateWithTol)
439       {                                           445       {
440         tmpareacode = GetAreaCode(tmpxx);         446         tmpareacode = GetAreaCode(tmpxx);
441         if (!IsOutside(tmpareacode))              447         if (!IsOutside(tmpareacode))
442         {                                         448         {
443           if (tmpdist >= 0) tmpisvalid = true;    449           if (tmpdist >= 0) tmpisvalid = true;
444         }                                         450         }
445       }                                           451       }
446       else if (validate == kValidateWithoutTol    452       else if (validate == kValidateWithoutTol)
447       {                                           453       {
448         tmpareacode = GetAreaCode(tmpxx, false    454         tmpareacode = GetAreaCode(tmpxx, false);
449         if (IsInside(tmpareacode))                455         if (IsInside(tmpareacode))
450         {                                         456         {
451           if (tmpdist >= 0) { tmpisvalid = tru    457           if (tmpdist >= 0) { tmpisvalid = true; }
452         }                                         458         }
453       }                                           459       }
454       else  // kDontValidate                      460       else  // kDontValidate
455       {                                           461       {
456         G4Exception("G4TwistTrapAlphaSide::Dis    462         G4Exception("G4TwistTrapAlphaSide::DistanceToSurface()",
457                     "GeomSolids0001", FatalExc    463                     "GeomSolids0001", FatalException,
458                     "Feature NOT implemented !    464                     "Feature NOT implemented !");
459       }                                           465       }
460     }                                             466     } 
461     else                                          467     else
462     {                                             468     {
463       tmpdist = kInfinity;     // no convergen    469       tmpdist = kInfinity;     // no convergence after 10 steps 
464       tmpisvalid = false ;     // solution is     470       tmpisvalid = false ;     // solution is not vaild
465     }                                             471     }  
466                                                   472 
467     // store the found values                     473     // store the found values
468     //                                            474     // 
469     k.xx = tmpxx ;                             << 475     xbuf[k].xx = tmpxx ;
470     k.distance = tmpdist ;                     << 476     xbuf[k].distance = tmpdist ;
471     k.areacode = tmpareacode ;                 << 477     xbuf[k].areacode = tmpareacode ;
472     k.isvalid = tmpisvalid ;                   << 478     xbuf[k].isvalid = tmpisvalid ;
473                                                   479 
474   }  // end loop over physical solutions (vari    480   }  // end loop over physical solutions (variable k)
475                                                   481 
476   std::sort(xbuf.begin() , xbuf.end(), Distanc    482   std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;  // sorting
477                                                   483 
478 #ifdef G4TWISTDEBUG                               484 #ifdef G4TWISTDEBUG
479   G4cout << G4endl << "list xbuf after sorting    485   G4cout << G4endl << "list xbuf after sorting : " << G4endl ;
480   G4cout << G4endl << G4endl ;                    486   G4cout << G4endl << G4endl ;
481 #endif                                            487 #endif
482                                                   488 
483   // erase identical intersection (within kCar    489   // erase identical intersection (within kCarTolerance) 
484   //                                              490   //
485   xbuf.erase( std::unique(xbuf.begin(), xbuf.e    491   xbuf.erase( std::unique(xbuf.begin(), xbuf.end() , EqualIntersection ),
486               xbuf.end() );                       492               xbuf.end() );
487                                                   493 
488                                                   494 
489   // add guesses                                  495   // add guesses
490   //                                              496   //
491   auto nxxtmp = (G4int)xbuf.size() ;           << 497   G4int nxxtmp = xbuf.size() ;
492                                                   498 
493   if ( nxxtmp<2 || IsParallel  )  // positive     499   if ( nxxtmp<2 || IsParallel  )  // positive end
494   {                                               500   {
495                                                   501 
496 #ifdef G4TWISTDEBUG                               502 #ifdef G4TWISTDEBUG
497     G4cout << "add guess at +z/2 .. " << G4end    503     G4cout << "add guess at +z/2 .. " << G4endl ;
498 #endif                                            504 #endif
499                                                   505 
500     phi = fPhiTwist/2 ;                           506     phi = fPhiTwist/2 ;
501     u   = 0 ;                                     507     u   = 0 ;
502                                                   508     
503     xbuftmp.phi = phi ;                           509     xbuftmp.phi = phi ;
504     xbuftmp.u = u ;                               510     xbuftmp.u = u ;
505     xbuftmp.areacode = sOutside ;                 511     xbuftmp.areacode = sOutside ;
506     xbuftmp.distance = kInfinity ;                512     xbuftmp.distance = kInfinity ;
507     xbuftmp.isvalid = false ;                     513     xbuftmp.isvalid = false ;
508                                                   514     
509     xbuf.push_back(xbuftmp) ;  // store it to     515     xbuf.push_back(xbuftmp) ;  // store it to xbuf
510                                                   516 
511 #ifdef G4TWISTDEBUG                               517 #ifdef G4TWISTDEBUG
512     G4cout << "add guess at -z/2 .. " << G4end    518     G4cout << "add guess at -z/2 .. " << G4endl ;
513 #endif                                            519 #endif
514                                                   520 
515     phi = -fPhiTwist/2 ;                          521     phi = -fPhiTwist/2 ;
516     u   = 0 ;                                     522     u   = 0 ;
517                                                   523     
518     xbuftmp.phi = phi ;                           524     xbuftmp.phi = phi ;
519     xbuftmp.u = u ;                               525     xbuftmp.u = u ;
520     xbuftmp.areacode = sOutside ;                 526     xbuftmp.areacode = sOutside ;
521     xbuftmp.distance = kInfinity ;                527     xbuftmp.distance = kInfinity ;
522     xbuftmp.isvalid = false ;                     528     xbuftmp.isvalid = false ;
523                                                   529     
524     xbuf.push_back(xbuftmp) ;  // store it to     530     xbuf.push_back(xbuftmp) ;  // store it to xbuf
525                                                   531 
526     for ( std::size_t k = nxxtmp ; k<xbuf.size << 532     for ( size_t k = nxxtmp ; k<xbuf.size() ; ++k )
527     {                                             533     {
528                                                   534 
529 #ifdef G4TWISTDEBUG                               535 #ifdef G4TWISTDEBUG
530       G4cout << "Solution " << k << " : "         536       G4cout << "Solution " << k << " : " 
531              << "reconstructed phiR = " << xbu    537              << "reconstructed phiR = " << xbuf[k].phi
532              << ", uR = " << xbuf[k].u << G4en    538              << ", uR = " << xbuf[k].u << G4endl ; 
533 #endif                                            539 #endif
534                                                   540       
535       phi = xbuf[k].phi ;  // get the stored v    541       phi = xbuf[k].phi ;  // get the stored values for phi and u
536       u   = xbuf[k].u ;                           542       u   = xbuf[k].u ;
537                                                   543 
538       IsConverged = false ;   // no convergenc    544       IsConverged = false ;   // no convergence at the beginning
539                                                   545       
540       for ( G4int i = 1 ; i<maxint ; ++i )        546       for ( G4int i = 1 ; i<maxint ; ++i )
541       {                                           547       {
542         xxonsurface = SurfacePoint(phi,u) ;       548         xxonsurface = SurfacePoint(phi,u) ;
543         surfacenormal = NormAng(phi,u) ;          549         surfacenormal = NormAng(phi,u) ;
544         tmpdist = DistanceToPlaneWithV(p, v, x    550         tmpdist = DistanceToPlaneWithV(p, v, xxonsurface, surfacenormal, tmpxx);
545         deltaX = ( tmpxx - xxonsurface ).mag()    551         deltaX = ( tmpxx - xxonsurface ).mag();
546         theta = std::fabs(std::acos(v*surfacen    552         theta = std::fabs(std::acos(v*surfacenormal) - pihalf);
547         if ( theta < 0.001 )                      553         if ( theta < 0.001 )
548         {                                         554         { 
549           factor = 50 ;                           555           factor = 50 ;    
550         }                                         556         }
551         else                                      557         else
552         {                                         558         {
553           factor = 1 ;                            559           factor = 1 ;
554         }                                         560         }
555                                                   561         
556 #ifdef G4TWISTDEBUG                               562 #ifdef G4TWISTDEBUG
557         G4cout << "Step i = " << i << ", dista    563         G4cout << "Step i = " << i << ", distance = " << tmpdist
558                << ", " << deltaX << G4endl        564                << ", " << deltaX << G4endl
559                << "X = " << tmpxx << G4endl ;     565                << "X = " << tmpxx << G4endl ;
560 #endif                                            566 #endif
561                                                   567 
562         GetPhiUAtX(tmpxx, phi, u) ;               568         GetPhiUAtX(tmpxx, phi, u) ;
563           // the new point xx is accepted and     569           // the new point xx is accepted and phi/u replaced
564                                                   570       
565 #ifdef G4TWISTDEBUG                               571 #ifdef G4TWISTDEBUG
566         G4cout << "approximated phi = " << phi    572         G4cout << "approximated phi = " << phi << ", u = " << u << G4endl ; 
567 #endif                                            573 #endif
568                                                   574       
569         if ( deltaX <= factor*ctol ) { IsConve    575         if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
570                                                   576       
571       }  // end iterative loop (i)                577       }  // end iterative loop (i)
572                                                   578     
573       if ( std::fabs(tmpdist)<ctol )  { tmpdis    579       if ( std::fabs(tmpdist)<ctol )  { tmpdist = 0; }
574                                                   580 
575 #ifdef G4TWISTDEBUG                               581 #ifdef G4TWISTDEBUG
576       G4cout << "refined solution "  << phi <<    582       G4cout << "refined solution "  << phi << " , " << u  <<  G4endl ;
577       G4cout << "distance = " << tmpdist << G4    583       G4cout << "distance = " << tmpdist << G4endl ;
578       G4cout << "local X = " << tmpxx << G4end    584       G4cout << "local X = " << tmpxx << G4endl ;
579 #endif                                            585 #endif
580                                                   586 
581       tmpisvalid = false ;  // init               587       tmpisvalid = false ;  // init 
582                                                   588 
583       if ( IsConverged )                          589       if ( IsConverged )
584       {                                           590       {
585         if (validate == kValidateWithTol)         591         if (validate == kValidateWithTol)
586         {                                         592         {
587           tmpareacode = GetAreaCode(tmpxx);       593           tmpareacode = GetAreaCode(tmpxx);
588           if (!IsOutside(tmpareacode))            594           if (!IsOutside(tmpareacode))
589           {                                       595           {
590             if (tmpdist >= 0)  { tmpisvalid =     596             if (tmpdist >= 0)  { tmpisvalid = true; }
591           }                                       597           }
592         }                                         598         }
593         else if (validate == kValidateWithoutT    599         else if (validate == kValidateWithoutTol)
594         {                                         600         {
595           tmpareacode = GetAreaCode(tmpxx, fal    601           tmpareacode = GetAreaCode(tmpxx, false);
596           if (IsInside(tmpareacode))              602           if (IsInside(tmpareacode))
597           {                                       603           {
598             if (tmpdist >= 0)  { tmpisvalid =     604             if (tmpdist >= 0)  { tmpisvalid = true; }
599           }                                       605           }
600         }                                         606         }
601         else  // kDontValidate                    607         else  // kDontValidate
602         {                                         608         {
603           G4Exception("G4TwistedBoxSide::Dista    609           G4Exception("G4TwistedBoxSide::DistanceToSurface()",
604                       "GeomSolids0001", FatalE    610                       "GeomSolids0001", FatalException,
605                       "Feature NOT implemented    611                       "Feature NOT implemented !");
606         }                                         612         }
607       }                                           613       } 
608       else                                        614       else
609       {                                           615       {
610         tmpdist = kInfinity;     // no converg    616         tmpdist = kInfinity;     // no convergence after 10 steps 
611         tmpisvalid = false ;     // solution i    617         tmpisvalid = false ;     // solution is not vaild
612       }                                           618       }  
613                                                   619 
614       // store the found values                   620       // store the found values
615       //                                          621       //
616       xbuf[k].xx = tmpxx ;                        622       xbuf[k].xx = tmpxx ;
617       xbuf[k].distance = tmpdist ;                623       xbuf[k].distance = tmpdist ;
618       xbuf[k].areacode = tmpareacode ;            624       xbuf[k].areacode = tmpareacode ;
619       xbuf[k].isvalid = tmpisvalid ;              625       xbuf[k].isvalid = tmpisvalid ;
620                                                   626 
621     }  // end loop over physical solutions        627     }  // end loop over physical solutions 
622   }  // end less than 2 solutions                 628   }  // end less than 2 solutions
623                                                   629 
624   // sort again                                   630   // sort again
625   std::sort(xbuf.begin() , xbuf.end(), Distanc    631   std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;  // sorting
626                                                   632 
627   // erase identical intersection (within kCar    633   // erase identical intersection (within kCarTolerance) 
628   xbuf.erase( std::unique(xbuf.begin(), xbuf.e    634   xbuf.erase( std::unique(xbuf.begin(), xbuf.end() , EqualIntersection ) ,
629               xbuf.end() );                       635               xbuf.end() );
630                                                   636 
631 #ifdef G4TWISTDEBUG                               637 #ifdef G4TWISTDEBUG
632   G4cout << G4endl << "list xbuf after sorting    638   G4cout << G4endl << "list xbuf after sorting : " << G4endl ;
633   G4cout << G4endl << G4endl ;                    639   G4cout << G4endl << G4endl ;
634 #endif                                            640 #endif
635                                                   641 
636   nxx = (G4int)xbuf.size() ;   // determine nu << 642   nxx = xbuf.size() ;   // determine number of solutions again.
637                                                   643 
638   for ( G4int i = 0 ; i<(G4int)xbuf.size() ; + << 644   for ( size_t i = 0 ; i<xbuf.size() ; ++i )
639   {                                               645   {
640     distance[i] = xbuf[i].distance;               646     distance[i] = xbuf[i].distance;
641     gxx[i]      = ComputeGlobalPoint(xbuf[i].x    647     gxx[i]      = ComputeGlobalPoint(xbuf[i].xx);
642     areacode[i] = xbuf[i].areacode ;              648     areacode[i] = xbuf[i].areacode ;
643     isvalid[i]  = xbuf[i].isvalid ;               649     isvalid[i]  = xbuf[i].isvalid ;
644                                                   650     
645     fCurStatWithV.SetCurrentStatus(i, gxx[i],     651     fCurStatWithV.SetCurrentStatus(i, gxx[i], distance[i], areacode[i],
646                                      isvalid[i    652                                      isvalid[i], nxx, validate, &gp, &gv);
647 #ifdef G4TWISTDEBUG                               653 #ifdef G4TWISTDEBUG
648     G4cout << "element Nr. " << i                 654     G4cout << "element Nr. " << i 
649            << ", local Intersection = " << xbu    655            << ", local Intersection = " << xbuf[i].xx 
650            << ", distance = " << xbuf[i].dista    656            << ", distance = " << xbuf[i].distance 
651            << ", u = " << xbuf[i].u               657            << ", u = " << xbuf[i].u 
652            << ", phi = " << xbuf[i].phi           658            << ", phi = " << xbuf[i].phi 
653            << ", isvalid = " << xbuf[i].isvali    659            << ", isvalid = " << xbuf[i].isvalid 
654            << G4endl ;                            660            << G4endl ;
655 #endif                                            661 #endif
656                                                   662 
657   }  // end for( i ) loop                         663   }  // end for( i ) loop
658                                                   664 
659 #ifdef G4TWISTDEBUG                               665 #ifdef G4TWISTDEBUG
660   G4cout << "G4TwistTrapAlphaSide finished " <    666   G4cout << "G4TwistTrapAlphaSide finished " << G4endl ;
661   G4cout << nxx << " possible physical solutio    667   G4cout << nxx << " possible physical solutions found" << G4endl ;
662   for ( G4int k= 0 ; k< nxx ; k++ )               668   for ( G4int k= 0 ; k< nxx ; k++ )
663   {                                               669   {
664     G4cout << "global intersection Point found    670     G4cout << "global intersection Point found: " << gxx[k] << G4endl ;
665     G4cout << "distance = " << distance[k] <<     671     G4cout << "distance = " << distance[k] << G4endl ;
666     G4cout << "isvalid = " << isvalid[k] << G4    672     G4cout << "isvalid = " << isvalid[k] << G4endl ;
667   }                                               673   }
668 #endif                                            674 #endif
669                                                   675 
670   return nxx ;                                    676   return nxx ;
671 }                                                 677 }
672                                                   678 
673                                                   679 
674 //============================================    680 //=====================================================================
675 //* DistanceToSurface ------------------------    681 //* DistanceToSurface -------------------------------------------------
676                                                   682 
677 G4int                                             683 G4int
678 G4TwistTrapAlphaSide::DistanceToSurface(const     684 G4TwistTrapAlphaSide::DistanceToSurface(const G4ThreeVector& gp,
679                                                   685                                               G4ThreeVector  gxx[],
680                                                   686                                               G4double       distance[],
681                                                   687                                               G4int          areacode[])
682 {                                                 688 {  
683    const G4double ctol = 0.5 * kCarTolerance;     689    const G4double ctol = 0.5 * kCarTolerance;
684                                                   690 
685    fCurStat.ResetfDone(kDontValidate, &gp);       691    fCurStat.ResetfDone(kDontValidate, &gp);
686                                                   692 
687    if (fCurStat.IsDone())                         693    if (fCurStat.IsDone())
688    {                                              694    {
689       for (G4int i=0; i<fCurStat.GetNXX(); ++i    695       for (G4int i=0; i<fCurStat.GetNXX(); ++i)
690       {                                           696       {
691          gxx[i] = fCurStat.GetXX(i);              697          gxx[i] = fCurStat.GetXX(i);
692          distance[i] = fCurStat.GetDistance(i)    698          distance[i] = fCurStat.GetDistance(i);
693          areacode[i] = fCurStat.GetAreacode(i)    699          areacode[i] = fCurStat.GetAreacode(i);
694       }                                           700       }
695       return fCurStat.GetNXX();                   701       return fCurStat.GetNXX();
696    }                                              702    }
697    else  // initialize                            703    else  // initialize
698    {                                              704    {
699       for (G4int i=0; i<G4VSURFACENXX; ++i)       705       for (G4int i=0; i<G4VSURFACENXX; ++i)
700       {                                           706       {
701          distance[i] = kInfinity;                 707          distance[i] = kInfinity;
702          areacode[i] = sOutside;                  708          areacode[i] = sOutside;
703          gxx[i].set(kInfinity, kInfinity, kInf    709          gxx[i].set(kInfinity, kInfinity, kInfinity);
704       }                                           710       }
705    }                                              711    }
706                                                   712 
707    G4ThreeVector p = ComputeLocalPoint(gp);       713    G4ThreeVector p = ComputeLocalPoint(gp);
708    G4ThreeVector xx;  // intersection point       714    G4ThreeVector xx;  // intersection point
709    G4ThreeVector xxonsurface ; // interpolated    715    G4ThreeVector xxonsurface ; // interpolated intersection point 
710                                                   716 
711    // the surfacenormal at that surface point     717    // the surfacenormal at that surface point
712    //                                             718    //
713    G4double phiR = 0  ;                           719    G4double phiR = 0  ;
714    G4double uR = 0 ;                              720    G4double uR = 0 ;
715                                                   721 
716    G4ThreeVector surfacenormal ;                  722    G4ThreeVector surfacenormal ; 
717    G4double deltaX, uMax ;                        723    G4double deltaX, uMax ;
718    G4double halfphi = 0.5*fPhiTwist ;             724    G4double halfphi = 0.5*fPhiTwist ;
719                                                   725    
720    for ( G4int i = 1 ; i<20 ; ++i )               726    for ( G4int i = 1 ; i<20 ; ++i )
721    {                                              727    {
722      xxonsurface = SurfacePoint(phiR,uR) ;        728      xxonsurface = SurfacePoint(phiR,uR) ;
723      surfacenormal = NormAng(phiR,uR) ;           729      surfacenormal = NormAng(phiR,uR) ;
724      distance[0] = DistanceToPlane(p,xxonsurfa    730      distance[0] = DistanceToPlane(p,xxonsurface,surfacenormal,xx); // new XX
725      deltaX = ( xx - xxonsurface ).mag() ;        731      deltaX = ( xx - xxonsurface ).mag() ; 
726                                                   732 
727 #ifdef G4TWISTDEBUG                               733 #ifdef G4TWISTDEBUG
728      G4cout << "i = " << i << ", distance = "     734      G4cout << "i = " << i << ", distance = " << distance[0]
729             << ", " << deltaX << G4endl           735             << ", " << deltaX << G4endl
730             << "X = " << xx << G4endl ;           736             << "X = " << xx << G4endl ;
731 #endif                                            737 #endif
732                                                   738 
733      // the new point xx is accepted and phi/p    739      // the new point xx is accepted and phi/psi replaced
734      //                                           740      //
735      GetPhiUAtX(xx, phiR, uR) ;                   741      GetPhiUAtX(xx, phiR, uR) ;
736                                                   742      
737      if ( deltaX <= ctol ) { break ; }            743      if ( deltaX <= ctol ) { break ; }
738    }                                              744    }
739                                                   745 
740    // check validity of solution ( valid phi,p    746    // check validity of solution ( valid phi,psi ) 
741                                                   747 
742    uMax = GetBoundaryMax(phiR) ;                  748    uMax = GetBoundaryMax(phiR) ;
743                                                   749 
744    if (  phiR > halfphi ) { phiR =  halfphi ;     750    if (  phiR > halfphi ) { phiR =  halfphi ; }
745    if ( phiR < -halfphi ) { phiR = -halfphi ;     751    if ( phiR < -halfphi ) { phiR = -halfphi ; }
746    if ( uR > uMax )  { uR = uMax ;  }             752    if ( uR > uMax )  { uR = uMax ;  }
747    if ( uR < -uMax ) { uR = -uMax ; }             753    if ( uR < -uMax ) { uR = -uMax ; }
748                                                   754 
749    xxonsurface = SurfacePoint(phiR,uR) ;          755    xxonsurface = SurfacePoint(phiR,uR) ;
750    distance[0] = (  p - xx ).mag() ;              756    distance[0] = (  p - xx ).mag() ;
751    if ( distance[0] <= ctol ) { distance[0] =     757    if ( distance[0] <= ctol ) { distance[0] = 0 ; } 
752                                                   758 
753    // end of validity                             759    // end of validity 
754                                                   760 
755 #ifdef G4TWISTDEBUG                               761 #ifdef G4TWISTDEBUG
756    G4cout << "refined solution "  << phiR << "    762    G4cout << "refined solution "  << phiR << " , " << uR << " , " << G4endl ;
757    G4cout << "distance = " << distance[0] << G    763    G4cout << "distance = " << distance[0] << G4endl ;
758    G4cout << "X = " << xx << G4endl ;             764    G4cout << "X = " << xx << G4endl ;
759 #endif                                            765 #endif
760                                                   766 
761    G4bool isvalid = true;                         767    G4bool isvalid = true;
762    gxx[0]      = ComputeGlobalPoint(xx);          768    gxx[0]      = ComputeGlobalPoint(xx);
763                                                   769    
764 #ifdef G4TWISTDEBUG                               770 #ifdef G4TWISTDEBUG
765    G4cout << "intersection Point found: " << g    771    G4cout << "intersection Point found: " << gxx[0] << G4endl ;
766    G4cout << "distance = " << distance[0] << G    772    G4cout << "distance = " << distance[0] << G4endl ;
767 #endif                                            773 #endif
768                                                   774 
769    fCurStat.SetCurrentStatus(0, gxx[0], distan    775    fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
770                             isvalid, 1, kDontV    776                             isvalid, 1, kDontValidate, &gp);
771    return 1;                                      777    return 1;
772 }                                                 778 }
773                                                   779 
774                                                   780 
775 //============================================    781 //=====================================================================
776 //* GetAreaCode ------------------------------    782 //* GetAreaCode -------------------------------------------------------
777                                                   783 
778 G4int                                             784 G4int
779 G4TwistTrapAlphaSide::GetAreaCode(const G4Thre    785 G4TwistTrapAlphaSide::GetAreaCode(const G4ThreeVector& xx, G4bool withTol)
780 {                                                 786 {
781    // We must use the function in local coordi    787    // We must use the function in local coordinate system.
782    // See the description of DistanceToSurface    788    // See the description of DistanceToSurface(p,v).
783                                                   789    
784    const G4double ctol = 0.5 * kCarTolerance;     790    const G4double ctol = 0.5 * kCarTolerance;
785                                                   791 
786    G4double phi ;                                 792    G4double phi ;
787    G4double yprime ;                              793    G4double yprime ;
788    GetPhiUAtX(xx, phi,yprime ) ;                  794    GetPhiUAtX(xx, phi,yprime ) ;
789                                                   795 
790    G4double fYAxisMax =  GetBoundaryMax(phi) ;    796    G4double fYAxisMax =  GetBoundaryMax(phi) ;
791    G4double fYAxisMin =  GetBoundaryMin(phi) ;    797    G4double fYAxisMin =  GetBoundaryMin(phi) ;
792                                                   798 
793 #ifdef G4TWISTDEBUG                               799 #ifdef G4TWISTDEBUG
794    G4cout << "GetAreaCode: phi = " << phi << G    800    G4cout << "GetAreaCode: phi = " << phi << G4endl ;
795    G4cout << "GetAreaCode: yprime = " << yprim    801    G4cout << "GetAreaCode: yprime = " << yprime << G4endl ;
796    G4cout << "Intervall is " << fYAxisMin << "    802    G4cout << "Intervall is " << fYAxisMin << " to " << fYAxisMax << G4endl ;
797 #endif                                            803 #endif
798                                                   804 
799    G4int areacode = sInside;                      805    G4int areacode = sInside;
800                                                   806    
801    if (fAxis[0] == kYAxis && fAxis[1] == kZAxi    807    if (fAxis[0] == kYAxis && fAxis[1] == kZAxis)
802    {                                              808    {
803       G4int zaxis = 1;                            809       G4int zaxis = 1;
804                                                   810 
805       if (withTol)                                811       if (withTol)
806       {                                           812       {
807         G4bool isoutside   = false;               813         G4bool isoutside   = false;
808                                                   814         
809         // test boundary of yaxis                 815         // test boundary of yaxis
810                                                   816 
811          if (yprime < fYAxisMin + ctol)           817          if (yprime < fYAxisMin + ctol)
812          {                                        818          {
813             areacode |= (sAxis0 & (sAxisY | sA    819             areacode |= (sAxis0 & (sAxisY | sAxisMin)) | sBoundary; 
814             if (yprime <= fYAxisMin - ctol)  {    820             if (yprime <= fYAxisMin - ctol)  { isoutside = true; }
815                                                   821 
816          }                                        822          }
817          else if (yprime > fYAxisMax - ctol)      823          else if (yprime > fYAxisMax - ctol)
818          {                                        824          {
819             areacode |= (sAxis0 & (sAxisY | sA    825             areacode |= (sAxis0 & (sAxisY | sAxisMax)) | sBoundary;
820             if (yprime >= fYAxisMax + ctol)  {    826             if (yprime >= fYAxisMax + ctol)  { isoutside = true; }
821          }                                        827          }
822                                                   828 
823          // test boundary of z-axis               829          // test boundary of z-axis
824                                                   830 
825          if (xx.z() < fAxisMin[zaxis] + ctol)     831          if (xx.z() < fAxisMin[zaxis] + ctol)
826          {                                        832          {
827             areacode |= (sAxis1 & (sAxisZ | sA    833             areacode |= (sAxis1 & (sAxisZ | sAxisMin)); 
828                                                   834 
829             if   ((areacode & sBoundary) != 0) << 835             if   (areacode & sBoundary)   // xx is on the corner
830               { areacode |= sCorner; }            836               { areacode |= sCorner; }
831                                                   837 
832             else                                  838             else
833               { areacode |= sBoundary; }          839               { areacode |= sBoundary; }
834             if (xx.z() <= fAxisMin[zaxis] - ct    840             if (xx.z() <= fAxisMin[zaxis] - ctol)  { isoutside = true; }
835          }                                        841          }
836          else if (xx.z() > fAxisMax[zaxis] - c    842          else if (xx.z() > fAxisMax[zaxis] - ctol)
837          {                                        843          {
838             areacode |= (sAxis1 & (sAxisZ | sA    844             areacode |= (sAxis1 & (sAxisZ | sAxisMax));
839                                                   845 
840             if   ((areacode & sBoundary) != 0) << 846             if   (areacode & sBoundary)   // xx is on the corner
841                { areacode |= sCorner; }           847                { areacode |= sCorner; }
842             else                                  848             else
843                { areacode |= sBoundary; }         849                { areacode |= sBoundary; }
844             if (xx.z() >= fAxisMax[zaxis] + ct    850             if (xx.z() >= fAxisMax[zaxis] + ctol)  { isoutside = true; }
845          }                                        851          }
846                                                   852 
847          // if isoutside = true, clear inside     853          // if isoutside = true, clear inside bit.             
848          // if not on boundary, add axis infor    854          // if not on boundary, add axis information.             
849                                                   855          
850          if (isoutside)                           856          if (isoutside)
851          {                                        857          {
852             G4int tmpareacode = areacode & (~s    858             G4int tmpareacode = areacode & (~sInside);
853             areacode = tmpareacode;               859             areacode = tmpareacode;
854          }                                        860          }
855          else if ((areacode & sBoundary) != sB    861          else if ((areacode & sBoundary) != sBoundary)
856          {                                        862          {
857             areacode |= (sAxis0 & sAxisY) | (s    863             areacode |= (sAxis0 & sAxisY) | (sAxis1 & sAxisZ);
858          }                                        864          }           
859                                                   865          
860       }                                           866       }
861       else                                        867       else
862       {                                           868       {
863          // boundary of y-axis                    869          // boundary of y-axis
864                                                   870 
865          if (yprime < fYAxisMin )                 871          if (yprime < fYAxisMin )
866          {                                        872          {
867             areacode |= (sAxis0 & (sAxisY | sA    873             areacode |= (sAxis0 & (sAxisY | sAxisMin)) | sBoundary;
868          }                                        874          }
869          else if (yprime > fYAxisMax)             875          else if (yprime > fYAxisMax)
870          {                                        876          {
871             areacode |= (sAxis0 & (sAxisY | sA    877             areacode |= (sAxis0 & (sAxisY | sAxisMax)) | sBoundary;
872          }                                        878          }
873                                                   879          
874          // boundary of z-axis                    880          // boundary of z-axis
875                                                   881 
876          if (xx.z() < fAxisMin[zaxis])            882          if (xx.z() < fAxisMin[zaxis])
877          {                                        883          {
878             areacode |= (sAxis1 & (sAxisZ | sA    884             areacode |= (sAxis1 & (sAxisZ | sAxisMin));
879             if   ((areacode & sBoundary) != 0) << 885             if   (areacode & sBoundary)   // xx is on the corner
880               { areacode |= sCorner; }            886               { areacode |= sCorner; }
881             else                                  887             else
882               { areacode |= sBoundary; }          888               { areacode |= sBoundary; }
883          }                                        889          }
884          else if (xx.z() > fAxisMax[zaxis])       890          else if (xx.z() > fAxisMax[zaxis])
885          {                                        891          {
886             areacode |= (sAxis1 & (sAxisZ | sA    892             areacode |= (sAxis1 & (sAxisZ | sAxisMax)) ;
887             if   ((areacode & sBoundary) != 0) << 893             if   (areacode & sBoundary)   // xx is on the corner
888               { areacode |= sCorner; }            894               { areacode |= sCorner; }
889             else                                  895             else
890               { areacode |= sBoundary; }          896               { areacode |= sBoundary; }
891          }                                        897          }
892                                                   898 
893          if ((areacode & sBoundary) != sBounda    899          if ((areacode & sBoundary) != sBoundary)
894          {                                        900          {
895             areacode |= (sAxis0 & sAxisY) | (s    901             areacode |= (sAxis0 & sAxisY) | (sAxis1 & sAxisZ);
896          }                                        902          }           
897       }                                           903       }
898       return areacode;                            904       return areacode;
899    }                                              905    }
900    else                                           906    else
901    {                                              907    {
902       G4Exception("G4TwistTrapAlphaSide::GetAr    908       G4Exception("G4TwistTrapAlphaSide::GetAreaCode()",
903                   "GeomSolids0001", FatalExcep    909                   "GeomSolids0001", FatalException,
904                   "Feature NOT implemented !")    910                   "Feature NOT implemented !");
905    }                                              911    }
906    return areacode;                               912    return areacode;
907 }                                                 913 }
908                                                   914 
909 //============================================    915 //=====================================================================
910 //* SetCorners() -----------------------------    916 //* SetCorners() ------------------------------------------------------
911                                                   917 
912 void G4TwistTrapAlphaSide::SetCorners()           918 void G4TwistTrapAlphaSide::SetCorners()
913 {                                                 919 {
914                                                   920 
915   // Set Corner points in local coodinate.        921   // Set Corner points in local coodinate.   
916                                                   922 
917   if (fAxis[0] == kYAxis && fAxis[1] == kZAxis    923   if (fAxis[0] == kYAxis && fAxis[1] == kZAxis)
918   {                                               924   {
919                                                   925     
920     G4double x, y, z;                             926     G4double x, y, z;
921                                                   927 
922     // corner of Axis0min and Axis1min            928     // corner of Axis0min and Axis1min
923     //                                            929     //
924     x = -fdeltaX/2. + (fDx1 - fDy1*fTAlph)*std    930     x = -fdeltaX/2. + (fDx1 - fDy1*fTAlph)*std::cos(fPhiTwist/2.)
925       - fDy1*std::sin(fPhiTwist/2.);              931       - fDy1*std::sin(fPhiTwist/2.);
926     y = -fdeltaY/2. - fDy1*std::cos(fPhiTwist/    932     y = -fdeltaY/2. - fDy1*std::cos(fPhiTwist/2.)
927       + (-fDx1 + fDy1*fTAlph)*std::sin(fPhiTwi    933       + (-fDx1 + fDy1*fTAlph)*std::sin(fPhiTwist/2.);
928     z = -fDz ;                                    934     z = -fDz ;
929                                                   935 
930     //    G4cout << "SetCorners: " << x << ",     936     //    G4cout << "SetCorners: " << x << ", " << y << ", " << z << G4endl ;
931                                                   937 
932     SetCorner(sC0Min1Min, x, y, z);               938     SetCorner(sC0Min1Min, x, y, z);
933                                                   939       
934     // corner of Axis0max and Axis1min            940     // corner of Axis0max and Axis1min
935     //                                            941     //
936     x = -fdeltaX/2. + (fDx2 + fDy1*fTAlph)*std    942     x = -fdeltaX/2. + (fDx2 + fDy1*fTAlph)*std::cos(fPhiTwist/2.)
937       + fDy1*std::sin(fPhiTwist/2.);              943       + fDy1*std::sin(fPhiTwist/2.);
938     y = -fdeltaY/2. + fDy1*std::cos(fPhiTwist/    944     y = -fdeltaY/2. + fDy1*std::cos(fPhiTwist/2.)
939       - (fDx2 + fDy1*fTAlph)*std::sin(fPhiTwis    945       - (fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.);
940     z = -fDz ;                                    946     z = -fDz ;
941                                                   947 
942     //    G4cout << "SetCorners: " << x << ",     948     //    G4cout << "SetCorners: " << x << ", " << y << ", " << z << G4endl ;
943                                                   949 
944     SetCorner(sC0Max1Min, x, y, z);               950     SetCorner(sC0Max1Min, x, y, z);
945                                                   951       
946     // corner of Axis0max and Axis1max            952     // corner of Axis0max and Axis1max
947     //                                            953     //
948     x = fdeltaX/2. + (fDx4 + fDy2*fTAlph)*std:    954     x = fdeltaX/2. + (fDx4 + fDy2*fTAlph)*std::cos(fPhiTwist/2.)
949       - fDy2*std::sin(fPhiTwist/2.);              955       - fDy2*std::sin(fPhiTwist/2.);
950     y = fdeltaY/2. + fDy2*std::cos(fPhiTwist/2    956     y = fdeltaY/2. + fDy2*std::cos(fPhiTwist/2.)
951       + (fDx4 + fDy2*fTAlph)*std::sin(fPhiTwis    957       + (fDx4 + fDy2*fTAlph)*std::sin(fPhiTwist/2.);
952     z = fDz ;                                     958     z = fDz ;
953                                                   959     
954     //    G4cout << "SetCorners: " << x << ",     960     //    G4cout << "SetCorners: " << x << ", " << y << ", " << z << G4endl ;
955                                                   961     
956     SetCorner(sC0Max1Max, x, y, z);               962     SetCorner(sC0Max1Max, x, y, z);
957                                                   963 
958     // corner of Axis0min and Axis1max            964     // corner of Axis0min and Axis1max
959     x = fdeltaX/2. + (fDx3 - fDy2*fTAlph)*std:    965     x = fdeltaX/2. + (fDx3 - fDy2*fTAlph)*std::cos(fPhiTwist/2.)
960       + fDy2*std::sin(fPhiTwist/2.) ;             966       + fDy2*std::sin(fPhiTwist/2.) ;
961     y = fdeltaY/2. - fDy2*std::cos(fPhiTwist/2    967     y = fdeltaY/2. - fDy2*std::cos(fPhiTwist/2.)
962       + (fDx3 - fDy2*fTAlph)*std::sin(fPhiTwis    968       + (fDx3 - fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
963     z = fDz ;                                     969     z = fDz ;
964                                                   970 
965     //    G4cout << "SetCorners: " << x << ",     971     //    G4cout << "SetCorners: " << x << ", " << y << ", " << z << G4endl ;
966                                                   972 
967     SetCorner(sC0Min1Max, x, y, z);               973     SetCorner(sC0Min1Max, x, y, z);
968                                                   974 
969   }                                               975   }
970   else                                            976   else
971   {                                               977   {
972     G4Exception("G4TwistTrapAlphaSide::SetCorn    978     G4Exception("G4TwistTrapAlphaSide::SetCorners()",
973                 "GeomSolids0001", FatalExcepti    979                 "GeomSolids0001", FatalException,
974                 "Method NOT implemented !");      980                 "Method NOT implemented !");
975   }                                               981   }
976 }                                                 982 }
977                                                   983 
978 //============================================    984 //=====================================================================
979 //* SetBoundaries() --------------------------    985 //* SetBoundaries() ---------------------------------------------------
980                                                   986 
981 void G4TwistTrapAlphaSide::SetBoundaries()        987 void G4TwistTrapAlphaSide::SetBoundaries()
982 {                                                 988 {
983    // Set direction-unit vector of boundary-li    989    // Set direction-unit vector of boundary-lines in local coodinate. 
984    //                                             990    //   
985                                                   991 
986   G4ThreeVector direction;                        992   G4ThreeVector direction;
987                                                   993    
988   if (fAxis[0] == kYAxis && fAxis[1] == kZAxis    994   if (fAxis[0] == kYAxis && fAxis[1] == kZAxis)
989   {                                               995   {     
990     // sAxis0 & sAxisMin                          996     // sAxis0 & sAxisMin
991     direction = GetCorner(sC0Min1Max) - GetCor    997     direction = GetCorner(sC0Min1Max) - GetCorner(sC0Min1Min);
992     direction = direction.unit();                 998     direction = direction.unit();
993     SetBoundary(sAxis0 & (sAxisY | sAxisMin),     999     SetBoundary(sAxis0 & (sAxisY | sAxisMin), direction, 
994                 GetCorner(sC0Min1Min), sAxisZ)    1000                 GetCorner(sC0Min1Min), sAxisZ) ;
995                                                   1001       
996       // sAxis0 & sAxisMax                        1002       // sAxis0 & sAxisMax
997     direction = GetCorner(sC0Max1Max) - GetCor    1003     direction = GetCorner(sC0Max1Max) - GetCorner(sC0Max1Min);
998     direction = direction.unit();                 1004     direction = direction.unit();
999     SetBoundary(sAxis0 & (sAxisY | sAxisMax),     1005     SetBoundary(sAxis0 & (sAxisY | sAxisMax), direction, 
1000                 GetCorner(sC0Max1Min), sAxisZ    1006                 GetCorner(sC0Max1Min), sAxisZ);
1001                                                  1007     
1002     // sAxis1 & sAxisMin                         1008     // sAxis1 & sAxisMin
1003     direction = GetCorner(sC0Max1Min) - GetCo    1009     direction = GetCorner(sC0Max1Min) - GetCorner(sC0Min1Min);
1004     direction = direction.unit();                1010     direction = direction.unit();
1005     SetBoundary(sAxis1 & (sAxisZ | sAxisMin),    1011     SetBoundary(sAxis1 & (sAxisZ | sAxisMin), direction, 
1006                 GetCorner(sC0Min1Min), sAxisY    1012                 GetCorner(sC0Min1Min), sAxisY);
1007                                                  1013     
1008     // sAxis1 & sAxisMax                         1014     // sAxis1 & sAxisMax
1009     direction = GetCorner(sC0Max1Max) - GetCo    1015     direction = GetCorner(sC0Max1Max) - GetCorner(sC0Min1Max);
1010     direction = direction.unit();                1016     direction = direction.unit();
1011     SetBoundary(sAxis1 & (sAxisZ | sAxisMax),    1017     SetBoundary(sAxis1 & (sAxisZ | sAxisMax), direction, 
1012                 GetCorner(sC0Min1Max), sAxisY    1018                 GetCorner(sC0Min1Max), sAxisY);
1013                                                  1019     
1014   }                                              1020   }
1015   else                                           1021   else
1016   {                                              1022   {
1017     G4Exception("G4TwistTrapAlphaSide::SetCor    1023     G4Exception("G4TwistTrapAlphaSide::SetCorners()",
1018                 "GeomSolids0001", FatalExcept    1024                 "GeomSolids0001", FatalException,
1019                 "Feature NOT implemented !");    1025                 "Feature NOT implemented !");
1020   }                                              1026   }
1021 }                                                1027 }
1022                                                  1028 
1023 //===========================================    1029 //=====================================================================
1024 //* GetPhiUAtX ------------------------------    1030 //* GetPhiUAtX --------------------------------------------------------
1025                                                  1031 
1026 void                                             1032 void
1027 G4TwistTrapAlphaSide::GetPhiUAtX( const G4Thr << 1033 G4TwistTrapAlphaSide::GetPhiUAtX( G4ThreeVector p, G4double& phi, G4double& u ) 
1028 {                                                1034 {
1029   // find closest point XX on surface for a g    1035   // find closest point XX on surface for a given point p
1030   // X0 is a point on the surface,  d is the     1036   // X0 is a point on the surface,  d is the direction
1031   // ( both for a fixed z = pz)                  1037   // ( both for a fixed z = pz)
1032                                                  1038   
1033   // phi is given by the z coordinate of p       1039   // phi is given by the z coordinate of p
1034                                                  1040 
1035   phi =  p.z()/(2*fDz)*fPhiTwist ;               1041   phi =  p.z()/(2*fDz)*fPhiTwist ;
1036   u = (fPhiTwist*(2*fDx1*fDx1 - 2*fDx2*fDx2 -    1042   u = (fPhiTwist*(2*fDx1*fDx1 - 2*fDx2*fDx2 - fa1md1*(fDx3 + fDx4)
1037              - 4*(fDx3plus1 + fDx4plus2)*fDy1    1043              - 4*(fDx3plus1 + fDx4plus2)*fDy1*fTAlph)
1038              - 2*(2*fDx1*fDx1 - 2*fDx2*fDx2 +    1044              - 2*(2*fDx1*fDx1 - 2*fDx2*fDx2 + fa1md1*(fDx3 + fDx4)
1039                 + 4*(fDx3minus1 + fDx4minus2)    1045                 + 4*(fDx3minus1 + fDx4minus2)*fDy1*fTAlph)*phi
1040              - 4*(fa1md1*(fdeltaX*phi - fPhiT    1046              - 4*(fa1md1*(fdeltaX*phi - fPhiTwist*p.x())
1041              + 4*fDy1*(fdeltaY*phi + fdeltaX*    1047              + 4*fDy1*(fdeltaY*phi + fdeltaX*fTAlph*phi
1042                      - fPhiTwist*(fTAlph*p.x(    1048                      - fPhiTwist*(fTAlph*p.x() + p.y())))*std::cos(phi)
1043              - 4*(fa1md1*fdeltaY*phi - 4*fdel    1049              - 4*(fa1md1*fdeltaY*phi - 4*fdeltaX*fDy1*phi
1044                 + 4*fdeltaY*fDy1*fTAlph*phi +    1050                 + 4*fdeltaY*fDy1*fTAlph*phi + 4*fDy1*fPhiTwist*p.x()
1045                 - fPhiTwist*(fa1md1 + 4*fDy1*    1051                 - fPhiTwist*(fa1md1 + 4*fDy1*fTAlph)*p.y())*std::sin(phi))
1046        /(fDy1* fPhiTwist*((std::fabs(((fa1md1    1052        /(fDy1* fPhiTwist*((std::fabs(((fa1md1 + 4*fDy1*fTAlph)*std::cos(phi))
1047                           /fDy1 - 4*std::sin(    1053                           /fDy1 - 4*std::sin(phi)))
1048                         *(std::fabs(((fa1md1     1054                         *(std::fabs(((fa1md1 + 4*fDy1*fTAlph)*std::cos(phi))
1049                           /fDy1 - 4*std::sin(    1055                           /fDy1 - 4*std::sin(phi)))
1050              + (std::fabs(4*std::cos(phi)        1056              + (std::fabs(4*std::cos(phi)
1051                 + ((fa1md1 + 4*fDy1*fTAlph)*s    1057                 + ((fa1md1 + 4*fDy1*fTAlph)*std::sin(phi))/fDy1))
1052              * (std::fabs(4*std::cos(phi)        1058              * (std::fabs(4*std::cos(phi)
1053                 + ((fa1md1 + 4*fDy1*fTAlph)*s    1059                 + ((fa1md1 + 4*fDy1*fTAlph)*std::sin(phi))/fDy1)))) ;
1054 }                                                1060 }
1055                                                  1061 
1056 //===========================================    1062 //=====================================================================
1057 //* ProjectPoint ----------------------------    1063 //* ProjectPoint ------------------------------------------------------
1058                                                  1064 
1059 G4ThreeVector                                    1065 G4ThreeVector
1060 G4TwistTrapAlphaSide::ProjectPoint(const G4Th    1066 G4TwistTrapAlphaSide::ProjectPoint(const G4ThreeVector& p, G4bool isglobal) 
1061 {                                                1067 {
1062   // Get Rho at p.z() on Hyperbolic Surface.     1068   // Get Rho at p.z() on Hyperbolic Surface.
1063                                                  1069 
1064   G4ThreeVector tmpp;                            1070   G4ThreeVector tmpp;
1065   if (isglobal)                                  1071   if (isglobal)
1066   {                                              1072   {
1067      tmpp = fRot.inverse()*p - fTrans;           1073      tmpp = fRot.inverse()*p - fTrans;
1068   }                                              1074   }
1069   else                                           1075   else
1070   {                                              1076   {
1071      tmpp = p;                                   1077      tmpp = p;
1072   }                                              1078   }
1073                                                  1079 
1074   G4double phi ;                                 1080   G4double phi ;
1075   G4double u ;                                   1081   G4double u ;
1076                                                  1082 
1077   GetPhiUAtX( tmpp, phi, u ) ;                   1083   GetPhiUAtX( tmpp, phi, u ) ;
1078     // calculate (phi, u) for a point p close    1084     // calculate (phi, u) for a point p close the surface
1079                                                  1085   
1080   G4ThreeVector xx = SurfacePoint(phi,u) ;       1086   G4ThreeVector xx = SurfacePoint(phi,u) ;
1081     // transform back to cartesian coordinate    1087     // transform back to cartesian coordinates
1082                                                  1088 
1083   if (isglobal)                                  1089   if (isglobal)
1084   {                                              1090   {
1085      return (fRot * xx + fTrans);                1091      return (fRot * xx + fTrans);
1086   }                                              1092   }
1087   else                                           1093   else
1088   {                                              1094   {
1089      return xx;                                  1095      return xx;
1090   }                                              1096   }
1091 }                                                1097 }
1092                                                  1098 
1093 //===========================================    1099 //=====================================================================
1094 //* GetFacets -------------------------------    1100 //* GetFacets ---------------------------------------------------------
1095                                                  1101 
1096 void                                             1102 void
1097 G4TwistTrapAlphaSide::GetFacets( G4int k, G4i    1103 G4TwistTrapAlphaSide::GetFacets( G4int k, G4int n, G4double xyz[][3],
1098                                  G4int faces[    1104                                  G4int faces[][4], G4int iside ) 
1099 {                                                1105 {
1100                                                  1106 
1101   G4double phi ;                                 1107   G4double phi ;
1102   G4double b ;                                   1108   G4double b ;   
1103                                                  1109 
1104   G4double z, u ;     // the two parameters f    1110   G4double z, u ;     // the two parameters for the surface equation
1105   G4ThreeVector p ;  // a point on the surfac    1111   G4ThreeVector p ;  // a point on the surface, given by (z,u)
1106                                                  1112 
1107   G4int nnode ;                                  1113   G4int nnode ;
1108   G4int nface ;                                  1114   G4int nface ;
1109                                                  1115 
1110   // calculate the (n-1)*(k-1) vertices          1116   // calculate the (n-1)*(k-1) vertices
1111                                                  1117 
1112   for ( G4int i = 0 ; i<n ; ++i )                1118   for ( G4int i = 0 ; i<n ; ++i )
1113   {                                              1119   {
1114     z = -fDz+i*(2.*fDz)/(n-1) ;                  1120     z = -fDz+i*(2.*fDz)/(n-1) ;
1115     phi = z*fPhiTwist/(2*fDz) ;                  1121     phi = z*fPhiTwist/(2*fDz) ;
1116     b = GetValueB(phi) ;                         1122     b = GetValueB(phi) ;
1117                                                  1123 
1118     for ( G4int j = 0 ; j<k ; ++j )              1124     for ( G4int j = 0 ; j<k ; ++j )
1119     {                                            1125     {
1120       nnode = GetNode(i,j,k,n,iside) ;           1126       nnode = GetNode(i,j,k,n,iside) ;
1121       u = -b/2 +j*b/(k-1) ;                      1127       u = -b/2 +j*b/(k-1) ;
1122       p = SurfacePoint(phi,u,true) ;  // surf    1128       p = SurfacePoint(phi,u,true) ;  // surface point in global coordinates
1123                                                  1129 
1124       xyz[nnode][0] = p.x() ;                    1130       xyz[nnode][0] = p.x() ;
1125       xyz[nnode][1] = p.y() ;                    1131       xyz[nnode][1] = p.y() ;
1126       xyz[nnode][2] = p.z() ;                    1132       xyz[nnode][2] = p.z() ;
1127                                                  1133 
1128       if ( i<n-1 && j<k-1 )  // conterclock w    1134       if ( i<n-1 && j<k-1 )  // conterclock wise filling 
1129       {                                          1135       {
1130         nface = GetFace(i,j,k,n,iside) ;         1136         nface = GetFace(i,j,k,n,iside) ;
1131         faces[nface][0] = GetEdgeVisibility(i    1137         faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,-1)
1132                         * (GetNode(i  ,j  ,k,    1138                         * (GetNode(i  ,j  ,k,n,iside)+1) ;  // f77 numbering
1133         faces[nface][1] = GetEdgeVisibility(i    1139         faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,-1)
1134                         * (GetNode(i  ,j+1,k,    1140                         * (GetNode(i  ,j+1,k,n,iside)+1) ;
1135         faces[nface][2] = GetEdgeVisibility(i    1141         faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,-1)
1136                         * (GetNode(i+1,j+1,k,    1142                         * (GetNode(i+1,j+1,k,n,iside)+1) ;
1137         faces[nface][3] = GetEdgeVisibility(i    1143         faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,-1)
1138                         * (GetNode(i+1,j  ,k,    1144                         * (GetNode(i+1,j  ,k,n,iside)+1) ;
1139       }                                          1145       }
1140     }                                            1146     }
1141   }                                              1147   }
1142 }                                                1148 }
1143                                                  1149