ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4TwistTubsFlatSide.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4TwistTubsFlatSide.cc
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 
33 #include "G4TwistTubsFlatSide.hh"
34 #include "G4GeometryTolerance.hh"
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 
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 
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 
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
492  direction = GetCorner(sC0Min1Max) - GetCorner(sC0Min1Min);
493  direction = direction.unit();
494  SetBoundary(sAxis0 & (sAxisPhi | sAxisMin), direction,
496 
497  // sAxis0 & sAxisMax
498  direction = GetCorner(sC0Max1Max) - GetCorner(sC0Max1Min);
499  direction = direction.unit();
500  SetBoundary(sAxis0 & (sAxisPhi | sAxisMax), direction,
502 
503  // sAxis1 & sAxisMin
504  direction = GetCorner(sC0Max1Min) - GetCorner(sC0Min1Min);
505  direction = direction.unit();
506  SetBoundary(sAxis1 & (sAxisRho | sAxisMin), direction,
508 
509  // sAxis1 & sAxisMax
510  direction = GetCorner(sC0Max1Max) - GetCorner(sC0Min1Max);
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 }