#include <G4TwistTrapAlphaSide.hh>
Inheritance diagram for G4TwistTrapAlphaSide:
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__ &) |
Definition at line 51 of file G4TwistTrapAlphaSide.hh.
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] |
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 }
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 }