Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4TwistBoxSide Class Reference

#include <G4TwistBoxSide.hh>

+ Inheritance diagram for G4TwistBoxSide:

Public Member Functions

 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)
 
virtual ~G4TwistBoxSide ()
 
virtual G4ThreeVector GetNormal (const G4ThreeVector &xx, G4bool isGlobal=false)
 
virtual G4int DistanceToSurface (const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)
 
virtual G4int DistanceToSurface (const G4ThreeVector &gp, G4ThreeVector gxx[], G4double distance[], G4int areacode[])
 
 G4TwistBoxSide (__void__ &)
 
- Public Member Functions inherited from G4VTwistSurface
 G4VTwistSurface (const G4String &name)
 
 G4VTwistSurface (const G4String &name, const G4RotationMatrix &rot, const G4ThreeVector &tlate, G4int handedness, const EAxis axis1, const EAxis axis2, G4double axis0min=-kInfinity, G4double axis1min=-kInfinity, G4double axis0max=kInfinity, G4double axis1max=kInfinity)
 
virtual ~G4VTwistSurface ()
 
virtual G4int AmIOnLeftSide (const G4ThreeVector &me, const G4ThreeVector &vec, G4bool withTol=true)
 
virtual G4double DistanceToBoundary (G4int areacode, G4ThreeVector &xx, const G4ThreeVector &p)
 
virtual G4double DistanceToIn (const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
 
virtual G4double DistanceToOut (const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector &gxxbest)
 
virtual G4double DistanceTo (const G4ThreeVector &gp, G4ThreeVector &gxx)
 
virtual G4int DistanceToSurface (const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)=0
 
virtual G4int DistanceToSurface (const G4ThreeVector &gp, G4ThreeVector gxx[], G4double distance[], G4int areacode[])=0
 
void DebugPrint () const
 
virtual G4ThreeVector GetNormal (const G4ThreeVector &xx, G4bool isGlobal)=0
 
virtual G4String GetName () const
 
virtual void GetBoundaryParameters (const G4int &areacode, G4ThreeVector &d, G4ThreeVector &x0, G4int &boundarytype) const
 
virtual G4ThreeVector GetBoundaryAtPZ (G4int areacode, const G4ThreeVector &p) const
 
G4double DistanceToPlaneWithV (const G4ThreeVector &p, const G4ThreeVector &v, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
 
G4double DistanceToPlane (const G4ThreeVector &p, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
 
G4double DistanceToPlane (const G4ThreeVector &p, const G4ThreeVector &x0, const G4ThreeVector &t1, const G4ThreeVector &t2, G4ThreeVector &xx, G4ThreeVector &n)
 
G4double DistanceToLine (const G4ThreeVector &p, const G4ThreeVector &x0, const G4ThreeVector &d, G4ThreeVector &xx)
 
G4bool IsAxis0 (G4int areacode) const
 
G4bool IsAxis1 (G4int areacode) const
 
G4bool IsOutside (G4int areacode) const
 
G4bool IsInside (G4int areacode, G4bool testbitmode=false) const
 
G4bool IsBoundary (G4int areacode, G4bool testbitmode=false) const
 
G4bool IsCorner (G4int areacode, G4bool testbitmode=false) const
 
G4bool IsValidNorm () const
 
G4bool IsSameBoundary (G4VTwistSurface *surface1, G4int areacode1, G4VTwistSurface *surface2, G4int areacode2) const
 
G4int GetAxisType (G4int areacode, G4int whichaxis) const
 
G4ThreeVector ComputeGlobalPoint (const G4ThreeVector &lp) const
 
G4ThreeVector ComputeLocalPoint (const G4ThreeVector &gp) const
 
G4ThreeVector ComputeGlobalDirection (const G4ThreeVector &lp) const
 
G4ThreeVector ComputeLocalDirection (const G4ThreeVector &gp) const
 
void SetAxis (G4int i, const EAxis axis)
 
void SetNeighbours (G4VTwistSurface *ax0min, G4VTwistSurface *ax1min, G4VTwistSurface *ax0max, G4VTwistSurface *ax1max)
 
virtual G4ThreeVector SurfacePoint (G4double, G4double, G4bool isGlobal=false)=0
 
virtual G4double GetBoundaryMin (G4double)=0
 
virtual G4double GetBoundaryMax (G4double)=0
 
virtual G4double GetSurfaceArea ()=0
 
virtual void GetFacets (G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)=0
 
G4int GetNode (G4int i, G4int j, G4int m, G4int n, G4int iside)
 
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)
 
 G4VTwistSurface (__void__ &)
 

Additional Inherited Members

- Public Types inherited from G4VTwistSurface
enum  EValidate { kDontValidate = 0 , kValidateWithTol = 1 , kValidateWithoutTol = 2 , kUninitialized = 3 }
 
- Static Public Attributes inherited from G4VTwistSurface
static const G4int sOutside = 0x00000000
 
static const G4int sInside = 0x10000000
 
static const G4int sBoundary = 0x20000000
 
static const G4int sCorner = 0x40000000
 
static const G4int sC0Min1Min = 0x40000101
 
static const G4int sC0Max1Min = 0x40000201
 
static const G4int sC0Max1Max = 0x40000202
 
static const G4int sC0Min1Max = 0x40000102
 
static const G4int sAxisMin = 0x00000101
 
static const G4int sAxisMax = 0x00000202
 
static const G4int sAxisX = 0x00000404
 
static const G4int sAxisY = 0x00000808
 
static const G4int sAxisZ = 0x00000C0C
 
static const G4int sAxisRho = 0x00001010
 
static const G4int sAxisPhi = 0x00001414
 
static const G4int sAxis0 = 0x0000FF00
 
static const G4int sAxis1 = 0x000000FF
 
static const G4int sSizeMask = 0x00000303
 
static const G4int sAxisMask = 0x0000FCFC
 
static const G4int sAreaMask = 0XF0000000
 
- Protected Member Functions inherited from G4VTwistSurface
G4VTwistSurface ** GetNeighbours ()
 
G4int GetNeighbours (G4int areacode, G4VTwistSurface *surfaces[])
 
G4ThreeVector GetCorner (G4int areacode) const
 
void GetBoundaryAxis (G4int areacode, EAxis axis[]) const
 
void GetBoundaryLimit (G4int areacode, G4double limit[]) const
 
virtual G4int GetAreaCode (const G4ThreeVector &xx, G4bool withtol=true)=0
 
virtual void SetBoundary (const G4int &axiscode, const G4ThreeVector &direction, const G4ThreeVector &x0, const G4int &boundarytype)
 
void SetCorner (G4int areacode, G4double x, G4double y, G4double z)
 
- Protected Attributes inherited from G4VTwistSurface
EAxis fAxis [2]
 
G4double fAxisMin [2]
 
G4double fAxisMax [2]
 
CurrentStatus fCurStatWithV
 
CurrentStatus fCurStat
 
G4RotationMatrix fRot
 
G4ThreeVector fTrans
 
G4int fHandedness
 
G4SurfCurNormal fCurrentNormal
 
G4bool fIsValidNorm
 
G4double kCarTolerance
 

Detailed Description

Definition at line 41 of file G4TwistBoxSide.hh.

Constructor & Destructor Documentation

◆ G4TwistBoxSide() [1/2]

G4TwistBoxSide::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 
)

Definition at line 40 of file G4TwistBoxSide.cc.

53 : G4VTwistSurface(name)
54{
55
56
57 fAxis[0] = kYAxis; // in local coordinate system
58 fAxis[1] = kZAxis;
59 fAxisMin[0] = -kInfinity ; // Y Axis boundary
60 fAxisMax[0] = kInfinity ; // depends on z !!
61 fAxisMin[1] = -pDz ; // Z Axis boundary
62 fAxisMax[1] = pDz ;
63
64 fDx1 = pDx1 ;
65 fDx2 = pDx2 ; // box
66 fDx3 = pDx3 ;
67 fDx4 = pDx4 ; // box
68
69 // this is an overhead. But the parameter naming scheme fits to the other surfaces.
70
71 if ( ! (fDx1 == fDx2 && fDx3 == fDx4 ) )
72 {
73 std::ostringstream message;
74 message << "TwistedTrapBoxSide is not used as a the side of a box: "
75 << GetName() << G4endl
76 << " Not a box !";
77 G4Exception("G4TwistBoxSide::G4TwistBoxSide()", "GeomSolids0002",
78 FatalException, message);
79 }
80
81 fDy1 = pDy1 ;
82 fDy2 = pDy2 ;
83
84 fDz = pDz ;
85
86 fAlph = pAlph ;
87 fTAlph = std::tan(fAlph) ;
88
89 fTheta = pTheta ;
90 fPhi = pPhi ;
91
92 // precalculate frequently used parameters
93
94 fDx4plus2 = fDx4 + fDx2 ;
95 fDx4minus2 = fDx4 - fDx2 ;
96 fDx3plus1 = fDx3 + fDx1 ;
97 fDx3minus1 = fDx3 - fDx1 ;
98 fDy2plus1 = fDy2 + fDy1 ;
99 fDy2minus1 = fDy2 - fDy1 ;
100
101 fa1md1 = 2*fDx2 - 2*fDx1 ;
102 fa2md2 = 2*fDx4 - 2*fDx3 ;
103
104
105 fPhiTwist = PhiTwist ; // dphi
106 fAngleSide = AngleSide ; // 0,90,180,270 deg
107
108 fdeltaX = 2*fDz * std::tan(fTheta) * std::cos(fPhi); // dx in surface equation
109 fdeltaY = 2*fDz * std::tan(fTheta) * std::sin(fPhi); // dy in surface equation
110
111 fRot.rotateZ( AngleSide ) ;
112
113 fTrans.set(0, 0, 0); // No Translation
114 fIsValidNorm = false;
115
116 SetCorners();
117 SetBoundaries();
118}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
#define G4endl
Definition: G4ios.hh:57
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
Definition: Rotation.cc:87
G4double fAxisMax[2]
G4RotationMatrix fRot
G4ThreeVector fTrans
G4double fAxisMin[2]
virtual G4String GetName() const
@ kYAxis
Definition: geomdefs.hh:56
@ kZAxis
Definition: geomdefs.hh:57

◆ ~G4TwistBoxSide()

G4TwistBoxSide::~G4TwistBoxSide ( )
virtual

Definition at line 137 of file G4TwistBoxSide.cc.

138{
139}

◆ G4TwistBoxSide() [2/2]

G4TwistBoxSide::G4TwistBoxSide ( __void__ &  a)

Definition at line 124 of file G4TwistBoxSide.cc.

125 : G4VTwistSurface(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.),
126 fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fAlph(0.), fTAlph(0.), fPhiTwist(0.),
127 fAngleSide(0.), fdeltaX(0.), fdeltaY(0.), fDx4plus2(0.), fDx4minus2(0.),
128 fDx3plus1(0.), fDx3minus1(0.), fDy2plus1(0.), fDy2minus1(0.), fa1md1(0.),
129 fa2md2(0.)
130{
131}

Member Function Documentation

◆ DistanceToSurface() [1/2]

G4int G4TwistBoxSide::DistanceToSurface ( const G4ThreeVector gp,
const G4ThreeVector gv,
G4ThreeVector  gxx[],
G4double  distance[],
G4int  areacode[],
G4bool  isvalid[],
EValidate  validate = kValidateWithTol 
)
virtual

Implements G4VTwistSurface.

Definition at line 198 of file G4TwistBoxSide.cc.

205{
206
207 static const G4double pihalf = pi/2 ;
208 const G4double ctol = 0.5 * kCarTolerance;
209
210 G4bool IsParallel = false ;
211 G4bool IsConverged = false ;
212
213 G4int nxx = 0 ; // number of physical solutions
214
215 fCurStatWithV.ResetfDone(validate, &gp, &gv);
216
217 if (fCurStatWithV.IsDone())
218 {
219 for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
220 {
221 gxx[i] = fCurStatWithV.GetXX(i);
222 distance[i] = fCurStatWithV.GetDistance(i);
223 areacode[i] = fCurStatWithV.GetAreacode(i);
224 isvalid[i] = fCurStatWithV.IsValid(i);
225 }
226 return fCurStatWithV.GetNXX();
227 }
228 else // initialize
229 {
230 for (G4int i=0; i<G4VSURFACENXX ; ++i)
231 {
232 distance[i] = kInfinity;
233 areacode[i] = sOutside;
234 isvalid[i] = false;
235 gxx[i].set(kInfinity, kInfinity, kInfinity);
236 }
237 }
238
241
242#ifdef G4TWISTDEBUG
243 G4cout << "Local point p = " << p << G4endl ;
244 G4cout << "Local direction v = " << v << G4endl ;
245#endif
246
247 G4double phi=0.,u=0.,q=0.; // parameters
248
249 // temporary variables
250
251 G4double tmpdist = kInfinity ;
252 G4ThreeVector tmpxx;
253 G4int tmpareacode = sOutside ;
254 G4bool tmpisvalid = false ;
255
256 std::vector<Intersection> xbuf ;
257 Intersection xbuftmp ;
258
259 // prepare some variables for the intersection finder
260
261 G4double L = 2*fDz ;
262
263 G4double phixz = fPhiTwist * ( p.x() * v.z() - p.z() * v.x() ) ;
264 G4double phiyz = fPhiTwist * ( p.y() * v.z() - p.z() * v.y() ) ;
265
266 // special case vz = 0
267
268 if ( v.z() == 0. )
269 {
270 if ( (std::fabs(p.z()) <= L) && fPhiTwist ) // intersection possible in z
271 {
272 phi = p.z() * fPhiTwist / L ; // phi is determined by the z-position
273
274 q = (2.* fPhiTwist*((v.x() - fTAlph*v.y())*std::cos(phi)
275 + (fTAlph*v.x() + v.y())*std::sin(phi)));
276
277 if (q)
278 {
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;
283 }
284 xbuftmp.phi = phi ;
285 xbuftmp.u = u ;
286 xbuftmp.areacode = sOutside ;
287 xbuftmp.distance = kInfinity ;
288 xbuftmp.isvalid = false ;
289
290 xbuf.push_back(xbuftmp) ; // store it to xbuf
291 }
292 else // no intersection possible
293 {
294 distance[0] = kInfinity;
295 gxx[0].set(kInfinity,kInfinity,kInfinity);
296 isvalid[0] = false ;
297 areacode[0] = sOutside ;
298 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0],
299 areacode[0], isvalid[0],
300 0, validate, &gp, &gv);
301
302 return 0;
303 } // end std::fabs(p.z() <= L
304 } // end v.z() == 0
305 else // general solution for non-zero vz
306 {
307 G4double c[8],srd[7],si[7] ;
308
309 c[7] = -14400*(-2*phixz + 2*fTAlph*phiyz + fDx4plus2*fPhiTwist*v.z()) ;
310 c[6] = 28800*(phiyz + 2*fDz*v.x() - (fdeltaX + fDx4minus2)*v.z() + fTAlph*(phixz - 2*fDz*v.y() + fdeltaY*v.z())) ;
311 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())) ;
312 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())) ;
313 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())) ;
314 c[2] = -16*(7*fTAlph* phixz + 7*phiyz - 6*fDz*v.x() + 6*fDz*fTAlph*v.y() + 3*(fdeltaX + fDx4minus2 - fdeltaY*fTAlph)*v.z()) ;
315 c[1] = 4*(9*phixz - 9*fTAlph*phiyz - 56*fDz*fTAlph*v.x() - 56*fDz*v.y() + 28*(fdeltaY + fdeltaX*fTAlph)*v.z()) ;
316 c[0] = 36*(2* fDz*(v.x() - fTAlph*v.y()) - fdeltaX*v.z() + fdeltaY*fTAlph*v.z()) ;
317
318#ifdef G4TWISTDEBUG
319 G4cout << "coef = " << c[0] << " "
320 << c[1] << " "
321 << c[2] << " "
322 << c[3] << " "
323 << c[4] << " "
324 << c[5] << " "
325 << c[6] << " "
326 << c[7] << G4endl ;
327#endif
328
329 G4JTPolynomialSolver trapEq ;
330 G4int num = trapEq.FindRoots(c,7,srd,si);
331
332 for (G4int i = 0 ; i<num ; ++i ) // loop over all mathematical solutions
333 {
334 if ( (si[i]==0.0) && fPhiTwist ) // only real solutions
335 {
336#ifdef G4TWISTDEBUG
337 G4cout << "Solution " << i << " : " << srd[i] << G4endl ;
338#endif
339 phi = std::fmod(srd[i], pihalf) ;
340
341 u = (2*phiyz + 4*fDz*phi*v.y() - 2*fdeltaY*phi*v.z()
342 - fDx4plus2*fPhiTwist*v.z()*std::sin(phi)
343 - 2*fDx4minus2*phi*v.z()*std::sin(phi))
344 /(2*fPhiTwist*v.z()*std::cos(phi)
345 + 2*fPhiTwist*fTAlph*v.z()*std::sin(phi)) ;
346
347 xbuftmp.phi = phi ;
348 xbuftmp.u = u ;
349 xbuftmp.areacode = sOutside ;
350 xbuftmp.distance = kInfinity ;
351 xbuftmp.isvalid = false ;
352
353 xbuf.push_back(xbuftmp) ; // store it to xbuf
354
355#ifdef G4TWISTDEBUG
356 G4cout << "solution " << i << " = " << phi << " , " << u << G4endl ;
357#endif
358 } // end if real solution
359 } // end loop i
360 } // end general case
361
362
363 nxx = (G4int)xbuf.size() ; // save the number of solutions
364
365 G4ThreeVector xxonsurface ; // point on surface
366 G4ThreeVector surfacenormal ; // normal vector
367 G4double deltaX ; // distance between intersection point and
368 // point on surface
369 G4double theta ; // angle between track and surfacenormal
370 G4double factor ; // a scaling factor
371 G4int maxint = 30 ; // number of iterations
372
373
374 for ( std::size_t k = 0 ; k<xbuf.size() ; ++k )
375 {
376#ifdef G4TWISTDEBUG
377 G4cout << "Solution " << k << " : "
378 << "reconstructed phiR = " << xbuf[k].phi
379 << ", uR = " << xbuf[k].u << G4endl ;
380#endif
381
382 phi = xbuf[k].phi ; // get the stored values for phi and u
383 u = xbuf[k].u ;
384
385 IsConverged = false ; // no convergence at the beginning
386
387 for ( G4int i = 1 ; i<maxint ; ++i )
388 {
389 xxonsurface = SurfacePoint(phi,u) ;
390 surfacenormal = NormAng(phi,u) ;
391 tmpdist = DistanceToPlaneWithV(p, v, xxonsurface, surfacenormal, tmpxx);
392 deltaX = ( tmpxx - xxonsurface ).mag() ;
393 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
394 if ( theta < 0.001 )
395 {
396 factor = 50 ;
397 IsParallel = true ;
398 }
399 else
400 {
401 factor = 1 ;
402 }
403
404#ifdef G4TWISTDEBUG
405 G4cout << "Step i = " << i << ", distance = " << tmpdist << ", " << deltaX << G4endl ;
406 G4cout << "X = " << tmpxx << G4endl ;
407#endif
408
409 GetPhiUAtX(tmpxx, phi, u) ; // the new point xx is accepted and phi/u replaced
410
411#ifdef G4TWISTDEBUG
412 G4cout << "approximated phi = " << phi << ", u = " << u << G4endl ;
413#endif
414
415 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
416
417 } // end iterative loop (i)
418
419 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
420
421#ifdef G4TWISTDEBUG
422 G4cout << "refined solution " << phi << " , " << u << G4endl ;
423 G4cout << "distance = " << tmpdist << G4endl ;
424 G4cout << "local X = " << tmpxx << G4endl ;
425#endif
426
427 tmpisvalid = false ; // init
428
429 if ( IsConverged )
430 {
431 if (validate == kValidateWithTol)
432 {
433 tmpareacode = GetAreaCode(tmpxx);
434 if (!IsOutside(tmpareacode))
435 {
436 if (tmpdist >= 0) tmpisvalid = true;
437 }
438 }
439 else if (validate == kValidateWithoutTol)
440 {
441 tmpareacode = GetAreaCode(tmpxx, false);
442 if (IsInside(tmpareacode))
443 {
444 if (tmpdist >= 0) tmpisvalid = true;
445 }
446 }
447 else // kDontValidate
448 {
449 G4Exception("G4TwistBoxSide::DistanceToSurface()",
450 "GeomSolids0001", FatalException,
451 "Feature NOT implemented !");
452 }
453 }
454 else
455 {
456 tmpdist = kInfinity; // no convergence after 10 steps
457 tmpisvalid = false ; // solution is not vaild
458 }
459
460 // store the found values
461 xbuf[k].xx = tmpxx ;
462 xbuf[k].distance = tmpdist ;
463 xbuf[k].areacode = tmpareacode ;
464 xbuf[k].isvalid = tmpisvalid ;
465
466 } // end loop over physical solutions (variable k)
467
468 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ; // sorting
469
470#ifdef G4TWISTDEBUG
471 G4cout << G4endl << "list xbuf after sorting : " << G4endl ;
472 G4cout << G4endl << G4endl ;
473#endif
474
475 // erase identical intersection (within kCarTolerance)
476 xbuf.erase(std::unique(xbuf.begin(),xbuf.end(),EqualIntersection),xbuf.end());
477
478 // add guesses
479
480 G4int nxxtmp = (G4int)xbuf.size() ;
481
482 if ( nxxtmp<2 || IsParallel )
483 {
484 // positive end
485#ifdef G4TWISTDEBUG
486 G4cout << "add guess at +z/2 .. " << G4endl ;
487#endif
488
489 phi = fPhiTwist/2 ;
490 u = 0. ;
491 xbuftmp.phi = phi ;
492 xbuftmp.u = u ;
493 xbuftmp.areacode = sOutside ;
494 xbuftmp.distance = kInfinity ;
495 xbuftmp.isvalid = false ;
496
497 xbuf.push_back(xbuftmp) ; // store it to xbuf
498
499#ifdef G4TWISTDEBUG
500 G4cout << "add guess at -z/2 .. " << G4endl ;
501#endif
502
503 phi = -fPhiTwist/2 ;
504 u = 0. ;
505
506 xbuftmp.phi = phi ;
507 xbuftmp.u = u ;
508 xbuftmp.areacode = sOutside ;
509 xbuftmp.distance = kInfinity ;
510 xbuftmp.isvalid = false ;
511
512 xbuf.push_back(xbuftmp) ; // store it to xbuf
513
514 for ( std::size_t k = nxxtmp ; k<xbuf.size() ; ++k )
515 {
516#ifdef G4TWISTDEBUG
517 G4cout << "Solution " << k << " : "
518 << "reconstructed phiR = " << xbuf[k].phi
519 << ", uR = " << xbuf[k].u << G4endl ;
520#endif
521
522 phi = xbuf[k].phi ; // get the stored values for phi and u
523 u = xbuf[k].u ;
524
525 IsConverged = false ; // no convergence at the beginning
526
527 for ( G4int i = 1 ; i<maxint ; ++i )
528 {
529 xxonsurface = SurfacePoint(phi,u) ;
530 surfacenormal = NormAng(phi,u) ;
531 tmpdist = DistanceToPlaneWithV(p, v, xxonsurface, surfacenormal, tmpxx);
532 deltaX = ( tmpxx - xxonsurface ).mag() ;
533 theta = std::fabs(std::acos(v*surfacenormal) - pihalf) ;
534 if ( theta < 0.001 )
535 {
536 factor = 50 ;
537 }
538 else
539 {
540 factor = 1 ;
541 }
542
543#ifdef G4TWISTDEBUG
544 G4cout << "Step i = " << i << ", distance = "
545 << tmpdist << ", " << deltaX << G4endl ;
546 G4cout << "X = " << tmpxx << G4endl ;
547#endif
548
549 GetPhiUAtX(tmpxx, phi, u) ;
550 // the new point xx is accepted and phi/u replaced
551
552#ifdef G4TWISTDEBUG
553 G4cout << "approximated phi = " << phi << ", u = " << u << G4endl ;
554#endif
555
556 if ( deltaX <= factor*ctol ) { IsConverged = true ; break ; }
557
558 } // end iterative loop (i)
559
560 if ( std::fabs(tmpdist)<ctol ) tmpdist = 0. ;
561
562#ifdef G4TWISTDEBUG
563 G4cout << "refined solution " << phi << " , " << u << G4endl ;
564 G4cout << "distance = " << tmpdist << G4endl ;
565 G4cout << "local X = " << tmpxx << G4endl ;
566#endif
567
568 tmpisvalid = false ; // init
569
570 if ( IsConverged )
571 {
572 if (validate == kValidateWithTol)
573 {
574 tmpareacode = GetAreaCode(tmpxx);
575 if (!IsOutside(tmpareacode))
576 {
577 if (tmpdist >= 0) tmpisvalid = true;
578 }
579 }
580 else if (validate == kValidateWithoutTol)
581 {
582 tmpareacode = GetAreaCode(tmpxx, false);
583 if (IsInside(tmpareacode))
584 {
585 if (tmpdist >= 0) tmpisvalid = true;
586 }
587 }
588 else // kDontValidate
589 {
590 G4Exception("G4TwistedBoxSide::DistanceToSurface()",
591 "GeomSolids0001", FatalException,
592 "Feature NOT implemented !");
593 }
594 }
595 else
596 {
597 tmpdist = kInfinity; // no convergence after 10 steps
598 tmpisvalid = false ; // solution is not vaild
599 }
600
601 // store the found values
602 xbuf[k].xx = tmpxx ;
603 xbuf[k].distance = tmpdist ;
604 xbuf[k].areacode = tmpareacode ;
605 xbuf[k].isvalid = tmpisvalid ;
606 } // end loop over physical solutions
607 } // end less than 2 solutions
608
609 // sort again
610 std::sort(xbuf.begin() , xbuf.end(), DistanceSort ) ; // sorting
611
612 // erase identical intersection (within kCarTolerance)
613 xbuf.erase(std::unique(xbuf.begin(),xbuf.end(),EqualIntersection),xbuf.end());
614
615#ifdef G4TWISTDEBUG
616 G4cout << G4endl << "list xbuf after sorting : " << G4endl ;
617 G4cout << G4endl << G4endl ;
618#endif
619
620 nxx = (G4int)xbuf.size() ; // determine number of solutions again.
621
622 for ( G4int i = 0 ; i<(G4int)xbuf.size() ; ++i )
623 {
624 distance[i] = xbuf[i].distance;
625 gxx[i] = ComputeGlobalPoint(xbuf[i].xx);
626 areacode[i] = xbuf[i].areacode ;
627 isvalid[i] = xbuf[i].isvalid ;
628
629 fCurStatWithV.SetCurrentStatus(i, gxx[i], distance[i], areacode[i],
630 isvalid[i], nxx, validate, &gp, &gv);
631
632#ifdef G4TWISTDEBUG
633 G4cout << "element Nr. " << i
634 << ", local Intersection = " << xbuf[i].xx
635 << ", distance = " << xbuf[i].distance
636 << ", u = " << xbuf[i].u
637 << ", phi = " << xbuf[i].phi
638 << ", isvalid = " << xbuf[i].isvalid
639 << G4endl ;
640#endif
641
642 } // end for( i ) loop
643
644#ifdef G4TWISTDEBUG
645 G4cout << "G4TwistBoxSide finished " << G4endl ;
646 G4cout << nxx << " possible physical solutions found" << G4endl ;
647 for ( G4int k= 0 ; k< nxx ; ++k )
648 {
649 G4cout << "global intersection Point found: " << gxx[k] << G4endl ;
650 G4cout << "distance = " << distance[k] << G4endl ;
651 G4cout << "isvalid = " << isvalid[k] << G4endl ;
652 }
653#endif
654
655 return nxx ;
656}
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4bool DistanceSort(const Intersection &a, const Intersection &b)
G4bool EqualIntersection(const Intersection &a, const Intersection &b)
#define G4VSURFACENXX
G4GLOB_DLL std::ostream G4cout
double z() const
double x() const
double y() const
G4int FindRoots(G4double *op, G4int degree, G4double *zeror, G4double *zeroi)
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 sOutside
G4ThreeVector ComputeLocalDirection(const G4ThreeVector &gp) const
G4bool IsInside(G4int areacode, G4bool testbitmode=false) const
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &gp) const
G4bool IsOutside(G4int areacode) const
CurrentStatus fCurStatWithV
G4double DistanceToPlaneWithV(const G4ThreeVector &p, const G4ThreeVector &v, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const
const G4double pi

◆ DistanceToSurface() [2/2]

G4int G4TwistBoxSide::DistanceToSurface ( const G4ThreeVector gp,
G4ThreeVector  gxx[],
G4double  distance[],
G4int  areacode[] 
)
virtual

Implements G4VTwistSurface.

Definition at line 661 of file G4TwistBoxSide.cc.

665{
666 const G4double ctol = 0.5 * kCarTolerance;
667
669
670 if (fCurStat.IsDone())
671 {
672 for (G4int i=0; i<fCurStat.GetNXX(); ++i)
673 {
674 gxx[i] = fCurStat.GetXX(i);
675 distance[i] = fCurStat.GetDistance(i);
676 areacode[i] = fCurStat.GetAreacode(i);
677 }
678 return fCurStat.GetNXX();
679 }
680 else // initialize
681 {
682 for (G4int i=0; i<G4VSURFACENXX; ++i)
683 {
684 distance[i] = kInfinity;
685 areacode[i] = sOutside;
686 gxx[i].set(kInfinity, kInfinity, kInfinity);
687 }
688 }
689
691 G4ThreeVector xx; // intersection point
692 G4ThreeVector xxonsurface ; // interpolated intersection point
693
694 // the surfacenormal at that surface point
695 G4double phiR = 0. ;
696 G4double uR = 0. ;
697
698 G4ThreeVector surfacenormal ;
699 G4double deltaX ;
700
701 G4int maxint = 20 ;
702
703 for ( G4int i = 1 ; i<maxint ; ++i )
704 {
705 xxonsurface = SurfacePoint(phiR,uR) ;
706 surfacenormal = NormAng(phiR,uR) ;
707 distance[0] = DistanceToPlane(p, xxonsurface, surfacenormal, xx); // new XX
708 deltaX = ( xx - xxonsurface ).mag() ;
709
710#ifdef G4TWISTDEBUG
711 G4cout << "i = " << i << ", distance = " << distance[0]
712 << ", " << deltaX << G4endl ;
713 G4cout << "X = " << xx << G4endl ;
714#endif
715
716 // the new point xx is accepted and phi/psi replaced
717 GetPhiUAtX(xx, phiR, uR) ;
718
719 if ( deltaX <= ctol ) { break ; }
720 }
721
722 // check validity of solution ( valid phi,psi )
723
724 G4double halfphi = 0.5*fPhiTwist ;
725 G4double uMax = GetBoundaryMax(phiR) ;
726
727 if ( phiR > halfphi ) phiR = halfphi ;
728 if ( phiR < -halfphi ) phiR = -halfphi ;
729 if ( uR > uMax ) uR = uMax ;
730 if ( uR < -uMax ) uR = -uMax ;
731
732 xxonsurface = SurfacePoint(phiR,uR) ;
733 distance[0] = ( p - xx ).mag() ;
734 if ( distance[0] <= ctol ) { distance[0] = 0 ; }
735
736 // end of validity
737
738#ifdef G4TWISTDEBUG
739 G4cout << "refined solution " << phiR << " , " << uR << " , " << G4endl ;
740 G4cout << "distance = " << distance[0] << G4endl ;
741 G4cout << "X = " << xx << G4endl ;
742#endif
743
744 G4bool isvalid = true;
745 gxx[0] = ComputeGlobalPoint(xx);
746
747#ifdef G4TWISTDEBUG
748 G4cout << "intersection Point found: " << gxx[0] << G4endl ;
749 G4cout << "distance = " << distance[0] << G4endl ;
750#endif
751
752 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
753 isvalid, 1, kDontValidate, &gp);
754 return 1;
755}
G4double DistanceToPlane(const G4ThreeVector &p, const G4ThreeVector &x0, const G4ThreeVector &n0, G4ThreeVector &xx)
CurrentStatus fCurStat

◆ GetNormal()

G4ThreeVector G4TwistBoxSide::GetNormal ( const G4ThreeVector xx,
G4bool  isGlobal = false 
)
virtual

Implements G4VTwistSurface.

Definition at line 144 of file G4TwistBoxSide.cc.

146{
147 // GetNormal returns a normal vector at a surface (or very close
148 // to surface) point at tmpxx.
149 // If isGlobal=true, it returns the normal in global coordinate.
150 //
151
152 G4ThreeVector xx;
153 if (isGlobal)
154 {
155 xx = ComputeLocalPoint(tmpxx);
156 if ((xx - fCurrentNormal.p).mag() < 0.5 * kCarTolerance)
157 {
159 }
160 }
161 else
162 {
163 xx = tmpxx;
164 if (xx == fCurrentNormal.p)
165 {
166 return fCurrentNormal.normal;
167 }
168 }
169
170 G4double phi ;
171 G4double u ;
172
173 GetPhiUAtX(xx,phi,u) ; // phi,u for point xx close to surface
174
175 G4ThreeVector normal = NormAng(phi,u) ; // the normal vector at phi,u
176
177#ifdef G4TWISTDEBUG
178 G4cout << "normal vector = " << normal << G4endl ;
179 G4cout << "phi = " << phi << " , u = " << u << G4endl ;
180#endif
181
182 // normal = normal/normal.mag() ;
183
184 if (isGlobal)
185 {
187 }
188 else
189 {
190 fCurrentNormal.normal = normal.unit();
191 }
192 return fCurrentNormal.normal;
193}
Hep3Vector unit() const
G4ThreeVector ComputeGlobalDirection(const G4ThreeVector &lp) const
G4SurfCurNormal fCurrentNormal

The documentation for this class was generated from the following files: