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;
165 if (fAmIOnLeftSide.me == me
166 && fAmIOnLeftSide.vec == vec
167 && fAmIOnLeftSide.withTol == withtol)
169 return fAmIOnLeftSide.amIOnLeftSide;
172 fAmIOnLeftSide.me = me;
173 fAmIOnLeftSide.vec = vec;
174 fAmIOnLeftSide.withTol = withtol;
182 G4double metcrossvect = met.
x() * vect.
y() - met.
y() * vect.
x();
186 if (met.
x() * ivect.
y() - met.
y() * ivect.
x() > 0 &&
188 fAmIOnLeftSide.amIOnLeftSide = 1;
189 }
else if (met.
x() * rvect.
y() - met.
y() * rvect.
x() < 0 &&
191 fAmIOnLeftSide.amIOnLeftSide = -1;
193 fAmIOnLeftSide.amIOnLeftSide = 0;
198 if (metcrossvect > 0) {
199 fAmIOnLeftSide.amIOnLeftSide = 1;
200 }
else if (metcrossvect < 0 ) {
201 fAmIOnLeftSide.amIOnLeftSide = -1;
203 fAmIOnLeftSide.amIOnLeftSide = 0;
208 G4cout <<
" === G4VTwistSurface::AmIOnLeftSide() =============="
210 G4cout <<
" Name , returncode : " << fName <<
" "
211 << fAmIOnLeftSide.amIOnLeftSide <<
G4endl;
212 G4cout <<
" me, vec : " << std::setprecision(14) << me
214 G4cout <<
" met, vect : " << met <<
" " << vect <<
G4endl;
215 G4cout <<
" ivec, rvec : " << ivect <<
" " << rvect <<
G4endl;
219 G4cout <<
" =============================================="
223 return fAmIOnLeftSide.amIOnLeftSide;
249 std::ostringstream message;
250 message <<
"Point is in the corner area." <<
G4endl
251 <<
" Point is in the corner area. This function returns"
253 <<
" a direction vector of a boundary line." <<
G4endl
254 <<
" areacode = " << areacode;
255 G4Exception(
"G4VTwistSurface::DistanceToBoundary()",
"GeomSolids0003",
264 xx.
set(t*p.
x(), t*p.
y(), x0.
z());
265 dist = (xx - p).mag();
276 std::ostringstream message;
277 message <<
"Bad areacode of boundary." <<
G4endl
278 <<
" areacode = " << areacode;
279 G4Exception(
"G4VTwistSurface::DistanceToBoundary()",
"GeomSolids0003",
293 G4cout <<
" ~~~~ G4VTwistSurface::DistanceToIn(p,v) - Start ~~~~" <<
G4endl;
297 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
307 distance[i] = kInfinity ;
321 for (
G4int i=0; i<nxx; ++i)
336 if ((normal * gv) >= 0)
340 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
341 <<
"particle goes outword the surface." <<
G4endl;
352 if (distance[i] < bestdistance)
354 bestdistance = distance[i];
358 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
359 <<
" areacode sInside name, distance = "
360 << fName <<
" "<< bestdistance <<
G4endl;
372 G4bool isaccepted[2] = {
false,
false};
375 for (
G4int j=0; j<nneighbours; ++j)
387 tmpdist[l] = kInfinity ;
389 tmpisvalid[l] = false ;
393 gp, gv, tmpgxx, tmpdist,
394 tmpareacode, tmpisvalid,
398 for (
G4int k=0; k< tmpnxx; ++k)
409 G4cout <<
" G4VTwistSurface:DistanceToIn(p,v): "
410 <<
" intersection "<< tmpgxx[k] <<
G4endl
411 <<
" is inside of neighbour surface of " << fName
412 <<
" . returning kInfinity." <<
G4endl;
413 G4cout <<
"~~ G4VTwistSurface::DistanceToIn(p,v) - return ~~"
417 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
420 if (tmpisvalid[k])
return kInfinity;
430 neighbours[j], tmpareacode[k]))
434 neighbournormal = neighbours[j]->
GetNormal(tmpgxx[k],
true);
435 if (neighbournormal * gv < 0) isaccepted[j] =
true;
442 if (nneighbours == 1) isaccepted[1] =
true;
448 if (isaccepted[0] && isaccepted[1])
450 if (distance[i] < bestdistance)
452 bestdistance = distance[i];
456 G4cout <<
" G4VTwistSurface::DistanceToIn(p,v): "
457 <<
" areacode sBoundary & sBoundary distance = "
458 << fName <<
" " << distance[i] <<
G4endl;
470 G4cout <<
"~~~ G4VTwistSurface::DistanceToIn(p,v) - return ~~~" <<
G4endl;
473 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
477 G4cout <<
"~~~ G4VTwistSurface::DistanceToIn(p,v) : return ~~~" <<
G4endl;
478 G4cout <<
" Name, i : " << fName <<
" , " << besti <<
G4endl;
481 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
497 G4cout <<
"~~~~~ G4VTwistSurface::DistanceToOut(p,v) - Start ~~~~" <<
G4endl;
501 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
511 distance[i] = kInfinity ;
522 for (
G4int i=0; i<nxx; ++i)
530 if (normal * gv <= 0)
534 G4cout <<
" G4VTwistSurface::DistanceToOut(p,v): normal*gv < 0 "
535 << fName <<
" " << normal
542 if (distance[i] < bestdistance)
544 bestdistance = distance[i];
553 G4cout <<
"~~ G4VTwistSurface::DistanceToOut(p,v) - return ~~" <<
G4endl;
557 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
561 G4cout <<
"~~ G4VTwistSurface::DistanceToOut(p,v) : return ~~" <<
G4endl;
562 G4cout <<
" Name, i : " << fName <<
" , " << i <<
G4endl;
565 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
579 G4cout <<
"~~~~~ G4VTwistSurface::DistanceTo(p) - Start ~~~~~~~~~" <<
G4endl;
582 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
592 distance[i] = kInfinity ;
600 G4cout <<
"~~~~~ G4VTwistSurface::DistanceTo(p) - return ~~~~~~~~" <<
G4endl;
604 G4cout <<
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" <<
G4endl;
623 G4bool testbitmode =
true;
627 if (iscorner[0] && iscorner[1])
637 else if ((
IsBoundary(areacode1, testbitmode) && (!iscorner[0])) &&
638 (
IsBoundary(areacode2, testbitmode) && (!iscorner[1])))
667 G4int& boundarytype)
const
673 for (
const auto & boundary : fBoundaries)
675 if (boundary.GetBoundaryParameters(areacode, d, x0, boundarytype))
681 std::ostringstream message;
682 message <<
"Not registered boundary." <<
G4endl
683 <<
" Boundary at areacode " << std::hex << areacode
685 <<
" is not registered.";
686 G4Exception(
"G4VTwistSurface::GetBoundaryParameters()",
"GeomSolids0002",
700 if (((areacode &
sAxis0) != 0) && ((areacode &
sAxis1) != 0))
702 std::ostringstream message;
703 message <<
"Point is in the corner area." <<
G4endl
704 <<
" This function returns "
705 <<
"a direction vector of a boundary line." <<
G4endl
706 <<
" areacode = " << areacode;
707 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0003",
713 G4int boundarytype = 0;
716 for (
const auto & boundary : fBoundaries)
718 if (boundary.GetBoundaryParameters(areacode, d, x0, boundarytype))
727 std::ostringstream message;
728 message <<
"Not registered boundary." <<
G4endl
729 <<
" Boundary at areacode " << areacode <<
G4endl
730 <<
" is not registered.";
731 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0002",
738 std::ostringstream message;
739 message <<
"Not a z-depended line boundary." <<
G4endl
740 <<
" Boundary at areacode " << areacode <<
G4endl
741 <<
" is not a z-depended line.";
742 G4Exception(
"G4VTwistSurface::GetBoundaryAtPZ()",
"GeomSolids0002",
745 return ((p.
z() - x0.
z()) / d.
z()) * d + x0;
756 std::ostringstream message;
757 message <<
"Area code must represents corner." <<
G4endl
758 <<
" areacode " << areacode;
759 G4Exception(
"G4VTwistSurface::SetCorner()",
"GeomSolids0002",
764 fCorners[0].
set(x, y, z);
766 fCorners[1].
set(x, y, z);
768 fCorners[2].
set(x, y, z);
770 fCorners[3].
set(x, y, z);
780 G4Exception(
"G4VTwistSurface::GetBoundaryAxis()",
"GeomSolids0003",
783 for (
G4int i=0; i<2; ++i)
785 G4int whichaxis = 0 ;
795 if (axiscode == (whichaxis &
sAxisX)) {
797 }
else if (axiscode == (whichaxis &
sAxisY)) {
799 }
else if (axiscode == (whichaxis &
sAxisZ)) {
801 }
else if (axiscode == (whichaxis &
sAxisRho)) {
803 }
else if (axiscode == (whichaxis &
sAxisPhi)) {
806 std::ostringstream message;
807 message <<
"Not supported areacode." <<
G4endl
808 <<
" areacode " << areacode;
809 G4Exception(
"G4VTwistSurface::GetBoundaryAxis()",
"GeomSolids0001",
821 if ((areacode &
sCorner) != 0) {
835 }
else if ((areacode &
sBoundary) != 0) {
846 std::ostringstream message;
847 message <<
"Not located on a boundary!" <<
G4endl
848 <<
" areacode " << areacode;
849 G4Exception(
"G4VTwistSurface::GetBoundaryLimit()",
"GeomSolids1002",
860 const G4int& boundarytype)
869 for (
auto & boundary : fBoundaries)
871 if (boundary.IsEmpty())
873 boundary.SetFields(axiscode, direction, x0, boundarytype);
881 G4Exception(
"G4VTwistSurface::SetBoundary()",
"GeomSolids0003",
887 std::ostringstream message;
888 message <<
"Invalid axis-code." <<
G4endl
890 << std::hex << axiscode << std::dec;
891 G4Exception(
"G4VTwistSurface::SetBoundary()",
"GeomSolids0003",
906 return i * ( k - 1 ) + j ;
909 else if ( iside == 1 ) {
910 return (k-1)*(k-1) + i*(k-1) + j ;
913 else if ( iside == 2 ) {
914 return 2*(k-1)*(k-1) + i*(k-1) + j ;
917 else if ( iside == 3 ) {
918 return 2*(k-1)*(k-1) + (n-1)*(k-1) + i*(k-1) + j ;
921 else if ( iside == 4 ) {
922 return 2*(k-1)*(k-1) + 2*(n-1)*(k-1) + i*(k-1) + j ;
925 else if ( iside == 5 ) {
926 return 2*(k-1)*(k-1) + 3*(n-1)*(k-1) + i*(k-1) + j ;
930 std::ostringstream message;
931 message <<
"Not correct side number: "
933 <<
"iside is " << iside <<
" but should be "
934 <<
"0,1,2,3,4 or 5" <<
".";
935 G4Exception(
"G4TwistSurface::G4GetFace()",
"GeomSolids0002",
963 return k*k + i*k + j ;
966 else if ( iside == 2 )
969 if ( i == 0 ) {
return j ; }
970 else if ( i == n-1 ) {
return k*k + j ; }
971 else {
return 2*k*k + 4*(i-1)*(k-1) + j ; }
974 else if ( iside == 3 )
977 if ( i == 0 ) {
return (j+1)*k - 1 ; }
978 else if ( i == n-1 ) {
return k*k + (j+1)*k - 1 ; }
981 return 2*k*k + 4*(i-1)*(k-1) + (k-1) + j ;
984 else if ( iside == 4 )
987 if ( i == 0 ) {
return k*k - 1 - j ; }
988 else if ( i == n-1 ) {
return 2*k*k - 1 - j ; }
991 return 2*k*k + 4*(i-1)*(k-1) + 2*(k-1) + j ;
994 else if ( iside == 5 )
997 if ( i == 0 ) {
return k*k - (j+1)*k ; }
998 else if ( i == n-1) {
return 2*k*k - (j+1)*k ; }
1001 if ( j == k-1 ) {
return 2*k*k + 4*(i-1)*(k-1) ; }
1004 return 2*k*k + 4*(i-1)*(k-1) + 3*(k-1) + j ;
1010 std::ostringstream message;
1011 message <<
"Not correct side number: "
1013 <<
"iside is " << iside <<
" but should be "
1014 <<
"0,1,2,3,4 or 5" <<
".";
1015 G4Exception(
"G4TwistSurface::G4GetNode()",
"GeomSolids0002",
1051 if ( ( i>0 && i<n-2 ) && ( j>0 && j<k-2 ) )
1058 if ( orientation < 0 ) { number = ( 3 - number ) ; }
1061 if ( ( j>=1 && j<=k-3 ) )
1064 return ( number == 3 ) ? 1 : -1 ;
1067 else if ( i == n-2 ) {
1068 return ( number == 1 ) ? 1 : -1 ;
1073 std::ostringstream message;
1074 message <<
"Not correct face number: " <<
GetName() <<
" !";
1075 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1080 if ( ( i>=1 && i<=n-3 ) )
1083 return ( number == 0 ) ? 1 : -1 ;
1086 else if ( j == k-2 ) {
1087 return ( number == 2 ) ? 1 : -1 ;
1092 std::ostringstream message;
1093 message <<
"Not correct face number: " <<
GetName() <<
" !";
1094 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1100 if ( i == 0 && j == 0 ) {
1101 return ( number == 0 || number == 3 ) ? 1 : -1 ;
1103 else if ( i == 0 && j == k-2 ) {
1104 return ( number == 2 || number == 3 ) ? 1 : -1 ;
1106 else if ( i == n-2 && j == k-2 ) {
1107 return ( number == 1 || number == 2 ) ? 1 : -1 ;
1109 else if ( i == n-2 && j == 0 ) {
1110 return ( number == 0 || number == 1 ) ? 1 : -1 ;
1114 std::ostringstream message;
1115 message <<
"Not correct face number: " <<
GetName() <<
" !";
1116 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
1120 std::ostringstream message;
1121 message <<
"Not correct face number: " <<
GetName() <<
" !";
1122 G4Exception(
"G4TwistSurface::G4GetEdgeVisibility()",
"GeomSolids0003",
1139 G4cout <<
"/* G4VTwistSurface::DebugPrint():--------------------------"
1142 G4cout <<
"/* Axis = " << std::hex <<
fAxis[0] <<
" "
1143 << std::hex <<
fAxis[1]
1144 <<
" (0,1,2,3,5 = kXAxis,kYAxis,kZAxis,kRho,kPhi)"
1146 G4cout <<
"/* BoundaryLimit(in local) fAxis0(min, max) = ("<<
fAxisMin[0]
1148 G4cout <<
"/* BoundaryLimit(in local) fAxis1(min, max) = ("<<
fAxisMin[1]
1154 G4cout <<
"/*---------------------------------------------------------"
1169 fDistance[i] = kInfinity;
1171 fIsValid[i] =
false;
1172 fXX[i].
set(kInfinity, kInfinity, kInfinity);
1175 fLastp.
set(kInfinity, kInfinity, kInfinity);
1176 fLastv.
set(kInfinity, kInfinity, kInfinity);
1201 fDistance[i] = dist;
1202 fAreacode[i] = areacode;
1203 fIsValid[i] = isvalid;
1206 fLastValidate = validate;
1213 G4Exception(
"G4VTwistSurface::CurrentStatus::SetCurrentStatus()",
1222 fLastv.set(kInfinity, kInfinity, kInfinity);
1236 if (validate == fLastValidate && p !=
nullptr && *p == fLastp)
1238 if (v ==
nullptr || (*v == fLastv))
return;
1243 fDistance[i] = kInfinity;
1245 fIsValid[i] =
false;
1249 fLastp.set(kInfinity, kInfinity, kInfinity);
1250 fLastv.set(kInfinity, kInfinity, kInfinity);
1261 G4cout <<
"CurrentStatus::Dist0,1= " << fDistance[0]
1262 <<
" " << fDistance[1] <<
" areacode = " << fAreacode[0]
1263 <<
" " << fAreacode[1] <<
G4endl;
1289 const G4int& boundarytype)
1291 fBoundaryAcode = areacode;
1292 fBoundaryDirection = d;
1294 fBoundaryType = boundarytype;
1302 return fBoundaryAcode == -1;
1312 G4int& boundarytype)
const
1318 if (((areacode &
sAxis0) != 0) && ((areacode &
sAxis1) != 0))
1320 std::ostringstream message;
1321 message <<
"Located in the corner area." <<
G4endl
1322 <<
" This function returns a direction vector of "
1323 <<
"a boundary line." <<
G4endl
1324 <<
" areacode = " << areacode;
1325 G4Exception(
"G4VTwistSurface::Boundary::GetBoundaryParameters()",
1332 d = fBoundaryDirection;
1334 boundarytype = fBoundaryType;
const G4double kCarTolerance
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::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