Geant4 9.6.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//
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 ([email protected])
38//
39// History:
40// 13-Nov-2003 - O.Link ([email protected]), 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