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

#include <G4TwistTrapParallelSide.hh>

+ Inheritance diagram for G4TwistTrapParallelSide:

Public Member Functions

 G4TwistTrapParallelSide (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 ~G4TwistTrapParallelSide ()
 
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[])
 
 G4TwistTrapParallelSide (__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 G4TwistTrapParallelSide.hh.

Constructor & Destructor Documentation

◆ G4TwistTrapParallelSide() [1/2]

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

54 : G4VTwistSurface(name)
55{
56
57 fAxis[0] = kXAxis; // in local coordinate system
58 fAxis[1] = kZAxis;
59 fAxisMin[0] = -kInfinity ; // X 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 //
82 fDx4plus2 = fDx4 + fDx2 ;
83 fDx4minus2 = fDx4 - fDx2 ;
84 fDx3plus1 = fDx3 + fDx1 ;
85 fDx3minus1 = fDx3 - fDx1 ;
86 fDy2plus1 = fDy2 + fDy1 ;
87 fDy2minus1 = fDy2 - fDy1 ;
88
89 fa1md1 = 2*fDx2 - 2*fDx1 ;
90 fa2md2 = 2*fDx4 - 2*fDx3 ;
91
92 fPhiTwist = PhiTwist ; // dphi
93 fAngleSide = AngleSide ; // 0,90,180,270 deg
94
95 fdeltaX = 2*fDz*std::tan(fTheta)*std::cos(fPhi); // dx in surface equation
96 fdeltaY = 2*fDz*std::tan(fTheta)*std::sin(fPhi); // dy in surface equation
97
98 fRot.rotateZ( AngleSide ) ;
99
100 fTrans.set(0, 0, 0); // No Translation
101 fIsValidNorm = false;
102
103 SetCorners() ;
104 SetBoundaries() ;
105}
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]
@ kXAxis
Definition: geomdefs.hh:55
@ kZAxis
Definition: geomdefs.hh:57

◆ ~G4TwistTrapParallelSide()

G4TwistTrapParallelSide::~G4TwistTrapParallelSide ( )
virtual

Definition at line 122 of file G4TwistTrapParallelSide.cc.

123{
124}

◆ G4TwistTrapParallelSide() [2/2]

G4TwistTrapParallelSide::G4TwistTrapParallelSide ( __void__ &  a)

Definition at line 110 of file G4TwistTrapParallelSide.cc.

111 : G4VTwistSurface(a), fTheta(0.), fPhi(0.), fDy1(0.), fDx1(0.), fDx2(0.),
112 fDy2(0.), fDx3(0.), fDx4(0.), fDz(0.), fAlph(0.), fTAlph(0.), fPhiTwist(0.),
113 fAngleSide(0.), fdeltaX(0.), fdeltaY(0.), fDx4plus2(0.), fDx4minus2(0.),
114 fDx3plus1(0.), fDx3minus1(0.), fDy2plus1(0.), fDy2minus1(0.), fa1md1(0.),
115 fa2md2(0.)
116{
117}

Member Function Documentation

◆ DistanceToSurface() [1/2]

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

Implements G4VTwistSurface.

Definition at line 183 of file G4TwistTrapParallelSide.cc.

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

Implements G4VTwistSurface.

Definition at line 642 of file G4TwistTrapParallelSide.cc.

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

◆ GetNormal()

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

Implements G4VTwistSurface.

Definition at line 129 of file G4TwistTrapParallelSide.cc.

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

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