71 if ( ! (fDx1 == fDx2 && fDx3 == fDx4 ) )
73 std::ostringstream message;
74 message <<
"TwistedTrapBoxSide is not used as a the side of a box: "
77 G4Exception(
"G4TwistBoxSide::G4TwistBoxSide()",
"GeomSolids0002",
87 fTAlph = std::tan(fAlph) ;
94 fDx4plus2 = fDx4 + fDx2 ;
95 fDx4minus2 = fDx4 - fDx2 ;
96 fDx3plus1 = fDx3 + fDx1 ;
97 fDx3minus1 = fDx3 - fDx1 ;
98 fDy2plus1 = fDy2 + fDy1 ;
99 fDy2minus1 = fDy2 - fDy1 ;
101 fa1md1 = 2*fDx2 - 2*fDx1 ;
102 fa2md2 = 2*fDx4 - 2*fDx3 ;
105 fPhiTwist = PhiTwist ;
106 fAngleSide = AngleSide ;
108 fdeltaX = 2*fDz * std::tan(fTheta) * std::cos(fPhi);
109 fdeltaY = 2*fDz * std::tan(fTheta) * std::sin(fPhi);
125 :
G4VTwistSurface(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.),
126 fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fAlph(0.), fTAlph(0.), fPhiTwist(0.),
127 fAngleSide(0.), fdeltaX(0.), fdeltaY(0.), fDx4plus2(0.), fDx4minus2(0.),
128 fDx3plus1(0.), fDx3minus1(0.), fDy2plus1(0.), fDy2minus1(0.), fa1md1(0.),
173 GetPhiUAtX(xx,phi,u) ;
207 static const G4double pihalf = pi/2 ;
210 G4bool IsParallel = false ;
211 G4bool IsConverged = false ;
232 distance[i] = kInfinity;
235 gxx[i].
set(kInfinity, kInfinity, kInfinity);
254 G4bool tmpisvalid = false ;
256 std::vector<Intersection> xbuf ;
263 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
264 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
270 if ( (std::fabs(p.
z()) <= L) && fPhiTwist )
272 phi = p.
z() * fPhiTwist / L ;
274 q = (2.* fPhiTwist*((v.
x() - fTAlph*v.
y())*std::cos(phi)
275 + (fTAlph*v.
x() + v.
y())*std::sin(phi)));
279 u = (2*(-(fdeltaY*phi*v.
x()) + fPhiTwist*p.
y()*v.
x()
280 + fdeltaX*phi*v.
y() - fPhiTwist*p.
x()*v.
y())
281 + (fDx4plus2*fPhiTwist + 2*fDx4minus2*phi)
282 * (v.
y()*std::cos(phi) - v.
x()*std::sin(phi))) / q;
290 xbuf.push_back(xbuftmp) ;
294 distance[0] = kInfinity;
295 gxx[0].
set(kInfinity,kInfinity,kInfinity);
299 areacode[0], isvalid[0],
300 0, validate, &gp, &gv);
309 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.
z()) ;
310 c[6] = 28800*(phiyz + 2*fDz*v.
x() - (fdeltaX + fDx4minus2)*v.
z() + fTAlph*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z())) ;
311 c[5] = -1200*(10*phixz - 48*fDz*v.
y() + 24*fdeltaY*v.
z() + fDx4plus2*fPhiTwist*v.
z() - 2*fTAlph*(5*phiyz + 24*fDz*v.
x() - 12*fdeltaX*v.
z())) ;
312 c[4] = -2400*(phiyz + 10*fDz*v.
x() - 5*fdeltaX*v.
z() + fDx4minus2*v.
z() + fTAlph*(phixz - 10*fDz*v.
y() + 5*fdeltaY*v.
z())) ;
313 c[3] = 24*(2*phixz - 200*fDz*v.
y() + 100*fdeltaY*v.
z() - fDx4plus2*fPhiTwist*v.
z() - 2*fTAlph*(phiyz + 100*fDz*v.
x() - 50*fdeltaX*v.
z())) ;
314 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.
z()) ;
315 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x() - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()) ;
316 c[0] = 36*(2* fDz*(v.
x() - fTAlph*v.
y()) - fdeltaX*v.
z() + fdeltaY*fTAlph*v.
z()) ;
319 G4cout <<
"coef = " << c[0] <<
" "
332 for (
G4int i = 0 ; i<num ; ++i )
334 if ( (si[i]==0.0) && fPhiTwist )
337 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
339 phi = std::fmod(srd[i], pihalf) ;
341 u = (2*phiyz + 4*fDz*phi*v.
y() - 2*fdeltaY*phi*v.
z()
342 - fDx4plus2*fPhiTwist*v.
z()*std::sin(phi)
343 - 2*fDx4minus2*phi*v.
z()*std::sin(phi))
344 /(2*fPhiTwist*v.
z()*std::cos(phi)
345 + 2*fPhiTwist*fTAlph*v.
z()*std::sin(phi)) ;
353 xbuf.push_back(xbuftmp) ;
356 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
374 for (
size_t k = 0 ; k<xbuf.size() ; ++k )
377 G4cout <<
"Solution " << k <<
" : "
378 <<
"reconstructed phiR = " << xbuf[k].phi
379 <<
", uR = " << xbuf[k].u <<
G4endl ;
385 IsConverged = false ;
387 for (
G4int i = 1 ; i<maxint ; ++i )
389 xxonsurface = SurfacePoint(phi,u) ;
390 surfacenormal = NormAng(phi,u) ;
392 deltaX = ( tmpxx - xxonsurface ).mag() ;
393 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
405 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
409 GetPhiUAtX(tmpxx, phi, u) ;
412 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
415 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
419 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
422 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
433 tmpareacode = GetAreaCode(tmpxx);
436 if (tmpdist >= 0) tmpisvalid =
true;
441 tmpareacode = GetAreaCode(tmpxx,
false);
444 if (tmpdist >= 0) tmpisvalid =
true;
451 "Feature NOT implemented !");
462 xbuf[k].distance = tmpdist ;
463 xbuf[k].areacode = tmpareacode ;
464 xbuf[k].isvalid = tmpisvalid ;
480 G4int nxxtmp = xbuf.size() ;
482 if ( nxxtmp<2 || IsParallel )
497 xbuf.push_back(xbuftmp) ;
512 xbuf.push_back(xbuftmp) ;
514 for (
size_t k = nxxtmp ; k<xbuf.size() ; ++k )
517 G4cout <<
"Solution " << k <<
" : "
518 <<
"reconstructed phiR = " << xbuf[k].phi
519 <<
", uR = " << xbuf[k].u <<
G4endl ;
525 IsConverged = false ;
527 for (
G4int i = 1 ; i<maxint ; ++i )
529 xxonsurface = SurfacePoint(phi,u) ;
530 surfacenormal = NormAng(phi,u) ;
532 deltaX = ( tmpxx - xxonsurface ).mag() ;
533 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
544 G4cout <<
"Step i = " << i <<
", distance = "
545 << tmpdist <<
", " << deltaX <<
G4endl ;
549 GetPhiUAtX(tmpxx, phi, u) ;
553 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
556 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
560 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
563 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
574 tmpareacode = GetAreaCode(tmpxx);
577 if (tmpdist >= 0) tmpisvalid =
true;
582 tmpareacode = GetAreaCode(tmpxx,
false);
585 if (tmpdist >= 0) tmpisvalid =
true;
590 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
592 "Feature NOT implemented !");
603 xbuf[k].distance = tmpdist ;
604 xbuf[k].areacode = tmpareacode ;
605 xbuf[k].isvalid = tmpisvalid ;
622 for (
size_t i = 0 ; i<xbuf.size() ; ++i )
624 distance[i] = xbuf[i].distance;
626 areacode[i] = xbuf[i].areacode ;
627 isvalid[i] = xbuf[i].isvalid ;
630 isvalid[i], nxx, validate, &gp, &gv);
633 G4cout <<
"element Nr. " << i
634 <<
", local Intersection = " << xbuf[i].xx
635 <<
", distance = " << xbuf[i].distance
636 <<
", u = " << xbuf[i].u
637 <<
", phi = " << xbuf[i].phi
638 <<
", isvalid = " << xbuf[i].isvalid
646 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
647 for (
G4int k= 0 ; k< nxx ; ++k )
649 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
684 distance[i] = kInfinity;
686 gxx[i].
set(kInfinity, kInfinity, kInfinity);
703 for (
G4int i = 1 ; i<maxint ; ++i )
705 xxonsurface = SurfacePoint(phiR,uR) ;
706 surfacenormal = NormAng(phiR,uR) ;
708 deltaX = ( xx - xxonsurface ).mag() ;
711 G4cout <<
"i = " << i <<
", distance = " << distance[0]
712 <<
", " << deltaX <<
G4endl ;
717 GetPhiUAtX(xx, phiR, uR) ;
719 if ( deltaX <= ctol ) { break ; }
725 G4double uMax = GetBoundaryMax(phiR) ;
727 if ( phiR > halfphi ) phiR = halfphi ;
728 if ( phiR < -halfphi ) phiR = -halfphi ;
729 if ( uR > uMax ) uR = uMax ;
730 if ( uR < -uMax ) uR = -uMax ;
732 xxonsurface = SurfacePoint(phiR,uR) ;
733 distance[0] = ( p - xx ).mag() ;
734 if ( distance[0] <= ctol ) { distance[0] = 0 ; }
739 G4cout <<
"refined solution " << phiR <<
" , " << uR <<
" , " <<
G4endl ;
748 G4cout <<
"intersection Point found: " << gxx[0] <<
G4endl ;
770 GetPhiUAtX(xx, phi,yprime ) ;
772 G4double fYAxisMax = GetBoundaryMax(phi) ;
777 G4cout <<
"GetAreaCode: yprime = " << yprime <<
G4endl ;
778 G4cout <<
"Intervall is " << fYAxisMin <<
" to " << fYAxisMax <<
G4endl ;
793 if (yprime < fYAxisMin + ctol)
796 if (yprime <= fYAxisMin - ctol) isoutside =
true;
799 else if (yprime > fYAxisMax - ctol)
802 if (yprime >= fYAxisMax + ctol) isoutside =
true;
813 if (xx.
z() <=
fAxisMin[zaxis] - ctol) isoutside =
true;
816 else if (xx.
z() >
fAxisMax[zaxis] - ctol)
822 if (xx.
z() >=
fAxisMax[zaxis] + ctol) isoutside =
true;
830 G4int tmpareacode = areacode & (~sInside);
831 areacode = tmpareacode;
843 if (yprime < fYAxisMin )
847 else if (yprime > fYAxisMax)
879 "Feature NOT implemented !");
887void G4TwistBoxSide::SetCorners()
898 x = -fdeltaX/2. + (fDx2 - fDy1*fTAlph)*std::cos(fPhiTwist/2.) - fDy1*std::sin(fPhiTwist/2.) ;
899 y = -fdeltaY/2. - fDy1*std::cos(fPhiTwist/2.) + (-fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
906 x = -fdeltaX/2. + (fDx2 + fDy1*fTAlph)*std::cos(fPhiTwist/2.) + fDy1*std::sin(fPhiTwist/2.) ;
907 y = -fdeltaY/2. + fDy1*std::cos(fPhiTwist/2.) - (fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
914 x = fdeltaX/2. + (fDx4 + fDy2*fTAlph)*std::cos(fPhiTwist/2.) - fDy2*std::sin(fPhiTwist/2.) ;
915 y = fdeltaY/2. + fDy2*std::cos(fPhiTwist/2.) + (fDx4 + fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
922 x = fdeltaX/2. + (fDx4 - fDy2*fTAlph)*std::cos(fPhiTwist/2.) + fDy2*std::sin(fPhiTwist/2.) ;
923 y = fdeltaY/2. - fDy2*std::cos(fPhiTwist/2.) + (fDx4 - fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
933 "Method NOT implemented !");
940void G4TwistBoxSide::SetBoundaries()
950 direction = direction.
unit();
956 direction = direction.
unit();
962 direction = direction.
unit();
968 direction = direction.
unit();
977 "Feature NOT implemented !");
990 phi = p.
z()/(2*fDz)*fPhiTwist ;
992 u = -(fTAlph*(fDx4plus2*fPhiTwist + 2*fDx4minus2*phi)
993 + 2*(fdeltaY*phi + fdeltaX*fTAlph*phi
994 - fPhiTwist*(fTAlph*p.
x() + p.
y()))* std::cos(phi)
995 + 2*(-(fdeltaX*phi) + fdeltaY*fTAlph*phi + fPhiTwist*(p.
x()
996 - fTAlph*p.
y()))*std::sin(phi))/(2.*(fPhiTwist
997 + fPhiTwist*fTAlph*fTAlph)) ;
1018 GetPhiUAtX( tmpp, phi, u ) ;
1050 for ( i = 0 ; i<
n ; ++i )
1052 z = -fDz+i*(2.*fDz)/(n-1) ;
1053 phi = z*fPhiTwist/(2*fDz) ;
1054 b = GetValueB(phi) ;
1056 for ( j = 0 ; j<k ; ++j )
1058 nnode =
GetNode(i,j,k,n,iside) ;
1059 u = -b/2 +j*b/(k-1) ;
1060 p = SurfacePoint(phi,u,
true) ;
1063 xyz[nnode][0] = p.
x() ;
1064 xyz[nnode][1] = p.
y() ;
1065 xyz[nnode][2] = p.
z() ;
1067 if ( i<n-1 && j<k-1 )
1069 nface =
GetFace(i,j,k,n,iside) ;
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
G4bool DistanceSort(const Intersection &a, const Intersection &b)
G4bool EqualIntersection(const Intersection &a, const Intersection &b)
G4GLOB_DLL std::ostream G4cout
void set(double x, double y, double z)
HepRotation inverse() const
HepRotation & rotateZ(double delta)
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
virtual ~G4TwistBoxSide()
virtual G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)
virtual G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal=false)
G4TwistBoxSide(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)
G4int GetAreacode(G4int i) const
G4double GetDistance(G4int i) const
G4bool IsValid(G4int i) const
void SetCurrentStatus(G4int i, G4ThreeVector &xx, G4double &dist, G4int &areacode, G4bool &isvalid, G4int nxx, EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
G4ThreeVector GetXX(G4int i) const
void ResetfDone(EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
static const G4int sC0Min1Min
static const G4int sC0Min1Max
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
virtual G4String GetName() const
CurrentStatus fCurStatWithV
static const G4int sAxisY
G4double DistanceToPlaneWithV(const G4ThreeVector &p, const G4ThreeVector &v, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const
G4SurfCurNormal fCurrentNormal