G4TwistTrapAlphaSide Class Reference

#include <G4TwistTrapAlphaSide.hh>

Inheritance diagram for G4TwistTrapAlphaSide:

G4VTwistSurface

Public Member Functions

 G4TwistTrapAlphaSide (const G4String &name, G4double PhiTwist, G4double pDz, G4double pTheta, G4double pPhi, G4double pDy1, G4double pDx1, G4double pDx2, G4double pDy2, G4double pDx3, G4double pDx4, G4double pAlph, G4double AngleSide)
virtual ~G4TwistTrapAlphaSide ()
virtual G4ThreeVector GetNormal (const G4ThreeVector &xx, G4bool isGlobal=false)
virtual G4int DistanceToSurface (const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)
virtual G4int DistanceToSurface (const G4ThreeVector &gp, G4ThreeVector gxx[], G4double distance[], G4int areacode[])
 G4TwistTrapAlphaSide (__void__ &)

Detailed Description

Definition at line 51 of file G4TwistTrapAlphaSide.hh.


Constructor & Destructor Documentation

G4TwistTrapAlphaSide::G4TwistTrapAlphaSide ( const G4String name,
G4double  PhiTwist,
G4double  pDz,
G4double  pTheta,
G4double  pPhi,
G4double  pDy1,
G4double  pDx1,
G4double  pDx2,
G4double  pDy2,
G4double  pDx3,
G4double  pDx4,
G4double  pAlph,
G4double  AngleSide 
)

Definition at line 52 of file G4TwistTrapAlphaSide.cc.

References G4VTwistSurface::fAxis, G4VTwistSurface::fAxisMax, G4VTwistSurface::fAxisMin, G4VTwistSurface::fIsValidNorm, G4VTwistSurface::fRot, G4VTwistSurface::fTrans, kYAxis, and kZAxis.

00066   : G4VTwistSurface(name)
00067 {
00068   fAxis[0]    = kYAxis; // in local coordinate system
00069   fAxis[1]    = kZAxis;
00070   fAxisMin[0] = -kInfinity ;  // Y Axis boundary
00071   fAxisMax[0] = kInfinity ;   //   depends on z !!
00072   fAxisMin[1] = -pDz ;      // Z Axis boundary
00073   fAxisMax[1] = pDz ;
00074   
00075   fDx1  = pDx1 ;
00076   fDx2  = pDx2 ;
00077   fDx3  = pDx3 ;
00078   fDx4  = pDx4 ;
00079 
00080   fDy1   = pDy1 ;
00081   fDy2   = pDy2 ;
00082 
00083   fDz   = pDz ;
00084 
00085   fAlph = pAlph  ;
00086   fTAlph = std::tan(fAlph) ;
00087 
00088   fTheta = pTheta ;
00089   fPhi   = pPhi ;
00090 
00091   // precalculate frequently used parameters
00092   fDx4plus2  = fDx4 + fDx2 ;
00093   fDx4minus2 = fDx4 - fDx2 ;
00094   fDx3plus1  = fDx3 + fDx1 ; 
00095   fDx3minus1 = fDx3 - fDx1 ;
00096   fDy2plus1  = fDy2 + fDy1 ;
00097   fDy2minus1 = fDy2 - fDy1 ;
00098 
00099   fa1md1 = 2*fDx2 - 2*fDx1  ; 
00100   fa2md2 = 2*fDx4 - 2*fDx3 ;
00101 
00102   fPhiTwist = PhiTwist ;     // dphi
00103   fAngleSide = AngleSide ;  // 0,90,180,270 deg
00104 
00105   fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi);
00106     // dx in surface equation
00107   fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi);
00108     // dy in surface equation
00109   
00110   fRot.rotateZ( AngleSide ) ; 
00111   
00112   fTrans.set(0, 0, 0);  // No Translation
00113   fIsValidNorm = false;
00114   
00115   SetCorners() ;
00116   SetBoundaries() ;
00117 
00118 }

G4TwistTrapAlphaSide::~G4TwistTrapAlphaSide (  )  [virtual]

Definition at line 137 of file G4TwistTrapAlphaSide.cc.

00138 {
00139 }

G4TwistTrapAlphaSide::G4TwistTrapAlphaSide ( __void__ &   ) 

Definition at line 124 of file G4TwistTrapAlphaSide.cc.

00125   : G4VTwistSurface(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.), 
00126     fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fAlph(0.), fTAlph(0.), fPhiTwist(0.), 
00127     fAngleSide(0.), fDx4plus2(0.), fDx4minus2(0.), fDx3plus1(0.), fDx3minus1(0.), 
00128     fDy2plus1(0.), fDy2minus1(0.), fa1md1(0.), fa2md2(0.), fdeltaX(0.),
00129     fdeltaY(0.)
00130 {
00131 }


Member Function Documentation

G4int G4TwistTrapAlphaSide::DistanceToSurface ( const G4ThreeVector gp,
G4ThreeVector  gxx[],
G4double  distance[],
G4int  areacode[] 
) [virtual]

Implements G4VTwistSurface.

Definition at line 696 of file G4TwistTrapAlphaSide.cc.

References G4VTwistSurface::ComputeGlobalPoint(), G4VTwistSurface::ComputeLocalPoint(), G4VTwistSurface::DistanceToPlane(), G4VTwistSurface::fCurStat, G4cout, G4endl, G4VSURFACENXX, G4VTwistSurface::kCarTolerance, G4VTwistSurface::kDontValidate, and G4VTwistSurface::sOutside.

00700 {  
00701   static const G4double ctol = 0.5 * kCarTolerance;
00702 
00703   fCurStat.ResetfDone(kDontValidate, &gp);
00704 
00705    if (fCurStat.IsDone())
00706    {
00707       for (register int i=0; i<fCurStat.GetNXX(); i++)
00708       {
00709          gxx[i] = fCurStat.GetXX(i);
00710          distance[i] = fCurStat.GetDistance(i);
00711          areacode[i] = fCurStat.GetAreacode(i);
00712       }
00713       return fCurStat.GetNXX();
00714    }
00715    else  // initialize
00716    {
00717       for (register int i=0; i<G4VSURFACENXX; i++)
00718       {
00719          distance[i] = kInfinity;
00720          areacode[i] = sOutside;
00721          gxx[i].set(kInfinity, kInfinity, kInfinity);
00722       }
00723    }
00724 
00725    G4ThreeVector p = ComputeLocalPoint(gp);
00726    G4ThreeVector xx;  // intersection point
00727    G4ThreeVector xxonsurface ; // interpolated intersection point 
00728 
00729    // the surfacenormal at that surface point
00730    //
00731    G4double phiR = 0  ;
00732    G4double uR = 0 ;
00733 
00734    G4ThreeVector surfacenormal ; 
00735    G4double deltaX, uMax ;
00736    G4double halfphi = 0.5*fPhiTwist ;
00737    
00738    for ( register int i = 1 ; i<20 ; i++ )
00739    {
00740      xxonsurface = SurfacePoint(phiR,uR) ;
00741      surfacenormal = NormAng(phiR,uR) ;
00742      distance[0] = DistanceToPlane(p,xxonsurface,surfacenormal,xx); // new XX
00743      deltaX = ( xx - xxonsurface ).mag() ; 
00744 
00745 #ifdef G4TWISTDEBUG
00746      G4cout << "i = " << i << ", distance = " << distance[0]
00747             << ", " << deltaX << G4endl
00748             << "X = " << xx << G4endl ;
00749 #endif
00750 
00751      // the new point xx is accepted and phi/psi replaced
00752      //
00753      GetPhiUAtX(xx, phiR, uR) ;
00754      
00755      if ( deltaX <= ctol ) { break ; }
00756    }
00757 
00758    // check validity of solution ( valid phi,psi ) 
00759 
00760    uMax = GetBoundaryMax(phiR) ;
00761 
00762    if (  phiR > halfphi ) { phiR =  halfphi ; }
00763    if ( phiR < -halfphi ) { phiR = -halfphi ; }
00764    if ( uR > uMax )  { uR = uMax ;  }
00765    if ( uR < -uMax ) { uR = -uMax ; }
00766 
00767    xxonsurface = SurfacePoint(phiR,uR) ;
00768    distance[0] = (  p - xx ).mag() ;
00769    if ( distance[0] <= ctol ) { distance[0] = 0 ; } 
00770 
00771    // end of validity 
00772 
00773 #ifdef G4TWISTDEBUG
00774    G4cout << "refined solution "  << phiR << " , " << uR << " , " << G4endl ;
00775    G4cout << "distance = " << distance[0] << G4endl ;
00776    G4cout << "X = " << xx << G4endl ;
00777 #endif
00778 
00779    G4bool isvalid = true;
00780    gxx[0]      = ComputeGlobalPoint(xx);
00781    
00782 #ifdef G4TWISTDEBUG
00783    G4cout << "intersection Point found: " << gxx[0] << G4endl ;
00784    G4cout << "distance = " << distance[0] << G4endl ;
00785 #endif
00786 
00787    fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
00788                             isvalid, 1, kDontValidate, &gp);
00789    return 1;
00790 }

G4int G4TwistTrapAlphaSide::DistanceToSurface ( const G4ThreeVector gp,
const G4ThreeVector gv,
G4ThreeVector  gxx[],
G4double  distance[],
G4int  areacode[],
G4bool  isvalid[],
EValidate  validate = kValidateWithTol 
) [virtual]

Definition at line 200 of file G4TwistTrapAlphaSide.cc.

References Intersection::areacode, G4VTwistSurface::ComputeGlobalPoint(), G4VTwistSurface::ComputeLocalDirection(), G4VTwistSurface::ComputeLocalPoint(), Intersection::distance, DistanceSort(), G4VTwistSurface::DistanceToPlaneWithV(), EqualIntersection(), FatalException, G4VTwistSurface::fCurStatWithV, G4JTPolynomialSolver::FindRoots(), G4cout, G4endl, G4Exception(), G4VSURFACENXX, G4VTwistSurface::IsInside(), G4VTwistSurface::IsOutside(), Intersection::isvalid, G4VTwistSurface::kCarTolerance, G4VTwistSurface::kValidateWithoutTol, G4VTwistSurface::kValidateWithTol, Intersection::phi, G4INCL::Math::pi, G4VTwistSurface::sOutside, and Intersection::u.

00207 {
00208   static const G4double ctol = 0.5 * kCarTolerance;
00209   static const G4double pihalf = pi/2 ;
00210 
00211   G4bool IsParallel = false ;
00212   G4bool IsConverged =  false ;
00213 
00214   G4int nxx = 0 ;  // number of physical solutions
00215 
00216   fCurStatWithV.ResetfDone(validate, &gp, &gv);
00217 
00218   if (fCurStatWithV.IsDone())
00219   {
00220     for (register int i=0; i<fCurStatWithV.GetNXX(); i++)
00221     {
00222       gxx[i] = fCurStatWithV.GetXX(i);
00223       distance[i] = fCurStatWithV.GetDistance(i);
00224       areacode[i] = fCurStatWithV.GetAreacode(i);
00225       isvalid[i]  = fCurStatWithV.IsValid(i);
00226     }
00227     return fCurStatWithV.GetNXX();
00228   }
00229   else  // initialise
00230   {
00231     for (register int j=0; j<G4VSURFACENXX ; j++)
00232     {
00233       distance[j] = kInfinity;
00234       areacode[j] = sOutside;
00235       isvalid[j]  = false;
00236       gxx[j].set(kInfinity, kInfinity, kInfinity);
00237     }
00238   }
00239 
00240   G4ThreeVector p = ComputeLocalPoint(gp);
00241   G4ThreeVector v = ComputeLocalDirection(gv);
00242   
00243 #ifdef G4TWISTDEBUG
00244   G4cout << "Local point p = " << p << G4endl ;
00245   G4cout << "Local direction v = " << v << G4endl ; 
00246 #endif
00247 
00248   G4double phi,u ;  // parameters
00249 
00250   // temporary variables
00251 
00252   G4double      tmpdist = kInfinity ;
00253   G4ThreeVector tmpxx;
00254   G4int         tmpareacode = sOutside ;
00255   G4bool        tmpisvalid  = false ;
00256 
00257   std::vector<Intersection> xbuf ;
00258   Intersection xbuftmp ;
00259   
00260   // prepare some variables for the intersection finder
00261 
00262   G4double L = 2*fDz ;
00263 
00264   G4double phixz = fPhiTwist * ( p.x() * v.z() - p.z() * v.x() ) ;
00265   G4double phiyz = fPhiTwist * ( p.y() * v.z() - p.z() * v.y() ) ;
00266 
00267 
00268   // special case vz = 0
00269 
00270   if ( v.z() == 0. )
00271  {
00272     if ( std::fabs(p.z()) <= L )   // intersection possible in z
00273     {
00274       phi = p.z() * fPhiTwist / L ;  // phi is determined by the z-position 
00275       u = (fDy1*(4*(-(fdeltaY*phi*v.x()) + fPhiTwist*p.y()*v.x()
00276                     + fdeltaX*phi*v.y() - fPhiTwist*p.x()*v.y())
00277                  + ((fDx3plus1 + fDx4plus2)*fPhiTwist
00278                  +  2*(fDx3minus1 + fDx4minus2)*phi)
00279                      *(v.y()*std::cos(phi) - v.x()*std::sin(phi))))
00280          /(fPhiTwist*(4*fDy1* v.x() - (fa1md1 + 4*fDy1*fTAlph)*v.y())
00281                     *std::cos(phi) + fPhiTwist*(fa1md1*v.x()
00282                        + 4*fDy1*(fTAlph*v.x() + v.y()))*std::sin(phi));
00283       xbuftmp.phi = phi ;
00284       xbuftmp.u = u ;
00285       xbuftmp.areacode = sOutside ;
00286       xbuftmp.distance = kInfinity ;
00287       xbuftmp.isvalid = false ;
00288 
00289       xbuf.push_back(xbuftmp) ;  // store it to xbuf
00290     }
00291     else   // no intersection possible
00292     {
00293       distance[0] = kInfinity;
00294       gxx[0].set(kInfinity,kInfinity,kInfinity);
00295       isvalid[0] = false ;
00296       areacode[0] = sOutside ;
00297       fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0],
00298                                      areacode[0], isvalid[0],
00299                                      0, validate, &gp, &gv);
00300       return 0;
00301     }  // end std::fabs(p.z() <= L 
00302   } // end v.z() == 0
00303   else  // general solution for non-zero vz
00304   {
00305 
00306     G4double c[8],srd[7],si[7] ;  
00307 
00308     c[7] = 57600*
00309       fDy1*(fa1md1*phiyz + 
00310             fDy1*(-4*phixz + 4*fTAlph*phiyz
00311                  + (fDx3plus1 + fDx4plus2)*fPhiTwist*v.z())) ;
00312     c[6] = -57600*
00313       fDy1*(4*fDy1*(phiyz + 2*fDz*v.x() + fTAlph*(phixz - 2*fDz*v.y()))
00314           - 2*fDy1*(2*fdeltaX + fDx3minus1 + fDx4minus2
00315                   - 2*fdeltaY*fTAlph)*v.z()
00316           + fa1md1*(phixz - 2*fDz*v.y() + fdeltaY*v.z()));
00317     c[5] = 4800*
00318       fDy1*(fa1md1*(-5*phiyz - 24*fDz*v.x() + 12*fdeltaX*v.z()) + 
00319             fDy1*(20*phixz - 4*(5*fTAlph*phiyz + 24*fDz*fTAlph*v.x()
00320                    + 24*fDz*v.y()) + (48*fdeltaY + (fDx3plus1 + fDx4plus2)
00321                                     *fPhiTwist + 48*fdeltaX*fTAlph)*v.z()));
00322     c[4] = 4800*
00323       fDy1*(fa1md1*(phixz - 10*fDz*v.y() + 5*fdeltaY*v.z())
00324           + 2*fDy1*(2*phiyz + 20*fDz*v.x()
00325                    + (-10*fdeltaX + fDx3minus1 + fDx4minus2)*v.z()
00326                    + 2*fTAlph*(phixz - 10*fDz*v.y() + 5*fdeltaY*v.z())));
00327     c[3] = -96*
00328       fDy1*(-(fa1md1*(phiyz + 100*fDz*v.x() - 50*fdeltaX*v.z()))
00329           + fDy1*(4*phixz - 400*fDz*v.y()
00330                   + (200*fdeltaY - (fDx3plus1 + fDx4plus2)*fPhiTwist)*v.z()
00331                   - 4*fTAlph*(phiyz + 100*fDz*v.x() - 50*fdeltaX*v.z())));
00332     c[2] = 32*
00333       fDy1*(4*fDy1*(7*fTAlph*phixz + 7*phiyz - 6*fDz*v.x() + 6*fDz*fTAlph*v.y())
00334           + 6*fDy1*(2*fdeltaX+fDx3minus1+fDx4minus2-2*fdeltaY*fTAlph)*v.z()
00335           + fa1md1*(7*phixz + 6*fDz*v.y() - 3*fdeltaY*v.z()));
00336     c[1] = -8*
00337       fDy1*(fa1md1*(-9*phiyz - 56*fDz*v.x() + 28*fdeltaX*v.z())
00338           + 4*fDy1*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.x()
00339                   - 56*fDz*v.y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.z()));
00340     c[0] = 72*
00341       fDy1*(fa1md1*(2*fDz*v.y() - fdeltaY*v.z())
00342           + fDy1*(-8*fDz*v.x() + 8*fDz*fTAlph*v.y()
00343                 + 4*fdeltaX*v.z() - 4*fdeltaY*fTAlph*v.z()));
00344 
00345 #ifdef G4TWISTDEBUG
00346     G4cout << "coef = " << c[0] << " " 
00347            <<  c[1] << " "  
00348            <<  c[2] << " "  
00349            <<  c[3] << " "  
00350            <<  c[4] << " "  
00351            <<  c[5] << " "  
00352            <<  c[6] << " "  
00353            <<  c[7] << G4endl ; 
00354 #endif    
00355 
00356     G4JTPolynomialSolver trapEq ;
00357     G4int num = trapEq.FindRoots(c,7,srd,si);
00358 
00359     for (register int i = 0 ; i<num ; i++ )   // loop over all math solutions
00360     {  
00361       if ( si[i]==0.0 )  // only real solutions
00362       { 
00363 #ifdef G4TWISTDEBUG
00364         G4cout << "Solution " << i << " : " << srd[i] << G4endl ;
00365 #endif
00366         phi = std::fmod(srd[i] , pihalf)  ;
00367         u   = (fDy1*(4*(phiyz + 2*fDz*phi*v.y() - fdeltaY*phi*v.z())
00368                      - ((fDx3plus1 + fDx4plus2)*fPhiTwist
00369                        + 2*(fDx3minus1 + fDx4minus2)*phi)*v.z()*std::sin(phi)))
00370              /(fPhiTwist*v.z()*(4*fDy1*std::cos(phi)
00371                              + (fa1md1 + 4*fDy1*fTAlph)*std::sin(phi)));        
00372         xbuftmp.phi = phi ;
00373         xbuftmp.u = u ;
00374         xbuftmp.areacode = sOutside ;
00375         xbuftmp.distance = kInfinity ;
00376         xbuftmp.isvalid = false ;
00377         
00378         xbuf.push_back(xbuftmp) ;  // store it to xbuf
00379       
00380 #ifdef G4TWISTDEBUG
00381         G4cout << "solution " << i << " = " << phi << " , " << u  << G4endl ;
00382 #endif
00383       }  // end if real solution
00384     }  // end loop i    
00385   }    // end general case
00386 
00387   nxx = xbuf.size() ;  // save the number of  solutions
00388 
00389   G4ThreeVector xxonsurface  ;    // point on surface
00390   G4ThreeVector surfacenormal  ;  // normal vector  
00391   G4double deltaX;  // distance between intersection point and point on surface
00392   G4double theta;   // angle between track and surfacenormal
00393   G4double factor;  // a scaling factor
00394   G4int maxint=30;  // number of iterations
00395 
00396   for ( register size_t k = 0 ; k<xbuf.size() ; k++ )
00397   {
00398 #ifdef G4TWISTDEBUG
00399     G4cout << "Solution " << k << " : " 
00400            << "reconstructed phiR = " << xbuf[k].phi
00401            << ", uR = " << xbuf[k].u << G4endl ; 
00402 #endif
00403     
00404     phi = xbuf[k].phi ;  // get the stored values for phi and u
00405     u = xbuf[k].u ;
00406 
00407     IsConverged = false ;   // no convergence at the beginning
00408     
00409     for ( register int i = 1 ; i<maxint ; i++ )
00410     {
00411       xxonsurface = SurfacePoint(phi,u) ;
00412       surfacenormal = NormAng(phi,u) ;
00413 
00414       tmpdist = DistanceToPlaneWithV(p, v, xxonsurface, surfacenormal, tmpxx); 
00415       deltaX = ( tmpxx - xxonsurface ).mag() ; 
00416       theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
00417       if ( theta < 0.001 )
00418       { 
00419         factor = 50 ;
00420         IsParallel = true ;
00421       }
00422       else
00423       {
00424         factor = 1 ;
00425       }
00426 
00427 #ifdef G4TWISTDEBUG
00428       G4cout << "Step i = " << i << ", distance = " << tmpdist
00429              << ", " << deltaX << G4endl ;
00430       G4cout << "X = " << tmpxx << G4endl ;
00431 #endif
00432       
00433       GetPhiUAtX(tmpxx, phi, u) ;
00434         // the new point xx is accepted and phi/u replaced
00435       
00436 #ifdef G4TWISTDEBUG
00437       G4cout << "approximated phi = " << phi << ", u = " << u << G4endl ; 
00438 #endif
00439       
00440       if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
00441       
00442     }  // end iterative loop (i)
00443     
00444     if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0 ; }
00445 
00446 #ifdef G4TWISTDEBUG
00447     G4cout << "refined solution "  << phi << " , " << u  <<  G4endl ;
00448     G4cout << "distance = " << tmpdist << G4endl ;
00449     G4cout << "local X = " << tmpxx << G4endl ;
00450 #endif
00451     
00452     tmpisvalid = false ;  // init 
00453 
00454     if ( IsConverged )
00455     {
00456       if (validate == kValidateWithTol)
00457       {
00458         tmpareacode = GetAreaCode(tmpxx);
00459         if (!IsOutside(tmpareacode))
00460         {
00461           if (tmpdist >= 0) tmpisvalid = true;
00462         }
00463       }
00464       else if (validate == kValidateWithoutTol)
00465       {
00466         tmpareacode = GetAreaCode(tmpxx, false);
00467         if (IsInside(tmpareacode))
00468         {
00469           if (tmpdist >= 0) { tmpisvalid = true; }
00470         }
00471       }
00472       else  // kDontValidate
00473       {
00474         G4Exception("G4TwistTrapAlphaSide::DistanceToSurface()",
00475                     "GeomSolids0001", FatalException,
00476                     "Feature NOT implemented !");
00477       }
00478     } 
00479     else
00480     {
00481       tmpdist = kInfinity;     // no convergence after 10 steps 
00482       tmpisvalid = false ;     // solution is not vaild
00483     }  
00484 
00485     // store the found values
00486     // 
00487     xbuf[k].xx = tmpxx ;
00488     xbuf[k].distance = tmpdist ;
00489     xbuf[k].areacode = tmpareacode ;
00490     xbuf[k].isvalid = tmpisvalid ;
00491 
00492   }  // end loop over physical solutions (variable k)
00493 
00494   std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;  // sorting
00495 
00496 #ifdef G4TWISTDEBUG
00497   G4cout << G4endl << "list xbuf after sorting : " << G4endl ;
00498   G4cout << G4endl << G4endl ;
00499 #endif
00500 
00501   // erase identical intersection (within kCarTolerance) 
00502   //
00503   xbuf.erase( std::unique(xbuf.begin(), xbuf.end() , EqualIntersection ),
00504               xbuf.end() );
00505 
00506 
00507   // add guesses
00508   //
00509   G4int nxxtmp = xbuf.size() ;
00510 
00511   if ( nxxtmp<2 || IsParallel  )  // positive end
00512   {
00513 
00514 #ifdef G4TWISTDEBUG
00515     G4cout << "add guess at +z/2 .. " << G4endl ;
00516 #endif
00517 
00518     phi = fPhiTwist/2 ;
00519     u   = 0 ;
00520     
00521     xbuftmp.phi = phi ;
00522     xbuftmp.u = u ;
00523     xbuftmp.areacode = sOutside ;
00524     xbuftmp.distance = kInfinity ;
00525     xbuftmp.isvalid = false ;
00526     
00527     xbuf.push_back(xbuftmp) ;  // store it to xbuf
00528 
00529 #ifdef G4TWISTDEBUG
00530     G4cout << "add guess at -z/2 .. " << G4endl ;
00531 #endif
00532 
00533     phi = -fPhiTwist/2 ;
00534     u   = 0 ;
00535     
00536     xbuftmp.phi = phi ;
00537     xbuftmp.u = u ;
00538     xbuftmp.areacode = sOutside ;
00539     xbuftmp.distance = kInfinity ;
00540     xbuftmp.isvalid = false ;
00541     
00542     xbuf.push_back(xbuftmp) ;  // store it to xbuf
00543 
00544     for ( register size_t k = nxxtmp ; k<xbuf.size() ; k++ )
00545     {
00546 
00547 #ifdef G4TWISTDEBUG
00548       G4cout << "Solution " << k << " : " 
00549              << "reconstructed phiR = " << xbuf[k].phi
00550              << ", uR = " << xbuf[k].u << G4endl ; 
00551 #endif
00552       
00553       phi = xbuf[k].phi ;  // get the stored values for phi and u
00554       u   = xbuf[k].u ;
00555 
00556       IsConverged = false ;   // no convergence at the beginning
00557       
00558       for ( register int i = 1 ; i<maxint ; i++ )
00559       {
00560         xxonsurface = SurfacePoint(phi,u) ;
00561         surfacenormal = NormAng(phi,u) ;
00562         tmpdist = DistanceToPlaneWithV(p, v, xxonsurface, surfacenormal, tmpxx);
00563         deltaX = ( tmpxx - xxonsurface ).mag();
00564         theta = std::fabs(std::acos(v*surfacenormal) - pihalf);
00565         if ( theta < 0.001 )
00566         { 
00567           factor = 50 ;    
00568         }
00569         else
00570         {
00571           factor = 1 ;
00572         }
00573         
00574 #ifdef G4TWISTDEBUG
00575         G4cout << "Step i = " << i << ", distance = " << tmpdist
00576                << ", " << deltaX << G4endl
00577                << "X = " << tmpxx << G4endl ;
00578 #endif
00579 
00580         GetPhiUAtX(tmpxx, phi, u) ;
00581           // the new point xx is accepted and phi/u replaced
00582       
00583 #ifdef G4TWISTDEBUG
00584         G4cout << "approximated phi = " << phi << ", u = " << u << G4endl ; 
00585 #endif
00586       
00587         if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
00588       
00589       }  // end iterative loop (i)
00590     
00591       if ( std::fabs(tmpdist)<ctol )  { tmpdist = 0; }
00592 
00593 #ifdef G4TWISTDEBUG
00594       G4cout << "refined solution "  << phi << " , " << u  <<  G4endl ;
00595       G4cout << "distance = " << tmpdist << G4endl ;
00596       G4cout << "local X = " << tmpxx << G4endl ;
00597 #endif
00598 
00599       tmpisvalid = false ;  // init 
00600 
00601       if ( IsConverged )
00602       {
00603         if (validate == kValidateWithTol)
00604         {
00605           tmpareacode = GetAreaCode(tmpxx);
00606           if (!IsOutside(tmpareacode))
00607           {
00608             if (tmpdist >= 0)  { tmpisvalid = true; }
00609           }
00610         }
00611         else if (validate == kValidateWithoutTol)
00612         {
00613           tmpareacode = GetAreaCode(tmpxx, false);
00614           if (IsInside(tmpareacode))
00615           {
00616             if (tmpdist >= 0)  { tmpisvalid = true; }
00617           }
00618         }
00619         else  // kDontValidate
00620         {
00621           G4Exception("G4TwistedBoxSide::DistanceToSurface()",
00622                       "GeomSolids0001", FatalException,
00623                       "Feature NOT implemented !");
00624         }
00625       } 
00626       else
00627       {
00628         tmpdist = kInfinity;     // no convergence after 10 steps 
00629         tmpisvalid = false ;     // solution is not vaild
00630       }  
00631 
00632       // store the found values
00633       //
00634       xbuf[k].xx = tmpxx ;
00635       xbuf[k].distance = tmpdist ;
00636       xbuf[k].areacode = tmpareacode ;
00637       xbuf[k].isvalid = tmpisvalid ;
00638 
00639     }  // end loop over physical solutions 
00640   }  // end less than 2 solutions
00641 
00642   // sort again
00643   std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;  // sorting
00644 
00645   // erase identical intersection (within kCarTolerance) 
00646   xbuf.erase( std::unique(xbuf.begin(), xbuf.end() , EqualIntersection ) ,
00647               xbuf.end() );
00648 
00649 #ifdef G4TWISTDEBUG
00650   G4cout << G4endl << "list xbuf after sorting : " << G4endl ;
00651   G4cout << G4endl << G4endl ;
00652 #endif
00653 
00654   nxx = xbuf.size() ;   // determine number of solutions again.
00655 
00656   for ( register size_t i = 0 ; i<xbuf.size() ; i++ )
00657   {
00658     distance[i] = xbuf[i].distance;
00659     gxx[i]      = ComputeGlobalPoint(xbuf[i].xx);
00660     areacode[i] = xbuf[i].areacode ;
00661     isvalid[i]  = xbuf[i].isvalid ;
00662     
00663     fCurStatWithV.SetCurrentStatus(i, gxx[i], distance[i], areacode[i],
00664                                      isvalid[i], nxx, validate, &gp, &gv);
00665 #ifdef G4TWISTDEBUG
00666     G4cout << "element Nr. " << i 
00667            << ", local Intersection = " << xbuf[i].xx 
00668            << ", distance = " << xbuf[i].distance 
00669            << ", u = " << xbuf[i].u 
00670            << ", phi = " << xbuf[i].phi 
00671            << ", isvalid = " << xbuf[i].isvalid 
00672            << G4endl ;
00673 #endif
00674 
00675   }  // end for( i ) loop
00676 
00677 #ifdef G4TWISTDEBUG
00678   G4cout << "G4TwistTrapAlphaSide finished " << G4endl ;
00679   G4cout << nxx << " possible physical solutions found" << G4endl ;
00680   for ( G4int k= 0 ; k< nxx ; k++ )
00681   {
00682     G4cout << "global intersection Point found: " << gxx[k] << G4endl ;
00683     G4cout << "distance = " << distance[k] << G4endl ;
00684     G4cout << "isvalid = " << isvalid[k] << G4endl ;
00685   }
00686 #endif
00687 
00688   return nxx ;
00689 }

G4ThreeVector G4TwistTrapAlphaSide::GetNormal ( const G4ThreeVector xx,
G4bool  isGlobal = false 
) [virtual]

Implements G4VTwistSurface.

Definition at line 146 of file G4TwistTrapAlphaSide.cc.

References G4VTwistSurface::ComputeGlobalDirection(), G4VTwistSurface::ComputeLocalPoint(), G4VTwistSurface::fCurrentNormal, G4cout, G4endl, and G4VTwistSurface::kCarTolerance.

00148 {
00149    // GetNormal returns a normal vector at a surface (or very close
00150    // to surface) point at tmpxx.
00151    // If isGlobal=true, it returns the normal in global coordinate.
00152    //
00153 
00154    G4ThreeVector xx;
00155    if (isGlobal)
00156    {
00157       xx = ComputeLocalPoint(tmpxx);
00158       if ((xx - fCurrentNormal.p).mag() < 0.5 * kCarTolerance)
00159       {
00160          return ComputeGlobalDirection(fCurrentNormal.normal);
00161       }
00162    }
00163    else
00164    {
00165       xx = tmpxx;
00166       if (xx == fCurrentNormal.p)
00167       {
00168          return fCurrentNormal.normal;
00169       }
00170    }
00171 
00172    G4double phi ;
00173    G4double u ;
00174 
00175    GetPhiUAtX(xx,phi,u) ;   // phi,u for point xx close to surface 
00176 
00177    G4ThreeVector normal =  NormAng(phi,u) ;  // the normal vector at phi,u
00178 
00179 #ifdef G4TWISTDEBUG
00180    G4cout  << "normal vector = " << normal << G4endl ;
00181    G4cout << "phi = " << phi << " , u = " << u << G4endl ;
00182 #endif
00183 
00184    if (isGlobal)
00185    {
00186       fCurrentNormal.normal = ComputeGlobalDirection(normal.unit());
00187    }
00188    else
00189    {
00190       fCurrentNormal.normal = normal.unit();
00191    }
00192 
00193    return fCurrentNormal.normal;
00194 }


The documentation for this class was generated from the following files:
Generated on Mon May 27 17:53:35 2013 for Geant4 by  doxygen 1.4.7