Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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//
27// $Id$
28//
29//
30// --------------------------------------------------------------------
31// GEANT 4 class source file
32//
33//
34// G4TwistTubsFlatSide.cc
35//
36// Author:
37// 01-Aug-2002 - Kotoyo Hoshina (hoshina@hepburn.s.chiba-u.ac.jp)
38//
39// History:
40// 13-Nov-2003 - O.Link (Oliver.Link@cern.ch), Integration in Geant4
41// from original version in Jupiter-2.5.02 application.
42// --------------------------------------------------------------------
43
46
47//=====================================================================
48//* constructors ------------------------------------------------------
49
51 const G4RotationMatrix &rot,
52 const G4ThreeVector &tlate,
53 const G4ThreeVector &n,
54 const EAxis axis0 ,
55 const EAxis axis1 ,
56 G4double axis0min,
57 G4double axis1min,
58 G4double axis0max,
59 G4double axis1max )
60 : G4VTwistSurface(name, rot, tlate, 0, axis0, axis1,
61 axis0min, axis1min, axis0max, axis1max)
62{
63 if (axis0 == kPhi && axis1 == kRho) {
64 G4Exception("G4TwistTubsFlatSide::G4TwistTubsFlatSide()",
65 "GeomSolids0002", FatalErrorInArgument,
66 "Should swap axis0 and axis1!");
67 }
68
69 G4ThreeVector normal = rot.inverse()*n;
70 fCurrentNormal.normal = normal.unit(); // in local coordinate system
71 fIsValidNorm = true;
72
73 SetCorners();
74 SetBoundaries();
75
76 fSurfaceArea = 1 ; // not yet implemented. This is NOT a problem for tracking
77
78}
79
80
81
83 G4double EndInnerRadius[2],
84 G4double EndOuterRadius[2],
85 G4double DPhi,
86 G4double EndPhi[2],
87 G4double EndZ[2],
88 G4int handedness )
89 : G4VTwistSurface(name)
90{
91 fHandedness = handedness; // +z = +ve, -z = -ve
92 fAxis[0] = kRho; // in local coordinate system
93 fAxis[1] = kPhi;
94 G4int i = (handedness < 0 ? 0 : 1);
95 fAxisMin[0] = EndInnerRadius[i]; // Inner-hype radius at z=0
96 fAxisMax[0] = EndOuterRadius[i]; // Outer-hype radius at z=0
97 fAxisMin[1] = -0.5*DPhi;
98 fAxisMax[1] = -fAxisMin[1];
99 fCurrentNormal.normal.set(0, 0, (fHandedness < 0 ? -1 : 1));
100 // Unit vector, in local coordinate system
101 fRot.rotateZ(EndPhi[i]);
102 fTrans.set(0, 0, EndZ[i]);
103 fIsValidNorm = true;
104
105 SetCorners();
106 SetBoundaries();
107
108 fSurfaceArea = 0.5*DPhi * (EndOuterRadius[i]*EndOuterRadius[i]
109 - EndInnerRadius[i]*EndInnerRadius[i] ) ;
110
111}
112
113
114//=====================================================================
115//* Fake default constructor ------------------------------------------
116
118 : G4VTwistSurface(a), fSurfaceArea(0.)
119{
120}
121
122
123//=====================================================================
124//* destructor --------------------------------------------------------
125
127{
128}
129
130//=====================================================================
131//* GetNormal ---------------------------------------------------------
132
134 G4bool isGlobal)
135{
136 if (isGlobal) {
138 } else {
139 return fCurrentNormal.normal;
140 }
141}
142
143//=====================================================================
144//* DistanceToSurface(p, v) -------------------------------------------
145
147 const G4ThreeVector &gv,
148 G4ThreeVector gxx[],
149 G4double distance[],
150 G4int areacode[],
151 G4bool isvalid[],
152 EValidate validate)
153{
154 fCurStatWithV.ResetfDone(validate, &gp, &gv);
155
156 if (fCurStatWithV.IsDone()) {
157 G4int i;
158 for (i=0; i<fCurStatWithV.GetNXX(); i++) {
159 gxx[i] = fCurStatWithV.GetXX(i);
160 distance[i] = fCurStatWithV.GetDistance(i);
161 areacode[i] = fCurStatWithV.GetAreacode(i);
162 isvalid[i] = fCurStatWithV.IsValid(i);
163 }
164 return fCurStatWithV.GetNXX();
165 } else {
166 // initialize
167 G4int i;
168 for (i=0; i<2; i++) {
169 distance[i] = kInfinity;
170 areacode[i] = sOutside;
171 isvalid[i] = false;
172 gxx[i].set(kInfinity, kInfinity, kInfinity);
173 }
174 }
175
178
179 //
180 // special case!
181 // if p is on surface, distance = 0.
182 //
183
184 if (std::fabs(p.z()) == 0.) { // if p is on the plane
185 distance[0] = 0;
186 G4ThreeVector xx = p;
187 gxx[0] = ComputeGlobalPoint(xx);
188
189 if (validate == kValidateWithTol) {
190 areacode[0] = GetAreaCode(xx);
191 if (!IsOutside(areacode[0])) {
192 isvalid[0] = true;
193 }
194 } else if (validate == kValidateWithoutTol) {
195 areacode[0] = GetAreaCode(xx, false);
196 if (IsInside(areacode[0])) {
197 isvalid[0] = true;
198 }
199 } else { // kDontValidate
200 areacode[0] = sInside;
201 isvalid[0] = true;
202 }
203
204 return 1;
205 }
206 //
207 // special case end
208 //
209
210 if (v.z() == 0) {
211
212 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
213 isvalid[0], 0, validate, &gp, &gv);
214 return 0;
215 }
216
217 distance[0] = - (p.z() / v.z());
218
219 G4ThreeVector xx = p + distance[0]*v;
220 gxx[0] = ComputeGlobalPoint(xx);
221
222 if (validate == kValidateWithTol) {
223 areacode[0] = GetAreaCode(xx);
224 if (!IsOutside(areacode[0])) {
225 if (distance[0] >= 0) isvalid[0] = true;
226 }
227 } else if (validate == kValidateWithoutTol) {
228 areacode[0] = GetAreaCode(xx, false);
229 if (IsInside(areacode[0])) {
230 if (distance[0] >= 0) isvalid[0] = true;
231 }
232 } else { // kDontValidate
233 areacode[0] = sInside;
234 if (distance[0] >= 0) isvalid[0] = true;
235 }
236
237 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
238 isvalid[0], 1, validate, &gp, &gv);
239
240#ifdef G4TWISTDEBUG
241 G4cerr << "ERROR - G4TwistTubsFlatSide::DistanceToSurface(p,v)" << G4endl;
242 G4cerr << " Name : " << GetName() << G4endl;
243 G4cerr << " xx : " << xx << G4endl;
244 G4cerr << " gxx[0] : " << gxx[0] << G4endl;
245 G4cerr << " dist[0] : " << distance[0] << G4endl;
246 G4cerr << " areacode[0] : " << areacode[0] << G4endl;
247 G4cerr << " isvalid[0] : " << isvalid[0] << G4endl;
248#endif
249 return 1;
250}
251
252//=====================================================================
253//* DistanceToSurface(p) ----------------------------------------------
254
256 G4ThreeVector gxx[],
257 G4double distance[],
258 G4int areacode[])
259{
260 // Calculate distance to plane in local coordinate,
261 // then return distance and global intersection points.
262 //
263
265
266 if (fCurStat.IsDone()) {
267 G4int i;
268 for (i=0; i<fCurStat.GetNXX(); i++) {
269 gxx[i] = fCurStat.GetXX(i);
270 distance[i] = fCurStat.GetDistance(i);
271 areacode[i] = fCurStat.GetAreacode(i);
272 }
273 return fCurStat.GetNXX();
274 } else {
275 // initialize
276 G4int i;
277 for (i=0; i<2; i++) {
278 distance[i] = kInfinity;
279 areacode[i] = sOutside;
280 gxx[i].set(kInfinity, kInfinity, kInfinity);
281 }
282 }
283
285 G4ThreeVector xx;
286
287 // The plane is placed on origin with making its normal
288 // parallel to z-axis.
289 if (std::fabs(p.z()) <= 0.5 * kCarTolerance) { // if p is on the plane, return 1
290 distance[0] = 0;
291 xx = p;
292 } else {
293 distance[0] = std::fabs(p.z());
294 xx.set(p.x(), p.y(), 0);
295 }
296
297 gxx[0] = ComputeGlobalPoint(xx);
298 areacode[0] = sInside;
299 G4bool isvalid = true;
300 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
301 isvalid, 1, kDontValidate, &gp);
302 return 1;
303
304}
305
306//=====================================================================
307//* GetAreaCode -------------------------------------------------------
308
310 G4bool withTol)
311{
312
313 static const G4double rtol
315
316 G4int areacode = sInside;
317
318 if (fAxis[0] == kRho && fAxis[1] == kPhi) {
319 G4int rhoaxis = 0;
320 // G4int phiaxis = 0;
321
322 G4ThreeVector dphimin; // direction of phi-minimum boundary
323 G4ThreeVector dphimax; // direction of phi-maximum boundary
324 dphimin = GetCorner(sC0Max1Min);
325 dphimax = GetCorner(sC0Max1Max);
326
327 if (withTol) {
328
329 G4bool isoutside = false;
330
331 // test boundary of rho-axis
332
333 if (xx.getRho() <= fAxisMin[rhoaxis] + rtol) {
334
335 areacode |= (sAxis0 & (sAxisRho | sAxisMin)) | sBoundary; // rho-min
336 if (xx.getRho() < fAxisMin[rhoaxis] - rtol) isoutside = true;
337
338 } else if (xx.getRho() >= fAxisMax[rhoaxis] - rtol) {
339
340 areacode |= (sAxis0 & (sAxisRho | sAxisMax)) | sBoundary; // rho-max
341 if (xx.getRho() > fAxisMax[rhoaxis] + rtol) isoutside = true;
342
343 }
344
345 // test boundary of phi-axis
346
347 if (AmIOnLeftSide(xx, dphimin) >= 0) { // xx is on dphimin
348
349 areacode |= (sAxis1 & (sAxisPhi | sAxisMin));
350 if (areacode & sBoundary) areacode |= sCorner; // xx is on the corner.
351 else areacode |= sBoundary;
352
353 if (AmIOnLeftSide(xx, dphimin) > 0) isoutside = true;
354
355 } else if (AmIOnLeftSide(xx, dphimax) <= 0) { // xx is on dphimax
356
357 areacode |= (sAxis1 & (sAxisPhi | sAxisMax));
358 if (areacode & sBoundary) areacode |= sCorner; // xx is on the corner.
359 else areacode |= sBoundary;
360
361 if (AmIOnLeftSide(xx, dphimax) < 0) isoutside = true;
362
363 }
364
365 // if isoutside = true, clear inside bit.
366 // if not on boundary, add axis information.
367
368 if (isoutside) {
369 G4int tmpareacode = areacode & (~sInside);
370 areacode = tmpareacode;
371 } else if ((areacode & sBoundary) != sBoundary) {
372 areacode |= (sAxis0 & sAxisRho) | (sAxis1 & sAxisPhi);
373 }
374
375 } else {
376
377 // out of boundary of rho-axis
378
379 if (xx.getRho() < fAxisMin[rhoaxis]) {
380 areacode |= (sAxis0 & (sAxisRho | sAxisMin)) | sBoundary;
381 } else if (xx.getRho() > fAxisMax[rhoaxis]) {
382 areacode |= (sAxis0 & (sAxisRho | sAxisMax)) | sBoundary;
383 }
384
385 // out of boundary of phi-axis
386
387 if (AmIOnLeftSide(xx, dphimin, false) >= 0) { // xx is leftside or
388 areacode |= (sAxis1 & (sAxisPhi | sAxisMin)) ; // boundary of dphimin
389 if (areacode & sBoundary) areacode |= sCorner; // xx is on the corner.
390 else areacode |= sBoundary;
391
392 } else if (AmIOnLeftSide(xx, dphimax, false) <= 0) { // xx is rightside or
393 areacode |= (sAxis1 & (sAxisPhi | sAxisMax)) ; // boundary of dphimax
394 if (areacode & sBoundary) areacode |= sCorner; // xx is on the corner.
395 else areacode |= sBoundary;
396
397 }
398
399 if ((areacode & sBoundary) != sBoundary) {
400 areacode |= (sAxis0 & sAxisRho) | (sAxis1 & sAxisPhi);
401 }
402
403 }
404 return areacode;
405 } else {
406
407 std::ostringstream message;
408 message << "Feature NOT implemented !" << G4endl
409 << " fAxis[0] = " << fAxis[0] << G4endl
410 << " fAxis[1] = " << fAxis[1];
411 G4Exception("G4TwistTubsFlatSide::GetAreaCode()", "GeomSolids0001",
412 FatalException, message);
413 }
414 return areacode;
415}
416
417
418//=====================================================================
419//* SetCorners --------------------------------------------------------
420
421void G4TwistTubsFlatSide::SetCorners()
422{
423 // Set Corner points in local coodinate.
424
425 if (fAxis[0] == kRho && fAxis[1] == kPhi) {
426
427 G4int rhoaxis = 0; // kRho
428 G4int phiaxis = 1; // kPhi
429
430 G4double x, y, z;
431 // corner of Axis0min and Axis1min
432 x = fAxisMin[rhoaxis]*std::cos(fAxisMin[phiaxis]);
433 y = fAxisMin[rhoaxis]*std::sin(fAxisMin[phiaxis]);
434 z = 0;
435 SetCorner(sC0Min1Min, x, y, z);
436 // corner of Axis0max and Axis1min
437 x = fAxisMax[rhoaxis]*std::cos(fAxisMin[phiaxis]);
438 y = fAxisMax[rhoaxis]*std::sin(fAxisMin[phiaxis]);
439 z = 0;
440 SetCorner(sC0Max1Min, x, y, z);
441 // corner of Axis0max and Axis1max
442 x = fAxisMax[rhoaxis]*std::cos(fAxisMax[phiaxis]);
443 y = fAxisMax[rhoaxis]*std::sin(fAxisMax[phiaxis]);
444 z = 0;
445 SetCorner(sC0Max1Max, x, y, z);
446 // corner of Axis0min and Axis1max
447 x = fAxisMin[rhoaxis]*std::cos(fAxisMax[phiaxis]);
448 y = fAxisMin[rhoaxis]*std::sin(fAxisMax[phiaxis]);
449 z = 0;
450 SetCorner(sC0Min1Max, x, y, z);
451
452 } else {
453 std::ostringstream message;
454 message << "Feature NOT implemented !" << G4endl
455 << " fAxis[0] = " << fAxis[0] << G4endl
456 << " fAxis[1] = " << fAxis[1];
457 G4Exception("G4TwistTubsFlatSide::SetCorners()", "GeomSolids0001",
458 FatalException, message);
459 }
460}
461
462//=====================================================================
463//* SetBoundaries() ---------------------------------------------------
464
465void G4TwistTubsFlatSide::SetBoundaries()
466{
467 // Set direction-unit vector of phi-boundary-lines in local coodinate.
468 // Don't call the function twice.
469
470 if (fAxis[0] == kRho && fAxis[1] == kPhi) {
471
472 G4ThreeVector direction;
473 // sAxis0 & sAxisMin
475 direction = direction.unit();
476 SetBoundary(sAxis0 & (sAxisPhi | sAxisMin), direction,
478
479 // sAxis0 & sAxisMax
481 direction = direction.unit();
482 SetBoundary(sAxis0 & (sAxisPhi | sAxisMax), direction,
484
485 // sAxis1 & sAxisMin
487 direction = direction.unit();
488 SetBoundary(sAxis1 & (sAxisRho | sAxisMin), direction,
490
491 // sAxis1 & sAxisMax
493 direction = direction.unit();
494 SetBoundary(sAxis1 & (sAxisRho | sAxisMax), direction,
496 } else {
497 std::ostringstream message;
498 message << "Feature NOT implemented !" << G4endl
499 << " fAxis[0] = " << fAxis[0] << G4endl
500 << " fAxis[1] = " << fAxis[1];
501 G4Exception("G4TwistTubsFlatSide::SetBoundaries()", "GeomSolids0001",
502 FatalException, message);
503 }
504}
505
506//=====================================================================
507//* GetFacets() -------------------------------------------------------
508
510 G4int faces[][4], G4int iside )
511{
512
513 G4ThreeVector p ;
514
515 G4double rmin = fAxisMin[0] ;
516 G4double rmax = fAxisMax[0] ;
517 G4double phimin, phimax ;
518
519 G4double r,phi ;
520
521 G4int i,j ;
522
523 G4int nnode,nface ;
524
525 for ( i = 0 ; i<n ; i++ ) {
526
527 r = rmin + i*(rmax-rmin)/(n-1) ;
528
529 phimin = GetBoundaryMin(r) ;
530 phimax = GetBoundaryMax(r) ;
531
532 for ( j = 0 ; j<k ; j++ )
533 {
534 phi = phimin + j*(phimax-phimin)/(k-1) ;
535
536 nnode = GetNode(i,j,k,n,iside) ;
537 p = SurfacePoint(phi,r,true) ; // surface point in global coord.system
538
539 xyz[nnode][0] = p.x() ;
540 xyz[nnode][1] = p.y() ;
541 xyz[nnode][2] = p.z() ;
542
543 if ( i<n-1 && j<k-1 ) { // conterclock wise filling
544
545 nface = GetFace(i,j,k,n,iside) ;
546
547 if (fHandedness < 0) { // lower side
548 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,-1) * ( GetNode(i ,j ,k,n,iside)+1) ;
549 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,-1) * ( GetNode(i ,j+1,k,n,iside)+1) ;
550 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,-1) * ( GetNode(i+1,j+1,k,n,iside)+1) ;
551 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,-1) * ( GetNode(i+1,j ,k,n,iside)+1) ;
552 } else { // upper side
553 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1) * ( GetNode(i ,j ,k,n,iside)+1) ;
554 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1) * ( GetNode(i+1,j ,k,n,iside)+1) ;
555 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1) * ( GetNode(i+1,j+1,k,n,iside)+1) ;
556 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1) * ( GetNode(i ,j+1,k,n,iside)+1) ;
557
558 }
559
560
561
562 }
563 }
564 }
565}
@ FatalException
@ FatalErrorInArgument
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cerr
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:92
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
void SetCurrentStatus(G4int i, G4ThreeVector &xx, G4double &dist, G4int &areacode, G4bool &isvalid, G4int nxx, EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=0)
G4bool IsValid(G4int i) const
G4ThreeVector GetXX(G4int i) const
void ResetfDone(EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=0)
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:54
@ kRho
Definition: geomdefs.hh:54
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41