75 fTAlph = std::tan(fAlph) ;
82 fDx4plus2 = fDx4 + fDx2 ;
83 fDx4minus2 = fDx4 - fDx2 ;
84 fDx3plus1 = fDx3 + fDx1 ;
85 fDx3minus1 = fDx3 - fDx1 ;
86 fDy2plus1 = fDy2 + fDy1 ;
87 fDy2minus1 = fDy2 - fDy1 ;
89 fa1md1 = 2*fDx2 - 2*fDx1 ;
90 fa2md2 = 2*fDx4 - 2*fDx3 ;
92 fPhiTwist = PhiTwist ;
93 fAngleSide = AngleSide ;
95 fdeltaX = 2*fDz*std::tan(fTheta)*std::cos(fPhi);
96 fdeltaY = 2*fDz*std::tan(fTheta)*std::sin(fPhi);
98 fRot.rotateZ( AngleSide ) ;
147 GetPhiUAtX(xx,phi,u) ;
180 static const G4double pihalf = pi/2 ;
183 G4bool IsParallel = false ;
184 G4bool IsConverged = false ;
205 distance[i] = kInfinity;
208 gxx[i].
set(kInfinity, kInfinity, kInfinity);
226 G4bool tmpisvalid = false ;
228 std::vector<Intersection> xbuf ;
229 Intersection xbuftmp ;
235 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
236 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
242 if ( std::fabs(p.
z()) <= L )
244 phi = p.
z() * fPhiTwist / L ;
246 u = (2*(fdeltaY*phi*v.
x() - fPhiTwist*p.
y()*v.
x() - fdeltaX*phi*v.
y()
247 + fPhiTwist*p.
x()*v.
y()) + (fDy2plus1*fPhiTwist
248 + 2*fDy2minus1*phi)*(v.
x()*std::cos(phi) + v.
y()*std::sin(phi)))
249 / (2.* fPhiTwist*(v.
y()*std::cos(phi) - v.
x()*std::sin(phi)));
254 xbuftmp.distance = kInfinity ;
255 xbuftmp.isvalid = false ;
257 xbuf.push_back(xbuftmp) ;
261 distance[0] = kInfinity;
262 gxx[0].
set(kInfinity,kInfinity,kInfinity);
266 areacode[0], isvalid[0],
267 0, validate, &gp, &gv);
276 c[8] = -3600*(-2*phiyz + fDy2plus1*fPhiTwist*v.
z()) ;
277 c[7] = -7200*(phixz - 2*fDz*v.
y() + (fdeltaY + fDy2minus1)*v.
z()) ;
278 c[6] = 120*(-52*phiyz - 120*fDz*v.
x() + 60*fdeltaX*v.
z()
279 + 11*fDy2plus1*fPhiTwist*v.
z()) ;
280 c[5] = 240*(16*phixz - 52*fDz*v.
y() + 26*fdeltaY*v.
z()
281 + 11*fDy2minus1*v.
z()) ;
282 c[4] = 12*(127*phiyz + 640*fDz*v.
x() - 320*fdeltaX*v.
z()
283 + 4*fDy2plus1*fPhiTwist*v.
z()) ;
284 c[3] = -404*phixz + 3048*fDz*v.
y() - 1524*fdeltaY*v.
z()
285 + 96*fDy2minus1*v.
z() ;
286 c[2] = -72*phiyz + 404*(-2*fDz*v.
x() + fdeltaX*v.
z()) ;
287 c[1] = 12*(phixz - 12*fDz*v.
y() + 6*fdeltaY*v.
z()) ;
288 c[0] = 24*fDz*v.
x() - 12*fdeltaX*v.
z() ;
292 G4cout <<
"coef = " << c[0] <<
" "
306 for (
G4int i = 0 ; i<num ; ++i )
311 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
313 phi = std::fmod(srd[i] , pihalf) ;
314 u = (1/std::cos(phi)*(2*phixz + 4*fDz*phi*v.
x()
315 - 2*fdeltaX*phi*v.
z() + (fDy2plus1*fPhiTwist
316 + 2*fDy2minus1*phi)*v.
z()* std::sin(phi)))/(2.*fPhiTwist*v.
z()) ;
321 xbuftmp.distance = kInfinity ;
322 xbuftmp.isvalid = false ;
324 xbuf.push_back(xbuftmp) ;
327 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
334 nxx = (
G4int)xbuf.size() ;
344 for (
auto & k : xbuf)
347 G4cout <<
"Solution " << k <<
" : "
348 <<
"reconstructed phiR = " << xbuf[k].phi
349 <<
", uR = " << xbuf[k].u <<
G4endl ;
355 IsConverged = false ;
357 for (
G4int i = 1 ; i<maxint ; ++i )
359 xxonsurface = SurfacePoint(phi,u) ;
360 surfacenormal = NormAng(phi,u) ;
362 deltaX = ( tmpxx - xxonsurface ).mag() ;
363 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
375 G4cout <<
"Step i = " << i <<
", distance = "
376 << tmpdist <<
", " << deltaX <<
G4endl ;
380 GetPhiUAtX(tmpxx, phi, u);
383 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
386 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
389 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0 ; }
392 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
403 tmpareacode = GetAreaCode(tmpxx);
406 if (tmpdist >= 0) { tmpisvalid =
true; }
411 tmpareacode = GetAreaCode(tmpxx,
false);
414 if (tmpdist >= 0) { tmpisvalid =
true; }
419 G4Exception(
"G4TwistTrapParallelSide::DistanceToSurface()",
421 "Feature NOT implemented !");
432 k.distance = tmpdist ;
433 k.areacode = tmpareacode ;
434 k.isvalid = tmpisvalid ;
437 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;
445 xbuf.erase(std::unique(xbuf.begin(),xbuf.end(),EqualIntersection),xbuf.end());
450 auto nxxtmp = (
G4int)xbuf.size() ;
452 if ( nxxtmp<2 || IsParallel )
465 xbuftmp.distance = kInfinity ;
466 xbuftmp.isvalid = false ;
468 xbuf.push_back(xbuftmp) ;
480 xbuftmp.distance = kInfinity ;
481 xbuftmp.isvalid = false ;
483 xbuf.push_back(xbuftmp) ;
485 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
488 G4cout <<
"Solution " << k <<
" : "
489 <<
"reconstructed phiR = " << xbuf[k].phi
490 <<
", uR = " << xbuf[k].u <<
G4endl ;
496 IsConverged = false ;
498 for (
G4int i = 1 ; i<maxint ; ++i )
500 xxonsurface = SurfacePoint(phi,u) ;
501 surfacenormal = NormAng(phi,u) ;
503 deltaX = ( tmpxx - xxonsurface ).mag() ;
504 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
515 G4cout <<
"Step i = " << i <<
", distance = "
516 << tmpdist <<
", " << deltaX <<
G4endl ;
520 GetPhiUAtX(tmpxx, phi, u) ;
523 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
526 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
529 if ( std::fabs(tmpdist)<ctol ) { tmpdist = 0 ; }
532 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
543 tmpareacode = GetAreaCode(tmpxx);
546 if (tmpdist >= 0) { tmpisvalid =
true; }
551 tmpareacode = GetAreaCode(tmpxx,
false);
554 if (tmpdist >= 0) { tmpisvalid =
true; }
559 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
561 "Feature NOT implemented !");
573 xbuf[k].distance = tmpdist ;
574 xbuf[k].areacode = tmpareacode ;
575 xbuf[k].isvalid = tmpisvalid ;
581 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ;
584 xbuf.erase(std::unique(xbuf.begin(),xbuf.end(),EqualIntersection),xbuf.end());
591 nxx = (
G4int)xbuf.size() ;
593 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
595 distance[i] = xbuf[i].distance;
597 areacode[i] = xbuf[i].areacode ;
598 isvalid[i] = xbuf[i].isvalid ;
600 fCurStatWithV.SetCurrentStatus(i, gxx[i], distance[i], areacode[i],
601 isvalid[i], nxx, validate, &gp, &gv);
603 G4cout <<
"element Nr. " << i
604 <<
", local Intersection = " << xbuf[i].xx
605 <<
", distance = " << xbuf[i].distance
606 <<
", u = " << xbuf[i].u
607 <<
", phi = " << xbuf[i].phi
608 <<
", isvalid = " << xbuf[i].isvalid
614 G4cout <<
"G4TwistTrapParallelSide finished " <<
G4endl ;
615 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
616 for (
G4int k= 0 ; k< nxx ; ++k )
618 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
644 distance[i] =
fCurStat.GetDistance(i);
645 areacode[i] =
fCurStat.GetAreacode(i);
653 distance[i] = kInfinity;
655 gxx[i].
set(kInfinity, kInfinity, kInfinity);
671 for (
G4int i = 1 ; i<maxint ; ++i )
673 xxonsurface = SurfacePoint(phiR,uR) ;
674 surfacenormal = NormAng(phiR,uR) ;
676 deltaX = ( xx - xxonsurface ).mag() ;
679 G4cout <<
"i = " << i <<
", distance = "
680 << distance[0] <<
", " << deltaX <<
G4endl ;
685 GetPhiUAtX(xx, phiR, uR) ;
687 if ( deltaX <= ctol ) { break ; }
693 G4double uMax = GetBoundaryMax(phiR) ;
694 G4double uMin = GetBoundaryMin(phiR) ;
696 if ( phiR > halfphi ) { phiR = halfphi ; }
697 if ( phiR < -halfphi ) { phiR = -halfphi ; }
698 if ( uR > uMax ) { uR = uMax ; }
699 if ( uR < uMin ) { uR = uMin ; }
701 xxonsurface = SurfacePoint(phiR,uR) ;
702 distance[0] = ( p - xx ).mag() ;
703 if ( distance[0] <= ctol ) { distance[0] = 0 ; }
708 G4cout <<
"refined solution " << phiR <<
" , " << uR <<
" , " <<
G4endl ;
717 G4cout <<
"intersection Point found: " << gxx[0] <<
G4endl ;
721 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
739 GetPhiUAtX(xx, phi,yprime ) ;
741 G4double fXAxisMax = GetBoundaryMax(phi) ;
742 G4double fXAxisMin = GetBoundaryMin(phi) ;
746 G4cout <<
"GetAreaCode: yprime = " << yprime <<
G4endl ;
747 G4cout <<
"Intervall is " << fXAxisMin <<
" to " << fXAxisMax <<
G4endl ;
762 if (yprime < fXAxisMin + ctol)
765 if (yprime <= fXAxisMin - ctol) { isoutside =
true; }
767 else if (yprime > fXAxisMax - ctol)
770 if (yprime >= fXAxisMax + ctol) { isoutside =
true; }
787 if (xx.
z() <=
fAxisMin[zaxis] - ctol) { isoutside =
true; }
789 else if (xx.
z() >
fAxisMax[zaxis] - ctol)
801 if (xx.
z() >=
fAxisMax[zaxis] + ctol) { isoutside =
true; }
810 areacode = tmpareacode;
822 if (yprime < fXAxisMin )
826 else if (yprime > fXAxisMax)
866 G4Exception(
"G4TwistTrapParallelSide::GetAreaCode()",
868 "Feature NOT implemented !");
876void G4TwistTrapParallelSide::SetCorners()
887 x = -fdeltaX/2. + (-fDx2 + fDy1*fTAlph)*std::cos(fPhiTwist/2.)
888 + fDy1*std::sin(fPhiTwist/2.) ;
889 y = -fdeltaY/2. + fDy1*std::cos(fPhiTwist/2.)
890 + (fDx2 - fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
897 x = -fdeltaX/2. + (fDx2 + fDy1*fTAlph)*std::cos(fPhiTwist/2.)
898 + fDy1*std::sin(fPhiTwist/2.) ;
899 y = -fdeltaY/2. + fDy1*std::cos(fPhiTwist/2.)
900 - (fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
906 x = fdeltaX/2. + (fDx4 + fDy2*fTAlph)*std::cos(fPhiTwist/2.)
907 - fDy2*std::sin(fPhiTwist/2.) ;
908 y = fdeltaY/2. + fDy2*std::cos(fPhiTwist/2.)
909 + (fDx4 + fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
915 x = fdeltaX/2. + (-fDx4 + fDy2*fTAlph)*std::cos(fPhiTwist/2.)
916 - fDy2*std::sin(fPhiTwist/2.) ;
917 y = fdeltaY/2. + fDy2*std::cos(fPhiTwist/2.)
918 + (-fDx4 + fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
925 G4Exception(
"G4TwistTrapParallelSide::SetCorners()",
927 "Method NOT implemented !");
934void G4TwistTrapParallelSide::SetBoundaries()
945 direction = direction.
unit();
951 direction = direction.
unit();
957 direction = direction.
unit();
963 direction = direction.
unit();
969 G4Exception(
"G4TwistTrapParallelSide::SetCorners()",
971 "Feature NOT implemented !");
988 phi = p.
z()/(2*fDz)*fPhiTwist ;
990 u = ((-(fdeltaX*phi) + fPhiTwist*p.
x())* std::cos(phi)
991 + (-(fdeltaY*phi) + fPhiTwist*p.
y())*std::sin(phi))/fPhiTwist ;
1014 GetPhiUAtX( tmpp, phi, u ) ;
1042 for (
G4int i = 0 ; i<
n ; ++i )
1044 z = -fDz+i*(2.*fDz)/(n-1) ;
1045 phi = z*fPhiTwist/(2*fDz) ;
1046 umin = GetBoundaryMin(phi) ;
1047 umax = GetBoundaryMax(phi) ;
1049 for (
G4int j = 0 ; j<k ; ++j )
1051 nnode =
GetNode(i,j,k,n,iside) ;
1052 u = umax - j*(umax-umin)/(k-1) ;
1053 p = SurfacePoint(phi,u,
true) ;
1055 xyz[nnode][0] = p.
x() ;
1056 xyz[nnode][1] = p.
y() ;
1057 xyz[nnode][2] = p.
z() ;
1059 if ( i<n-1 && j<k-1 )
1061 nface =
GetFace(i,j,k,n,iside) ;
1063 * (
GetNode(i ,j ,k,n,iside)+1) ;
1065 * (
GetNode(i ,j+1,k,n,iside)+1) ;
1067 * (
GetNode(i+1,j+1,k,n,iside)+1) ;
1069 * (
GetNode(i+1,j ,k,n,iside)+1) ;
const G4double kCarTolerance
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol) override
G4TwistTrapParallelSide(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)
G4ThreeVector GetNormal(const G4ThreeVector &p, G4bool isGlobal=false) override
static const G4int sC0Min1Min
static const G4int sC0Min1Max
G4VTwistSurface(const G4String &name)
G4double DistanceToPlane(const G4ThreeVector &p, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
G4int GetNode(G4int i, G4int j, G4int m, G4int n, G4int iside)
static const G4int sOutside
G4ThreeVector ComputeGlobalDirection(const G4ThreeVector &lp) const
static const G4int sAxisMax
static const G4int sAxis0
G4int GetFace(G4int i, G4int j, G4int m, G4int n, G4int iside)
G4int GetEdgeVisibility(G4int i, G4int j, G4int m, G4int n, G4int number, G4int orientation)
G4ThreeVector ComputeLocalDirection(const G4ThreeVector &gp) const
static const G4int sAxisMin
static const G4int sC0Max1Max
static const G4int sAxis1
G4bool IsInside(G4int areacode, G4bool testbitmode=false) const
virtual void SetBoundary(const G4int &axiscode, const G4ThreeVector &direction, const G4ThreeVector &x0, const G4int &boundarytype)
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &gp) const
void SetCorner(G4int areacode, G4double x, G4double y, G4double z)
G4ThreeVector GetCorner(G4int areacode) const
static const G4int sBoundary
static const G4int sAxisZ
G4bool IsOutside(G4int areacode) const
static const G4int sCorner
static const G4int sC0Max1Min
static const G4int sInside
CurrentStatus fCurStatWithV
static const G4int sAxisX
G4double DistanceToPlaneWithV(const G4ThreeVector &p, const G4ThreeVector &v, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const
G4SurfCurNormal fCurrentNormal