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