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

#include <G4TwistTubsHypeSide.hh>

+ Inheritance diagram for G4TwistTubsHypeSide:

Public Member Functions

 G4TwistTubsHypeSide (const G4String &name, const G4RotationMatrix &rot, const G4ThreeVector &tlate, const G4int handedness, const G4double kappa, const G4double tanstereo, const G4double r0, const EAxis axis0=kPhi, const EAxis axis1=kZAxis, G4double axis0min=-kInfinity, G4double axis1min=-kInfinity, G4double axis0max=kInfinity, G4double axis1max=kInfinity)
 
 G4TwistTubsHypeSide (const G4String &name, G4double EndInnerRadius[2], G4double EndOuterRadius[2], G4double DPhi, G4double EndPhi[2], G4double EndZ[2], G4double InnerRadius, G4double OuterRadius, G4double Kappa, G4double TanInnerStereo, G4double TanOuterStereo, G4int handedness)
 
virtual ~G4TwistTubsHypeSide ()
 
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[])
 
virtual G4ThreeVector GetNormal (const G4ThreeVector &xx, G4bool isGlobal=false)
 
virtual EInside Inside (const G4ThreeVector &gp)
 
virtual G4double GetRhoAtPZ (const G4ThreeVector &p, G4bool isglobal=false) const
 
virtual G4ThreeVector SurfacePoint (G4double, G4double, G4bool isGlobal=false)
 
virtual G4double GetBoundaryMin (G4double phi)
 
virtual G4double GetBoundaryMax (G4double phi)
 
virtual G4double GetSurfaceArea ()
 
virtual void GetFacets (G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)
 
 G4TwistTubsHypeSide (__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 43 of file G4TwistTubsHypeSide.hh.

Constructor & Destructor Documentation

◆ G4TwistTubsHypeSide() [1/3]

G4TwistTubsHypeSide::G4TwistTubsHypeSide ( const G4String name,
const G4RotationMatrix rot,
const G4ThreeVector tlate,
const G4int  handedness,
const G4double  kappa,
const G4double  tanstereo,
const G4double  r0,
const EAxis  axis0 = kPhi,
const EAxis  axis1 = kZAxis,
G4double  axis0min = -kInfinity,
G4double  axis1min = -kInfinity,
G4double  axis0max = kInfinity,
G4double  axis1max = kInfinity 
)

Definition at line 40 of file G4TwistTubsHypeSide.cc.

53 : G4VTwistSurface(name, rot, tlate, handedness, axis0, axis1,
54 axis0min, axis1min, axis0max, axis1max),
55 fKappa(kappa), fTanStereo(tanstereo),
56 fTan2Stereo(tanstereo*tanstereo), fR0(r0), fR02(r0*r0), fDPhi(twopi)
57{
58 if ( (axis0 == kZAxis) && (axis1 == kPhi) )
59 {
60 G4Exception("G4TwistTubsHypeSide::G4TwistTubsHypeSide()",
61 "GeomSolids0002", FatalErrorInArgument,
62 "Should swap axis0 and axis1!");
63 }
64 fInside.gp.set(kInfinity, kInfinity, kInfinity);
65 fInside.inside = kOutside;
66 fIsValidNorm = false;
67 SetCorners();
68 SetBoundaries();
69}
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
@ kPhi
Definition: geomdefs.hh:60
@ kZAxis
Definition: geomdefs.hh:57
@ kOutside
Definition: geomdefs.hh:68

◆ G4TwistTubsHypeSide() [2/3]

G4TwistTubsHypeSide::G4TwistTubsHypeSide ( const G4String name,
G4double  EndInnerRadius[2],
G4double  EndOuterRadius[2],
G4double  DPhi,
G4double  EndPhi[2],
G4double  EndZ[2],
G4double  InnerRadius,
G4double  OuterRadius,
G4double  Kappa,
G4double  TanInnerStereo,
G4double  TanOuterStereo,
G4int  handedness 
)

Definition at line 71 of file G4TwistTubsHypeSide.cc.

83 : G4VTwistSurface(name)
84{
85
86 fHandedness = handedness; // +z = +ve, -z = -ve
87 fAxis[0] = kPhi;
88 fAxis[1] = kZAxis;
89 fAxisMin[0] = kInfinity; // we cannot fix boundary min of Phi,
90 fAxisMax[0] = kInfinity; // because it depends on z.
91 fAxisMin[1] = EndZ[0];
92 fAxisMax[1] = EndZ[1];
93 fKappa = Kappa;
94 fDPhi = DPhi ;
95
96 if (handedness < 0) // inner hyperbolic surface
97 {
98 fTanStereo = TanInnerStereo;
99 fR0 = InnerRadius;
100 }
101 else // outer hyperbolic surface
102 {
103 fTanStereo = TanOuterStereo;
104 fR0 = OuterRadius;
105 }
106 fTan2Stereo = fTanStereo * fTanStereo;
107 fR02 = fR0 * fR0;
108
109 fTrans.set(0, 0, 0);
110 fIsValidNorm = false;
111
112 fInside.gp.set(kInfinity, kInfinity, kInfinity);
113 fInside.inside = kOutside;
114
115 SetCorners(EndInnerRadius, EndOuterRadius, DPhi, EndPhi, EndZ) ;
116
117 SetBoundaries();
118}
void set(double x, double y, double z)
G4double fAxisMax[2]
G4ThreeVector fTrans
G4double fAxisMin[2]

◆ ~G4TwistTubsHypeSide()

G4TwistTubsHypeSide::~G4TwistTubsHypeSide ( )
virtual

Definition at line 132 of file G4TwistTubsHypeSide.cc.

133{
134}

◆ G4TwistTubsHypeSide() [3/3]

G4TwistTubsHypeSide::G4TwistTubsHypeSide ( __void__ &  a)

Definition at line 123 of file G4TwistTubsHypeSide.cc.

124 : G4VTwistSurface(a), fKappa(0.), fTanStereo(0.), fTan2Stereo(0.),
125 fR0(0.), fR02(0.), fDPhi(0.)
126{
127}

Member Function Documentation

◆ DistanceToSurface() [1/2]

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

Implements G4VTwistSurface.

Definition at line 251 of file G4TwistTubsHypeSide.cc.

258{
259 // Decide if and where a line intersects with a hyperbolic
260 // surface (of infinite extent)
261 //
262 // Arguments:
263 // p - (in) Point on trajectory
264 // v - (in) Vector along trajectory
265 // r2 - (in) Square of radius at z = 0
266 // tan2phi - (in) std::tan(stereo)**2
267 // s - (out) Up to two points of intersection, where the
268 // intersection point is p + s*v, and if there are
269 // two intersections, s[0] < s[1]. May be negative.
270 // Returns:
271 // The number of intersections. If 0, the trajectory misses.
272 //
273 //
274 // Equation of a line:
275 //
276 // x = x0 + s*tx y = y0 + s*ty z = z0 + s*tz
277 //
278 // Equation of a hyperbolic surface:
279 //
280 // x**2 + y**2 = r**2 + (z*tanPhi)**2
281 //
282 // Solution is quadratic:
283 //
284 // a*s**2 + b*s + c = 0
285 //
286 // where:
287 //
288 // a = tx**2 + ty**2 - (tz*tanPhi)**2
289 //
290 // b = 2*( x0*tx + y0*ty - z0*tz*tanPhi**2 )
291 //
292 // c = x0**2 + y0**2 - r**2 - (z0*tanPhi)**2
293 //
294
295 fCurStatWithV.ResetfDone(validate, &gp, &gv);
296
297 if (fCurStatWithV.IsDone())
298 {
299 for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
300 {
301 gxx[i] = fCurStatWithV.GetXX(i);
302 distance[i] = fCurStatWithV.GetDistance(i);
303 areacode[i] = fCurStatWithV.GetAreacode(i);
304 isvalid[i] = fCurStatWithV.IsValid(i);
305 }
306 return fCurStatWithV.GetNXX();
307 }
308 else // initialize
309 {
310 for (auto i=0; i<2; ++i)
311 {
312 distance[i] = kInfinity;
313 areacode[i] = sOutside;
314 isvalid[i] = false;
315 gxx[i].set(kInfinity, kInfinity, kInfinity);
316 }
317 }
318
321 G4ThreeVector xx[2];
322
323 //
324 // special case! p is on origin.
325 //
326
327 if (p.mag() == 0)
328 {
329 // p is origin.
330 // unique solution of 2-dimension question in r-z plane
331 // Equations:
332 // r^2 = fR02 + z^2*fTan2Stere0
333 // r = beta*z
334 // where
335 // beta = vrho / vz
336 // Solution (z value of intersection point):
337 // xxz = +- std::sqrt (fR02 / (beta^2 - fTan2Stereo))
338 //
339
340 G4double vz = v.z();
341 G4double absvz = std::fabs(vz);
342 G4double vrho = v.getRho();
343 G4double vslope = vrho/vz;
344 G4double vslope2 = vslope * vslope;
345 if (vrho == 0 || (vrho/absvz) <= (absvz*std::fabs(fTanStereo)/absvz))
346 {
347 // vz/vrho is bigger than slope of asymptonic line
348 distance[0] = kInfinity;
349 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
350 isvalid[0], 0, validate, &gp, &gv);
351 return 0;
352 }
353
354 if (vz)
355 {
356 G4double xxz = std::sqrt(fR02 / (vslope2 - fTan2Stereo))
357 * (vz / std::fabs(vz)) ;
358 G4double t = xxz / vz;
359 xx[0].set(t*v.x(), t*v.y(), xxz);
360 }
361 else
362 {
363 // p.z = 0 && v.z =0
364 xx[0].set(v.x()*fR0, v.y()*fR0, 0); // v is a unit vector.
365 }
366 distance[0] = xx[0].mag();
367 gxx[0] = ComputeGlobalPoint(xx[0]);
368
369 if (validate == kValidateWithTol)
370 {
371 areacode[0] = GetAreaCode(xx[0]);
372 if (!IsOutside(areacode[0]))
373 {
374 if (distance[0] >= 0) isvalid[0] = true;
375 }
376 }
377 else if (validate == kValidateWithoutTol)
378 {
379 areacode[0] = GetAreaCode(xx[0], false);
380 if (IsInside(areacode[0]))
381 {
382 if (distance[0] >= 0) isvalid[0] = true;
383 }
384 }
385 else // kDontValidate
386 {
387 areacode[0] = sInside;
388 if (distance[0] >= 0) isvalid[0] = true;
389 }
390
391 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
392 isvalid[0], 1, validate, &gp, &gv);
393 return 1;
394 }
395
396 //
397 // special case end.
398 //
399
400 G4double a = v.x()*v.x() + v.y()*v.y() - v.z()*v.z()*fTan2Stereo;
401 G4double b = 2.0
402 * ( p.x() * v.x() + p.y() * v.y() - p.z() * v.z() * fTan2Stereo );
403 G4double c = p.x()*p.x() + p.y()*p.y() - fR02 - p.z()*p.z()*fTan2Stereo;
404 G4double D = b*b - 4*a*c; //discriminant
405 G4int vout = 0;
406
407 if (std::fabs(a) < DBL_MIN)
408 {
409 if (std::fabs(b) > DBL_MIN) // single solution
410 {
411 distance[0] = -c/b;
412 xx[0] = p + distance[0]*v;
413 gxx[0] = ComputeGlobalPoint(xx[0]);
414
415 if (validate == kValidateWithTol)
416 {
417 areacode[0] = GetAreaCode(xx[0]);
418 if (!IsOutside(areacode[0]))
419 {
420 if (distance[0] >= 0) isvalid[0] = true;
421 }
422 }
423 else if (validate == kValidateWithoutTol)
424 {
425 areacode[0] = GetAreaCode(xx[0], false);
426 if (IsInside(areacode[0]))
427 {
428 if (distance[0] >= 0) isvalid[0] = true;
429 }
430 }
431 else // kDontValidate
432 {
433 areacode[0] = sInside;
434 if (distance[0] >= 0) isvalid[0] = true;
435 }
436
437 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
438 isvalid[0], 1, validate, &gp, &gv);
439 vout = 1;
440 }
441 else
442 {
443 // if a=b=0 and c != 0, p is origin and v is parallel to asymptotic line
444 // if a=b=c=0, p is on surface and v is paralell to stereo wire.
445 // return distance = infinity
446
447 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
448 isvalid[0], 0, validate, &gp, &gv);
449 vout = 0;
450 }
451 }
452 else if (D > DBL_MIN) // double solutions
453 {
454 D = std::sqrt(D);
455 G4double factor = 0.5/a;
456 G4double tmpdist[2] = {kInfinity, kInfinity};
457 G4ThreeVector tmpxx[2] ;
458 G4int tmpareacode[2] = {sOutside, sOutside};
459 G4bool tmpisvalid[2] = {false, false};
460
461 for (auto i=0; i<2; ++i)
462 {
463 tmpdist[i] = factor*(-b - D);
464 D = -D;
465 tmpxx[i] = p + tmpdist[i]*v;
466
467 if (validate == kValidateWithTol)
468 {
469 tmpareacode[i] = GetAreaCode(tmpxx[i]);
470 if (!IsOutside(tmpareacode[i]))
471 {
472 if (tmpdist[i] >= 0) tmpisvalid[i] = true;
473 continue;
474 }
475 }
476 else if (validate == kValidateWithoutTol)
477 {
478 tmpareacode[i] = GetAreaCode(tmpxx[i], false);
479 if (IsInside(tmpareacode[i]))
480 {
481 if (tmpdist[i] >= 0) tmpisvalid[i] = true;
482 continue;
483 }
484 }
485 else // kDontValidate
486 {
487 tmpareacode[i] = sInside;
488 if (tmpdist[i] >= 0) tmpisvalid[i] = true;
489 continue;
490 }
491 }
492
493 if (tmpdist[0] <= tmpdist[1])
494 {
495 distance[0] = tmpdist[0];
496 distance[1] = tmpdist[1];
497 xx[0] = tmpxx[0];
498 xx[1] = tmpxx[1];
499 gxx[0] = ComputeGlobalPoint(tmpxx[0]);
500 gxx[1] = ComputeGlobalPoint(tmpxx[1]);
501 areacode[0] = tmpareacode[0];
502 areacode[1] = tmpareacode[1];
503 isvalid[0] = tmpisvalid[0];
504 isvalid[1] = tmpisvalid[1];
505 }
506 else
507 {
508 distance[0] = tmpdist[1];
509 distance[1] = tmpdist[0];
510 xx[0] = tmpxx[1];
511 xx[1] = tmpxx[0];
512 gxx[0] = ComputeGlobalPoint(tmpxx[1]);
513 gxx[1] = ComputeGlobalPoint(tmpxx[0]);
514 areacode[0] = tmpareacode[1];
515 areacode[1] = tmpareacode[0];
516 isvalid[0] = tmpisvalid[1];
517 isvalid[1] = tmpisvalid[0];
518 }
519
520 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
521 isvalid[0], 2, validate, &gp, &gv);
522 fCurStatWithV.SetCurrentStatus(1, gxx[1], distance[1], areacode[1],
523 isvalid[1], 2, validate, &gp, &gv);
524 vout = 2;
525 }
526 else
527 {
528 // if D<0, no solution
529 // if D=0, just grazing the surfaces, return kInfinity
530
531 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
532 isvalid[0], 0, validate, &gp, &gv);
533 vout = 0;
534 }
535 return vout;
536}
double D(double temp)
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
double z() const
double x() const
double y() const
double mag() const
double getRho() const
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
static const G4int sInside
CurrentStatus fCurStatWithV
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const
#define DBL_MIN
Definition: templates.hh:54

◆ DistanceToSurface() [2/2]

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

Implements G4VTwistSurface.

Definition at line 541 of file G4TwistTubsHypeSide.cc.

545{
546 // Find the approximate distance of a point of a hyperbolic surface.
547 // The distance must be an underestimate.
548 // It will also be nice (although not necessary) that the estimate is
549 // always finite no matter how close the point is.
550 //
551 // We arranged G4Hype::ApproxDistOutside and G4Hype::ApproxDistInside
552 // for this function. See these discriptions.
553
554 const G4double halftol
556
558
559 if (fCurStat.IsDone())
560 {
561 for (G4int i=0; i<fCurStat.GetNXX(); ++i)
562 {
563 gxx[i] = fCurStat.GetXX(i);
564 distance[i] = fCurStat.GetDistance(i);
565 areacode[i] = fCurStat.GetAreacode(i);
566 }
567 return fCurStat.GetNXX();
568 }
569 else // initialize
570 {
571 for (auto i=0; i<2; ++i)
572 {
573 distance[i] = kInfinity;
574 areacode[i] = sOutside;
575 gxx[i].set(kInfinity, kInfinity, kInfinity);
576 }
577 }
578
579
581 G4ThreeVector xx;
582
583 //
584 // special case!
585 // If p is on surface, return distance = 0 immediatery .
586 //
587 G4ThreeVector lastgxx[2];
588 for (auto i=0; i<2; ++i)
589 {
590 lastgxx[i] = fCurStatWithV.GetXX(i);
591 }
592
593 if ((gp - lastgxx[0]).mag() < halftol || (gp - lastgxx[1]).mag() < halftol)
594 {
595 // last winner, or last poststep point is on the surface.
596 xx = p;
597 gxx[0] = gp;
598 distance[0] = 0;
599
600 G4bool isvalid = true;
601 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
602 isvalid, 1, kDontValidate, &gp);
603
604 return 1;
605 }
606 //
607 // special case end
608 //
609
610 G4double prho = p.getRho();
611 G4double pz = std::fabs(p.z()); // use symmetry
612 G4double r1 = std::sqrt(fR02 + pz * pz * fTan2Stereo);
613
614 G4ThreeVector pabsz(p.x(), p.y(), pz);
615
616 if (prho > r1 + halftol) // p is outside of Hyperbolic surface
617 {
618 // First point xx1
619 G4double t = r1 / prho;
620 G4ThreeVector xx1(t * pabsz.x(), t * pabsz.y() , pz);
621
622 // Second point xx2
623 G4double z2 = (prho * fTanStereo + pz) / (1 + fTan2Stereo);
624 G4double r2 = std::sqrt(fR02 + z2 * z2 * fTan2Stereo);
625 t = r2 / prho;
626 G4ThreeVector xx2(t * pabsz.x(), t * pabsz.y() , z2);
627
628 G4double len = (xx2 - xx1).mag();
629 if (len < DBL_MIN)
630 {
631 // xx2 = xx1?? I guess we
632 // must have really bracketed the normal
633 distance[0] = (pabsz - xx1).mag();
634 xx = xx1;
635 }
636 else
637 {
638 distance[0] = DistanceToLine(pabsz, xx1, (xx2 - xx1) , xx);
639 }
640
641 }
642 else if (prho < r1 - halftol) // p is inside of Hyperbolic surface.
643 {
644 // First point xx1
645 G4double t;
646 G4ThreeVector xx1;
647 if (prho < DBL_MIN)
648 {
649 xx1.set(r1, 0. , pz);
650 }
651 else
652 {
653 t = r1 / prho;
654 xx1.set(t * pabsz.x(), t * pabsz.y() , pz);
655 }
656
657 // dr, dz is tangential vector of Hyparbolic surface at xx1
658 // dr = r, dz = z*tan2stereo
659 G4double dr = pz * fTan2Stereo;
660 G4double dz = r1;
661 G4double tanbeta = dr / dz;
662 G4double pztanbeta = pz * tanbeta;
663
664 // Second point xx2
665 // xx2 is intersection between x-axis and tangential vector
666 G4double r2 = r1 - pztanbeta;
667 G4ThreeVector xx2;
668 if (prho < DBL_MIN)
669 {
670 xx2.set(r2, 0. , 0.);
671 }
672 else
673 {
674 t = r2 / prho;
675 xx2.set(t * pabsz.x(), t * pabsz.y() , 0.);
676 }
677
678 G4ThreeVector d = xx2 - xx1;
679 distance[0] = DistanceToLine(pabsz, xx1, d, xx);
680
681 }
682 else // p is on Hyperbolic surface.
683 {
684 distance[0] = 0;
685 xx.set(p.x(), p.y(), pz);
686 }
687
688 if (p.z() < 0)
689 {
690 G4ThreeVector tmpxx(xx.x(), xx.y(), -xx.z());
691 xx = tmpxx;
692 }
693
694 gxx[0] = ComputeGlobalPoint(xx);
695 areacode[0] = sInside;
696 G4bool isvalid = true;
697 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
698 isvalid, 1, kDontValidate, &gp);
699 return 1;
700}
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4double DistanceToLine(const G4ThreeVector &p, const G4ThreeVector &x0, const G4ThreeVector &d, G4ThreeVector &xx)
CurrentStatus fCurStat

◆ GetBoundaryMax()

G4double G4TwistTubsHypeSide::GetBoundaryMax ( G4double  phi)
inlinevirtual

Implements G4VTwistSurface.

Definition at line 182 of file G4TwistTubsHypeSide.hh.

183{
184 G4ThreeVector ptmp(0,0,z) ; // temporary point with z Komponent only
185 G4ThreeVector upperlimit; // upper phi-boundary limit at z = ptmp.z()
186 upperlimit = GetBoundaryAtPZ(sAxis0 & sAxisMax, ptmp);
187 return std::atan2( upperlimit.y(), upperlimit.x() ) ;
188}
static const G4int sAxisMax
static const G4int sAxis0
virtual G4ThreeVector GetBoundaryAtPZ(G4int areacode, const G4ThreeVector &p) const

Referenced by GetFacets().

◆ GetBoundaryMin()

G4double G4TwistTubsHypeSide::GetBoundaryMin ( G4double  phi)
inlinevirtual

Implements G4VTwistSurface.

Definition at line 173 of file G4TwistTubsHypeSide.hh.

174{
175 G4ThreeVector ptmp(0,0,z) ; // temporary point with z Komponent only
176 G4ThreeVector lowerlimit; // lower phi-boundary limit at z = ptmp.z()
177 lowerlimit = GetBoundaryAtPZ(sAxis0 & sAxisMin, ptmp);
178 return std::atan2( lowerlimit.y(), lowerlimit.x() ) ;
179}
static const G4int sAxisMin

Referenced by GetFacets().

◆ GetFacets()

void G4TwistTubsHypeSide::GetFacets ( G4int  m,
G4int  n,
G4double  xyz[][3],
G4int  faces[][4],
G4int  iside 
)
virtual

Implements G4VTwistSurface.

Definition at line 996 of file G4TwistTubsHypeSide.cc.

998{
999 G4double z ; // the two parameters for the surface equation
1000 G4double x,xmin,xmax ;
1001
1002 G4ThreeVector p ; // a point on the surface, given by (z,u)
1003
1004 G4int nnode ;
1005 G4int nface ;
1006
1007 // calculate the (n-1)*(k-1) vertices
1008
1009 for ( G4int i = 0 ; i<n ; ++i )
1010 {
1011 z = fAxisMin[1] + i*(fAxisMax[1]-fAxisMin[1])/(n-1) ;
1012
1013 for ( G4int j = 0 ; j<k ; ++j )
1014 {
1015 nnode = GetNode(i,j,k,n,iside) ;
1016
1017 xmin = GetBoundaryMin(z) ;
1018 xmax = GetBoundaryMax(z) ;
1019
1020 if (fHandedness < 0) // inner hyperbolic surface
1021 {
1022 x = xmin + j*(xmax-xmin)/(k-1) ;
1023 }
1024 else // outer hyperbolic surface
1025 {
1026 x = xmax - j*(xmax-xmin)/(k-1) ;
1027 }
1028
1029 p = SurfacePoint(x,z,true) ; // surface point in global coord.system
1030
1031 xyz[nnode][0] = p.x() ;
1032 xyz[nnode][1] = p.y() ;
1033 xyz[nnode][2] = p.z() ;
1034
1035 if ( i<n-1 && j<k-1 ) // clock wise filling
1036 {
1037 nface = GetFace(i,j,k,n,iside) ;
1038 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1)
1039 * ( GetNode(i ,j ,k,n,iside)+1) ;
1040 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1)
1041 * ( GetNode(i+1,j ,k,n,iside)+1) ;
1042 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1)
1043 * ( GetNode(i+1,j+1,k,n,iside)+1) ;
1044 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1)
1045 * ( GetNode(i ,j+1,k,n,iside)+1) ;
1046 }
1047 }
1048 }
1049}
virtual G4double GetBoundaryMin(G4double phi)
virtual G4ThreeVector SurfacePoint(G4double, G4double, G4bool isGlobal=false)
virtual G4double GetBoundaryMax(G4double phi)
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)

◆ GetNormal()

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

Implements G4VTwistSurface.

Definition at line 139 of file G4TwistTubsHypeSide.cc.

141{
142 // GetNormal returns a normal vector at a surface (or very close
143 // to surface) point at tmpxx.
144 // If isGlobal=true, it returns the normal in global coordinate.
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 fCurrentNormal.p = xx;
165
166 G4ThreeVector normal( xx.x(), xx.y(), -xx.z() * fTan2Stereo);
167 normal *= fHandedness;
168 normal = normal.unit();
169
170 if (isGlobal)
171 {
173 }
174 else
175 {
176 fCurrentNormal.normal = normal;
177 }
178 return fCurrentNormal.normal;
179}
G4ThreeVector ComputeGlobalDirection(const G4ThreeVector &lp) const
G4SurfCurNormal fCurrentNormal

◆ GetRhoAtPZ()

G4double G4TwistTubsHypeSide::GetRhoAtPZ ( const G4ThreeVector p,
G4bool  isglobal = false 
) const
inlinevirtual

Definition at line 149 of file G4TwistTubsHypeSide.hh.

151{
152 // Get Rho at p.z() on Hyperbolic Surface.
153 G4ThreeVector tmpp;
154 if (isglobal) { tmpp = fRot.inverse()*p - fTrans; }
155 else { tmpp = p; }
156
157 return std::sqrt(fR02 + tmpp.z() * tmpp.z() * fTan2Stereo);
158}
HepRotation inverse() const
G4RotationMatrix fRot

Referenced by Inside().

◆ GetSurfaceArea()

G4double G4TwistTubsHypeSide::GetSurfaceArea ( )
inlinevirtual

Implements G4VTwistSurface.

Definition at line 191 of file G4TwistTubsHypeSide.hh.

192{
193 // approximation with tube surface
194
195 return ( fAxisMax[1] - fAxisMin[1] ) * fR0 * fDPhi ;
196}

◆ Inside()

EInside G4TwistTubsHypeSide::Inside ( const G4ThreeVector gp)
virtual

Definition at line 184 of file G4TwistTubsHypeSide.cc.

185{
186 // Inside returns
187 const G4double halftol
189
190 if (fInside.gp == gp)
191 {
192 return fInside.inside;
193 }
194 fInside.gp = gp;
195
197
198
199 if (p.mag() < DBL_MIN)
200 {
201 fInside.inside = kOutside;
202 return fInside.inside;
203 }
204
205 G4double rhohype = GetRhoAtPZ(p);
206 G4double distanceToOut = fHandedness * (rhohype - p.getRho());
207 // +ve : inside
208
209 if (distanceToOut < -halftol)
210 {
211 fInside.inside = kOutside;
212 }
213 else
214 {
215 G4int areacode = GetAreaCode(p);
216 if (IsOutside(areacode))
217 {
218 fInside.inside = kOutside;
219 }
220 else if (IsBoundary(areacode))
221 {
222 fInside.inside = kSurface;
223 }
224 else if (IsInside(areacode))
225 {
226 if (distanceToOut <= halftol)
227 {
228 fInside.inside = kSurface;
229 }
230 else
231 {
232 fInside.inside = kInside;
233 }
234 }
235 else
236 {
237 G4cout << "WARNING - G4TwistTubsHypeSide::Inside()" << G4endl
238 << " Invalid option !" << G4endl
239 << " name, areacode, distanceToOut = "
240 << GetName() << ", " << std::hex << areacode
241 << std::dec << ", " << distanceToOut << G4endl;
242 }
243 }
244
245 return fInside.inside;
246}
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
virtual G4double GetRhoAtPZ(const G4ThreeVector &p, G4bool isglobal=false) const
virtual G4String GetName() const
G4bool IsBoundary(G4int areacode, G4bool testbitmode=false) const
@ kInside
Definition: geomdefs.hh:70
@ kSurface
Definition: geomdefs.hh:69

◆ SurfacePoint()

G4ThreeVector G4TwistTubsHypeSide::SurfacePoint ( G4double  phi,
G4double  z,
G4bool  isGlobal = false 
)
inlinevirtual

Implements G4VTwistSurface.

Definition at line 161 of file G4TwistTubsHypeSide.hh.

163{
164 G4double rho = std::sqrt(fR02 + z * z * fTan2Stereo) ;
165
166 G4ThreeVector SurfPoint (rho*std::cos(phi), rho*std::sin(phi), z) ;
167
168 if (isGlobal) { return (fRot * SurfPoint + fTrans); }
169 return SurfPoint;
170}

Referenced by GetFacets().


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