Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/solids/specific/src/G4TwistTubsHypeSide.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/G4TwistTubsHypeSide.cc (Version 11.3.0) and /geometry/solids/specific/src/G4TwistTubsHypeSide.cc (Version 5.2.p1)


  1 //                                                  1 
  2 // *******************************************    
  3 // * License and Disclaimer                       
  4 // *                                              
  5 // * The  Geant4 software  is  copyright of th    
  6 // * the Geant4 Collaboration.  It is provided    
  7 // * conditions of the Geant4 Software License    
  8 // * LICENSE and available at  http://cern.ch/    
  9 // * include a list of copyright holders.         
 10 // *                                              
 11 // * Neither the authors of this software syst    
 12 // * institutes,nor the agencies providing fin    
 13 // * work  make  any representation or  warran    
 14 // * regarding  this  software system or assum    
 15 // * use.  Please see the license in the file     
 16 // * for the full disclaimer and the limitatio    
 17 // *                                              
 18 // * This  code  implementation is the result     
 19 // * technical work of the GEANT4 collaboratio    
 20 // * By using,  copying,  modifying or  distri    
 21 // * any work based  on the software)  you  ag    
 22 // * use  in  resulting  scientific  publicati    
 23 // * acceptance of all terms of the Geant4 Sof    
 24 // *******************************************    
 25 //                                                
 26 // G4TwistTubsHypeSide implementation             
 27 //                                                
 28 // 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepbu    
 29 // 13-Nov-2003 - O.Link (Oliver.Link@cern.ch),    
 30 //               from original version in Jupi    
 31 // -------------------------------------------    
 32                                                   
 33 #include "G4TwistTubsHypeSide.hh"                 
 34 #include "G4PhysicalConstants.hh"                 
 35 #include "G4GeometryTolerance.hh"                 
 36                                                   
 37 //============================================    
 38 //* constructors -----------------------------    
 39                                                   
 40 G4TwistTubsHypeSide::G4TwistTubsHypeSide(const    
 41                                          const    
 42                                          const    
 43                                          const    
 44                                          const    
 45                                          const    
 46                                          const    
 47                                          const    
 48                                          const    
 49                                                   
 50                                                   
 51                                                   
 52                                                   
 53   : G4VTwistSurface(name, rot, tlate, handedne    
 54                     axis0min, axis1min, axis0m    
 55     fKappa(kappa), fTanStereo(tanstereo),         
 56     fTan2Stereo(tanstereo*tanstereo), fR0(r0),    
 57 {                                                 
 58    if ( (axis0 == kZAxis) && (axis1 == kPhi) )    
 59    {                                              
 60       G4Exception("G4TwistTubsHypeSide::G4Twis    
 61                   "GeomSolids0002", FatalError    
 62                   "Should swap axis0 and axis1    
 63    }                                              
 64    fInside.gp.set(kInfinity, kInfinity, kInfin    
 65    fInside.inside = kOutside;                     
 66    fIsValidNorm = false;                          
 67    SetCorners();                                  
 68    SetBoundaries();                               
 69 }                                                 
 70                                                   
 71 G4TwistTubsHypeSide::G4TwistTubsHypeSide(const    
 72                                                   
 73                                                   
 74                                                   
 75                                                   
 76                                                   
 77                                                   
 78                                                   
 79                                                   
 80                                                   
 81                                                   
 82                                                   
 83    : G4VTwistSurface(name)                        
 84 {                                                 
 85                                                   
 86    fHandedness = handedness;   // +z = +ve, -z    
 87    fAxis[0]    = kPhi;                            
 88    fAxis[1]    = kZAxis;                          
 89    fAxisMin[0] = kInfinity;         // we cann    
 90    fAxisMax[0] = kInfinity;         // because    
 91    fAxisMin[1] = EndZ[0];                         
 92    fAxisMax[1] = EndZ[1];                         
 93    fKappa      = Kappa;                           
 94    fDPhi       = DPhi ;                           
 95                                                   
 96    if (handedness < 0)  // inner hyperbolic su    
 97    {                                              
 98       fTanStereo  = TanInnerStereo;               
 99       fR0         = InnerRadius;                  
100    }                                              
101    else                 // outer hyperbolic su    
102    {                                              
103       fTanStereo  = TanOuterStereo;               
104       fR0         = OuterRadius;                  
105    }                                              
106    fTan2Stereo = fTanStereo * fTanStereo;         
107    fR02        = fR0 * fR0;                       
108                                                   
109    fTrans.set(0, 0, 0);                           
110    fIsValidNorm = false;                          
111                                                   
112    fInside.gp.set(kInfinity, kInfinity, kInfin    
113    fInside.inside = kOutside;                     
114                                                   
115    SetCorners(EndInnerRadius, EndOuterRadius,     
116                                                   
117    SetBoundaries();                               
118 }                                                 
119                                                   
120 //============================================    
121 //* Fake default constructor -----------------    
122                                                   
123 G4TwistTubsHypeSide::G4TwistTubsHypeSide( __vo    
124   : G4VTwistSurface(a)                            
125 {                                                 
126 }                                                 
127                                                   
128 //============================================    
129 //* destructor -------------------------------    
130                                                   
131 G4TwistTubsHypeSide::~G4TwistTubsHypeSide() =     
132                                                   
133 //============================================    
134 //* GetNormal --------------------------------    
135                                                   
136 G4ThreeVector G4TwistTubsHypeSide::GetNormal(c    
137                                                   
138 {                                                 
139    // GetNormal returns a normal vector at a s    
140    // to surface) point at tmpxx.                 
141    // If isGlobal=true, it returns the normal     
142                                                   
143    G4ThreeVector xx;                              
144    if (isGlobal)                                  
145    {                                              
146       xx = ComputeLocalPoint(tmpxx);              
147       if ((xx - fCurrentNormal.p).mag() < 0.5     
148       {                                           
149          return ComputeGlobalDirection(fCurren    
150       }                                           
151    }                                              
152    else                                           
153    {                                              
154       xx = tmpxx;                                 
155       if (xx == fCurrentNormal.p)                 
156       {                                           
157          return fCurrentNormal.normal;            
158       }                                           
159    }                                              
160                                                   
161    fCurrentNormal.p = xx;                         
162                                                   
163    G4ThreeVector normal( xx.x(), xx.y(), -xx.z    
164    normal *= fHandedness;                         
165    normal = normal.unit();                        
166                                                   
167    if (isGlobal)                                  
168    {                                              
169       fCurrentNormal.normal = ComputeLocalDire    
170    }                                              
171    else                                           
172    {                                              
173       fCurrentNormal.normal = normal;             
174    }                                              
175    return fCurrentNormal.normal;                  
176 }                                                 
177                                                   
178 //============================================    
179 //* Inside() ---------------------------------    
180                                                   
181 EInside G4TwistTubsHypeSide::Inside(const G4Th    
182 {                                                 
183    // Inside returns                              
184    const G4double halftol                         
185      = 0.5 * G4GeometryTolerance::GetInstance(    
186                                                   
187    if (fInside.gp == gp)                          
188    {                                              
189       return fInside.inside;                      
190    }                                              
191    fInside.gp = gp;                               
192                                                   
193    G4ThreeVector p = ComputeLocalPoint(gp);       
194                                                   
195                                                   
196    if (p.mag() < DBL_MIN)                         
197    {                                              
198       fInside.inside = kOutside;                  
199       return fInside.inside;                      
200    }                                              
201                                                   
202    G4double rhohype = GetRhoAtPZ(p);              
203    G4double distanceToOut = fHandedness * (rho    
204                             // +ve : inside       
205                                                   
206    if (distanceToOut < -halftol)                  
207    {                                              
208      fInside.inside = kOutside;                   
209    }                                              
210    else                                           
211    {                                              
212       G4int areacode = GetAreaCode(p);            
213       if (IsOutside(areacode))                    
214       {                                           
215          fInside.inside = kOutside;               
216       }                                           
217       else if (IsBoundary(areacode))              
218       {                                           
219          fInside.inside = kSurface;               
220       }                                           
221       else if (IsInside(areacode))                
222       {                                           
223          if (distanceToOut <= halftol)            
224          {                                        
225             fInside.inside = kSurface;            
226          }                                        
227          else                                     
228          {                                        
229             fInside.inside = kInside;             
230          }                                        
231       }                                           
232       else                                        
233       {                                           
234          G4cout << "WARNING - G4TwistTubsHypeS    
235                 << "          Invalid option !    
236                 << "          name, areacode,     
237                 << GetName() << ", " << std::h    
238                 << std::dec << ", " << distanc    
239       }                                           
240    }                                              
241                                                   
242    return fInside.inside;                         
243 }                                                 
244                                                   
245 //============================================    
246 //* DistanceToSurface ------------------------    
247                                                   
248 G4int G4TwistTubsHypeSide::DistanceToSurface(c    
249                                              c    
250                                                   
251                                                   
252                                                   
253                                                   
254                                                   
255 {                                                 
256    // Decide if and where a line intersects wi    
257    // surface (of infinite extent)                
258    //                                             
259    // Arguments:                                  
260    //     p       - (in) Point on trajectory      
261    //     v       - (in) Vector along trajecto    
262    //     r2      - (in) Square of radius at z    
263    //     tan2phi - (in) std::tan(stereo)**2      
264    //     s       - (out) Up to two points of     
265    //                     intersection point i    
266    //                     two intersections, s    
267    // Returns:                                    
268    //     The number of intersections. If 0, t    
269    //                                             
270    //                                             
271    // Equation of a line:                         
272    //                                             
273    //       x = x0 + s*tx      y = y0 + s*ty      
274    //                                             
275    // Equation of a hyperbolic surface:           
276    //                                             
277    //       x**2 + y**2 = r**2 + (z*tanPhi)**2    
278    //                                             
279    // Solution is quadratic:                      
280    //                                             
281    //  a*s**2 + b*s + c = 0                       
282    //                                             
283    // where:                                      
284    //                                             
285    //  a = tx**2 + ty**2 - (tz*tanPhi)**2         
286    //                                             
287    //  b = 2*( x0*tx + y0*ty - z0*tz*tanPhi**2    
288    //                                             
289    //  c = x0**2 + y0**2 - r**2 - (z0*tanPhi)*    
290    //                                             
291                                                   
292    fCurStatWithV.ResetfDone(validate, &gp, &gv    
293                                                   
294    if (fCurStatWithV.IsDone())                    
295    {                                              
296       for (G4int i=0; i<fCurStatWithV.GetNXX()    
297       {                                           
298          gxx[i] = fCurStatWithV.GetXX(i);         
299          distance[i] = fCurStatWithV.GetDistan    
300          areacode[i] = fCurStatWithV.GetAreaco    
301          isvalid[i]  = fCurStatWithV.IsValid(i    
302       }                                           
303       return fCurStatWithV.GetNXX();              
304    }                                              
305    else   // initialize                           
306    {                                              
307       for (auto i=0; i<2; ++i)                    
308       {                                           
309          distance[i] = kInfinity;                 
310          areacode[i] = sOutside;                  
311          isvalid[i]  = false;                     
312          gxx[i].set(kInfinity, kInfinity, kInf    
313       }                                           
314    }                                              
315                                                   
316    G4ThreeVector p = ComputeLocalPoint(gp);       
317    G4ThreeVector v = ComputeLocalDirection(gv)    
318    G4ThreeVector xx[2];                           
319                                                   
320    //                                             
321    // special case!  p is on origin.              
322    //                                             
323                                                   
324    if (p.mag() == 0)                              
325    {                                              
326       // p is origin.                             
327       // unique solution of 2-dimension questi    
328       // Equations:                               
329       //    r^2 = fR02 + z^2*fTan2Stere0          
330       //    r = beta*z                            
331       //        where                             
332       //        beta = vrho / vz                  
333       // Solution (z value of intersection poi    
334       //    xxz = +- std::sqrt (fR02 / (beta^2    
335       //                                          
336                                                   
337       G4double vz    = v.z();                     
338       G4double absvz = std::fabs(vz);             
339       G4double vrho  = v.getRho();                
340       G4double vslope = vrho/vz;                  
341       G4double vslope2 = vslope * vslope;         
342       if (vrho == 0 || (vrho/absvz) <= (absvz*    
343       {                                           
344          // vz/vrho is bigger than slope of as    
345          distance[0] = kInfinity;                 
346          fCurStatWithV.SetCurrentStatus(0, gxx    
347                                         isvali    
348          return 0;                                
349       }                                           
350                                                   
351       if (vz != 0.0)                              
352       {                                           
353          G4double xxz  = std::sqrt(fR02 / (vsl    
354                         * (vz / std::fabs(vz))    
355          G4double t = xxz / vz;                   
356          xx[0].set(t*v.x(), t*v.y(), xxz);        
357       }                                           
358       else                                        
359       {                                           
360          // p.z = 0 && v.z =0                     
361          xx[0].set(v.x()*fR0, v.y()*fR0, 0);      
362       }                                           
363       distance[0] = xx[0].mag();                  
364       gxx[0]      = ComputeGlobalPoint(xx[0]);    
365                                                   
366       if (validate == kValidateWithTol)           
367       {                                           
368          areacode[0] = GetAreaCode(xx[0]);        
369          if (!IsOutside(areacode[0]))             
370          {                                        
371             if (distance[0] >= 0) isvalid[0] =    
372          }                                        
373       }                                           
374       else if (validate == kValidateWithoutTol    
375       {                                           
376          areacode[0] = GetAreaCode(xx[0], fals    
377          if (IsInside(areacode[0]))               
378          {                                        
379             if (distance[0] >= 0) isvalid[0] =    
380          }                                        
381       }                                           
382       else  // kDontValidate                      
383       {                                           
384          areacode[0] = sInside;                   
385             if (distance[0] >= 0) isvalid[0] =    
386       }                                           
387                                                   
388       fCurStatWithV.SetCurrentStatus(0, gxx[0]    
389                                      isvalid[0    
390       return 1;                                   
391    }                                              
392                                                   
393    //                                             
394    // special case end.                           
395    //                                             
396                                                   
397    G4double a = v.x()*v.x() + v.y()*v.y() - v.    
398    G4double b = 2.0                               
399               * ( p.x() * v.x() + p.y() * v.y(    
400    G4double c = p.x()*p.x() + p.y()*p.y() - fR    
401    G4double D = b*b - 4*a*c;          //discri    
402    G4int vout = 0;                                
403                                                   
404    if (std::fabs(a) < DBL_MIN)                    
405    {                                              
406       if (std::fabs(b) > DBL_MIN)            /    
407       {                                           
408          distance[0] = -c/b;                      
409          xx[0] = p + distance[0]*v;               
410          gxx[0] = ComputeGlobalPoint(xx[0]);      
411                                                   
412          if (validate == kValidateWithTol)        
413          {                                        
414             areacode[0] = GetAreaCode(xx[0]);     
415             if (!IsOutside(areacode[0]))          
416             {                                     
417                if (distance[0] >= 0) isvalid[0    
418             }                                     
419          }                                        
420          else if (validate == kValidateWithout    
421          {                                        
422             areacode[0] = GetAreaCode(xx[0], f    
423             if (IsInside(areacode[0]))            
424             {                                     
425                if (distance[0] >= 0) isvalid[0    
426             }                                     
427          }                                        
428          else  // kDontValidate                   
429          {                                        
430             areacode[0] = sInside;                
431                if (distance[0] >= 0) isvalid[0    
432          }                                        
433                                                   
434          fCurStatWithV.SetCurrentStatus(0, gxx    
435                                         isvali    
436          vout = 1;                                
437       }                                           
438       else                                        
439       {                                           
440         // if a=b=0 and c != 0, p is origin an    
441         // if a=b=c=0, p is on surface and v i    
442         // return distance = infinity             
443                                                   
444          fCurStatWithV.SetCurrentStatus(0, gxx    
445                                         isvali    
446          vout = 0;                                
447       }                                           
448    }                                              
449    else if (D > DBL_MIN)          // double so    
450    {                                              
451       D = std::sqrt(D);                           
452       G4double      factor = 0.5/a;               
453       G4double      tmpdist[2] = {kInfinity, k    
454       G4ThreeVector tmpxx[2] ;                    
455       G4int         tmpareacode[2] = {sOutside    
456       G4bool        tmpisvalid[2]  = {false, f    
457                                                   
458       for (auto i=0; i<2; ++i)                    
459       {                                           
460          tmpdist[i] = factor*(-b - D);            
461          D = -D;                                  
462          tmpxx[i] = p + tmpdist[i]*v;             
463                                                   
464          if (validate == kValidateWithTol)        
465          {                                        
466             tmpareacode[i] = GetAreaCode(tmpxx    
467             if (!IsOutside(tmpareacode[i]))       
468             {                                     
469                if (tmpdist[i] >= 0) tmpisvalid    
470                continue;                          
471             }                                     
472          }                                        
473          else if (validate == kValidateWithout    
474          {                                        
475             tmpareacode[i] = GetAreaCode(tmpxx    
476             if (IsInside(tmpareacode[i]))         
477             {                                     
478                if (tmpdist[i] >= 0) tmpisvalid    
479                continue;                          
480             }                                     
481          }                                        
482          else  // kDontValidate                   
483          {                                        
484             tmpareacode[i] = sInside;             
485                if (tmpdist[i] >= 0) tmpisvalid    
486             continue;                             
487          }                                        
488       }                                           
489                                                   
490       if (tmpdist[0] <= tmpdist[1])               
491       {                                           
492           distance[0] = tmpdist[0];               
493           distance[1] = tmpdist[1];               
494           xx[0]       = tmpxx[0];                 
495           xx[1]       = tmpxx[1];                 
496           gxx[0]      = ComputeGlobalPoint(tmp    
497           gxx[1]      = ComputeGlobalPoint(tmp    
498           areacode[0] = tmpareacode[0];           
499           areacode[1] = tmpareacode[1];           
500           isvalid[0]  = tmpisvalid[0];            
501           isvalid[1]  = tmpisvalid[1];            
502       }                                           
503       else                                        
504       {                                           
505           distance[0] = tmpdist[1];               
506           distance[1] = tmpdist[0];               
507           xx[0]       = tmpxx[1];                 
508           xx[1]       = tmpxx[0];                 
509           gxx[0]      = ComputeGlobalPoint(tmp    
510           gxx[1]      = ComputeGlobalPoint(tmp    
511           areacode[0] = tmpareacode[1];           
512           areacode[1] = tmpareacode[0];           
513           isvalid[0]  = tmpisvalid[1];            
514           isvalid[1]  = tmpisvalid[0];            
515       }                                           
516                                                   
517       fCurStatWithV.SetCurrentStatus(0, gxx[0]    
518                                      isvalid[0    
519       fCurStatWithV.SetCurrentStatus(1, gxx[1]    
520                                      isvalid[1    
521       vout = 2;                                   
522    }                                              
523    else                                           
524    {                                              
525       // if D<0, no solution                      
526       // if D=0, just grazing the surfaces, re    
527                                                   
528       fCurStatWithV.SetCurrentStatus(0, gxx[0]    
529                                      isvalid[0    
530       vout = 0;                                   
531    }                                              
532    return vout;                                   
533 }                                                 
534                                                   
535 //============================================    
536 //* DistanceToSurface ------------------------    
537                                                   
538 G4int G4TwistTubsHypeSide::DistanceToSurface(c    
539                                                   
540                                                   
541                                                   
542 {                                                 
543     // Find the approximate distance of a poin    
544     // The distance must be an underestimate.     
545     // It will also be nice (although not nece    
546     // always finite no matter how close the p    
547     //                                            
548     // We arranged G4Hype::ApproxDistOutside a    
549     // for this function. See these discriptio    
550                                                   
551    const G4double halftol                         
552      = 0.5 * G4GeometryTolerance::GetInstance(    
553                                                   
554    fCurStat.ResetfDone(kDontValidate, &gp);       
555                                                   
556    if (fCurStat.IsDone())                         
557    {                                              
558       for (G4int i=0; i<fCurStat.GetNXX(); ++i    
559       {                                           
560          gxx[i] = fCurStat.GetXX(i);              
561          distance[i] = fCurStat.GetDistance(i)    
562          areacode[i] = fCurStat.GetAreacode(i)    
563       }                                           
564       return fCurStat.GetNXX();                   
565    }                                              
566    else  // initialize                            
567    {                                              
568       for (auto i=0; i<2; ++i)                    
569       {                                           
570          distance[i] = kInfinity;                 
571          areacode[i] = sOutside;                  
572          gxx[i].set(kInfinity, kInfinity, kInf    
573       }                                           
574    }                                              
575                                                   
576                                                   
577    G4ThreeVector p = ComputeLocalPoint(gp);       
578    G4ThreeVector xx;                              
579                                                   
580    //                                             
581    // special case!                               
582    // If p is on surface, return distance = 0     
583    //                                             
584    G4ThreeVector  lastgxx[2];                     
585    for (auto i=0; i<2; ++i)                       
586    {                                              
587       lastgxx[i] = fCurStatWithV.GetXX(i);        
588    }                                              
589                                                   
590    if ((gp - lastgxx[0]).mag() < halftol || (g    
591    {                                              
592       // last winner, or last poststep point i    
593       xx = p;                                     
594       gxx[0] = gp;                                
595       distance[0] = 0;                            
596                                                   
597       G4bool isvalid = true;                      
598       fCurStat.SetCurrentStatus(0, gxx[0], dis    
599                                 isvalid, 1, kD    
600                                                   
601       return 1;                                   
602    }                                              
603    //                                             
604    // special case end                            
605    //                                             
606                                                   
607    G4double prho       = p.getRho();              
608    G4double pz         = std::fabs(p.z());        
609    G4double r1         = std::sqrt(fR02 + pz *    
610                                                   
611    G4ThreeVector pabsz(p.x(), p.y(), pz);         
612                                                   
613    if (prho > r1 + halftol)   // p is outside     
614    {                                              
615       // First point xx1                          
616       G4double t = r1 / prho;                     
617       G4ThreeVector xx1(t * pabsz.x(), t * pab    
618                                                   
619       // Second point xx2                         
620       G4double z2 = (prho * fTanStereo + pz) /    
621       G4double r2 = std::sqrt(fR02 + z2 * z2 *    
622       t = r2 / prho;                              
623       G4ThreeVector xx2(t * pabsz.x(), t * pab    
624                                                   
625       G4double len = (xx2 - xx1).mag();           
626       if (len < DBL_MIN)                          
627       {                                           
628          // xx2 = xx1?? I guess we                
629          // must have really bracketed the nor    
630          distance[0] = (pabsz - xx1).mag();       
631          xx = xx1;                                
632       }                                           
633       else                                        
634       {                                           
635          distance[0] = DistanceToLine(pabsz, x    
636       }                                           
637                                                   
638    }                                              
639    else if (prho < r1 - halftol)  // p is insi    
640    {                                              
641       // First point xx1                          
642       G4double t;                                 
643       G4ThreeVector xx1;                          
644       if (prho < DBL_MIN)                         
645       {                                           
646          xx1.set(r1, 0. , pz);                    
647       }                                           
648       else                                        
649       {                                           
650          t = r1 / prho;                           
651          xx1.set(t * pabsz.x(), t * pabsz.y()     
652       }                                           
653                                                   
654       // dr, dz is tangential vector of Hyparb    
655       // dr = r, dz = z*tan2stereo                
656       G4double dr  = pz * fTan2Stereo;            
657       G4double dz  = r1;                          
658       G4double tanbeta   = dr / dz;               
659       G4double pztanbeta = pz * tanbeta;          
660                                                   
661       // Second point xx2                         
662       // xx2 is intersection between x-axis an    
663       G4double r2 = r1 - pztanbeta;               
664       G4ThreeVector xx2;                          
665       if (prho < DBL_MIN)                         
666       {                                           
667          xx2.set(r2, 0. , 0.);                    
668       }                                           
669       else                                        
670       {                                           
671          t  = r2 / prho;                          
672          xx2.set(t * pabsz.x(), t * pabsz.y()     
673       }                                           
674                                                   
675       G4ThreeVector d = xx2 - xx1;                
676       distance[0] = DistanceToLine(pabsz, xx1,    
677                                                   
678    }                                              
679    else   // p is on Hyperbolic surface.          
680    {                                              
681       distance[0] = 0;                            
682       xx.set(p.x(), p.y(), pz);                   
683    }                                              
684                                                   
685    if (p.z() < 0)                                 
686    {                                              
687       G4ThreeVector tmpxx(xx.x(), xx.y(), -xx.    
688       xx = tmpxx;                                 
689    }                                              
690                                                   
691    gxx[0] = ComputeGlobalPoint(xx);               
692    areacode[0]    = sInside;                      
693    G4bool isvalid = true;                         
694    fCurStat.SetCurrentStatus(0, gxx[0], distan    
695                              isvalid, 1, kDont    
696    return 1;                                      
697 }                                                 
698                                                   
699 //============================================    
700 //* GetAreaCode ------------------------------    
701                                                   
702 G4int G4TwistTubsHypeSide::GetAreaCode(const G    
703                                              G    
704 {                                                 
705    const G4double ctol = 0.5 * kCarTolerance;     
706    G4int areacode = sInside;                      
707                                                   
708    if ((fAxis[0] == kPhi && fAxis[1] == kZAxis    
709    {                                              
710       G4int zaxis   = 1;                          
711                                                   
712       if (withTol)                                
713       {                                           
714          G4bool isoutside      = false;           
715          G4int  phiareacode    = GetAreaCodeIn    
716          G4bool isoutsideinphi = IsOutside(phi    
717                                                   
718          // test boundary of phiaxis              
719                                                   
720          if ((phiareacode & sAxisMin) == sAxis    
721          {                                        
722             areacode |= (sAxis0 & (sAxisPhi |     
723             if (isoutsideinphi) isoutside = tr    
724          }                                        
725          else if ((phiareacode & sAxisMax)  ==    
726          {                                        
727             areacode |= (sAxis0 & (sAxisPhi |     
728             if (isoutsideinphi) isoutside = tr    
729          }                                        
730                                                   
731          // test boundary of zaxis                
732                                                   
733          if (xx.z() < fAxisMin[zaxis] + ctol)     
734          {                                        
735             areacode |= (sAxis1 & (sAxisZ | sA    
736             if   ((areacode & sBoundary) != 0)    
737             else                        areaco    
738                                                   
739             if (xx.z() <= fAxisMin[zaxis] - ct    
740                                                   
741          }                                        
742          else if (xx.z() > fAxisMax[zaxis] - c    
743          {                                        
744             areacode |= (sAxis1 & (sAxisZ | sA    
745             if   ((areacode & sBoundary) != 0)    
746             else                        areaco    
747                                                   
748             if (xx.z() >= fAxisMax[zaxis] + ct    
749          }                                        
750                                                   
751          // if isoutside = true, clear sInside    
752          // if not on boundary, add boundary i    
753                                                   
754          if (isoutside)                           
755          {                                        
756             G4int tmpareacode = areacode & (~s    
757             areacode = tmpareacode;               
758          }                                        
759          else if ((areacode & sBoundary) != sB    
760          {                                        
761             areacode |= (sAxis0 & sAxisPhi) |     
762          }                                        
763                                                   
764          return areacode;                         
765       }                                           
766       else                                        
767       {                                           
768          G4int phiareacode = GetAreaCodeInPhi(    
769                                                   
770          // test boundary of z-axis               
771                                                   
772          if (xx.z() < fAxisMin[zaxis])            
773          {                                        
774             areacode |= (sAxis1 & (sAxisZ | sA    
775                                                   
776          }                                        
777          else if (xx.z() > fAxisMax[zaxis])       
778          {                                        
779             areacode |= (sAxis1 & (sAxisZ | sA    
780          }                                        
781                                                   
782          // boundary of phi-axis                  
783                                                   
784          if (phiareacode == sAxisMin)             
785          {                                        
786             areacode |= (sAxis0 & (sAxisPhi |     
787             if   ((areacode & sBoundary) != 0)    
788             else                        areaco    
789                                                   
790          }                                        
791          else if (phiareacode == sAxisMax)        
792          {                                        
793             areacode |= (sAxis0 & (sAxisPhi |     
794             if   ((areacode & sBoundary) != 0)    
795             else                        areaco    
796          }                                        
797                                                   
798          // if not on boundary, add boundary i    
799                                                   
800          if ((areacode & sBoundary) != sBounda    
801          {                                        
802             areacode |= (sAxis0 & sAxisPhi) |     
803          }                                        
804          return areacode;                         
805       }                                           
806    }                                              
807    else                                           
808    {                                              
809       std::ostringstream message;                 
810       message << "Feature NOT implemented !" <    
811               << "        fAxis[0] = " << fAxi    
812               << "        fAxis[1] = " << fAxi    
813       G4Exception("G4TwistTubsHypeSide::GetAre    
814                   "GeomSolids0001", FatalExcep    
815    }                                              
816    return areacode;                               
817 }                                                 
818                                                   
819 //============================================    
820 //* GetAreaCodeInPhi -------------------------    
821                                                   
822 G4int G4TwistTubsHypeSide::GetAreaCodeInPhi(co    
823                                                   
824 {                                                 
825                                                   
826    G4ThreeVector lowerlimit; // lower phi-boun    
827    G4ThreeVector upperlimit; // upper phi-boun    
828    lowerlimit = GetBoundaryAtPZ(sAxis0 & sAxis    
829    upperlimit = GetBoundaryAtPZ(sAxis0 & sAxis    
830                                                   
831    G4int  areacode  = sInside;                    
832    G4bool isoutside = false;                      
833                                                   
834    if (withTol)                                   
835    {                                              
836       if (AmIOnLeftSide(xx, lowerlimit) >= 0)     
837       {                                           
838          areacode |= (sAxisMin | sBoundary);      
839          if (AmIOnLeftSide(xx, lowerlimit) > 0    
840                                                   
841       }                                           
842       else if (AmIOnLeftSide(xx, upperlimit) <    
843       {                                           
844          areacode |= (sAxisMax | sBoundary);      
845          if (AmIOnLeftSide(xx, upperlimit) < 0    
846       }                                           
847                                                   
848       // if isoutside = true, clear inside bit    
849                                                   
850       if (isoutside)                              
851       {                                           
852          G4int tmpareacode = areacode & (~sIns    
853          areacode = tmpareacode;                  
854       }                                           
855    }                                              
856    else                                           
857    {                                              
858       if (AmIOnLeftSide(xx, lowerlimit, false)    
859       {                                           
860          areacode |= (sAxisMin | sBoundary);      
861       }                                           
862       else if (AmIOnLeftSide(xx, upperlimit, f    
863       {                                           
864          areacode |= (sAxisMax | sBoundary);      
865       }                                           
866    }                                              
867                                                   
868    return areacode;                               
869 }                                                 
870                                                   
871 //============================================    
872 //* SetCorners(EndInnerRadius, EndOuterRadius,    
873                                                   
874 void G4TwistTubsHypeSide::SetCorners( G4double    
875                                       G4double    
876                                       G4double    
877                                       G4double    
878                                       G4double    
879 {                                                 
880    // Set Corner points in local coodinate.       
881                                                   
882    if (fAxis[0] == kPhi && fAxis[1] == kZAxis)    
883                                                   
884       G4double endRad[2];                         
885       G4double halfdphi = 0.5*DPhi;               
886                                                   
887       for (auto i=0; i<2; ++i) // i=0,1 : -ve     
888       {                                           
889         endRad[i] = (fHandedness == 1 ? EndOut    
890       }                                           
891                                                   
892       G4int zmin = 0 ;  // at -ve z               
893       G4int zmax = 1 ;  // at +ve z               
894                                                   
895       G4double x, y, z;                           
896                                                   
897       // corner of Axis0min and Axis1min          
898       x = endRad[zmin]*std::cos(endPhi[zmin] -    
899       y = endRad[zmin]*std::sin(endPhi[zmin] -    
900       z = endZ[zmin];                             
901       SetCorner(sC0Min1Min, x, y, z);             
902                                                   
903       // corner of Axis0max and Axis1min          
904       x = endRad[zmin]*std::cos(endPhi[zmin] +    
905       y = endRad[zmin]*std::sin(endPhi[zmin] +    
906       z = endZ[zmin];                             
907       SetCorner(sC0Max1Min, x, y, z);             
908                                                   
909       // corner of Axis0max and Axis1max          
910       x = endRad[zmax]*std::cos(endPhi[zmax] +    
911       y = endRad[zmax]*std::sin(endPhi[zmax] +    
912       z = endZ[zmax];                             
913       SetCorner(sC0Max1Max, x, y, z);             
914                                                   
915       // corner of Axis0min and Axis1max          
916       x = endRad[zmax]*std::cos(endPhi[zmax] -    
917       y = endRad[zmax]*std::sin(endPhi[zmax] -    
918       z = endZ[zmax];                             
919       SetCorner(sC0Min1Max, x, y, z);             
920                                                   
921    }                                              
922    else                                           
923    {                                              
924       std::ostringstream message;                 
925       message << "Feature NOT implemented !" <    
926               << "        fAxis[0] = " << fAxi    
927               << "        fAxis[1] = " << fAxi    
928       G4Exception("G4TwistTubsHypeSide::SetCor    
929                   "GeomSolids0001", FatalExcep    
930    }                                              
931 }                                                 
932                                                   
933 //============================================    
934 //* SetCorners() -----------------------------    
935                                                   
936 void G4TwistTubsHypeSide::SetCorners()            
937 {                                                 
938    G4Exception("G4TwistTubsHypeSide::SetCorner    
939                "GeomSolids0001", FatalExceptio    
940                "Method NOT implemented !");       
941 }                                                 
942                                                   
943 //============================================    
944 //* SetBoundaries() --------------------------    
945                                                   
946 void G4TwistTubsHypeSide::SetBoundaries()         
947 {                                                 
948    // Set direction-unit vector of phi-boundar    
949    // sAxis0 must be kPhi.                        
950    // This fanction set lower phi-boundary and    
951                                                   
952    if (fAxis[0] == kPhi && fAxis[1] == kZAxis)    
953    {                                              
954       G4ThreeVector direction;                    
955       // sAxis0 & sAxisMin                        
956       direction = GetCorner(sC0Min1Max) - GetC    
957       direction = direction.unit();               
958       SetBoundary(sAxis0 & (sAxisPhi | sAxisMi    
959                    GetCorner(sC0Min1Min), sAxi    
960                                                   
961       // sAxis0 & sAxisMax                        
962       direction = GetCorner(sC0Max1Max) - GetC    
963       direction = direction.unit();               
964       SetBoundary(sAxis0 & (sAxisPhi | sAxisMa    
965                   GetCorner(sC0Max1Min), sAxis    
966                                                   
967       // sAxis1 & sAxisMin                        
968       direction = GetCorner(sC0Max1Min) - GetC    
969       direction = direction.unit();               
970       SetBoundary(sAxis1 & (sAxisZ | sAxisMin)    
971                    GetCorner(sC0Min1Min), sAxi    
972                                                   
973       // sAxis1 & sAxisMax                        
974       direction = GetCorner(sC0Max1Max) - GetC    
975       direction = direction.unit();               
976       SetBoundary(sAxis1 & (sAxisZ | sAxisMax)    
977                   GetCorner(sC0Min1Max), sAxis    
978    }                                              
979    else                                           
980    {                                              
981       std::ostringstream message;                 
982       message << "Feature NOT implemented !" <    
983               << "        fAxis[0] = " << fAxi    
984               << "        fAxis[1] = " << fAxi    
985       G4Exception("G4TwistTubsHypeSide::SetBou    
986                   "GeomSolids0001", FatalExcep    
987    }                                              
988 }                                                 
989                                                   
990 //============================================    
991 //* GetFacets() ------------------------------    
992                                                   
993 void G4TwistTubsHypeSide::GetFacets( G4int k,     
994                                      G4int fac    
995 {                                                 
996   G4double z ;     // the two parameters for t    
997   G4double x,xmin,xmax ;                          
998                                                   
999   G4ThreeVector p ;  // a point on the surface    
1000                                                  
1001   G4int nnode ;                                  
1002   G4int nface ;                                  
1003                                                  
1004   // calculate the (n-1)*(k-1) vertices          
1005                                                  
1006   for ( G4int i = 0 ; i<n ; ++i )                
1007   {                                              
1008     z = fAxisMin[1] + i*(fAxisMax[1]-fAxisMin    
1009                                                  
1010     for ( G4int j = 0 ; j<k ; ++j )              
1011     {                                            
1012       nnode = GetNode(i,j,k,n,iside) ;           
1013                                                  
1014       xmin = GetBoundaryMin(z) ;                 
1015       xmax = GetBoundaryMax(z) ;                 
1016                                                  
1017       if (fHandedness < 0)  // inner hyperbol    
1018       {                                          
1019         x = xmin + j*(xmax-xmin)/(k-1) ;         
1020       }                                          
1021       else                  // outer hyperbol    
1022       {                                          
1023         x = xmax - j*(xmax-xmin)/(k-1) ;         
1024       }                                          
1025                                                  
1026       p = SurfacePoint(x,z,true) ;  // surfac    
1027                                                  
1028       xyz[nnode][0] = p.x() ;                    
1029       xyz[nnode][1] = p.y() ;                    
1030       xyz[nnode][2] = p.z() ;                    
1031                                                  
1032       if ( i<n-1 && j<k-1 )    // clock wise     
1033       {                                          
1034         nface = GetFace(i,j,k,n,iside) ;         
1035   faces[nface][0] = GetEdgeVisibility(i,j,k,n    
1036                         * ( GetNode(i  ,j  ,k    
1037   faces[nface][1] = GetEdgeVisibility(i,j,k,n    
1038                         * ( GetNode(i+1,j  ,k    
1039   faces[nface][2] = GetEdgeVisibility(i,j,k,n    
1040                         * ( GetNode(i+1,j+1,k    
1041   faces[nface][3] = GetEdgeVisibility(i,j,k,n    
1042                         * ( GetNode(i  ,j+1,k    
1043       }                                          
1044     }                                            
1045   }                                              
1046 }                                                
1047