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