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);
167 GetPhiUAtX(xx,phi,u) ;
201 static const G4double pihalf = pi/2 ;
204 G4bool IsParallel = false ;
205 G4bool IsConverged = false ;
226 distance[i] = kInfinity;
229 gxx[i].
set(kInfinity, kInfinity, kInfinity);
248 G4bool tmpisvalid = false ;
250 std::vector<Intersection> xbuf ;
257 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
258 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
264 if ( (std::fabs(p.
z()) <= L) && (fPhiTwist != 0.0) )
266 phi = p.
z() * fPhiTwist / L ;
268 q = (2.* fPhiTwist*((v.
x() - fTAlph*v.
y())*std::cos(phi)
269 + (fTAlph*v.
x() + v.
y())*std::sin(phi)));
273 u = (2*(-(fdeltaY*phi*v.
x()) + fPhiTwist*p.
y()*v.
x()
274 + fdeltaX*phi*v.
y() - fPhiTwist*p.
x()*v.
y())
275 + (fDx4plus2*fPhiTwist + 2*fDx4minus2*phi)
276 * (v.
y()*std::cos(phi) - v.
x()*std::sin(phi))) / q;
284 xbuf.push_back(xbuftmp) ;
288 distance[0] = kInfinity;
289 gxx[0].
set(kInfinity,kInfinity,kInfinity);
293 areacode[0], isvalid[0],
294 0, validate, &gp, &gv);
303 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.
z()) ;
304 c[6] = 28800*(phiyz + 2*fDz*v.
x() - (fdeltaX + fDx4minus2)*v.
z() + fTAlph*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z())) ;
305 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())) ;
306 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())) ;
307 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())) ;
308 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.
z()) ;
309 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x() - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()) ;
310 c[0] = 36*(2* fDz*(v.
x() - fTAlph*v.
y()) - fdeltaX*v.
z() + fdeltaY*fTAlph*v.
z()) ;
313 G4cout <<
"coef = " << c[0] <<
" "
326 for (
G4int i = 0 ; i<num ; ++i )
328 if ( (si[i]==0.0) && (fPhiTwist != 0.0) )
331 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
333 phi = std::fmod(srd[i], pihalf) ;
335 u = (2*phiyz + 4*fDz*phi*v.
y() - 2*fdeltaY*phi*v.
z()
336 - fDx4plus2*fPhiTwist*v.
z()*std::sin(phi)
337 - 2*fDx4minus2*phi*v.
z()*std::sin(phi))
338 /(2*fPhiTwist*v.
z()*std::cos(phi)
339 + 2*fPhiTwist*fTAlph*v.
z()*std::sin(phi)) ;
347 xbuf.push_back(xbuftmp) ;
350 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
357 nxx = (
G4int)xbuf.size() ;
368 for (
auto & k : xbuf)
371 G4cout <<
"Solution " << k <<
" : "
372 <<
"reconstructed phiR = " << xbuf[k].phi
373 <<
", uR = " << xbuf[k].u <<
G4endl ;
379 IsConverged = false ;
381 for (
G4int i = 1 ; i<maxint ; ++i )
383 xxonsurface = SurfacePoint(phi,u) ;
384 surfacenormal = NormAng(phi,u) ;
386 deltaX = ( tmpxx - xxonsurface ).mag() ;
387 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
399 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
403 GetPhiUAtX(tmpxx, phi, u) ;
406 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
409 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
413 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
416 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
427 tmpareacode = GetAreaCode(tmpxx);
430 if (tmpdist >= 0) tmpisvalid =
true;
435 tmpareacode = GetAreaCode(tmpxx,
false);
438 if (tmpdist >= 0) tmpisvalid =
true;
445 "Feature NOT implemented !");
456 k.distance = tmpdist ;
457 k.areacode = tmpareacode ;
458 k.isvalid = tmpisvalid ;
474 auto nxxtmp = (
G4int)xbuf.size() ;
476 if ( nxxtmp<2 || IsParallel )
491 xbuf.push_back(xbuftmp) ;
506 xbuf.push_back(xbuftmp) ;
508 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
511 G4cout <<
"Solution " << k <<
" : "
512 <<
"reconstructed phiR = " << xbuf[k].phi
513 <<
", uR = " << xbuf[k].u <<
G4endl ;
519 IsConverged = false ;
521 for (
G4int i = 1 ; i<maxint ; ++i )
523 xxonsurface = SurfacePoint(phi,u) ;
524 surfacenormal = NormAng(phi,u) ;
526 deltaX = ( tmpxx - xxonsurface ).mag() ;
527 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
538 G4cout <<
"Step i = " << i <<
", distance = "
539 << tmpdist <<
", " << deltaX <<
G4endl ;
543 GetPhiUAtX(tmpxx, phi, u) ;
547 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
550 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
554 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
557 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
568 tmpareacode = GetAreaCode(tmpxx);
571 if (tmpdist >= 0) tmpisvalid =
true;
576 tmpareacode = GetAreaCode(tmpxx,
false);
579 if (tmpdist >= 0) tmpisvalid =
true;
584 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
586 "Feature NOT implemented !");
597 xbuf[k].distance = tmpdist ;
598 xbuf[k].areacode = tmpareacode ;
599 xbuf[k].isvalid = tmpisvalid ;
614 nxx = (
G4int)xbuf.size() ;
616 for (
G4int i = 0 ; i<(
G4int)xbuf.size() ; ++i )
618 distance[i] = xbuf[i].distance;
620 areacode[i] = xbuf[i].areacode ;
621 isvalid[i] = xbuf[i].isvalid ;
624 isvalid[i], nxx, validate, &gp, &gv);
627 G4cout <<
"element Nr. " << i
628 <<
", local Intersection = " << xbuf[i].xx
629 <<
", distance = " << xbuf[i].distance
630 <<
", u = " << xbuf[i].u
631 <<
", phi = " << xbuf[i].phi
632 <<
", isvalid = " << xbuf[i].isvalid
640 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
641 for (
G4int k= 0 ; k< nxx ; ++k )
643 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
678 distance[i] = kInfinity;
680 gxx[i].
set(kInfinity, kInfinity, kInfinity);
697 for (
G4int i = 1 ; i<maxint ; ++i )
699 xxonsurface = SurfacePoint(phiR,uR) ;
700 surfacenormal = NormAng(phiR,uR) ;
702 deltaX = ( xx - xxonsurface ).mag() ;
705 G4cout <<
"i = " << i <<
", distance = " << distance[0]
706 <<
", " << deltaX <<
G4endl ;
711 GetPhiUAtX(xx, phiR, uR) ;
713 if ( deltaX <= ctol ) { break ; }
719 G4double uMax = GetBoundaryMax(phiR) ;
721 if ( phiR > halfphi ) phiR = halfphi ;
722 if ( phiR < -halfphi ) phiR = -halfphi ;
723 if ( uR > uMax ) uR = uMax ;
724 if ( uR < -uMax ) uR = -uMax ;
726 xxonsurface = SurfacePoint(phiR,uR) ;
727 distance[0] = ( p - xx ).mag() ;
728 if ( distance[0] <= ctol ) { distance[0] = 0 ; }
733 G4cout <<
"refined solution " << phiR <<
" , " << uR <<
" , " <<
G4endl ;
742 G4cout <<
"intersection Point found: " << gxx[0] <<
G4endl ;
764 GetPhiUAtX(xx, phi,yprime ) ;
766 G4double fYAxisMax = GetBoundaryMax(phi) ;
771 G4cout <<
"GetAreaCode: yprime = " << yprime <<
G4endl ;
772 G4cout <<
"Intervall is " << fYAxisMin <<
" to " << fYAxisMax <<
G4endl ;
787 if (yprime < fYAxisMin + ctol)
790 if (yprime <= fYAxisMin - ctol) isoutside =
true;
793 else if (yprime > fYAxisMax - ctol)
796 if (yprime >= fYAxisMax + ctol) isoutside =
true;
807 if (xx.
z() <=
fAxisMin[zaxis] - ctol) isoutside =
true;
810 else if (xx.
z() >
fAxisMax[zaxis] - ctol)
816 if (xx.
z() >=
fAxisMax[zaxis] + ctol) isoutside =
true;
824 G4int tmpareacode = areacode & (~sInside);
825 areacode = tmpareacode;
837 if (yprime < fYAxisMin )
841 else if (yprime > fYAxisMax)
873 "Feature NOT implemented !");
881void G4TwistBoxSide::SetCorners()
892 x = -fdeltaX/2. + (fDx2 - fDy1*fTAlph)*std::cos(fPhiTwist/2.) - fDy1*std::sin(fPhiTwist/2.) ;
893 y = -fdeltaY/2. - fDy1*std::cos(fPhiTwist/2.) + (-fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
900 x = -fdeltaX/2. + (fDx2 + fDy1*fTAlph)*std::cos(fPhiTwist/2.) + fDy1*std::sin(fPhiTwist/2.) ;
901 y = -fdeltaY/2. + fDy1*std::cos(fPhiTwist/2.) - (fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
908 x = fdeltaX/2. + (fDx4 + fDy2*fTAlph)*std::cos(fPhiTwist/2.) - fDy2*std::sin(fPhiTwist/2.) ;
909 y = fdeltaY/2. + fDy2*std::cos(fPhiTwist/2.) + (fDx4 + fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
916 x = fdeltaX/2. + (fDx4 - fDy2*fTAlph)*std::cos(fPhiTwist/2.) + fDy2*std::sin(fPhiTwist/2.) ;
917 y = fdeltaY/2. - fDy2*std::cos(fPhiTwist/2.) + (fDx4 - fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
927 "Method NOT implemented !");
934void G4TwistBoxSide::SetBoundaries()
944 direction = direction.
unit();
950 direction = direction.
unit();
956 direction = direction.
unit();
962 direction = direction.
unit();
971 "Feature NOT implemented !");
984 phi = p.
z()/(2*fDz)*fPhiTwist ;
986 u = -(fTAlph*(fDx4plus2*fPhiTwist + 2*fDx4minus2*phi)
987 + 2*(fdeltaY*phi + fdeltaX*fTAlph*phi
988 - fPhiTwist*(fTAlph*p.
x() + p.
y()))* std::cos(phi)
989 + 2*(-(fdeltaX*phi) + fdeltaY*fTAlph*phi + fPhiTwist*(p.
x()
990 - fTAlph*p.
y()))*std::sin(phi))/(2.*(fPhiTwist
991 + fPhiTwist*fTAlph*fTAlph)) ;
1012 GetPhiUAtX( tmpp, phi, u ) ;
1044 for ( i = 0 ; i<
n ; ++i )
1046 z = -fDz+i*(2.*fDz)/(n-1) ;
1047 phi = z*fPhiTwist/(2*fDz) ;
1048 b = GetValueB(phi) ;
1050 for ( j = 0 ; j<k ; ++j )
1052 nnode =
GetNode(i,j,k,n,iside) ;
1053 u = -b/2 +j*b/(k-1) ;
1054 p = SurfacePoint(phi,u,
true) ;
1057 xyz[nnode][0] = p.
x() ;
1058 xyz[nnode][1] = p.
y() ;
1059 xyz[nnode][2] = p.
z() ;
1061 if ( i<n-1 && j<k-1 )
1063 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)
G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal=false) override
G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol) override
~G4TwistBoxSide() override
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