Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros 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// G4TwistTrapFlatSide implementation
27//
28// Author: 30-Aug-2002 - O.Link (Oliver.Link@cern.ch)
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
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
285 G4ThreeVector xx;
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
426void G4TwistTrapFlatSide::SetCorners()
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
473void G4TwistTrapFlatSide::SetBoundaries()
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
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}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
const G4double fAlpha
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:57
double z() const
Hep3Vector unit() const
double x() const
double y() const
void set(double x, double y, double z)
HepRotation & rotateZ(double delta)
Definition: Rotation.cc:87
virtual G4int GetAreaCode(const G4ThreeVector &xx, G4bool withTol=true)
virtual void GetFacets(G4int m, G4int n, G4double xyz[][3], G4int faces[][4], G4int iside)
virtual G4ThreeVector GetNormal(const G4ThreeVector &, G4bool isGlobal=false)
virtual G4double GetBoundaryMin(G4double u)
virtual G4double GetBoundaryMax(G4double u)
virtual G4ThreeVector SurfacePoint(G4double x, G4double y, G4bool isGlobal=false)
G4TwistTrapFlatSide(const G4String &name, G4double PhiTwist, G4double pDx1, G4double pDx2, G4double pDy, G4double pDz, G4double pAlpha, G4double pPhi, G4double pTheta, G4int handedness)
virtual G4int DistanceToSurface(const G4ThreeVector &gp, const G4ThreeVector &gv, G4ThreeVector gxx[], G4double distance[], G4int areacode[], G4bool isvalid[], EValidate validate=kValidateWithTol)
G4int GetAreacode(G4int i) const
G4double GetDistance(G4int i) const
G4bool IsValid(G4int i) const
void SetCurrentStatus(G4int i, G4ThreeVector &xx, G4double &dist, G4int &areacode, G4bool &isvalid, G4int nxx, EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
G4ThreeVector GetXX(G4int i) const
void ResetfDone(EValidate validate, const G4ThreeVector *p, const G4ThreeVector *v=nullptr)
static const G4int sC0Min1Min
static const G4int sC0Min1Max
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)
G4double fAxisMax[2]
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
G4double fAxisMin[2]
static const G4int sCorner
static const G4int sC0Max1Min
static const G4int sInside
virtual G4String GetName() const
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