ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4TwistTrapFlatSide.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4TwistTrapFlatSide.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 // G4TwistTrapFlatSide implementation
27 //
28 // Author: 30-Aug-2002 - O.Link (Oliver.Link@cern.ch)
29 // --------------------------------------------------------------------
30 
31 #include "G4TwistTrapFlatSide.hh"
32 
33 //=====================================================================
34 //* constructors ------------------------------------------------------
35 
37  G4double PhiTwist,
38  G4double pDx1,
39  G4double pDx2,
40  G4double pDy,
41  G4double pDz,
42  G4double pAlpha,
43  G4double pPhi,
44  G4double pTheta,
45  G4int handedness)
46  : G4VTwistSurface(name)
47 {
48  fHandedness = handedness; // +z = +ve, -z = -ve
49 
50  fDx1 = pDx1 ;
51  fDx2 = pDx2 ;
52  fDy = pDy ;
53  fDz = pDz ;
54  fAlpha = pAlpha ;
55  fTAlph = std::tan(fAlpha) ;
56  fPhi = pPhi ;
57  fTheta = pTheta ;
58 
59  fdeltaX = 2 * fDz * std::tan(fTheta) * std::cos(fPhi) ;
60  // dx in surface equation
61  fdeltaY = 2 * fDz * std::tan(fTheta) * std::sin(fPhi) ;
62  // dy in surface equation
63 
64  fPhiTwist = PhiTwist ;
65 
66  fCurrentNormal.normal.set( 0, 0, (fHandedness < 0 ? -1 : 1));
67  // Unit vector, in local coordinate system
69  ? 0.5 * fPhiTwist
70  : -0.5 * fPhiTwist );
71 
72  fTrans.set(
73  fHandedness > 0 ? 0.5*fdeltaX : -0.5*fdeltaX ,
74  fHandedness > 0 ? 0.5*fdeltaY : -0.5*fdeltaY ,
75  fHandedness > 0 ? fDz : -fDz ) ;
76 
77  fIsValidNorm = true;
78 
79 
80  fAxis[0] = kXAxis ;
81  fAxis[1] = kYAxis ;
82  fAxisMin[0] = kInfinity ; // x-Axis cannot be fixed, because it
83  fAxisMax[0] = kInfinity ; // depends on y
84  fAxisMin[1] = -fDy ; // y - axis
85  fAxisMax[1] = fDy ;
86 
87  SetCorners();
88  SetBoundaries();
89 }
90 
91 
92 //=====================================================================
93 //* Fake default constructor ------------------------------------------
94 
96  : G4VTwistSurface(a), fDx1(0.), fDx2(0.), fDy(0.), fDz(0.), fPhiTwist(0.),
97  fAlpha(0.), fTAlph(0.), fPhi(0.), fTheta(0.), fdeltaX(0.), fdeltaY(0.)
98 {
99 }
100 
101 
102 //=====================================================================
103 //* destructor --------------------------------------------------------
104 
106 {
107 }
108 
109 //=====================================================================
110 //* GetNormal ---------------------------------------------------------
111 
113  G4bool isGlobal)
114 {
115  if (isGlobal)
116  {
118  }
119  else
120  {
121  return fCurrentNormal.normal;
122  }
123 }
124 
125 //=====================================================================
126 //* DistanceToSurface(p, v) -------------------------------------------
127 
129  const G4ThreeVector& gv,
130  G4ThreeVector gxx[],
131  G4double distance[],
132  G4int areacode[],
133  G4bool isvalid[],
134  EValidate validate)
135 {
136  fCurStatWithV.ResetfDone(validate, &gp, &gv);
137 
138  if (fCurStatWithV.IsDone())
139  {
140  for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
141  {
142  gxx[i] = fCurStatWithV.GetXX(i);
143  distance[i] = fCurStatWithV.GetDistance(i);
144  areacode[i] = fCurStatWithV.GetAreacode(i);
145  isvalid[i] = fCurStatWithV.IsValid(i);
146  }
147  return fCurStatWithV.GetNXX();
148  }
149  else // initialize
150  {
151  for (auto i=0; i<2; ++i)
152  {
153  distance[i] = kInfinity;
154  areacode[i] = sOutside;
155  isvalid[i] = false;
156  gxx[i].set(kInfinity, kInfinity, kInfinity);
157  }
158  }
159 
162 
163  //
164  // special case!
165  // if p is on surface, distance = 0.
166  //
167 
168  if (std::fabs(p.z()) == 0.) // if p is on the plane
169  {
170  distance[0] = 0;
171  G4ThreeVector xx = p;
172  gxx[0] = ComputeGlobalPoint(xx);
173 
174  if (validate == kValidateWithTol)
175  {
176  areacode[0] = GetAreaCode(xx);
177  if (!IsOutside(areacode[0]))
178  {
179  isvalid[0] = true;
180  }
181  }
182  else if (validate == kValidateWithoutTol)
183  {
184  areacode[0] = GetAreaCode(xx, false);
185  if (IsInside(areacode[0]))
186  {
187  isvalid[0] = true;
188  }
189  }
190  else // kDontValidate
191  {
192  areacode[0] = sInside;
193  isvalid[0] = true;
194  }
195  return 1;
196  }
197  //
198  // special case end
199  //
200 
201  if (v.z() == 0) {
202 
203  fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
204  isvalid[0], 0, validate, &gp, &gv);
205  return 0;
206  }
207 
208  distance[0] = - (p.z() / v.z());
209 
210  G4ThreeVector xx = p + distance[0]*v;
211  gxx[0] = ComputeGlobalPoint(xx);
212 
213  if (validate == kValidateWithTol)
214  {
215  areacode[0] = GetAreaCode(xx);
216  if (!IsOutside(areacode[0]))
217  {
218  if (distance[0] >= 0) isvalid[0] = true;
219  }
220  }
221  else if (validate == kValidateWithoutTol)
222  {
223  areacode[0] = GetAreaCode(xx, false);
224  if (IsInside(areacode[0]))
225  {
226  if (distance[0] >= 0) isvalid[0] = true;
227  }
228  }
229  else // kDontValidate
230  {
231  areacode[0] = sInside;
232  if (distance[0] >= 0) isvalid[0] = true;
233  }
234 
235  fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
236  isvalid[0], 1, validate, &gp, &gv);
237 
238 #ifdef G4TWISTDEBUG
239  G4cerr << "ERROR - G4TwistTrapFlatSide::DistanceToSurface(p,v)" << G4endl;
240  G4cerr << " Name : " << GetName() << G4endl;
241  G4cerr << " xx : " << xx << G4endl;
242  G4cerr << " gxx[0] : " << gxx[0] << G4endl;
243  G4cerr << " dist[0] : " << distance[0] << G4endl;
244  G4cerr << " areacode[0] : " << areacode[0] << G4endl;
245  G4cerr << " isvalid[0] : " << isvalid[0] << G4endl;
246 #endif
247  return 1;
248 }
249 
250 //=====================================================================
251 //* DistanceToSurface(p) ----------------------------------------------
252 
254  G4ThreeVector gxx[],
255  G4double distance[],
256  G4int areacode[])
257 {
258  // Calculate distance to plane in local coordinate,
259  // then return distance and global intersection points.
260  //
261 
263 
264  if (fCurStat.IsDone())
265  {
266  for (G4int i=0; i<fCurStat.GetNXX(); ++i)
267  {
268  gxx[i] = fCurStat.GetXX(i);
269  distance[i] = fCurStat.GetDistance(i);
270  areacode[i] = fCurStat.GetAreacode(i);
271  }
272  return fCurStat.GetNXX();
273  }
274  else // initialize
275  {
276  for (auto i=0; i<2; ++i)
277  {
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)
290  { // if p is on the plane, return 1
291  distance[0] = 0;
292  xx = p;
293  }
294  else
295  {
296  distance[0] = std::fabs(p.z());
297  xx.set(p.x(), p.y(), 0);
298  }
299 
300  gxx[0] = ComputeGlobalPoint(xx);
301  areacode[0] = sInside;
302  G4bool isvalid = true;
303  fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
304  isvalid, 1, kDontValidate, &gp);
305  return 1;
306 
307 }
308 
309 //=====================================================================
310 //* GetAreaCode() -----------------------------------------------------
311 
313  G4bool withTol)
314 {
315 
316  static const G4double ctol = 0.5 * kCarTolerance;
317  G4int areacode = sInside;
318 
319  if (fAxis[0] == kXAxis && fAxis[1] == kYAxis)
320  {
321  G4int yaxis = 1;
322 
323  G4double wmax = xAxisMax(xx.y(), fTAlph ) ;
324  G4double wmin = -xAxisMax(xx.y(), -fTAlph ) ;
325 
326  if (withTol)
327  {
328  G4bool isoutside = false;
329 
330  // test boundary of x-axis
331 
332  if (xx.x() < wmin + ctol)
333  {
334  areacode |= (sAxis0 & (sAxisX | sAxisMin)) | sBoundary;
335  if (xx.x() <= wmin - ctol) isoutside = true;
336 
337  }
338  else if (xx.x() > wmax - ctol)
339  {
340  areacode |= (sAxis0 & (sAxisX | sAxisMax)) | sBoundary;
341  if (xx.x() >= wmax + ctol) isoutside = true;
342  }
343 
344  // test boundary of y-axis
345 
346  if (xx.y() < fAxisMin[yaxis] + ctol)
347  {
348  areacode |= (sAxis1 & (sAxisY | sAxisMin));
349 
350  if (areacode & sBoundary) areacode |= sCorner; // xx is on corner.
351  else areacode |= sBoundary;
352  if (xx.y() <= fAxisMin[yaxis] - ctol) isoutside = true;
353 
354  }
355  else if (xx.y() > fAxisMax[yaxis] - ctol)
356  {
357  areacode |= (sAxis1 & (sAxisY | sAxisMax));
358 
359  if (areacode & sBoundary) areacode |= sCorner; // xx is on corner.
360  else areacode |= sBoundary;
361  if (xx.y() >= fAxisMax[yaxis] + ctol) isoutside = true;
362  }
363 
364  // if isoutside = true, clear inside bit.
365  // if not on boundary, add axis information.
366 
367  if (isoutside)
368  {
369  G4int tmpareacode = areacode & (~sInside);
370  areacode = tmpareacode;
371  }
372  else if ((areacode & sBoundary) != sBoundary)
373  {
374  areacode |= (sAxis0 & sAxisX) | (sAxis1 & sAxisY);
375  }
376  }
377  else
378  {
379  // boundary of x-axis
380 
381  if (xx.x() < wmin )
382  {
383  areacode |= (sAxis0 & (sAxisX | sAxisMin)) | sBoundary;
384  }
385  else if (xx.x() > wmax)
386  {
387  areacode |= (sAxis0 & (sAxisX | sAxisMax)) | sBoundary;
388  }
389 
390  // boundary of y-axis
391 
392  if (xx.y() < fAxisMin[yaxis])
393  {
394  areacode |= (sAxis1 & (sAxisY | sAxisMin));
395  if (areacode & sBoundary) areacode |= sCorner; // xx is on corner.
396  else areacode |= sBoundary;
397 
398  }
399  else if (xx.y() > fAxisMax[yaxis])
400  {
401  areacode |= (sAxis1 & (sAxisY | sAxisMax)) ;
402  if (areacode & sBoundary) areacode |= sCorner; // xx is on corner.
403  else areacode |= sBoundary;
404  }
405 
406  if ((areacode & sBoundary) != sBoundary)
407  {
408  areacode |= (sAxis0 & sAxisX) | (sAxis1 & sAxisY);
409  }
410  }
411  return areacode;
412  }
413  else
414  {
415  G4Exception("G4TwistTrapFlatSide::GetAreaCode()",
416  "GeomSolids0001", FatalException,
417  "Feature NOT implemented !");
418  }
419 
420  return areacode;
421 }
422 
423 //=====================================================================
424 //* SetCorners --------------------------------------------------------
425 
427 {
428  // Set Corner points in local coodinate.
429 
430  if (fAxis[0] == kXAxis && fAxis[1] == kYAxis)
431  {
432  G4double x, y, z;
433 
434  // corner of Axis0min and Axis1min
435  x = -fDx1 + fDy * fTAlph ;
436  y = -fDy ;
437  z = 0 ;
438  SetCorner(sC0Min1Min, x, y, z);
439 
440  // corner of Axis0max and Axis1min
441  x = fDx1 + fDy * fTAlph ;
442  y = -fDy ;
443  z = 0 ;
444  SetCorner(sC0Max1Min, x, y, z);
445 
446  // corner of Axis0max and Axis1max
447  x = fDx2 - fDy * fTAlph ;
448  y = fDy ;
449  z = 0 ;
450  SetCorner(sC0Max1Max, x, y, z);
451 
452  // corner of Axis0min and Axis1max
453  x = -fDx2 - fDy * fTAlph ;
454  y = fDy ;
455  z = 0 ;
456  SetCorner(sC0Min1Max, x, y, z);
457 
458  }
459  else
460  {
461  std::ostringstream message;
462  message << "Feature NOT implemented !" << G4endl
463  << " fAxis[0] = " << fAxis[0] << G4endl
464  << " fAxis[1] = " << fAxis[1];
465  G4Exception("G4TwistTrapFlatSide::SetCorners()",
466  "GeomSolids0001", FatalException, message);
467  }
468 }
469 
470 //=====================================================================
471 //* SetBoundaries() ---------------------------------------------------
472 
474 {
475  // Set direction-unit vector of phi-boundary-lines in local coodinate.
476  // Don't call the function twice.
477 
478  G4ThreeVector direction ;
479 
480  if (fAxis[0] == kXAxis && fAxis[1] == kYAxis)
481  {
482  // sAxis0 & sAxisMin
483  direction = - ( GetCorner(sC0Min1Max) - GetCorner(sC0Min1Min) ) ;
484  direction = direction.unit();
485  SetBoundary(sAxis0 & (sAxisX | sAxisMin), direction,
487 
488  // sAxis0 & sAxisMax
489  direction = GetCorner(sC0Max1Max) - GetCorner(sC0Max1Min) ; // inverse
490  direction = direction.unit();
491  SetBoundary(sAxis0 & (sAxisX | sAxisMax), direction,
493 
494  // sAxis1 & sAxisMin
495  direction = GetCorner(sC0Max1Min) - GetCorner(sC0Min1Min);
496  direction = direction.unit();
497  SetBoundary(sAxis1 & (sAxisY | sAxisMin), direction,
499 
500  // sAxis1 & sAxisMax
501  direction = - ( GetCorner(sC0Max1Max) - GetCorner(sC0Min1Max) ) ;
502  direction = direction.unit();
503  SetBoundary(sAxis1 & (sAxisY | sAxisMax), direction,
505 
506  }
507  else
508  {
509  std::ostringstream message;
510  message << "Feature NOT implemented !" << G4endl
511  << " fAxis[0] = " << fAxis[0] << G4endl
512  << " fAxis[1] = " << fAxis[1];
513  G4Exception("G4TwistTrapFlatSide::SetCorners()",
514  "GeomSolids0001", FatalException, message);
515  }
516 }
517 
518 //=====================================================================
519 //* GetFacets() -------------------------------------------------------
520 
522  G4int faces[][4], G4int iside )
523 {
524  G4double x,y ; // the two parameters for the surface equation
525  G4ThreeVector p ; // a point on the surface, given by (z,u)
526 
527  G4int nnode ;
528  G4int nface ;
529 
530  G4double xmin,xmax ;
531 
532  // calculate the (n-1)*(k-1) vertices
533 
534  for ( G4int i = 0 ; i<n ; ++i )
535  {
536  y = -fDy + i*(2*fDy)/(n-1) ;
537 
538  for ( G4int j = 0 ; j<k ; ++j )
539  {
540  xmin = GetBoundaryMin(y) ;
541  xmax = GetBoundaryMax(y) ;
542  x = xmin + j*(xmax-xmin)/(k-1) ;
543 
544  nnode = GetNode(i,j,k,n,iside) ;
545  p = SurfacePoint(x,y,true) ; // surface point in global coordinate system
546 
547  xyz[nnode][0] = p.x() ;
548  xyz[nnode][1] = p.y() ;
549  xyz[nnode][2] = p.z() ;
550 
551  if ( i<n-1 && j<k-1 )
552  {
553  nface = GetFace(i,j,k,n,iside) ;
554 
555  if (fHandedness < 0) // lower side
556  {
557  faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1)
558  * ( GetNode(i ,j ,k,n,iside)+1) ;
559  faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1)
560  * ( GetNode(i+1,j ,k,n,iside)+1) ;
561  faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1)
562  * ( GetNode(i+1,j+1,k,n,iside)+1) ;
563  faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1)
564  * ( GetNode(i ,j+1,k,n,iside)+1) ;
565  }
566  else // upper side
567  {
568  faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,-1)
569  * ( GetNode(i ,j ,k,n,iside)+1) ;
570  faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,-1)
571  * ( GetNode(i ,j+1,k,n,iside)+1) ;
572  faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,-1)
573  * ( GetNode(i+1,j+1,k,n,iside)+1) ;
574  faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,-1)
575  * ( GetNode(i+1,j ,k,n,iside)+1) ;
576  }
577  }
578  }
579  }
580 }