Geant4 11.4.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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// G4TwistTrapFlatSide implementation
27//
28// Author: Oliver Link (CERN), 27.10.2004 - Created
29// --------------------------------------------------------------------
30
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
68 fRot.rotateZ( fHandedness > 0
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
99
100
101//=====================================================================
102//* GetNormal ---------------------------------------------------------
103
105 G4bool isGlobal)
106{
107 if (isGlobal)
108 {
110 }
111 return fCurrentNormal.normal;
112}
113
114//=====================================================================
115//* DistanceToSurface(p, v) -------------------------------------------
116
118 const G4ThreeVector& gv,
119 G4ThreeVector gxx[],
120 G4double distance[],
121 G4int areacode[],
122 G4bool isvalid[],
123 EValidate validate)
124{
125 fCurStatWithV.ResetfDone(validate, &gp, &gv);
126
127 if (fCurStatWithV.IsDone())
128 {
129 for (G4int i=0; i<fCurStatWithV.GetNXX(); ++i)
130 {
131 gxx[i] = fCurStatWithV.GetXX(i);
132 distance[i] = fCurStatWithV.GetDistance(i);
133 areacode[i] = fCurStatWithV.GetAreacode(i);
134 isvalid[i] = fCurStatWithV.IsValid(i);
135 }
136 return fCurStatWithV.GetNXX();
137 }
138
139 // initialize
140 for (auto i=0; i<2; ++i)
141 {
142 distance[i] = kInfinity;
143 areacode[i] = sOutside;
144 isvalid[i] = false;
145 gxx[i].set(kInfinity, kInfinity, kInfinity);
146 }
147
150
151 //
152 // special case!
153 // if p is on surface, distance = 0.
154 //
155
156 if (std::fabs(p.z()) == 0.) // if p is on the plane
157 {
158 distance[0] = 0;
159 G4ThreeVector xx = p;
160 gxx[0] = ComputeGlobalPoint(xx);
161
162 if (validate == kValidateWithTol)
163 {
164 areacode[0] = GetAreaCode(xx);
165 if (!IsOutside(areacode[0]))
166 {
167 isvalid[0] = true;
168 }
169 }
170 else if (validate == kValidateWithoutTol)
171 {
172 areacode[0] = GetAreaCode(xx, false);
173 if (IsInside(areacode[0]))
174 {
175 isvalid[0] = true;
176 }
177 }
178 else // kDontValidate
179 {
180 areacode[0] = sInside;
181 isvalid[0] = true;
182 }
183 return 1;
184 }
185 //
186 // special case end
187 //
188
189 if (v.z() == 0)
190 {
191 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
192 isvalid[0], 0, validate, &gp, &gv);
193 return 0;
194 }
195
196 distance[0] = - (p.z() / v.z());
197
198 G4ThreeVector xx = p + distance[0]*v;
199 gxx[0] = ComputeGlobalPoint(xx);
200
201 if (validate == kValidateWithTol)
202 {
203 areacode[0] = GetAreaCode(xx);
204 if (!IsOutside(areacode[0]))
205 {
206 if (distance[0] >= 0) { isvalid[0] = true; }
207 }
208 }
209 else if (validate == kValidateWithoutTol)
210 {
211 areacode[0] = GetAreaCode(xx, false);
212 if (IsInside(areacode[0]))
213 {
214 if (distance[0] >= 0) { isvalid[0] = true; }
215 }
216 }
217 else // kDontValidate
218 {
219 areacode[0] = sInside;
220 if (distance[0] >= 0) { isvalid[0] = true; }
221 }
222
223 fCurStatWithV.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
224 isvalid[0], 1, validate, &gp, &gv);
225
226#ifdef G4TWISTDEBUG
227 G4cerr << "ERROR - G4TwistTrapFlatSide::DistanceToSurface(p,v)" << G4endl;
228 G4cerr << " Name : " << GetName() << G4endl;
229 G4cerr << " xx : " << xx << G4endl;
230 G4cerr << " gxx[0] : " << gxx[0] << G4endl;
231 G4cerr << " dist[0] : " << distance[0] << G4endl;
232 G4cerr << " areacode[0] : " << areacode[0] << G4endl;
233 G4cerr << " isvalid[0] : " << isvalid[0] << G4endl;
234#endif
235 return 1;
236}
237
238//=====================================================================
239//* DistanceToSurface(p) ----------------------------------------------
240
242 G4ThreeVector gxx[],
243 G4double distance[],
244 G4int areacode[])
245{
246 // Calculate distance to plane in local coordinate,
247 // then return distance and global intersection points.
248 //
249
250 fCurStat.ResetfDone(kDontValidate, &gp);
251
252 if (fCurStat.IsDone())
253 {
254 for (G4int i=0; i<fCurStat.GetNXX(); ++i)
255 {
256 gxx[i] = fCurStat.GetXX(i);
257 distance[i] = fCurStat.GetDistance(i);
258 areacode[i] = fCurStat.GetAreacode(i);
259 }
260 return fCurStat.GetNXX();
261 }
262
263 // initialize
264 for (auto i=0; i<2; ++i)
265 {
266 distance[i] = kInfinity;
267 areacode[i] = sOutside;
268 gxx[i].set(kInfinity, kInfinity, kInfinity);
269 }
270
272 G4ThreeVector xx;
273
274 // The plane is placed on origin with making its normal
275 // parallel to z-axis.
276 if (std::fabs(p.z()) <= 0.5 * kCarTolerance)
277 { // if p is on the plane, return 1
278 distance[0] = 0;
279 xx = p;
280 }
281 else
282 {
283 distance[0] = std::fabs(p.z());
284 xx.set(p.x(), p.y(), 0);
285 }
286
287 gxx[0] = ComputeGlobalPoint(xx);
288 areacode[0] = sInside;
289 G4bool isvalid = true;
290 fCurStat.SetCurrentStatus(0, gxx[0], distance[0], areacode[0],
291 isvalid, 1, kDontValidate, &gp);
292 return 1;
293
294}
295
296//=====================================================================
297//* GetAreaCode() -----------------------------------------------------
298
299G4int G4TwistTrapFlatSide::GetAreaCode(const G4ThreeVector& xx,
300 G4bool withTol)
301{
302
303 static const G4double ctol = 0.5 * kCarTolerance;
304 G4int areacode = sInside;
305
306 if (fAxis[0] == kXAxis && fAxis[1] == kYAxis)
307 {
308 G4int yaxis = 1;
309
310 G4double wmax = xAxisMax(xx.y(), fTAlph ) ;
311 G4double wmin = -xAxisMax(xx.y(), -fTAlph ) ;
312
313 if (withTol)
314 {
315 G4bool isoutside = false;
316
317 // test boundary of x-axis
318
319 if (xx.x() < wmin + ctol)
320 {
321 areacode |= (sAxis0 & (sAxisX | sAxisMin)) | sBoundary;
322 if (xx.x() <= wmin - ctol) { isoutside = true; }
323 }
324 else if (xx.x() > wmax - ctol)
325 {
326 areacode |= (sAxis0 & (sAxisX | sAxisMax)) | sBoundary;
327 if (xx.x() >= wmax + ctol) { isoutside = true; }
328 }
329
330 // test boundary of y-axis
331
332 if (xx.y() < fAxisMin[yaxis] + ctol)
333 {
334 areacode |= (sAxis1 & (sAxisY | sAxisMin));
335
336 if ((areacode & sBoundary) != 0)
337 {
338 areacode |= sCorner; // xx is on corner.
339 }
340 else
341 {
342 areacode |= sBoundary;
343 }
344 if (xx.y() <= fAxisMin[yaxis] - ctol) { isoutside = true; }
345 }
346 else if (xx.y() > fAxisMax[yaxis] - ctol)
347 {
348 areacode |= (sAxis1 & (sAxisY | sAxisMax));
349
350 if ((areacode & sBoundary) != 0)
351 {
352 areacode |= sCorner; // xx is on corner.
353 }
354 else
355 {
356 areacode |= sBoundary;
357 }
358 if (xx.y() >= fAxisMax[yaxis] + ctol) { isoutside = true; }
359 }
360
361 // if isoutside = true, clear inside bit.
362 // if not on boundary, add axis information.
363
364 if (isoutside)
365 {
366 G4int tmpareacode = areacode & (~sInside);
367 areacode = tmpareacode;
368 }
369 else if ((areacode & sBoundary) != sBoundary)
370 {
371 areacode |= (sAxis0 & sAxisX) | (sAxis1 & sAxisY);
372 }
373 }
374 else
375 {
376 // boundary of x-axis
377
378 if (xx.x() < wmin )
379 {
380 areacode |= (sAxis0 & (sAxisX | sAxisMin)) | sBoundary;
381 }
382 else if (xx.x() > wmax)
383 {
384 areacode |= (sAxis0 & (sAxisX | sAxisMax)) | sBoundary;
385 }
386
387 // boundary of y-axis
388
389 if (xx.y() < fAxisMin[yaxis])
390 {
391 areacode |= (sAxis1 & (sAxisY | sAxisMin));
392 if ((areacode & sBoundary) != 0)
393 {
394 areacode |= sCorner; // xx is on corner.
395 }
396 else
397 {
398 areacode |= sBoundary;
399 }
400 }
401 else if (xx.y() > fAxisMax[yaxis])
402 {
403 areacode |= (sAxis1 & (sAxisY | sAxisMax)) ;
404 if ((areacode & sBoundary) != 0)
405 {
406 areacode |= sCorner; // xx is on corner.
407 }
408 else
409 {
410 areacode |= sBoundary;
411 }
412 }
413
414 if ((areacode & sBoundary) != sBoundary)
415 {
416 areacode |= (sAxis0 & sAxisX) | (sAxis1 & sAxisY);
417 }
418 }
419 return areacode;
420 }
421
422 G4Exception("G4TwistTrapFlatSide::GetAreaCode()",
423 "GeomSolids0001", FatalException,
424 "Feature NOT implemented !");
425
426 return areacode;
427}
428
429//=====================================================================
430//* SetCorners --------------------------------------------------------
431
432void G4TwistTrapFlatSide::SetCorners()
433{
434 // Set Corner points in local coodinate.
435
436 if (fAxis[0] == kXAxis && fAxis[1] == kYAxis)
437 {
438 G4double x, y, z;
439
440 // corner of Axis0min and Axis1min
441 x = -fDx1 + fDy * fTAlph ;
442 y = -fDy ;
443 z = 0 ;
444 SetCorner(sC0Min1Min, x, y, z);
445
446 // corner of Axis0max and Axis1min
447 x = fDx1 + fDy * fTAlph ;
448 y = -fDy ;
449 z = 0 ;
450 SetCorner(sC0Max1Min, x, y, z);
451
452 // corner of Axis0max and Axis1max
453 x = fDx2 - fDy * fTAlph ;
454 y = fDy ;
455 z = 0 ;
456 SetCorner(sC0Max1Max, x, y, z);
457
458 // corner of Axis0min and Axis1max
459 x = -fDx2 - fDy * fTAlph ;
460 y = fDy ;
461 z = 0 ;
462 SetCorner(sC0Min1Max, x, y, z);
463
464 }
465 else
466 {
467 std::ostringstream message;
468 message << "Feature NOT implemented !" << G4endl
469 << " fAxis[0] = " << fAxis[0] << G4endl
470 << " fAxis[1] = " << fAxis[1];
471 G4Exception("G4TwistTrapFlatSide::SetCorners()",
472 "GeomSolids0001", FatalException, message);
473 }
474}
475
476//=====================================================================
477//* SetBoundaries() ---------------------------------------------------
478
479void G4TwistTrapFlatSide::SetBoundaries()
480{
481 // Set direction-unit vector of phi-boundary-lines in local coodinate.
482 // Don't call the function twice.
483
484 G4ThreeVector direction ;
485
486 if (fAxis[0] == kXAxis && fAxis[1] == kYAxis)
487 {
488 // sAxis0 & sAxisMin
489 direction = - ( GetCorner(sC0Min1Max) - GetCorner(sC0Min1Min) ) ;
490 direction = direction.unit();
491 SetBoundary(sAxis0 & (sAxisX | sAxisMin), direction,
493
494 // sAxis0 & sAxisMax
495 direction = GetCorner(sC0Max1Max) - GetCorner(sC0Max1Min) ; // inverse
496 direction = direction.unit();
497 SetBoundary(sAxis0 & (sAxisX | sAxisMax), direction,
499
500 // sAxis1 & sAxisMin
502 direction = direction.unit();
503 SetBoundary(sAxis1 & (sAxisY | sAxisMin), direction,
505
506 // sAxis1 & sAxisMax
507 direction = - ( GetCorner(sC0Max1Max) - GetCorner(sC0Min1Max) ) ;
508 direction = direction.unit();
509 SetBoundary(sAxis1 & (sAxisY | sAxisMax), direction,
511
512 }
513 else
514 {
515 std::ostringstream message;
516 message << "Feature NOT implemented !" << G4endl
517 << " fAxis[0] = " << fAxis[0] << G4endl
518 << " fAxis[1] = " << fAxis[1];
519 G4Exception("G4TwistTrapFlatSide::SetCorners()",
520 "GeomSolids0001", FatalException, message);
521 }
522}
523
524//=====================================================================
525//* GetFacets() -------------------------------------------------------
526
527void G4TwistTrapFlatSide::GetFacets( G4int k, G4int n, G4double xyz[][3],
528 G4int faces[][4], G4int iside )
529{
530 G4double x,y ; // the two parameters for the surface equation
531 G4ThreeVector p ; // a point on the surface, given by (z,u)
532
533 G4int nnode ;
534 G4int nface ;
535
536 G4double xmin,xmax ;
537
538 // calculate the (n-1)*(k-1) vertices
539
540 for ( G4int i = 0 ; i<n ; ++i )
541 {
542 y = -fDy + i*(2*fDy)/(n-1) ;
543
544 for ( G4int j = 0 ; j<k ; ++j )
545 {
546 xmin = GetBoundaryMin(y) ;
547 xmax = GetBoundaryMax(y) ;
548 x = xmin + j*(xmax-xmin)/(k-1) ;
549
550 nnode = GetNode(i,j,k,n,iside) ;
551 p = SurfacePoint(x,y,true) ; // surface point in global coordinate system
552
553 xyz[nnode][0] = p.x() ;
554 xyz[nnode][1] = p.y() ;
555 xyz[nnode][2] = p.z() ;
556
557 if ( i<n-1 && j<k-1 )
558 {
559 nface = GetFace(i,j,k,n,iside) ;
560
561 if (fHandedness < 0) // lower side
562 {
563 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,1)
564 * ( GetNode(i ,j ,k,n,iside)+1) ;
565 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,1)
566 * ( GetNode(i+1,j ,k,n,iside)+1) ;
567 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,1)
568 * ( GetNode(i+1,j+1,k,n,iside)+1) ;
569 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,1)
570 * ( GetNode(i ,j+1,k,n,iside)+1) ;
571 }
572 else // upper side
573 {
574 faces[nface][0] = GetEdgeVisibility(i,j,k,n,0,-1)
575 * ( GetNode(i ,j ,k,n,iside)+1) ;
576 faces[nface][1] = GetEdgeVisibility(i,j,k,n,1,-1)
577 * ( GetNode(i ,j+1,k,n,iside)+1) ;
578 faces[nface][2] = GetEdgeVisibility(i,j,k,n,2,-1)
579 * ( GetNode(i+1,j+1,k,n,iside)+1) ;
580 faces[nface][3] = GetEdgeVisibility(i,j,k,n,3,-1)
581 * ( GetNode(i+1,j ,k,n,iside)+1) ;
582 }
583 }
584 }
585 }
586}
const G4double kCarTolerance
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
double z() const
Hep3Vector unit() const
double x() const
double y() const
void set(double x, double y, double z)
G4ThreeVector GetNormal(const G4ThreeVector &, G4bool isGlobal=false) override
G4TwistTrapFlatSide(const G4String &name, G4double PhiTwist, G4double pDx1, G4double pDx2, G4double pDy, G4double pDz, G4double pAlpha, G4double pPhi, G4double pTheta, G4int handedness)
G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol) override
static const G4int sC0Min1Min
static const G4int sC0Min1Max
G4VTwistSurface(const G4String &name)
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)
const G4String & GetName() const
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 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
void SetCorner(G4int areacode, G4double x, G4double y, G4double z)
G4ThreeVector GetCorner(G4int areacode) const
static const G4int sBoundary
G4bool IsOutside(G4int areacode) const
static const G4int sCorner
static const G4int sC0Max1Min
static const G4int sInside
CurrentStatus fCurStatWithV
static const G4int sAxisY
static const G4int sAxisX
G4ThreeVector ComputeGlobalPoint(const G4ThreeVector &lp) const
G4SurfCurNormal fCurrentNormal
CurrentStatus fCurStat
@ kYAxis
Definition geomdefs.hh:56
@ kXAxis
Definition geomdefs.hh:55