82 if ( ! (fDx1 == fDx2 && fDx3 == fDx4 ) ) {
83 std::ostringstream message;
84 message <<
"TwistedTrapBoxSide is not used as a the side of a box: "
87 G4Exception(
"G4TwistBoxSide::G4TwistBoxSide()",
"GeomSolids0002",
97 fTAlph = std::tan(fAlph) ;
103 fDx4plus2 = fDx4 + fDx2 ;
104 fDx4minus2 = fDx4 - fDx2 ;
105 fDx3plus1 = fDx3 + fDx1 ;
106 fDx3minus1 = fDx3 - fDx1 ;
107 fDy2plus1 = fDy2 + fDy1 ;
108 fDy2minus1 = fDy2 - fDy1 ;
110 fa1md1 = 2*fDx2 - 2*fDx1 ;
111 fa2md2 = 2*fDx4 - 2*fDx3 ;
114 fPhiTwist = PhiTwist ;
115 fAngleSide = AngleSide ;
117 fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi) ;
118 fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi) ;
135 :
G4VTwistSurface(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.),
136 fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fAlph(0.), fTAlph(0.), fPhiTwist(0.),
137 fAngleSide(0.), fdeltaX(0.), fdeltaY(0.), fDx4plus2(0.), fDx4minus2(0.),
138 fDx3plus1(0.), fDx3minus1(0.), fDy2plus1(0.), fDy2minus1(0.), fa1md1(0.),
178 GetPhiUAtX(xx,phi,u) ;
212 G4bool IsParallel = false ;
213 G4bool IsConverged = false ;
233 distance[i] = kInfinity;
236 gxx[i].
set(kInfinity, kInfinity, kInfinity);
255 G4bool tmpisvalid = false ;
257 std::vector<Intersection> xbuf ;
264 G4double phixz = fPhiTwist * ( p.
x() * v.
z() - p.
z() * v.
x() ) ;
265 G4double phiyz = fPhiTwist * ( p.
y() * v.
z() - p.
z() * v.
y() ) ;
271 if ( (std::fabs(p.
z()) <= L) && fPhiTwist ) {
273 phi = p.
z() * fPhiTwist / L ;
275 q = (2.* fPhiTwist*((v.
x() - fTAlph*v.
y())*std::cos(phi)
276 + (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;
291 xbuf.push_back(xbuftmp) ;
297 distance[0] = kInfinity;
298 gxx[0].
set(kInfinity,kInfinity,kInfinity);
302 areacode[0], isvalid[0],
303 0, validate, &gp, &gv);
319 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.
z()) ;
320 c[6] = 28800*(phiyz + 2*fDz*v.
x() - (fdeltaX + fDx4minus2)*v.
z() + fTAlph*(phixz - 2*fDz*v.
y() + fdeltaY*v.
z())) ;
321 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())) ;
322 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())) ;
323 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())) ;
324 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.
x() + 6*fDz*fTAlph*v.
y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.
z()) ;
325 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.
x() - 56*fDz*v.
y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.
z()) ;
326 c[0] = 36*(2* fDz*(v.
x() - fTAlph*v.
y()) - fdeltaX*v.
z() + fdeltaY*fTAlph*v.
z()) ;
330 G4cout <<
"coef = " << c[0] <<
" "
344 for (
G4int i = 0 ; i<num ; i++ ) {
345 if ( (si[i]==0.0) && fPhiTwist ) {
347 G4cout <<
"Solution " << i <<
" : " << srd[i] <<
G4endl ;
349 phi = std::fmod(srd[i] , pihalf) ;
351 u = (2*phiyz + 4*fDz*phi*v.
y() - 2*fdeltaY*phi*v.
z()
352 - fDx4plus2*fPhiTwist*v.
z()*std::sin(phi)
353 - 2*fDx4minus2*phi*v.
z()*std::sin(phi))
354 /(2*fPhiTwist*v.
z()*std::cos(phi)
355 + 2*fPhiTwist*fTAlph*v.
z()*std::sin(phi)) ;
363 xbuf.push_back(xbuftmp) ;
366 G4cout <<
"solution " << i <<
" = " << phi <<
" , " << u <<
G4endl ;
385 for (
size_t k = 0 ; k<xbuf.size() ; k++ ) {
388 G4cout <<
"Solution " << k <<
" : "
389 <<
"reconstructed phiR = " << xbuf[k].phi
390 <<
", uR = " << xbuf[k].u <<
G4endl ;
396 IsConverged = false ;
398 for (
G4int i = 1 ; i<maxint ; i++ ) {
400 xxonsurface = SurfacePoint(phi,u) ;
401 surfacenormal = NormAng(phi,u) ;
403 deltaX = ( tmpxx - xxonsurface ).mag() ;
404 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
405 if ( theta < 0.001 ) {
414 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
418 GetPhiUAtX(tmpxx, phi, u) ;
421 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
424 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
430 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
433 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
443 tmpareacode = GetAreaCode(tmpxx);
445 if (tmpdist >= 0) tmpisvalid =
true;
448 tmpareacode = GetAreaCode(tmpxx,
false);
450 if (tmpdist >= 0) tmpisvalid =
true;
455 "Feature NOT implemented !");
467 xbuf[k].distance = tmpdist ;
468 xbuf[k].areacode = tmpareacode ;
469 xbuf[k].isvalid = tmpisvalid ;
478 G4cout << G4endl <<
"list xbuf after sorting : " <<
G4endl ;
484 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() ,
EqualIntersection ) , xbuf.end() ) ;
489 G4int nxxtmp = xbuf.size() ;
491 if ( nxxtmp<2 || IsParallel ) {
509 xbuf.push_back(xbuftmp) ;
525 xbuf.push_back(xbuftmp) ;
527 for (
size_t k = nxxtmp ; k<xbuf.size() ; k++ ) {
530 G4cout <<
"Solution " << k <<
" : "
531 <<
"reconstructed phiR = " << xbuf[k].phi
532 <<
", uR = " << xbuf[k].u <<
G4endl ;
538 IsConverged = false ;
540 for (
G4int i = 1 ; i<maxint ; i++ ) {
542 xxonsurface = SurfacePoint(phi,u) ;
543 surfacenormal = NormAng(phi,u) ;
545 deltaX = ( tmpxx - xxonsurface ).mag() ;
546 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
547 if ( theta < 0.001 ) {
555 G4cout <<
"Step i = " << i <<
", distance = " << tmpdist <<
", " << deltaX <<
G4endl ;
559 GetPhiUAtX(tmpxx, phi, u) ;
562 G4cout <<
"approximated phi = " << phi <<
", u = " << u <<
G4endl ;
565 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
571 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0 ;
574 G4cout <<
"refined solution " << phi <<
" , " << u <<
G4endl ;
584 tmpareacode = GetAreaCode(tmpxx);
586 if (tmpdist >= 0) tmpisvalid =
true;
589 tmpareacode = GetAreaCode(tmpxx,
false);
591 if (tmpdist >= 0) tmpisvalid =
true;
594 G4Exception(
"G4TwistedBoxSide::DistanceToSurface()",
596 "Feature NOT implemented !");
608 xbuf[k].distance = tmpdist ;
609 xbuf[k].areacode = tmpareacode ;
610 xbuf[k].isvalid = tmpisvalid ;
623 xbuf.erase( std::unique(xbuf.begin(), xbuf.end() ,
EqualIntersection ) , xbuf.end() ) ;
626 G4cout << G4endl <<
"list xbuf after sorting : " <<
G4endl ;
632 for (
size_t i = 0 ; i<xbuf.size() ; i++ ) {
634 distance[i] = xbuf[i].distance;
636 areacode[i] = xbuf[i].areacode ;
637 isvalid[i] = xbuf[i].isvalid ;
640 isvalid[i], nxx, validate, &gp, &gv);
643 G4cout <<
"element Nr. " << i
644 <<
", local Intersection = " << xbuf[i].xx
645 <<
", distance = " << xbuf[i].distance
646 <<
", u = " << xbuf[i].u
647 <<
", phi = " << xbuf[i].phi
648 <<
", isvalid = " << xbuf[i].isvalid
657 G4cout << nxx <<
" possible physical solutions found" <<
G4endl ;
658 for (
G4int k= 0 ; k< nxx ; k++ ) {
659 G4cout <<
"global intersection Point found: " << gxx[k] <<
G4endl ;
696 distance[i] = kInfinity;
698 gxx[i].
set(kInfinity, kInfinity, kInfinity);
715 for (
G4int i = 1 ; i<maxint ; i++ ) {
717 xxonsurface = SurfacePoint(phiR,uR) ;
718 surfacenormal = NormAng(phiR,uR) ;
720 deltaX = ( xx - xxonsurface ).mag() ;
723 G4cout <<
"i = " << i <<
", distance = " << distance[0] <<
", " << deltaX <<
G4endl ;
728 GetPhiUAtX(xx, phiR, uR) ;
730 if ( deltaX <= ctol ) { break ; }
737 G4double uMax = GetBoundaryMax(phiR) ;
739 if ( phiR > halfphi ) phiR = halfphi ;
740 if ( phiR < -halfphi ) phiR = -halfphi ;
741 if ( uR > uMax ) uR = uMax ;
742 if ( uR < -uMax ) uR = -uMax ;
744 xxonsurface = SurfacePoint(phiR,uR) ;
745 distance[0] = ( p -
xx ).mag() ;
746 if ( distance[0] <= ctol ) { distance[0] = 0 ; }
751 G4cout <<
"refined solution " << phiR <<
" , " << uR <<
" , " <<
G4endl ;
760 G4cout <<
"intersection Point found: " << gxx[0] <<
G4endl ;
785 GetPhiUAtX(xx, phi,yprime ) ;
787 G4double fYAxisMax = GetBoundaryMax(phi) ;
792 G4cout <<
"GetAreaCode: yprime = " << yprime <<
G4endl ;
793 G4cout <<
"Intervall is " << fYAxisMin <<
" to " << fYAxisMax <<
G4endl ;
808 if (yprime < fYAxisMin + ctol) {
810 if (yprime <= fYAxisMin - ctol) isoutside =
true;
812 }
else if (yprime > fYAxisMax - ctol) {
814 if (yprime >= fYAxisMax + ctol) isoutside =
true;
824 if (xx.
z() <=
fAxisMin[zaxis] - ctol) isoutside =
true;
826 }
else if (xx.
z() >
fAxisMax[zaxis] - ctol) {
829 if (areacode & sBoundary) areacode |=
sCorner;
831 if (xx.
z() >=
fAxisMax[zaxis] + ctol) isoutside =
true;
839 areacode = tmpareacode;
840 }
else if ((areacode & sBoundary) !=
sBoundary) {
848 if (yprime < fYAxisMin ) {
850 }
else if (yprime > fYAxisMax) {
858 if (areacode & sBoundary) areacode |=
sCorner;
863 if (areacode & sBoundary) areacode |=
sCorner;
867 if ((areacode & sBoundary) !=
sBoundary) {
875 "Feature NOT implemented !");
883 void G4TwistBoxSide::SetCorners()
894 x = -fdeltaX/2. + (fDx2 - fDy1*fTAlph)*std::cos(fPhiTwist/2.) - fDy1*std::sin(fPhiTwist/2.) ;
895 y = -fdeltaY/2. - fDy1*std::cos(fPhiTwist/2.) + (-fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
902 x = -fdeltaX/2. + (fDx2 + fDy1*fTAlph)*std::cos(fPhiTwist/2.) + fDy1*std::sin(fPhiTwist/2.) ;
903 y = -fdeltaY/2. + fDy1*std::cos(fPhiTwist/2.) - (fDx2 + fDy1*fTAlph)*std::sin(fPhiTwist/2.) ;
910 x = fdeltaX/2. + (fDx4 + fDy2*fTAlph)*std::cos(fPhiTwist/2.) - fDy2*std::sin(fPhiTwist/2.) ;
911 y = fdeltaY/2. + fDy2*std::cos(fPhiTwist/2.) + (fDx4 + fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
918 x = fdeltaX/2. + (fDx4 - fDy2*fTAlph)*std::cos(fPhiTwist/2.) + fDy2*std::sin(fPhiTwist/2.) ;
919 y = fdeltaY/2. - fDy2*std::cos(fPhiTwist/2.) + (fDx4 - fDy2*fTAlph)*std::sin(fPhiTwist/2.) ;
928 "Method NOT implemented !");
935 void G4TwistBoxSide::SetBoundaries()
946 direction = direction.
unit();
952 direction = direction.
unit();
958 direction = direction.
unit();
964 direction = direction.
unit();
972 "Feature NOT implemented !");
984 phi = p.
z()/(2*fDz)*fPhiTwist ;
986 u = -(fTAlph*(fDx4plus2*fPhiTwist + 2*fDx4minus2*phi) + 2*(fdeltaY*phi + fdeltaX*fTAlph*phi - fPhiTwist*(fTAlph*p.
x() + p.
y()))* std::cos(phi) + 2*(-(fdeltaX*phi) + fdeltaY*fTAlph*phi + fPhiTwist*(p.
x() - fTAlph*p.
y()))*std::sin(phi))/(2.*(fPhiTwist + fPhiTwist*fTAlph*fTAlph)) ;
1006 GetPhiUAtX( tmpp, phi, u ) ;
1033 for ( i = 0 ; i<
n ; i++ ) {
1035 z = -fDz+i*(2.*fDz)/(n-1) ;
1036 phi = z*fPhiTwist/(2*fDz) ;
1037 b = GetValueB(phi) ;
1039 for ( j = 0 ; j<k ; j++ ) {
1041 nnode =
GetNode(i,j,k,n,iside) ;
1042 u = -b/2 +j*b/(k-1) ;
1043 p = SurfacePoint(phi,u,
true) ;
1045 xyz[nnode][0] = p.
x() ;
1046 xyz[nnode][1] = p.
y() ;
1047 xyz[nnode][2] = p.
z() ;
1049 if ( i<n-1 && j<k-1 ) {
1051 nface =
GetFace(i,j,k,n,iside) ;