Geant4  9.6.p02
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 //
27 // $Id: G4TwistTubsFlatSide.cc 67011 2013-01-29 16:17:41Z gcosmo $
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 
44 #include "G4TwistTubsFlatSide.hh"
45 #include "G4GeometryTolerance.hh"
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 
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 
421 void 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 
465 void 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
474  direction = GetCorner(sC0Min1Max) - GetCorner(sC0Min1Min);
475  direction = direction.unit();
476  SetBoundary(sAxis0 & (sAxisPhi | sAxisMin), direction,
478 
479  // sAxis0 & sAxisMax
480  direction = GetCorner(sC0Max1Max) - GetCorner(sC0Max1Min);
481  direction = direction.unit();
482  SetBoundary(sAxis0 & (sAxisPhi | sAxisMax), direction,
484 
485  // sAxis1 & sAxisMin
486  direction = GetCorner(sC0Max1Min) - GetCorner(sC0Min1Min);
487  direction = direction.unit();
488  SetBoundary(sAxis1 & (sAxisRho | sAxisMin), direction,
490 
491  // sAxis1 & sAxisMax
492  direction = GetCorner(sC0Max1Max) - GetCorner(sC0Min1Max);
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 }