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

#include <G4TwistTrapAlphaSide.hh>

+ Inheritance diagram for G4TwistTrapAlphaSide:

Public Member Functions

 G4TwistTrapAlphaSide (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)
 
 ~G4TwistTrapAlphaSide () 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
 
 G4TwistTrapAlphaSide (__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 G4TwistTrapAlphaSide.hh.

Constructor & Destructor Documentation

◆ G4TwistTrapAlphaSide() [1/2]

G4TwistTrapAlphaSide::G4TwistTrapAlphaSide ( 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 G4TwistTrapAlphaSide.cc.

55 : G4VTwistSurface(name)
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 ;
66 fDx3 = pDx3 ;
67 fDx4 = pDx4 ;
68
69 fDy1 = pDy1 ;
70 fDy2 = pDy2 ;
71
72 fDz = pDz ;
73
74 fAlph = pAlph ;
75 fTAlph = std::tan(fAlph) ;
76
77 fTheta = pTheta ;
78 fPhi = pPhi ;
79
80 // precalculate frequently used parameters
81 fDx4plus2 = fDx4 + fDx2 ;
82 fDx4minus2 = fDx4 - fDx2 ;
83 fDx3plus1 = fDx3 + fDx1 ;
84 fDx3minus1 = fDx3 - fDx1 ;
85 fDy2plus1 = fDy2 + fDy1 ;
86 fDy2minus1 = fDy2 - fDy1 ;
87
88 fa1md1 = 2*fDx2 - 2*fDx1 ;
89 fa2md2 = 2*fDx4 - 2*fDx3 ;
90
91 fPhiTwist = PhiTwist ; // dphi
92 fAngleSide = AngleSide ; // 0,90,180,270 deg
93
94 fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi);
95 // dx in surface equation
96 fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi);
97 // dy in surface equation
98
99 fRot.rotateZ( AngleSide ) ;
100
101 fTrans.set(0, 0, 0); // No Translation
102 fIsValidNorm = false;
103
104 SetCorners() ;
105 SetBoundaries() ;
106}
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
Definition Rotation.cc:87
G4VTwistSurface(const G4String &name)
G4RotationMatrix fRot
G4ThreeVector fTrans
@ kYAxis
Definition geomdefs.hh:56
@ kZAxis
Definition geomdefs.hh:57

◆ ~G4TwistTrapAlphaSide()

G4TwistTrapAlphaSide::~G4TwistTrapAlphaSide ( )
overridedefault

◆ G4TwistTrapAlphaSide() [2/2]

G4TwistTrapAlphaSide::G4TwistTrapAlphaSide ( __void__ & a)

Definition at line 112 of file G4TwistTrapAlphaSide.cc.

113 : G4VTwistSurface(a)
114{
115}

Member Function Documentation

◆ DistanceToSurface() [1/2]

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

Implements G4VTwistSurface.

Definition at line 182 of file G4TwistTrapAlphaSide.cc.

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

Implements G4VTwistSurface.

Definition at line 678 of file G4TwistTrapAlphaSide.cc.

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

◆ GetNormal()

G4ThreeVector G4TwistTrapAlphaSide::GetNormal ( const G4ThreeVector & xx,
G4bool isGlobal = false )
overridevirtual

Implements G4VTwistSurface.

Definition at line 128 of file G4TwistTrapAlphaSide.cc.

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

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