65 : fIsValidNorm(false), fName(name)
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);
99 : fIsValidNorm(false), fName(name)
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;
167 if (fAmIOnLeftSide.me == me
168 && fAmIOnLeftSide.vec == vec
169 && fAmIOnLeftSide.withTol == withtol)
171 return fAmIOnLeftSide.amIOnLeftSide;
174 fAmIOnLeftSide.me = me;
175 fAmIOnLeftSide.vec = vec;
176 fAmIOnLeftSide.withTol = withtol;
184 G4double metcrossvect = met.
x() * vect.
y() - met.
y() * vect.
x();
188 if (met.
x() * ivect.
y() - met.
y() * ivect.
x() > 0 &&
190 fAmIOnLeftSide.amIOnLeftSide = 1;
191 }
else if (met.
x() * rvect.
y() - met.
y() * rvect.
x() < 0 &&
193 fAmIOnLeftSide.amIOnLeftSide = -1;
195 fAmIOnLeftSide.amIOnLeftSide = 0;
200 if (metcrossvect > 0) {
201 fAmIOnLeftSide.amIOnLeftSide = 1;
202 }
else if (metcrossvect < 0 ) {
203 fAmIOnLeftSide.amIOnLeftSide = -1;
205 fAmIOnLeftSide.amIOnLeftSide = 0;
210 G4cout <<
" === G4VTwistSurface::AmIOnLeftSide() =============="
212 G4cout <<
" Name , returncode : " << fName <<
" "
213 << fAmIOnLeftSide.amIOnLeftSide <<
G4endl;
214 G4cout <<
" me, vec : " << std::setprecision(14) << me
216 G4cout <<
" met, vect : " << met <<
" " << vect <<
G4endl;
217 G4cout <<
" ivec, rvec : " << ivect <<
" " << rvect <<
G4endl;
221 G4cout <<
" =============================================="
225 return fAmIOnLeftSide.amIOnLeftSide;
251 std::ostringstream message;
252 message <<
"Point is in the corner area." <<
G4endl
253 <<
" Point is in the corner area. This function returns"
255 <<
" a direction vector of a boundary line." <<
G4endl
256 <<
" areacode = " << areacode;
257 G4Exception(
"G4VTwistSurface::DistanceToBoundary()",
"GeomSolids0003",
266 xx.
set(t*p.
x(), t*p.
y(), x0.
z());
267 dist = (xx - p).mag();
278 std::ostringstream message;
279 message <<
"Bad areacode of boundary." <<
G4endl
280 <<
" areacode = " << areacode;
281 G4Exception(
"G4VTwistSurface::DistanceToBoundary()",
"GeomSolids0003",
295 G4cout <<
" ~~~~ G4VTwistSurface::DistanceToIn(p,v) - Start ~~~~" <<
G4endl;
299 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
309 distance[i] = kInfinity ;
323 for (
G4int i=0; i<nxx; ++i)
338 if ((normal * gv) >= 0)
342 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
343 <<
"particle goes outword the surface." <<
G4endl;
354 if (distance[i] < bestdistance)
356 bestdistance = distance[i];
360 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
361 <<
" areacode sInside name, distance = "
362 << fName <<
" "<< bestdistance <<
G4endl;
374 G4bool isaccepted[2] = {
false,
false};
377 for (
G4int j=0; j<nneighbours; ++j)
389 tmpdist[l] = kInfinity ;
391 tmpisvalid[l] = false ;
395 gp, gv, tmpgxx, tmpdist,
396 tmpareacode, tmpisvalid,
400 for (
G4int k=0; k< tmpnxx; ++k)
411 G4cout <<
" G4VTwistSurface:DistanceToIn(p,v): "
412 <<
" intersection "<< tmpgxx[k] <<
G4endl
413 <<
" is inside of neighbour surface of " << fName
414 <<
" . returning kInfinity." <<
G4endl;
415 G4cout <<
"~~ G4VTwistSurface::DistanceToIn(p,v) - return ~~"
419 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
422 if (tmpisvalid[k])
return kInfinity;
432 neighbours[j], tmpareacode[k]))
436 neighbournormal = neighbours[j]->
GetNormal(tmpgxx[k],
true);
437 if (neighbournormal * gv < 0) isaccepted[j] =
true;
444 if (nneighbours == 1) isaccepted[1] =
true;
450 if (isaccepted[0] ==
true && isaccepted[1] ==
true)
452 if (distance[i] < bestdistance)
454 bestdistance = distance[i];
458 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
459 <<
" areacode sBoundary & sBoundary distance = "
460 << fName <<
" " << distance[i] <<
G4endl;
472 G4cout <<
"~~~ G4VTwistSurface::DistanceToIn(p,v) - return ~~~" <<
G4endl;
475 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
479 G4cout <<
"~~~ G4VTwistSurface::DistanceToIn(p,v) : return ~~~" <<
G4endl;
480 G4cout <<
" Name, i : " << fName <<
" , " << besti <<
G4endl;
483 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
499 G4cout <<
"~~~~~ G4VTwistSurface::DistanceToOut(p,v) - Start ~~~~" <<
G4endl;
503 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
513 distance[i] = kInfinity ;
524 for (
G4int i=0; i<nxx; ++i)
532 if (normal * gv <= 0)
536 G4cout <<
" G4VTwistSurface::DistanceToOut(p,v): normal*gv < 0 "
537 << fName <<
" " << normal
544 if (distance[i] < bestdistance)
546 bestdistance = distance[i];
555 G4cout <<
"~~ G4VTwistSurface::DistanceToOut(p,v) - return ~~" <<
G4endl;
559 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
563 G4cout <<
"~~ G4VTwistSurface::DistanceToOut(p,v) : return ~~" <<
G4endl;
564 G4cout <<
" Name, i : " << fName <<
" , " << i <<
G4endl;
567 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
581 G4cout <<
"~~~~~ G4VTwistSurface::DistanceTo(p) - Start ~~~~~~~~~" <<
G4endl;
584 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
594 distance[i] = kInfinity ;
602 G4cout <<
"~~~~~ G4VTwistSurface::DistanceTo(p) - return ~~~~~~~~" <<
G4endl;
606 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
625 G4bool testbitmode =
true;
629 if (iscorner[0] && iscorner[1])
637 if ((corner1 - corner2).mag() <
kCarTolerance) {
return true; }
638 else {
return false; }
640 else if ((
IsBoundary(areacode1, testbitmode) && (!iscorner[0])) &&
641 (
IsBoundary(areacode2, testbitmode) && (!iscorner[1])))
657 else {
return false; }
671 G4int& boundarytype)
const
677 for (
G4int i=0; i<4; ++i)
686 std::ostringstream message;
687 message <<
"Not registered boundary." <<
G4endl
688 <<
" Boundary at areacode " << std::hex << areacode
690 <<
" is not registered.";
691 G4Exception(
"G4VTwistSurface::GetBoundaryParameters()",
"GeomSolids0002",
707 std::ostringstream message;
708 message <<
"Point is in the corner area." <<
G4endl
709 <<
" This function returns "
710 <<
"a direction vector of a boundary line." <<
G4endl
711 <<
" areacode = " << areacode;
712 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0003",
721 for (
G4int i=0; i<4; ++i)
733 std::ostringstream message;
734 message <<
"Not registered boundary." <<
G4endl
735 <<
" Boundary at areacode " << areacode <<
G4endl
736 <<
" is not registered.";
737 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0002",
744 std::ostringstream message;
745 message <<
"Not a z-depended line boundary." <<
G4endl
746 <<
" Boundary at areacode " << areacode <<
G4endl
747 <<
" is not a z-depended line.";
748 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0002",
751 return ((p.
z() - x0.
z()) / d.
z()) * d + x0;
762 std::ostringstream message;
763 message <<
"Area code must represents corner." <<
G4endl
764 <<
" areacode " << areacode;
765 G4Exception(
"G4VTwistSurface::SetCorner()",
"GeomSolids0002",
770 fCorners[0].
set(x, y, z);
772 fCorners[1].
set(x, y, z);
774 fCorners[2].
set(x, y, z);
776 fCorners[3].
set(x, y, z);
786 G4Exception(
"G4VTwistSurface::GetBoundaryAxis()",
"GeomSolids0003",
789 for (
G4int i=0; i<2; ++i)
791 G4int whichaxis = 0 ;
801 if (axiscode == (whichaxis &
sAxisX)) {
803 }
else if (axiscode == (whichaxis &
sAxisY)) {
805 }
else if (axiscode == (whichaxis &
sAxisZ)) {
807 }
else if (axiscode == (whichaxis &
sAxisRho)) {
809 }
else if (axiscode == (whichaxis &
sAxisPhi)) {
812 std::ostringstream message;
813 message <<
"Not supported areacode." <<
G4endl
814 <<
" areacode " << areacode;
815 G4Exception(
"G4VTwistSurface::GetBoundaryAxis()",
"GeomSolids0001",
852 std::ostringstream message;
853 message <<
"Not located on a boundary!" <<
G4endl
854 <<
" areacode " << areacode;
855 G4Exception(
"G4VTwistSurface::GetBoundaryLimit()",
"GeomSolids1002",
866 const G4int& boundarytype)
875 for (
auto i=0; i<4; ++i)
877 if (fBoundaries[i].IsEmpty())
879 fBoundaries[i].
SetFields(axiscode, direction,
888 G4Exception(
"G4VTwistSurface::SetBoundary()",
"GeomSolids0003",
894 std::ostringstream message;
895 message <<
"Invalid axis-code." <<
G4endl
897 << std::hex << axiscode << std::dec;
898 G4Exception(
"G4VTwistSurface::SetBoundary()",
"GeomSolids0003",
913 return i * ( k - 1 ) + j ;
916 else if ( iside == 1 ) {
917 return (k-1)*(k-1) + i*(k-1) + j ;
920 else if ( iside == 2 ) {
921 return 2*(k-1)*(k-1) + i*(k-1) + j ;
924 else if ( iside == 3 ) {
925 return 2*(k-1)*(k-1) + (n-1)*(k-1) + i*(k-1) + j ;
928 else if ( iside == 4 ) {
929 return 2*(k-1)*(k-1) + 2*(n-1)*(k-1) + i*(k-1) + j ;
932 else if ( iside == 5 ) {
933 return 2*(k-1)*(k-1) + 3*(n-1)*(k-1) + i*(k-1) + j ;
937 std::ostringstream message;
938 message <<
"Not correct side number: "
940 <<
"iside is " << iside <<
" but should be "
941 <<
"0,1,2,3,4 or 5" <<
".";
942 G4Exception(
"G4TwistSurface::G4GetFace()",
"GeomSolids0002",
970 return k*k + i*k + j ;
973 else if ( iside == 2 )
976 if ( i == 0 ) {
return j ; }
977 else if ( i == n-1 ) {
return k*k + j ; }
978 else {
return 2*k*k + 4*(i-1)*(k-1) + j ; }
981 else if ( iside == 3 )
984 if ( i == 0 ) {
return (j+1)*k - 1 ; }
985 else if ( i == n-1 ) {
return k*k + (j+1)*k - 1 ; }
988 return 2*k*k + 4*(i-1)*(k-1) + (k-1) + j ;
991 else if ( iside == 4 )
994 if ( i == 0 ) {
return k*k - 1 - j ; }
995 else if ( i == n-1 ) {
return 2*k*k - 1 - j ; }
998 return 2*k*k + 4*(i-1)*(k-1) + 2*(k-1) + j ;
1001 else if ( iside == 5 )
1004 if ( i == 0 ) {
return k*k - (j+1)*k ; }
1005 else if ( i == n-1) {
return 2*k*k - (j+1)*k ; }
1008 if ( j == k-1 ) {
return 2*k*k + 4*(i-1)*(k-1) ; }
1011 return 2*k*k + 4*(i-1)*(k-1) + 3*(k-1) + j ;
1017 std::ostringstream message;
1018 message <<
"Not correct side number: "
1020 <<
"iside is " << iside <<
" but should be "
1021 <<
"0,1,2,3,4 or 5" <<
".";
1022 G4Exception(
"G4TwistSurface::G4GetNode()",
"GeomSolids0002",
1058 if ( ( i>0 && i<n-2 ) && ( j>0 && j<k-2 ) )
1065 if ( orientation < 0 ) { number = ( 3 - number ) ; }
1068 if ( ( j>=1 && j<=k-3 ) )
1071 return ( number == 3 ) ? 1 : -1 ;
1074 else if ( i == n-2 ) {
1075 return ( number == 1 ) ? 1 : -1 ;
1080 std::ostringstream message;
1081 message <<
"Not correct face number: " <<
GetName() <<
" !";
1082 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1087 if ( ( i>=1 && i<=n-3 ) )
1090 return ( number == 0 ) ? 1 : -1 ;
1093 else if ( j == k-2 ) {
1094 return ( number == 2 ) ? 1 : -1 ;
1099 std::ostringstream message;
1100 message <<
"Not correct face number: " <<
GetName() <<
" !";
1101 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1107 if ( i == 0 && j == 0 ) {
1108 return ( number == 0 || number == 3 ) ? 1 : -1 ;
1110 else if ( i == 0 && j == k-2 ) {
1111 return ( number == 2 || number == 3 ) ? 1 : -1 ;
1113 else if ( i == n-2 && j == k-2 ) {
1114 return ( number == 1 || number == 2 ) ? 1 : -1 ;
1116 else if ( i == n-2 && j == 0 ) {
1117 return ( number == 0 || number == 1 ) ? 1 : -1 ;
1121 std::ostringstream message;
1122 message <<
"Not correct face number: " <<
GetName() <<
" !";
1123 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1127 std::ostringstream message;
1128 message <<
"Not correct face number: " <<
GetName() <<
" !";
1129 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
"GeomSolids0003",
1146 G4cout <<
"/* G4VTwistSurface::DebugPrint():--------------------------"
1149 G4cout <<
"/* Axis = " << std::hex <<
fAxis[0] <<
" "
1150 << std::hex <<
fAxis[1]
1151 <<
" (0,1,2,3,5 = kXAxis,kYAxis,kZAxis,kRho,kPhi)"
1153 G4cout <<
"/* BoundaryLimit(in local) fAxis0(min, max) = ("<<
fAxisMin[0]
1155 G4cout <<
"/* BoundaryLimit(in local) fAxis1(min, max) = ("<<
fAxisMin[1]
1161 G4cout <<
"/*---------------------------------------------------------"
1176 fDistance[i] = kInfinity;
1178 fIsValid[i] =
false;
1179 fXX[i].
set(kInfinity, kInfinity, kInfinity);
1182 fLastp.
set(kInfinity, kInfinity, kInfinity);
1183 fLastv.
set(kInfinity, kInfinity, kInfinity);
1209 fDistance[i] = dist;
1210 fAreacode[i] = areacode;
1211 fIsValid[i] = isvalid;
1214 fLastValidate = validate;
1221 G4Exception(
"G4VTwistSurface::CurrentStatus::SetCurrentStatus()",
1230 fLastv.
set(kInfinity, kInfinity, kInfinity);
1244 if (validate == fLastValidate && p !=
nullptr && *p == fLastp)
1246 if (v ==
nullptr || (*v == fLastv))
return;
1251 fDistance[i] = kInfinity;
1253 fIsValid[i] =
false;
1257 fLastp.
set(kInfinity, kInfinity, kInfinity);
1258 fLastv.set(kInfinity, kInfinity, kInfinity);
1269 G4cout <<
"CurrentStatus::Dist0,1= " << fDistance[0]
1270 <<
" " << fDistance[1] <<
" areacode = " << fAreacode[0]
1271 <<
" " << fAreacode[1] <<
G4endl;
1282 : fBoundaryAcode(-1), fBoundaryType(0)
1300 const G4int& boundarytype)
1302 fBoundaryAcode = areacode;
1303 fBoundaryDirection = d;
1305 fBoundaryType = boundarytype;
1313 if (fBoundaryAcode == -1)
return true;
1324 G4int& boundarytype)
const
1332 std::ostringstream message;
1333 message <<
"Located in the corner area." <<
G4endl
1334 <<
" This function returns a direction vector of "
1335 <<
"a boundary line." <<
G4endl
1336 <<
" areacode = " << areacode;
1337 G4Exception(
"G4VTwistSurface::Boundary::GetBoundaryParameters()",
1344 d = fBoundaryDirection;
1346 boundarytype = fBoundaryType;
const G4double kCarTolerance
double B(double temperature)
double A(double temperature)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
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
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 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
virtual ~G4VTwistSurface()
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
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
virtual G4String GetName() const
virtual G4ThreeVector GetNormal(const G4ThreeVector &xx, G4bool isGlobal)=0
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