Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// Author: Kotoyo Hoshina (Chiba University), 01.08.2002 - Created.
29// Oliver Link (CERN), 13.11.2003 - 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
106
107//=====================================================================
108//* GetNormal ---------------------------------------------------------
109
111 G4bool isGlobal)
112{
113 if (isGlobal)
114 {
116 }
117 return fCurrentNormal.normal;
118}
119
120//=====================================================================
121//* DistanceToSurface(p, v) -------------------------------------------
122
124 const G4ThreeVector& gv,
125 G4ThreeVector gxx[],
126 G4double distance[],
127 G4int areacode[],
128 G4bool isvalid[],
129 EValidate validate)
130{
131 fCurStatWithV.ResetfDone(validate, &gp, &gv);
132
133 if (fCurStatWithV.IsDone())
134 {
135 for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
136 {
137 gxx[i] = fCurStatWithV.GetXX(i);
138 distance[i] = fCurStatWithV.GetDistance(i);
139 areacode[i] = fCurStatWithV.GetAreacode(i);
140 isvalid[i] = fCurStatWithV.IsValid(i);
141 }
142 return fCurStatWithV.GetNXX();
143 }
144
145 // initialize
146 for (G4int i=0; i<2; ++i)
147 {
148 distance[i] = kInfinity;
149 areacode[i] = sOutside;
150 isvalid[i] = false;
151 gxx[i].set(kInfinity, kInfinity, kInfinity);
152 }
153
156
157 //
158 // special case!
159 // if p is on surface, distance = 0.
160 //
161
162 if (std::fabs(p.z()) == 0.) // if p is on the plane
163 {
164 distance[0] = 0;
165 G4ThreeVector xx = p;
166 gxx[0] = ComputeGlobalPoint(xx);
167
168 if (validate == kValidateWithTol)
169 {
170 areacode[0] = GetAreaCode(xx);
171 if (!IsOutside(areacode[0]))
172 {
173 isvalid[0] = true;
174 }
175 }
176 else if (validate == kValidateWithoutTol)
177 {
178 areacode[0] = GetAreaCode(xx, false);
179 if (IsInside(areacode[0]))
180 {
181 isvalid[0] = true;
182 }
183 }
184 else // kDontValidate
185 {
186 areacode[0] = sInside;
187 isvalid[0] = true;
188 }
189 return 1;
190 }
191 //
192 // special case end
193 //
194
195 if (v.z() == 0)
196 {
197 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
198 isvalid[0], 0, validate, &gp, &gv);
199 return 0;
200 }
201
202 distance[0] = - (p.z() / v.z());
203
204 G4ThreeVector xx = p + distance[0]*v;
205 gxx[0] = ComputeGlobalPoint(xx);
206
207 if (validate == kValidateWithTol)
208 {
209 areacode[0] = GetAreaCode(xx);
210 if (!IsOutside(areacode[0]))
211 {
212 if (distance[0] >= 0) { isvalid[0] = true; }
213 }
214 }
215 else if (validate == kValidateWithoutTol)
216 {
217 areacode[0] = GetAreaCode(xx, false);
218 if (IsInside(areacode[0]))
219 {
220 if (distance[0] >= 0) { isvalid[0] = true; }
221 }
222 }
223 else // kDontValidate
224 {
225 areacode[0] = sInside;
226 if (distance[0] >= 0) { isvalid[0] = true; }
227 }
228
229 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
230 isvalid[0], 1, validate, &gp, &gv);
231
232#ifdef G4TWISTDEBUG
233 G4cerr << "ERROR - G4TwistTubsFlatSide::DistanceToSurface(p,v)" << G4endl;
234 G4cerr << " Name : " << GetName() << G4endl;
235 G4cerr << " xx : " << xx << G4endl;
236 G4cerr << " gxx[0] : " << gxx[0] << G4endl;
237 G4cerr << " dist[0] : " << distance[0] << G4endl;
238 G4cerr << " areacode[0] : " << areacode[0] << G4endl;
239 G4cerr << " isvalid[0] : " << isvalid[0] << G4endl;
240#endif
241 return 1;
242}
243
244//=====================================================================
245//* DistanceToSurface(p) ----------------------------------------------
246
248 G4ThreeVector gxx[],
249 G4double distance[],
250 G4int areacode[])
251{
252 // Calculate distance to plane in local coordinate,
253 // then return distance and global intersection points.
254 //
255
256 fCurStat.ResetfDone(kDontValidate, &gp);
257
258 if (fCurStat.IsDone())
259 {
260 for (G4int i=0; i<fCurStat.GetNXX(); ++i)
261 {
262 gxx[i] = fCurStat.GetXX(i);
263 distance[i] = fCurStat.GetDistance(i);
264 areacode[i] = fCurStat.GetAreacode(i);
265 }
266 return fCurStat.GetNXX();
267 }
268
269 // initialize
270 for (auto i=0; i<2; ++i)
271 {
272 distance[i] = kInfinity;
273 areacode[i] = sOutside;
274 gxx[i].set(kInfinity, kInfinity, kInfinity);
275 }
276
278 G4ThreeVector xx;
279
280 // The plane is placed on origin with making its normal
281 // parallel to z-axis.
282 if (std::fabs(p.z()) <= 0.5 * kCarTolerance) // if p is on plane, return 1
283 {
284 distance[0] = 0;
285 xx = p;
286 }
287 else
288 {
289 distance[0] = std::fabs(p.z());
290 xx.set(p.x(), p.y(), 0);
291 }
292
293 gxx[0] = ComputeGlobalPoint(xx);
294 areacode[0] = sInside;
295 G4bool isvalid = true;
296 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
297 isvalid, 1, kDontValidate, &gp);
298 return 1;
299}
300
301//=====================================================================
302//* GetAreaCode -------------------------------------------------------
303
304G4int G4TwistTubsFlatSide::GetAreaCode(const G4ThreeVector &xx,
305 G4bool withTol)
306{
307 const G4double rtol
309
310 G4int areacode = sInside;
311
312 if (fAxis[0] == kRho && fAxis[1] == kPhi)
313 {
314 G4int rhoaxis = 0;
315
316 G4ThreeVector dphimin; // direction of phi-minimum boundary
317 G4ThreeVector dphimax; // direction of phi-maximum boundary
318 dphimin = GetCorner(sC0Max1Min);
319 dphimax = GetCorner(sC0Max1Max);
320
321 if (withTol)
322 {
323 G4bool isoutside = false;
324
325 // test boundary of rho-axis
326
327 if (xx.getRho() <= fAxisMin[rhoaxis] + rtol)
328 {
329 areacode |= (sAxis0 & (sAxisRho|sAxisMin)) | sBoundary; // rho-min
330 if (xx.getRho() < fAxisMin[rhoaxis] - rtol) { isoutside = true; }
331 }
332 else if (xx.getRho() >= fAxisMax[rhoaxis] - rtol)
333 {
334 areacode |= (sAxis0 & (sAxisRho|sAxisMax)) | sBoundary; // rho-max
335 if (xx.getRho() > fAxisMax[rhoaxis] + rtol) { isoutside = true; }
336 }
337
338 // test boundary of phi-axis
339
340 if (AmIOnLeftSide(xx, dphimin) >= 0) // xx is on dphimin
341 {
342 areacode |= (sAxis1 & (sAxisPhi | sAxisMin));
343 if ((areacode & sBoundary) != 0)
344 {
345 areacode |= sCorner; // xx is on corner.
346 }
347 else
348 {
349 areacode |= sBoundary;
350 }
351 if (AmIOnLeftSide(xx, dphimin) > 0) { isoutside = true; }
352 }
353 else if (AmIOnLeftSide(xx, dphimax) <= 0) // xx is on dphimax
354 {
355 areacode |= (sAxis1 & (sAxisPhi | sAxisMax));
356 if ((areacode & sBoundary) != 0)
357 {
358 areacode |= sCorner; // xx is on corner.
359 }
360 else
361 {
362 areacode |= sBoundary;
363 }
364 if (AmIOnLeftSide(xx, dphimax) < 0) { isoutside = true; }
365 }
366
367 // if isoutside = true, clear inside bit.
368 // if not on boundary, add axis information.
369
370 if (isoutside)
371 {
372 G4int tmpareacode = areacode & (~sInside);
373 areacode = tmpareacode;
374 }
375 else if ((areacode & sBoundary) != sBoundary)
376 {
377 areacode |= (sAxis0 & sAxisRho) | (sAxis1 & sAxisPhi);
378 }
379
380 }
381 else
382 {
383 // out of boundary of rho-axis
384
385 if (xx.getRho() < fAxisMin[rhoaxis])
386 {
387 areacode |= (sAxis0 & (sAxisRho | sAxisMin)) | sBoundary;
388 }
389 else if (xx.getRho() > fAxisMax[rhoaxis])
390 {
391 areacode |= (sAxis0 & (sAxisRho | sAxisMax)) | sBoundary;
392 }
393
394 // out of boundary of phi-axis
395
396 if (AmIOnLeftSide(xx, dphimin, false) >= 0) // xx is leftside or
397 {
398 areacode |= (sAxis1 & (sAxisPhi | sAxisMin)) ; // boundary of dphimin
399 if ((areacode & sBoundary) != 0)
400 {
401 areacode |= sCorner; // xx is on corner
402 }
403 else
404 {
405 areacode |= sBoundary;
406 }
407 }
408 else if (AmIOnLeftSide(xx, dphimax, false) <= 0) // xx is rightside or
409 {
410 areacode |= (sAxis1 & (sAxisPhi | sAxisMax)); // boundary of dphimax
411 if ((areacode & sBoundary) != 0)
412 {
413 areacode |= sCorner; // xx is on corner
414 }
415 else
416 {
417 areacode |= sBoundary;
418 }
419 }
420
421 if ((areacode & sBoundary) != sBoundary) {
422 areacode |= (sAxis0 & sAxisRho) | (sAxis1 & sAxisPhi);
423 }
424
425 }
426 return areacode;
427 }
428 else
429 {
430 std::ostringstream message;
431 message << "Feature NOT implemented !" << G4endl
432 << " fAxis[0] = " << fAxis[0] << G4endl
433 << " fAxis[1] = " << fAxis[1];
434 G4Exception("G4TwistTubsFlatSide::GetAreaCode()", "GeomSolids0001",
435 FatalException, message);
436 }
437 return areacode;
438}
439
440//=====================================================================
441//* SetCorners --------------------------------------------------------
442
443void G4TwistTubsFlatSide::SetCorners()
444{
445 // Set Corner points in local coodinate.
446
447 if (fAxis[0] == kRho && fAxis[1] == kPhi)
448 {
449 G4int rhoaxis = 0; // kRho
450 G4int phiaxis = 1; // kPhi
451
452 G4double x, y, z;
453 // corner of Axis0min and Axis1min
454 x = fAxisMin[rhoaxis]*std::cos(fAxisMin[phiaxis]);
455 y = fAxisMin[rhoaxis]*std::sin(fAxisMin[phiaxis]);
456 z = 0;
457 SetCorner(sC0Min1Min, x, y, z);
458 // corner of Axis0max and Axis1min
459 x = fAxisMax[rhoaxis]*std::cos(fAxisMin[phiaxis]);
460 y = fAxisMax[rhoaxis]*std::sin(fAxisMin[phiaxis]);
461 z = 0;
462 SetCorner(sC0Max1Min, x, y, z);
463 // corner of Axis0max and Axis1max
464 x = fAxisMax[rhoaxis]*std::cos(fAxisMax[phiaxis]);
465 y = fAxisMax[rhoaxis]*std::sin(fAxisMax[phiaxis]);
466 z = 0;
467 SetCorner(sC0Max1Max, x, y, z);
468 // corner of Axis0min and Axis1max
469 x = fAxisMin[rhoaxis]*std::cos(fAxisMax[phiaxis]);
470 y = fAxisMin[rhoaxis]*std::sin(fAxisMax[phiaxis]);
471 z = 0;
472 SetCorner(sC0Min1Max, x, y, z);
473
474 }
475 else
476 {
477 std::ostringstream message;
478 message << "Feature NOT implemented !" << G4endl
479 << " fAxis[0] = " << fAxis[0] << G4endl
480 << " fAxis[1] = " << fAxis[1];
481 G4Exception("G4TwistTubsFlatSide::SetCorners()", "GeomSolids0001",
482 FatalException, message);
483 }
484}
485
486//=====================================================================
487//* SetBoundaries() ---------------------------------------------------
488
489void G4TwistTubsFlatSide::SetBoundaries()
490{
491 // Set direction-unit vector of phi-boundary-lines in local coodinate.
492 // Don't call the function twice.
493
494 if (fAxis[0] == kRho && fAxis[1] == kPhi)
495 {
496 G4ThreeVector direction;
497 // sAxis0 & sAxisMin
499 direction = direction.unit();
500 SetBoundary(sAxis0 & (sAxisPhi | sAxisMin), direction,
502
503 // sAxis0 & sAxisMax
505 direction = direction.unit();
506 SetBoundary(sAxis0 & (sAxisPhi | sAxisMax), direction,
508
509 // sAxis1 & sAxisMin
511 direction = direction.unit();
512 SetBoundary(sAxis1 & (sAxisRho | sAxisMin), direction,
514
515 // sAxis1 & sAxisMax
517 direction = direction.unit();
518 SetBoundary(sAxis1 & (sAxisRho | sAxisMax), direction,
520 }
521 else
522 {
523 std::ostringstream message;
524 message << "Feature NOT implemented !" << G4endl
525 << " fAxis[0] = " << fAxis[0] << G4endl
526 << " fAxis[1] = " << fAxis[1];
527 G4Exception("G4TwistTubsFlatSide::SetBoundaries()", "GeomSolids0001",
528 FatalException, message);
529 }
530}
531
532//=====================================================================
533//* GetFacets() -------------------------------------------------------
534
535void G4TwistTubsFlatSide::GetFacets( G4int k, G4int n, G4double xyz[][3],
536 G4int faces[][4], G4int iside )
537{
538 G4ThreeVector p ;
539
540 G4double rmin = fAxisMin[0] ;
541 G4double rmax = fAxisMax[0] ;
542 G4double phimin, phimax ;
543
544 G4double r,phi ;
545 G4int nnode,nface ;
546
547 for ( G4int i = 0 ; i<n ; ++i )
548 {
549 r = rmin + i*(rmax-rmin)/(n-1) ;
550
551 phimin = GetBoundaryMin(r) ;
552 phimax = GetBoundaryMax(r) ;
553
554 for ( G4int j = 0 ; j<k ; ++j )
555 {
556 phi = phimin + j*(phimax-phimin)/(k-1) ;
557
558 nnode = GetNode(i,j,k,n,iside) ;
559 p = SurfacePoint(phi,r,true) ; // surface point in global coord.system
560
561 xyz[nnode][0] = p.x() ;
562 xyz[nnode][1] = p.y() ;
563 xyz[nnode][2] = p.z() ;
564
565 if ( i<n-1 && j<k-1 ) // conterclock wise filling
566 {
567 nface = GetFace(i,j,k,n,iside) ;
568
569 if (fHandedness < 0) // lower side
570 {
571 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,-1)
572 * ( GetNode(i ,j ,k,n,iside)+1) ;
573 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,-1)
574 * ( GetNode(i ,j+1,k,n,iside)+1) ;
575 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,-1)
576 * ( GetNode(i+1,j+1,k,n,iside)+1) ;
577 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,-1)
578 * ( GetNode(i+1,j ,k,n,iside)+1) ;
579 }
580 else // upper side
581 {
582 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1)
583 * ( GetNode(i ,j ,k,n,iside)+1) ;
584 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1)
585 * ( GetNode(i+1,j ,k,n,iside)+1) ;
586 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1)
587 * ( GetNode(i+1,j+1,k,n,iside)+1) ;
588 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1)
589 * ( GetNode(i ,j+1,k,n,iside)+1) ;
590 }
591 }
592 }
593 }
594}
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::HepRotation G4RotationMatrix
CLHEP::Hep3Vector G4ThreeVector
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:67
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
G4double GetRadialTolerance() const
static G4GeometryTolerance * GetInstance()
G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol) override
G4ThreeVector GetNormal(const G4ThreeVector &, G4bool isGlobal=false) override
G4TwistTubsFlatSide(const G4String &name, const G4RotationMatrix &rot, const G4ThreeVector &tlate, const G4ThreeVector &n, const EAxis axis0=kRho, const EAxis axis1=kPhi, G4double axis0min=-kInfinity, G4double axis1min=-kInfinity, G4double axis0max=kInfinity, G4double axis1max=kInfinity)
virtual G4int AmIOnLeftSide(const G4ThreeVector &me, const G4ThreeVector &vec, G4bool withTol=true)
static const G4int sC0Min1Min
static const G4int sC0Min1Max
G4VTwistSurface(const G4String &name)
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)
const G4String & GetName() const
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
static const G4int sCorner
static const G4int sC0Max1Min
static const G4int sInside
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