76 for (
auto i=0; i<4; ++i)
78 fCorners[i].set(kInfinity, kInfinity, kInfinity);
79 fNeighbours[i] =
nullptr;
84 fAmIOnLeftSide.me.set(kInfinity, kInfinity, kInfinity);
85 fAmIOnLeftSide.vec.set(kInfinity, kInfinity, kInfinity);
111 for (
auto i=0; i<4; ++i)
113 fCorners[i].set(kInfinity, kInfinity, kInfinity);
114 fNeighbours[i] =
nullptr;
119 fAmIOnLeftSide.me.set(kInfinity, kInfinity, kInfinity);
120 fAmIOnLeftSide.vec.set(kInfinity, kInfinity, kInfinity);
134 fNeighbours[0] = fNeighbours[1] = fNeighbours[2] = fNeighbours[3] =
nullptr;
160 if (fAmIOnLeftSide.me == me
161 && fAmIOnLeftSide.vec == vec
162 && fAmIOnLeftSide.withTol == withtol)
164 return fAmIOnLeftSide.amIOnLeftSide;
167 fAmIOnLeftSide.me = me;
168 fAmIOnLeftSide.vec = vec;
169 fAmIOnLeftSide.withTol = withtol;
177 G4double metcrossvect = met.
x() * vect.
y() - met.
y() * vect.
x();
181 if (met.
x() * ivect.
y() - met.
y() * ivect.
x() > 0 &&
183 fAmIOnLeftSide.amIOnLeftSide = 1;
184 }
else if (met.
x() * rvect.
y() - met.
y() * rvect.
x() < 0 &&
186 fAmIOnLeftSide.amIOnLeftSide = -1;
188 fAmIOnLeftSide.amIOnLeftSide = 0;
193 if (metcrossvect > 0) {
194 fAmIOnLeftSide.amIOnLeftSide = 1;
195 }
else if (metcrossvect < 0 ) {
196 fAmIOnLeftSide.amIOnLeftSide = -1;
198 fAmIOnLeftSide.amIOnLeftSide = 0;
203 G4cout <<
" === G4VTwistSurface::AmIOnLeftSide() =============="
205 G4cout <<
" Name , returncode : " << fName <<
" "
206 << fAmIOnLeftSide.amIOnLeftSide <<
G4endl;
207 G4cout <<
" me, vec : " << std::setprecision(14) << me
209 G4cout <<
" met, vect : " << met <<
" " << vect <<
G4endl;
210 G4cout <<
" ivec, rvec : " << ivect <<
" " << rvect <<
G4endl;
214 G4cout <<
" =============================================="
218 return fAmIOnLeftSide.amIOnLeftSide;
244 std::ostringstream message;
245 message <<
"Point is in the corner area." <<
G4endl
246 <<
" Point is in the corner area. This function returns"
248 <<
" a direction vector of a boundary line." <<
G4endl
249 <<
" areacode = " << areacode;
250 G4Exception(
"G4VTwistSurface::DistanceToBoundary()",
"GeomSolids0003",
259 xx.
set(t*p.
x(), t*p.
y(), x0.
z());
260 dist = (xx - p).mag();
271 std::ostringstream message;
272 message <<
"Bad areacode of boundary." <<
G4endl
273 <<
" areacode = " << areacode;
274 G4Exception(
"G4VTwistSurface::DistanceToBoundary()",
"GeomSolids0003",
288 G4cout <<
" ~~~~ G4VTwistSurface::DistanceToIn(p,v) - Start ~~~~" <<
G4endl;
292 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
302 distance[i] = kInfinity ;
316 for (
G4int i=0; i<nxx; ++i)
331 if ((normal * gv) >= 0)
335 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
336 <<
"particle goes outword the surface." <<
G4endl;
347 if (distance[i] < bestdistance)
349 bestdistance = distance[i];
353 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
354 <<
" areacode sInside name, distance = "
355 << fName <<
" "<< bestdistance <<
G4endl;
367 G4bool isaccepted[2] = {
false,
false};
370 for (
G4int j=0; j<nneighbours; ++j)
382 tmpdist[l] = kInfinity ;
384 tmpisvalid[l] = false ;
388 gp, gv, tmpgxx, tmpdist,
389 tmpareacode, tmpisvalid,
393 for (
G4int k=0; k< tmpnxx; ++k)
404 G4cout <<
" G4VTwistSurface:DistanceToIn(p,v): "
405 <<
" intersection "<< tmpgxx[k] <<
G4endl
406 <<
" is inside of neighbour surface of " << fName
407 <<
" . returning kInfinity." <<
G4endl;
408 G4cout <<
"~~ G4VTwistSurface::DistanceToIn(p,v) - return ~~"
412 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
415 if (tmpisvalid[k]) {
return kInfinity; }
425 neighbours[j], tmpareacode[k]))
429 neighbournormal = neighbours[j]->
GetNormal(tmpgxx[k],
true);
430 if (neighbournormal * gv < 0) { isaccepted[j] =
true; }
437 if (nneighbours == 1) { isaccepted[1] =
true; }
443 if (isaccepted[0] && isaccepted[1])
445 if (distance[i] < bestdistance)
447 bestdistance = distance[i];
451 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
452 <<
" areacode sBoundary & sBoundary distance = "
453 << fName <<
" " << distance[i] <<
G4endl;
465 G4cout <<
"~~~ G4VTwistSurface::DistanceToIn(p,v) - return ~~~" <<
G4endl;
468 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
472 G4cout <<
"~~~ G4VTwistSurface::DistanceToIn(p,v) : return ~~~" <<
G4endl;
473 G4cout <<
" Name, i : " << fName <<
" , " << besti <<
G4endl;
476 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
492 G4cout <<
"~~~~~ G4VTwistSurface::DistanceToOut(p,v) - Start ~~~~" <<
G4endl;
496 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
506 distance[i] = kInfinity ;
517 for (
G4int i=0; i<nxx; ++i)
525 if (normal * gv <= 0)
529 G4cout <<
" G4VTwistSurface::DistanceToOut(p,v): normal*gv < 0 "
530 << fName <<
" " << normal
537 if (distance[i] < bestdistance)
539 bestdistance = distance[i];
548 G4cout <<
"~~ G4VTwistSurface::DistanceToOut(p,v) - return ~~" <<
G4endl;
552 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
556 G4cout <<
"~~ G4VTwistSurface::DistanceToOut(p,v) : return ~~" <<
G4endl;
557 G4cout <<
" Name, i : " << fName <<
" , " << i <<
G4endl;
560 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
574 G4cout <<
"~~~~~ G4VTwistSurface::DistanceTo(p) - Start ~~~~~~~~~" <<
G4endl;
577 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
587 distance[i] = kInfinity ;
595 G4cout <<
"~~~~~ G4VTwistSurface::DistanceTo(p) - return ~~~~~~~~" <<
G4endl;
599 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
618 G4bool testbitmode =
true;
622 if (iscorner[0] && iscorner[1])
632 if ((
IsBoundary(areacode1, testbitmode) && (!iscorner[0])) &&
633 (
IsBoundary(areacode2, testbitmode) && (!iscorner[1])))
659 G4int& boundarytype)
const
665 for (
const auto & boundary : fBoundaries)
667 if (boundary.GetBoundaryParameters(areacode, d, x0, boundarytype))
673 std::ostringstream message;
674 message <<
"Not registered boundary." <<
G4endl
675 <<
" Boundary at areacode " << std::hex << areacode
677 <<
" is not registered.";
678 G4Exception(
"G4VTwistSurface::GetBoundaryParameters()",
"GeomSolids0002",
692 if (((areacode &
sAxis0) != 0) && ((areacode &
sAxis1) != 0))
694 std::ostringstream message;
695 message <<
"Point is in the corner area." <<
G4endl
696 <<
" This function returns "
697 <<
"a direction vector of a boundary line." <<
G4endl
698 <<
" areacode = " << areacode;
699 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0003",
705 G4int boundarytype = 0;
708 for (
const auto & boundary : fBoundaries)
710 if (boundary.GetBoundaryParameters(areacode, d, x0, boundarytype))
719 std::ostringstream message;
720 message <<
"Not registered boundary." <<
G4endl
721 <<
" Boundary at areacode " << areacode <<
G4endl
722 <<
" is not registered.";
723 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0002",
730 std::ostringstream message;
731 message <<
"Not a z-depended line boundary." <<
G4endl
732 <<
" Boundary at areacode " << areacode <<
G4endl
733 <<
" is not a z-depended line.";
734 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0002",
737 return ((p.
z() - x0.
z()) / d.
z()) * d + x0;
748 std::ostringstream message;
749 message <<
"Area code must represents corner." <<
G4endl
750 <<
" areacode " << areacode;
751 G4Exception(
"G4VTwistSurface::SetCorner()",
"GeomSolids0002",
756 fCorners[0].set(x, y, z);
758 fCorners[1].set(x, y, z);
760 fCorners[2].set(x, y, z);
762 fCorners[3].set(x, y, z);
772 G4Exception(
"G4VTwistSurface::GetBoundaryAxis()",
"GeomSolids0003",
775 for (
G4int i=0; i<2; ++i)
777 G4int whichaxis = 0 ;
787 if (axiscode == (whichaxis &
sAxisX)) {
789 }
else if (axiscode == (whichaxis &
sAxisY)) {
791 }
else if (axiscode == (whichaxis &
sAxisZ)) {
793 }
else if (axiscode == (whichaxis &
sAxisRho)) {
795 }
else if (axiscode == (whichaxis &
sAxisPhi)) {
798 std::ostringstream message;
799 message <<
"Not supported areacode." <<
G4endl
800 <<
" areacode " << areacode;
801 G4Exception(
"G4VTwistSurface::GetBoundaryAxis()",
"GeomSolids0001",
813 if ((areacode &
sCorner) != 0) {
827 }
else if ((areacode &
sBoundary) != 0) {
838 std::ostringstream message;
839 message <<
"Not located on a boundary!" <<
G4endl
840 <<
" areacode " << areacode;
841 G4Exception(
"G4VTwistSurface::GetBoundaryLimit()",
"GeomSolids1002",
852 const G4int& boundarytype)
861 for (
auto & boundary : fBoundaries)
863 if (boundary.IsEmpty())
865 boundary.SetFields(axiscode, direction, x0, boundarytype);
873 G4Exception(
"G4VTwistSurface::SetBoundary()",
"GeomSolids0003",
879 std::ostringstream message;
880 message <<
"Invalid axis-code." <<
G4endl
882 << std::hex << axiscode << std::dec;
883 G4Exception(
"G4VTwistSurface::SetBoundary()",
"GeomSolids0003",
897 if ( iside == 0 ) {
return i * ( k - 1 ) + j ; }
898 if ( iside == 1 ) {
return (k-1)*(k-1) + i*(k-1) + j ; }
899 if ( iside == 2 ) {
return 2*(k-1)*(k-1) + i*(k-1) + j ; }
900 if ( iside == 3 ) {
return 2*(k-1)*(k-1) + (n-1)*(k-1) + i*(k-1) + j ; }
901 if ( iside == 4 ) {
return 2*(k-1)*(k-1) + 2*(n-1)*(k-1) + i*(k-1) + j ; }
902 if ( iside == 5 ) {
return 2*(k-1)*(k-1) + 3*(n-1)*(k-1) + i*(k-1) + j ; }
904 std::ostringstream message;
905 message <<
"Not correct side number: "
907 <<
"iside is " << iside <<
" but should be "
908 <<
"0,1,2,3,4 or 5" <<
".";
909 G4Exception(
"G4TwistSurface::G4GetFace()",
"GeomSolids0002",
935 return k*k + i*k + j ;
940 if ( i == 0 ) {
return j ; }
941 if ( i == n-1 ) {
return k*k + j ; }
942 return 2*k*k + 4*(i-1)*(k-1) + j ;
947 if ( i == 0 ) {
return (j+1)*k - 1 ; }
948 if ( i == n-1 ) {
return k*k + (j+1)*k - 1 ; }
949 return 2*k*k + 4*(i-1)*(k-1) + (k-1) + j ;
954 if ( i == 0 ) {
return k*k - 1 - j ; }
955 if ( i == n-1 ) {
return 2*k*k - 1 - j ; }
956 return 2*k*k + 4*(i-1)*(k-1) + 2*(k-1) + j ;
961 if ( i == 0 ) {
return k*k - (j+1)*k ; }
962 if ( i == n-1) {
return 2*k*k - (j+1)*k ; }
963 if ( j == k-1 ) {
return 2*k*k + 4*(i-1)*(k-1) ; }
964 return 2*k*k + 4*(i-1)*(k-1) + 3*(k-1) + j ;
967 std::ostringstream message;
968 message <<
"Not correct side number: "
970 <<
"iside is " << iside <<
" but should be "
971 <<
"0,1,2,3,4 or 5" <<
".";
972 G4Exception(
"G4TwistSurface::G4GetNode()",
"GeomSolids0002",
1008 if ( ( i>0 && i<n-2 ) && ( j>0 && j<k-2 ) )
1015 if ( orientation < 0 ) { number = ( 3 - number ) ; }
1018 if ( ( j>=1 && j<=k-3 ) )
1022 return ( number == 3 ) ? 1 : -1 ;
1027 return ( number == 1 ) ? 1 : -1 ;
1030 std::ostringstream message;
1031 message <<
"Not correct face number: " <<
GetName() <<
" !";
1032 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1036 if ( ( i>=1 && i<=n-3 ) )
1040 return ( number == 0 ) ? 1 : -1 ;
1045 return ( number == 2 ) ? 1 : -1 ;
1048 std::ostringstream message;
1049 message <<
"Not correct face number: " <<
GetName() <<
" !";
1050 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1055 if ( i == 0 && j == 0 )
1057 return ( number == 0 || number == 3 ) ? 1 : -1 ;
1059 if ( i == 0 && j == k-2 )
1061 return ( number == 2 || number == 3 ) ? 1 : -1 ;
1063 if ( i == n-2 && j == k-2 )
1065 return ( number == 1 || number == 2 ) ? 1 : -1 ;
1067 if ( i == n-2 && j == 0 )
1069 return ( number == 0 || number == 1 ) ? 1 : -1 ;
1072 std::ostringstream message;
1073 message <<
"Not correct face number: " <<
GetName() <<
" !";
1074 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
"GeomSolids0003",
1091 G4cout <<
"/* G4VTwistSurface::DebugPrint():--------------------------"
1094 G4cout <<
"/* Axis = " << std::hex <<
fAxis[0] <<
" "
1095 << std::hex <<
fAxis[1]
1096 <<
" (0,1,2,3,5 = kXAxis,kYAxis,kZAxis,kRho,kPhi)"
1098 G4cout <<
"/* BoundaryLimit(in local) fAxis0(min, max) = ("<<
fAxisMin[0]
1100 G4cout <<
"/* BoundaryLimit(in local) fAxis1(min, max) = ("<<
fAxisMin[1]
1106 G4cout <<
"/*---------------------------------------------------------"
1121 fDistance[i] = kInfinity;
1123 fIsValid[i] =
false;
1124 fXX[i].set(kInfinity, kInfinity, kInfinity);
1127 fLastp.set(kInfinity, kInfinity, kInfinity);
1128 fLastv.set(kInfinity, kInfinity, kInfinity);
1153 fDistance[i] = dist;
1154 fAreacode[i] = areacode;
1155 fIsValid[i] = isvalid;
1158 fLastValidate = validate;
1165 G4Exception(
"G4VTwistSurface::CurrentStatus::SetCurrentStatus()",
1174 fLastv.set(kInfinity, kInfinity, kInfinity);
1188 if (validate == fLastValidate && p !=
nullptr && *p == fLastp)
1190 if (v ==
nullptr || (*v == fLastv)) {
return; }
1195 fDistance[i] = kInfinity;
1197 fIsValid[i] =
false;
1201 fLastp.set(kInfinity, kInfinity, kInfinity);
1202 fLastv.set(kInfinity, kInfinity, kInfinity);
1213 G4cout <<
"CurrentStatus::Dist0,1= " << fDistance[0]
1214 <<
" " << fDistance[1] <<
" areacode = " << fAreacode[0]
1215 <<
" " << fAreacode[1] <<
G4endl;
1229 const G4int& boundarytype)
1231 fBoundaryAcode = areacode;
1232 fBoundaryDirection = d;
1234 fBoundaryType = boundarytype;
1242 return fBoundaryAcode == -1;
1252 G4int& boundarytype)
const
1258 if (((areacode &
sAxis0) != 0) && ((areacode &
sAxis1) != 0))
1260 std::ostringstream message;
1261 message <<
"Located in the corner area." <<
G4endl
1262 <<
" This function returns a direction vector of "
1263 <<
"a boundary line." <<
G4endl
1264 <<
" areacode = " << areacode;
1265 G4Exception(
"G4VTwistSurface::Boundary::GetBoundaryParameters()",
1272 d = fBoundaryDirection;
1274 boundarytype = fBoundaryType;
G4double C(G4double temp)
G4double B(G4double temperature)
G4double D(G4double temp)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::HepRotation G4RotationMatrix
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
Hep3Vector cross(const Hep3Vector &) const
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4double GetAngularTolerance() const
void SetFields(const G4int &areacode, const G4ThreeVector &d, const G4ThreeVector &x0, const G4int &boundarytype)
G4bool GetBoundaryParameters(const G4int &areacode, G4ThreeVector &d, G4ThreeVector &x0, G4int &boundarytype) const
CurrentStatus()
Internal class defining the surface status.
void SetCurrentStatus(G4int i, G4ThreeVector &xx, G4double &dist, G4int &areacode, G4bool &isvalid, G4int nxx, EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
void ResetfDone(EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
virtual G4ThreeVector GetNormal(const G4ThreeVector &p, G4bool isGlobal)=0
virtual G4int AmIOnLeftSide(const G4ThreeVector &me, const G4ThreeVector &vec, G4bool withTol=true)
static const G4int sAxisMask
static const G4int sC0Min1Min
static const G4int sC0Min1Max
G4VTwistSurface(const G4String &name)
G4bool IsAxis1(G4int areacode) const
G4int GetNode(G4int i, G4int j, G4int m, G4int n, G4int iside)
static const G4int sOutside
G4ThreeVector ComputeGlobalDirection(const G4ThreeVector &lp) const
G4bool IsCorner(G4int areacode, G4bool testbitmode=false) const
static const G4int sAxisMax
static const G4int sAxis0
G4int GetFace(G4int i, G4int j, G4int m, G4int n, G4int iside)
void GetBoundaryAxis(G4int areacode, EAxis axis[]) const
const G4String & GetName() const
virtual G4double DistanceTo(const G4ThreeVector &gp, G4ThreeVector &gxx)
G4bool IsAxis0(G4int areacode) const
G4int GetEdgeVisibility(G4int i, G4int j, G4int m, G4int n, G4int number, G4int orientation)
virtual G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)=0
G4VTwistSurface ** GetNeighbours()
G4double DistanceToLine(const G4ThreeVector &p, const G4ThreeVector &x0, const G4ThreeVector &d, G4ThreeVector &xx)
void GetBoundaryLimit(G4int areacode, G4double limit[]) const
static const G4int sAxisPhi
static const G4int sAxisMin
static const G4int sC0Max1Max
virtual G4double DistanceToOut(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
virtual G4double DistanceToIn(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
static const G4int sAxis1
virtual G4ThreeVector GetBoundaryAtPZ(G4int areacode, const G4ThreeVector &p) const
G4bool IsInside(G4int areacode, G4bool testbitmode=false) const
virtual void SetBoundary(const G4int &axiscode, const G4ThreeVector &direction, const G4ThreeVector &x0, const G4int &boundarytype)
static const G4int sAxisRho
void SetCorner(G4int areacode, G4double x, G4double y, G4double z)
G4ThreeVector GetCorner(G4int areacode) const
static const G4int sBoundary
static const G4int sAxisZ
virtual G4double DistanceToBoundary(G4int areacode, G4ThreeVector &xx, const G4ThreeVector &p)
static const G4int sCorner
static const G4int sC0Max1Min
static const G4int sInside
G4bool IsSameBoundary(G4VTwistSurface *surface1, G4int areacode1, G4VTwistSurface *surface2, G4int areacode2) const
static const G4int sAxisY
static const G4int sSizeMask
static const G4int sAxisX
static const G4int sAreaMask
G4bool IsBoundary(G4int areacode, G4bool testbitmode=false) const
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const
G4SurfCurNormal fCurrentNormal
virtual void GetBoundaryParameters(const G4int &areacode, G4ThreeVector &d, G4ThreeVector &x0, G4int &boundarytype) const
const axis_t axis_to_type< N >::axis