Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4TwistTubsFlatSide.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4TwistTubsFlatSide implementation
27//
28// 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepburn.s.chiba-u.ac.jp), created.
29// 13-Nov-2003 - O.Link (Oliver.Link@cern.ch), Integration in Geant4
30// from original version in Jupiter-2.5.02 application.
31// --------------------------------------------------------------------
32
35
36//=====================================================================
37//* constructors ------------------------------------------------------
38
40 const G4RotationMatrix& rot,
41 const G4ThreeVector& tlate,
42 const G4ThreeVector& n,
43 const EAxis axis0 ,
44 const EAxis axis1 ,
45 G4double axis0min,
46 G4double axis1min,
47 G4double axis0max,
48 G4double axis1max )
49 : G4VTwistSurface(name, rot, tlate, 0, axis0, axis1,
50 axis0min, axis1min, axis0max, axis1max)
51{
52 if (axis0 == kPhi && axis1 == kRho)
53 {
54 G4Exception("G4TwistTubsFlatSide::G4TwistTubsFlatSide()",
55 "GeomSolids0002", FatalErrorInArgument,
56 "Should swap axis0 and axis1!");
57 }
58
59 G4ThreeVector normal = rot.inverse()*n;
60 fCurrentNormal.normal = normal.unit(); // in local coordinate system
61 fIsValidNorm = true;
62
63 SetCorners();
64 SetBoundaries();
65
66 fSurfaceArea = 1. ; // NOTE: not yet implemented!
67}
68
70 G4double EndInnerRadius[2],
71 G4double EndOuterRadius[2],
72 G4double DPhi,
73 G4double EndPhi[2],
74 G4double EndZ[2],
75 G4int handedness )
76 : G4VTwistSurface(name)
77{
78 fHandedness = handedness; // +z = +ve, -z = -ve
79 fAxis[0] = kRho; // in local coordinate system
80 fAxis[1] = kPhi;
81 G4int i = (handedness < 0 ? 0 : 1);
82 fAxisMin[0] = EndInnerRadius[i]; // Inner-hype radius at z=0
83 fAxisMax[0] = EndOuterRadius[i]; // Outer-hype radius at z=0
84 fAxisMin[1] = -0.5*DPhi;
85 fAxisMax[1] = -fAxisMin[1];
86 fCurrentNormal.normal.set(0, 0, (fHandedness < 0 ? -1 : 1));
87 // Unit vector, in local coordinate system
88 fRot.rotateZ(EndPhi[i]);
89 fTrans.set(0, 0, EndZ[i]);
90 fIsValidNorm = true;
91
92 SetCorners();
93 SetBoundaries();
94
95 fSurfaceArea = 0.5*DPhi * (EndOuterRadius[i]*EndOuterRadius[i]
96 - EndInnerRadius[i]*EndInnerRadius[i] ) ;
97}
98
99//=====================================================================
100//* Fake default constructor ------------------------------------------
101
103 : G4VTwistSurface(a)
104{
105}
106
107//=====================================================================
108//* destructor --------------------------------------------------------
109
111{
112}
113
114//=====================================================================
115//* GetNormal ---------------------------------------------------------
116
118 G4bool isGlobal)
119{
120 if (isGlobal)
121 {
123 }
124 else
125 {
126 return fCurrentNormal.normal;
127 }
128}
129
130//=====================================================================
131//* DistanceToSurface(p, v) -------------------------------------------
132
134 const G4ThreeVector& gv,
135 G4ThreeVector gxx[],
136 G4double distance[],
137 G4int areacode[],
138 G4bool isvalid[],
139 EValidate validate)
140{
141 fCurStatWithV.ResetfDone(validate, &gp, &gv);
142
143 if (fCurStatWithV.IsDone())
144 {
145 for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
146 {
147 gxx[i] = fCurStatWithV.GetXX(i);
148 distance[i] = fCurStatWithV.GetDistance(i);
149 areacode[i] = fCurStatWithV.GetAreacode(i);
150 isvalid[i] = fCurStatWithV.IsValid(i);
151 }
152 return fCurStatWithV.GetNXX();
153 }
154 else // initialize
155 {
156 for (G4int i=0; i<2; ++i)
157 {
158 distance[i] = kInfinity;
159 areacode[i] = sOutside;
160 isvalid[i] = false;
161 gxx[i].set(kInfinity, kInfinity, kInfinity);
162 }
163 }
164
167
168 //
169 // special case!
170 // if p is on surface, distance = 0.
171 //
172
173 if (std::fabs(p.z()) == 0.) // if p is on the plane
174 {
175 distance[0] = 0;
176 G4ThreeVector xx = p;
177 gxx[0] = ComputeGlobalPoint(xx);
178
179 if (validate == kValidateWithTol)
180 {
181 areacode[0] = GetAreaCode(xx);
182 if (!IsOutside(areacode[0]))
183 {
184 isvalid[0] = true;
185 }
186 }
187 else if (validate == kValidateWithoutTol)
188 {
189 areacode[0] = GetAreaCode(xx, false);
190 if (IsInside(areacode[0]))
191 {
192 isvalid[0] = true;
193 }
194 }
195 else // kDontValidate
196 {
197 areacode[0] = sInside;
198 isvalid[0] = true;
199 }
200 return 1;
201 }
202 //
203 // special case end
204 //
205
206 if (v.z() == 0)
207 {
208 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
209 isvalid[0], 0, validate, &gp, &gv);
210 return 0;
211 }
212
213 distance[0] = - (p.z() / v.z());
214
215 G4ThreeVector xx = p + distance[0]*v;
216 gxx[0] = ComputeGlobalPoint(xx);
217
218 if (validate == kValidateWithTol)
219 {
220 areacode[0] = GetAreaCode(xx);
221 if (!IsOutside(areacode[0]))
222 {
223 if (distance[0] >= 0) isvalid[0] = true;
224 }
225 }
226 else if (validate == kValidateWithoutTol)
227 {
228 areacode[0] = GetAreaCode(xx, false);
229 if (IsInside(areacode[0]))
230 {
231 if (distance[0] >= 0) isvalid[0] = true;
232 }
233 }
234 else // kDontValidate
235 {
236 areacode[0] = sInside;
237 if (distance[0] >= 0) isvalid[0] = true;
238 }
239
240 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
241 isvalid[0], 1, validate, &gp, &gv);
242
243#ifdef G4TWISTDEBUG
244 G4cerr << "ERROR - G4TwistTubsFlatSide::DistanceToSurface(p,v)" << G4endl;
245 G4cerr << " Name : " << GetName() << G4endl;
246 G4cerr << " xx : " << xx << G4endl;
247 G4cerr << " gxx[0] : " << gxx[0] << G4endl;
248 G4cerr << " dist[0] : " << distance[0] << G4endl;
249 G4cerr << " areacode[0] : " << areacode[0] << G4endl;
250 G4cerr << " isvalid[0] : " << isvalid[0] << G4endl;
251#endif
252 return 1;
253}
254
255//=====================================================================
256//* DistanceToSurface(p) ----------------------------------------------
257
259 G4ThreeVector gxx[],
260 G4double distance[],
261 G4int areacode[])
262{
263 // Calculate distance to plane in local coordinate,
264 // then return distance and global intersection points.
265 //
266
268
269 if (fCurStat.IsDone())
270 {
271 for (G4int i=0; i<fCurStat.GetNXX(); ++i)
272 {
273 gxx[i] = fCurStat.GetXX(i);
274 distance[i] = fCurStat.GetDistance(i);
275 areacode[i] = fCurStat.GetAreacode(i);
276 }
277 return fCurStat.GetNXX();
278 }
279 else // initialize
280 {
281 for (auto i=0; i<2; ++i)
282 {
283 distance[i] = kInfinity;
284 areacode[i] = sOutside;
285 gxx[i].set(kInfinity, kInfinity, kInfinity);
286 }
287 }
288
290 G4ThreeVector xx;
291
292 // The plane is placed on origin with making its normal
293 // parallel to z-axis.
294 if (std::fabs(p.z()) <= 0.5 * kCarTolerance) // if p is on plane, return 1
295 {
296 distance[0] = 0;
297 xx = p;
298 }
299 else
300 {
301 distance[0] = std::fabs(p.z());
302 xx.set(p.x(), p.y(), 0);
303 }
304
305 gxx[0] = ComputeGlobalPoint(xx);
306 areacode[0] = sInside;
307 G4bool isvalid = true;
308 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
309 isvalid, 1, kDontValidate, &gp);
310 return 1;
311}
312
313//=====================================================================
314//* GetAreaCode -------------------------------------------------------
315
317 G4bool withTol)
318{
319 const G4double rtol
321
322 G4int areacode = sInside;
323
324 if (fAxis[0] == kRho && fAxis[1] == kPhi)
325 {
326 G4int rhoaxis = 0;
327
328 G4ThreeVector dphimin; // direction of phi-minimum boundary
329 G4ThreeVector dphimax; // direction of phi-maximum boundary
330 dphimin = GetCorner(sC0Max1Min);
331 dphimax = GetCorner(sC0Max1Max);
332
333 if (withTol)
334 {
335 G4bool isoutside = false;
336
337 // test boundary of rho-axis
338
339 if (xx.getRho() <= fAxisMin[rhoaxis] + rtol)
340 {
341 areacode |= (sAxis0 & (sAxisRho|sAxisMin)) | sBoundary; // rho-min
342 if (xx.getRho() < fAxisMin[rhoaxis] - rtol) isoutside = true;
343
344 }
345 else if (xx.getRho() >= fAxisMax[rhoaxis] - rtol)
346 {
347 areacode |= (sAxis0 & (sAxisRho|sAxisMax)) | sBoundary; // rho-max
348 if (xx.getRho() > fAxisMax[rhoaxis] + rtol) isoutside = true;
349 }
350
351 // test boundary of phi-axis
352
353 if (AmIOnLeftSide(xx, dphimin) >= 0) // xx is on dphimin
354 {
355 areacode |= (sAxis1 & (sAxisPhi | sAxisMin));
356 if (areacode & sBoundary) areacode |= sCorner; // xx is on corner.
357 else areacode |= sBoundary;
358
359 if (AmIOnLeftSide(xx, dphimin) > 0) isoutside = true;
360
361 }
362 else if (AmIOnLeftSide(xx, dphimax) <= 0) // xx is on dphimax
363 {
364 areacode |= (sAxis1 & (sAxisPhi | sAxisMax));
365 if (areacode & sBoundary) areacode |= sCorner; // xx is on corner.
366 else areacode |= sBoundary;
367
368 if (AmIOnLeftSide(xx, dphimax) < 0) isoutside = true;
369 }
370
371 // if isoutside = true, clear inside bit.
372 // if not on boundary, add axis information.
373
374 if (isoutside)
375 {
376 G4int tmpareacode = areacode & (~sInside);
377 areacode = tmpareacode;
378 }
379 else if ((areacode & sBoundary) != sBoundary)
380 {
381 areacode |= (sAxis0 & sAxisRho) | (sAxis1 & sAxisPhi);
382 }
383
384 }
385 else
386 {
387 // out of boundary of rho-axis
388
389 if (xx.getRho() < fAxisMin[rhoaxis])
390 {
391 areacode |= (sAxis0 & (sAxisRho | sAxisMin)) | sBoundary;
392 }
393 else if (xx.getRho() > fAxisMax[rhoaxis])
394 {
395 areacode |= (sAxis0 & (sAxisRho | sAxisMax)) | sBoundary;
396 }
397
398 // out of boundary of phi-axis
399
400 if (AmIOnLeftSide(xx, dphimin, false) >= 0) // xx is leftside or
401 {
402 areacode |= (sAxis1 & (sAxisPhi | sAxisMin)) ; // boundary of dphimin
403 if (areacode & sBoundary) areacode |= sCorner; // xx is on corner
404 else areacode |= sBoundary;
405
406 }
407 else if (AmIOnLeftSide(xx, dphimax, false) <= 0) // xx is rightside or
408 {
409 areacode |= (sAxis1 & (sAxisPhi | sAxisMax)); // boundary of dphimax
410 if (areacode & sBoundary) areacode |= sCorner; // xx is on corner
411 else areacode |= sBoundary;
412
413 }
414
415 if ((areacode & sBoundary) != sBoundary) {
416 areacode |= (sAxis0 & sAxisRho) | (sAxis1 & sAxisPhi);
417 }
418
419 }
420 return areacode;
421 }
422 else
423 {
424 std::ostringstream message;
425 message << "Feature NOT implemented !" << G4endl
426 << " fAxis[0] = " << fAxis[0] << G4endl
427 << " fAxis[1] = " << fAxis[1];
428 G4Exception("G4TwistTubsFlatSide::GetAreaCode()", "GeomSolids0001",
429 FatalException, message);
430 }
431 return areacode;
432}
433
434//=====================================================================
435//* SetCorners --------------------------------------------------------
436
437void G4TwistTubsFlatSide::SetCorners()
438{
439 // Set Corner points in local coodinate.
440
441 if (fAxis[0] == kRho && fAxis[1] == kPhi)
442 {
443 G4int rhoaxis = 0; // kRho
444 G4int phiaxis = 1; // kPhi
445
446 G4double x, y, z;
447 // corner of Axis0min and Axis1min
448 x = fAxisMin[rhoaxis]*std::cos(fAxisMin[phiaxis]);
449 y = fAxisMin[rhoaxis]*std::sin(fAxisMin[phiaxis]);
450 z = 0;
451 SetCorner(sC0Min1Min, x, y, z);
452 // corner of Axis0max and Axis1min
453 x = fAxisMax[rhoaxis]*std::cos(fAxisMin[phiaxis]);
454 y = fAxisMax[rhoaxis]*std::sin(fAxisMin[phiaxis]);
455 z = 0;
456 SetCorner(sC0Max1Min, x, y, z);
457 // corner of Axis0max and Axis1max
458 x = fAxisMax[rhoaxis]*std::cos(fAxisMax[phiaxis]);
459 y = fAxisMax[rhoaxis]*std::sin(fAxisMax[phiaxis]);
460 z = 0;
461 SetCorner(sC0Max1Max, x, y, z);
462 // corner of Axis0min and Axis1max
463 x = fAxisMin[rhoaxis]*std::cos(fAxisMax[phiaxis]);
464 y = fAxisMin[rhoaxis]*std::sin(fAxisMax[phiaxis]);
465 z = 0;
466 SetCorner(sC0Min1Max, x, y, z);
467
468 }
469 else
470 {
471 std::ostringstream message;
472 message << "Feature NOT implemented !" << G4endl
473 << " fAxis[0] = " << fAxis[0] << G4endl
474 << " fAxis[1] = " << fAxis[1];
475 G4Exception("G4TwistTubsFlatSide::SetCorners()", "GeomSolids0001",
476 FatalException, message);
477 }
478}
479
480//=====================================================================
481//* SetBoundaries() ---------------------------------------------------
482
483void G4TwistTubsFlatSide::SetBoundaries()
484{
485 // Set direction-unit vector of phi-boundary-lines in local coodinate.
486 // Don't call the function twice.
487
488 if (fAxis[0] == kRho && fAxis[1] == kPhi)
489 {
490 G4ThreeVector direction;
491 // sAxis0 & sAxisMin
493 direction = direction.unit();
494 SetBoundary(sAxis0 & (sAxisPhi | sAxisMin), direction,
496
497 // sAxis0 & sAxisMax
499 direction = direction.unit();
500 SetBoundary(sAxis0 & (sAxisPhi | sAxisMax), direction,
502
503 // sAxis1 & sAxisMin
505 direction = direction.unit();
506 SetBoundary(sAxis1 & (sAxisRho | sAxisMin), direction,
508
509 // sAxis1 & sAxisMax
511 direction = direction.unit();
512 SetBoundary(sAxis1 & (sAxisRho | sAxisMax), direction,
514 }
515 else
516 {
517 std::ostringstream message;
518 message << "Feature NOT implemented !" << G4endl
519 << " fAxis[0] = " << fAxis[0] << G4endl
520 << " fAxis[1] = " << fAxis[1];
521 G4Exception("G4TwistTubsFlatSide::SetBoundaries()", "GeomSolids0001",
522 FatalException, message);
523 }
524}
525
526//=====================================================================
527//* GetFacets() -------------------------------------------------------
528
530 G4int faces[][4], G4int iside )
531{
532 G4ThreeVector p ;
533
534 G4double rmin = fAxisMin[0] ;
535 G4double rmax = fAxisMax[0] ;
536 G4double phimin, phimax ;
537
538 G4double r,phi ;
539 G4int nnode,nface ;
540
541 for ( G4int i = 0 ; i<n ; ++i )
542 {
543 r = rmin + i*(rmax-rmin)/(n-1) ;
544
545 phimin = GetBoundaryMin(r) ;
546 phimax = GetBoundaryMax(r) ;
547
548 for ( G4int j = 0 ; j<k ; ++j )
549 {
550 phi = phimin + j*(phimax-phimin)/(k-1) ;
551
552 nnode = GetNode(i,j,k,n,iside) ;
553 p = SurfacePoint(phi,r,true) ; // surface point in global coord.system
554
555 xyz[nnode][0] = p.x() ;
556 xyz[nnode][1] = p.y() ;
557 xyz[nnode][2] = p.z() ;
558
559 if ( i<n-1 && j<k-1 ) // conterclock wise filling
560 {
561 nface = GetFace(i,j,k,n,iside) ;
562
563 if (fHandedness < 0) // lower side
564 {
565 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,-1)
566 * ( GetNode(i ,j ,k,n,iside)+1) ;
567 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,-1)
568 * ( GetNode(i ,j+1,k,n,iside)+1) ;
569 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,-1)
570 * ( GetNode(i+1,j+1,k,n,iside)+1) ;
571 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,-1)
572 * ( GetNode(i+1,j ,k,n,iside)+1) ;
573 }
574 else // upper side
575 {
576 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1)
577 * ( GetNode(i ,j ,k,n,iside)+1) ;
578 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1)
579 * ( GetNode(i+1,j ,k,n,iside)+1) ;
580 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1)
581 * ( GetNode(i+1,j+1,k,n,iside)+1) ;
582 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1)
583 * ( GetNode(i ,j+1,k,n,iside)+1) ;
584 }
585 }
586 }
587 }
588}
@ FatalException
@ FatalErrorInArgument
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
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition: G4ios.hh:57
double z() const
Hep3Vector unit() const
double x() const
double y() const
double getRho() const
void set(double x, double y, double z)
HepRotation inverse() const
HepRotation & rotateZ(double delta)
Definition: Rotation.cc:87
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
virtual void GetFacets(G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)
virtual G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)
G4TwistTubsFlatSide(const G4String &name, const G4RotationMatrix &rot, const G4ThreeVector &tlate, const G4ThreeVector &n, const EAxis axis1=kRho, const EAxis axis2=kPhi, G4double axis0min=-kInfinity, G4double axis1min=-kInfinity, G4double axis0max=kInfinity, G4double axis1max=kInfinity)
virtual G4double GetBoundaryMin(G4double phi)
virtual G4int GetAreaCode(const G4ThreeVector &xx, G4bool withTol=true)
virtual G4ThreeVector GetNormal(const G4ThreeVector &, G4bool isGlobal=false)
virtual G4double GetBoundaryMax(G4double phi)
virtual G4ThreeVector SurfacePoint(G4double, G4double, G4bool isGlobal=false)
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)
virtual G4int AmIOnLeftSide(const G4ThreeVector &me, const G4ThreeVector &vec, G4bool withTol=true)
static const G4int sC0Min1Min
static const G4int sC0Min1Max
G4int GetNode(G4int i, G4int j, G4int m, G4int n, G4int iside)
static const G4int sOutside
G4ThreeVector ComputeGlobalDirection(const G4ThreeVector &lp) const
static const G4int sAxisMax
static const G4int sAxis0
G4int GetFace(G4int i, G4int j, G4int m, G4int n, G4int iside)
G4double fAxisMax[2]
G4RotationMatrix fRot
G4int GetEdgeVisibility(G4int i, G4int j, G4int m, G4int n, G4int number, G4int orientation)
G4ThreeVector ComputeLocalDirection(const G4ThreeVector &gp) const
static const G4int sAxisPhi
static const G4int sAxisMin
static const G4int sC0Max1Max
static const G4int sAxis1
G4bool IsInside(G4int areacode, G4bool testbitmode=false) const
G4ThreeVector fTrans
virtual void SetBoundary(const G4int &axiscode, const G4ThreeVector &direction, const G4ThreeVector &x0, const G4int &boundarytype)
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &gp) const
static const G4int sAxisRho
void SetCorner(G4int areacode, G4double x, G4double y, G4double z)
G4ThreeVector GetCorner(G4int areacode) const
static const G4int sBoundary
G4bool IsOutside(G4int areacode) const
G4double fAxisMin[2]
static const G4int sCorner
static const G4int sC0Max1Min
static const G4int sInside
virtual G4String GetName() const
CurrentStatus fCurStatWithV
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const
G4SurfCurNormal fCurrentNormal
CurrentStatus fCurStat
EAxis
Definition: geomdefs.hh:54
@ kPhi
Definition: geomdefs.hh:60
@ kRho
Definition: geomdefs.hh:58