Geant4 11.2.2
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)
 
 ~G4TwistBoxSide () override
 
G4ThreeVector GetNormal (const G4ThreeVector &xx, G4bool isGlobal=false) override
 
G4int DistanceToSurface (const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol) override
 
G4int DistanceToSurface (const G4ThreeVector &gp, G4ThreeVector gxx[], G4double distance[], G4int areacode[]) override
 
 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)
 
void DebugPrint () const
 
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)
 
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 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)
#define G4endl
Definition G4ios.hh:67
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
Definition Rotation.cc:87
G4VTwistSurface(const G4String &name)
G4RotationMatrix fRot
G4ThreeVector fTrans
virtual G4String GetName() const
@ kYAxis
Definition geomdefs.hh:56
@ kZAxis
Definition geomdefs.hh:57

◆ ~G4TwistBoxSide()

G4TwistBoxSide::~G4TwistBoxSide ( )
overridedefault

◆ G4TwistBoxSide() [2/2]

G4TwistBoxSide::G4TwistBoxSide ( __void__ & a)

Definition at line 124 of file G4TwistBoxSide.cc.

125 : G4VTwistSurface(a)
126{
127}

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 )
overridevirtual

Implements G4VTwistSurface.

Definition at line 192 of file G4TwistBoxSide.cc.

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

◆ DistanceToSurface() [2/2]

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

Implements G4VTwistSurface.

Definition at line 655 of file G4TwistBoxSide.cc.

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

Implements G4VTwistSurface.

Definition at line 138 of file G4TwistBoxSide.cc.

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

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