Geant4  v4-10.4-release
 모두 클래스 네임스페이스들 파일들 함수 변수 타입정의 열거형 타입 열거형 멤버 Friends 매크로 그룹들 페이지들
G4UPolycone.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 //
27 // $Id:$
28 //
29 // Implementation of G4UPolycone wrapper class
30 // --------------------------------------------------------------------
31 
32 #include "G4Polycone.hh"
33 #include "G4UPolycone.hh"
34 
35 #if ( defined(G4GEOM_USE_USOLIDS) || defined(G4GEOM_USE_PARTIAL_USOLIDS) )
36 
37 #include "G4GeomTools.hh"
38 #include "G4AffineTransform.hh"
39 #include "G4VPVParameterisation.hh"
40 #include "G4BoundingEnvelope.hh"
41 
42 using namespace CLHEP;
43 
45 //
46 // Constructor (GEANT3 style parameters)
47 //
48 G4UPolycone::G4UPolycone( const G4String& name,
49  G4double phiStart,
50  G4double phiTotal,
51  G4int numZPlanes,
52  const G4double zPlane[],
53  const G4double rInner[],
54  const G4double rOuter[] )
55  : Base_t(name, phiStart, phiTotal, numZPlanes, zPlane, rInner, rOuter)
56 {
57  fGenericPcon = false;
58  SetOriginalParameters();
59  wrStart = phiStart;
60  while (wrStart < 0)
61  {
62  wrStart += twopi;
63  }
64  wrDelta = phiTotal;
65  if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_EPSILON))
66  {
67  wrStart = 0;
68  wrDelta = twopi;
69  }
70  rzcorners.resize(0);
71  for (G4int i=0; i<numZPlanes; ++i)
72  {
73  G4double z = zPlane[i];
74  G4double r = rOuter[i];
75  rzcorners.push_back(G4TwoVector(r,z));
76  }
77  for (G4int i=numZPlanes-1; i>=0; --i)
78  {
79  G4double z = zPlane[i];
80  G4double r = rInner[i];
81  rzcorners.push_back(G4TwoVector(r,z));
82  }
83  std::vector<G4int> iout;
85 }
86 
87 
89 //
90 // Constructor (generic parameters)
91 //
92 G4UPolycone::G4UPolycone(const G4String& name,
93  G4double phiStart,
94  G4double phiTotal,
95  G4int numRZ,
96  const G4double r[],
97  const G4double z[] )
98  : Base_t(name, phiStart, phiTotal, numRZ, r, z)
99 {
100  fGenericPcon = true;
101  SetOriginalParameters();
102  wrStart = phiStart; while (wrStart < 0) wrStart += twopi;
103  wrDelta = phiTotal;
104  if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_EPSILON))
105  {
106  wrStart = 0;
107  wrDelta = twopi;
108  }
109  rzcorners.resize(0);
110  for (G4int i=0; i<numRZ; ++i)
111  {
112  rzcorners.push_back(G4TwoVector(r[i],z[i]));
113  }
114  std::vector<G4int> iout;
116 }
117 
118 
120 //
121 // Fake default constructor - sets only member data and allocates memory
122 // for usage restricted to object persistency.
123 //
124 G4UPolycone::G4UPolycone( __void__& a )
125  : Base_t(a)
126 {
127 }
128 
129 
131 //
132 // Destructor
133 //
134 G4UPolycone::~G4UPolycone()
135 {
136 }
137 
138 
140 //
141 // Copy constructor
142 //
143 G4UPolycone::G4UPolycone( const G4UPolycone &source )
144  : Base_t( source )
145 {
146  fGenericPcon = source.fGenericPcon;
147  fOriginalParameters = source.fOriginalParameters;
148  wrStart = source.wrStart;
149  wrDelta = source.wrDelta;
150  rzcorners = source.rzcorners;
151 }
152 
153 
155 //
156 // Assignment operator
157 //
158 G4UPolycone &G4UPolycone::operator=( const G4UPolycone &source )
159 {
160  if (this == &source) return *this;
161 
162  Base_t::operator=( source );
163  fGenericPcon = source.fGenericPcon;
164  fOriginalParameters = source.fOriginalParameters;
165  wrStart = source.wrStart;
166  wrDelta = source.wrDelta;
167  rzcorners = source.rzcorners;
168 
169  return *this;
170 }
171 
172 
174 //
175 // Accessors & modifiers
176 //
177 G4double G4UPolycone::GetStartPhi() const
178 {
179  return wrStart;
180 }
181 G4double G4UPolycone::GetDeltaPhi() const
182 {
183  return wrDelta;
184 }
185 G4double G4UPolycone::GetEndPhi() const
186 {
187  return (wrStart + wrDelta);
188 }
189 G4double G4UPolycone::GetSinStartPhi() const
190 {
191  if (!IsOpen()) return 0;
192  G4double phi = GetStartPhi();
193  return std::sin(phi);
194 }
195 G4double G4UPolycone::GetCosStartPhi() const
196 {
197  if (!IsOpen()) return 1;
198  G4double phi = GetStartPhi();
199  return std::cos(phi);
200 }
201 G4double G4UPolycone::GetSinEndPhi() const
202 {
203  if (!IsOpen()) return 0;
204  G4double phi = GetEndPhi();
205  return std::sin(phi);
206 }
207 G4double G4UPolycone::GetCosEndPhi() const
208 {
209  if (!IsOpen()) return 1;
210  G4double phi = GetEndPhi();
211  return std::cos(phi);
212 }
213 G4bool G4UPolycone::IsOpen() const
214 {
215  return (wrDelta < twopi);
216 }
217 G4int G4UPolycone::GetNumRZCorner() const
218 {
219  return rzcorners.size();
220 }
221 G4PolyconeSideRZ G4UPolycone::GetCorner(G4int index) const
222 {
223  G4TwoVector rz = rzcorners.at(index);
224  G4PolyconeSideRZ psiderz = { rz.x(), rz.y() };
225 
226  return psiderz;
227 }
228 G4PolyconeHistorical* G4UPolycone::GetOriginalParameters() const
229 {
230  return new G4PolyconeHistorical(fOriginalParameters);
231 }
232 void G4UPolycone::SetOriginalParameters()
233 {
234  vecgeom::PolyconeHistorical* original_parameters = Base_t::GetOriginalParameters();
235 
236  fOriginalParameters.Start_angle = original_parameters->fHStart_angle;
237  fOriginalParameters.Opening_angle = original_parameters->fHOpening_angle;
238  fOriginalParameters.Num_z_planes = original_parameters->fHNum_z_planes;
239 
240  delete [] fOriginalParameters.Z_values;
241  delete [] fOriginalParameters.Rmin;
242  delete [] fOriginalParameters.Rmax;
243 
244  G4int numPlanes = fOriginalParameters.Num_z_planes;
245  fOriginalParameters.Z_values = new G4double[numPlanes];
246  fOriginalParameters.Rmin = new G4double[numPlanes];
247  fOriginalParameters.Rmax = new G4double[numPlanes];
248  for (G4int i=0; i<numPlanes; ++i)
249  {
250  fOriginalParameters.Z_values[i] = original_parameters->fHZ_values[i];
251  fOriginalParameters.Rmin[i] = original_parameters->fHRmin[i];
252  fOriginalParameters.Rmax[i] = original_parameters->fHRmax[i];
253  }
254 }
255 void G4UPolycone::SetOriginalParameters(G4PolyconeHistorical* pars)
256 {
257  fOriginalParameters = *pars;
258  fRebuildPolyhedron = true;
259  Reset();
260 }
261 
263 {
264  if (fGenericPcon)
265  {
266  std::ostringstream message;
267  message << "Solid " << GetName() << " built using generic construct."
268  << G4endl << "Not applicable to the generic construct !";
269  G4Exception("G4UPolycone::Reset()", "GeomSolids1001",
270  JustWarning, message, "Parameters NOT resetted.");
271  return true; // error code set
272  }
273 
274  //
275  // Rebuild polycone based on original parameters
276  //
277  wrStart = fOriginalParameters.Start_angle;
278  while (wrStart < 0)
279  {
280  wrStart += twopi;
281  }
282  wrDelta = fOriginalParameters.Opening_angle;
283  if (wrDelta <= 0 || wrDelta >= twopi*(1-DBL_EPSILON))
284  {
285  wrStart = 0;
286  wrDelta = twopi;
287  }
288  rzcorners.resize(0);
289  for (G4int i=0; i<fOriginalParameters.Num_z_planes; ++i)
290  {
291  G4double z = fOriginalParameters.Z_values[i];
292  G4double r = fOriginalParameters.Rmax[i];
293  rzcorners.push_back(G4TwoVector(r,z));
294  }
295  for (G4int i=fOriginalParameters.Num_z_planes-1; i>=0; --i)
296  {
297  G4double z = fOriginalParameters.Z_values[i];
298  G4double r = fOriginalParameters.Rmin[i];
299  rzcorners.push_back(G4TwoVector(r,z));
300  }
301  std::vector<G4int> iout;
303 
304  return false; // error code unset
305 }
306 
308 //
309 // Dispatch to parameterisation for replication mechanism dimension
310 // computation & modification.
311 //
312 void G4UPolycone::ComputeDimensions(G4VPVParameterisation* p,
313  const G4int n,
314  const G4VPhysicalVolume* pRep)
315 {
316  p->ComputeDimensions(*(G4Polycone*)this,n,pRep);
317 }
318 
319 
321 //
322 // Make a clone of the object
323 
324 G4VSolid* G4UPolycone::Clone() const
325 {
326  return new G4UPolycone(*this);
327 }
328 
330 //
331 // Get bounding box
332 
333 void G4UPolycone::BoundingLimits(G4ThreeVector& pMin,
334  G4ThreeVector& pMax) const
335 {
336  static G4bool checkBBox = true;
337  static G4bool checkPhi = true;
338 
339  G4double rmin = kInfinity, rmax = -kInfinity;
340  G4double zmin = kInfinity, zmax = -kInfinity;
341 
342  for (G4int i=0; i<GetNumRZCorner(); ++i)
343  {
344  G4PolyconeSideRZ corner = GetCorner(i);
345  if (corner.r < rmin) rmin = corner.r;
346  if (corner.r > rmax) rmax = corner.r;
347  if (corner.z < zmin) zmin = corner.z;
348  if (corner.z > zmax) zmax = corner.z;
349  }
350 
351  if (IsOpen())
352  {
353  G4TwoVector vmin,vmax;
354  G4GeomTools::DiskExtent(rmin,rmax,
355  GetSinStartPhi(),GetCosStartPhi(),
356  GetSinEndPhi(),GetCosEndPhi(),
357  vmin,vmax);
358  pMin.set(vmin.x(),vmin.y(),zmin);
359  pMax.set(vmax.x(),vmax.y(),zmax);
360  }
361  else
362  {
363  pMin.set(-rmax,-rmax, zmin);
364  pMax.set( rmax, rmax, zmax);
365  }
366 
367  // Check correctness of the bounding box
368  //
369  if (pMin.x() >= pMax.x() || pMin.y() >= pMax.y() || pMin.z() >= pMax.z())
370  {
371  std::ostringstream message;
372  message << "Bad bounding box (min >= max) for solid: "
373  << GetName() << " !"
374  << "\npMin = " << pMin
375  << "\npMax = " << pMax;
376  G4Exception("G4UPolycone::BoundingLimits()", "GeomMgt0001",
377  JustWarning, message);
378  StreamInfo(G4cout);
379  }
380 
381  // Check consistency of bounding boxes
382  //
383  if (checkBBox)
384  {
385  U3Vector vmin, vmax;
386  Extent(vmin,vmax);
387  if (std::abs(pMin.x()-vmin.x()) > kCarTolerance ||
388  std::abs(pMin.y()-vmin.y()) > kCarTolerance ||
389  std::abs(pMin.z()-vmin.z()) > kCarTolerance ||
390  std::abs(pMax.x()-vmax.x()) > kCarTolerance ||
391  std::abs(pMax.y()-vmax.y()) > kCarTolerance ||
392  std::abs(pMax.z()-vmax.z()) > kCarTolerance)
393  {
394  std::ostringstream message;
395  message << "Inconsistency in bounding boxes for solid: "
396  << GetName() << " !"
397  << "\nBBox min: wrapper = " << pMin << " solid = " << vmin
398  << "\nBBox max: wrapper = " << pMax << " solid = " << vmax;
399  G4Exception("G4UPolycone::BoundingLimits()", "GeomMgt0001",
400  JustWarning, message);
401  checkBBox = false;
402  }
403  }
404 
405  // Check consistency of angles
406  //
407  if (checkPhi)
408  {
409  if (GetStartPhi() != Base_t::GetStartPhi() ||
410  GetEndPhi() != Base_t::GetEndPhi() ||
411  IsOpen() != (Base_t::GetDeltaPhi() < twopi))
412  {
413  std::ostringstream message;
414  message << "Inconsistency in Phi angles or # of sides for solid: "
415  << GetName() << " !"
416  << "\nPhi start : wrapper = " << GetStartPhi()
417  << " solid = " << Base_t::GetStartPhi()
418  << "\nPhi end : wrapper = " << GetEndPhi()
419  << " solid = " << Base_t::GetEndPhi()
420  << "\nPhi is open: wrapper = " << (IsOpen() ? "true" : "false")
421  << " solid = "
422  << ((Base_t::GetDeltaPhi() < twopi) ? "true" : "false");
423  G4Exception("G4UPolycone::BoundingLimits()", "GeomMgt0001",
424  JustWarning, message);
425  checkPhi = false;
426  }
427  }
428 }
429 
431 //
432 // Calculate extent under transform and specified limit
433 
434 G4bool G4UPolycone::CalculateExtent(const EAxis pAxis,
435  const G4VoxelLimits& pVoxelLimit,
436  const G4AffineTransform& pTransform,
437  G4double& pMin, G4double& pMax) const
438 {
439  G4ThreeVector bmin, bmax;
440  G4bool exist;
441 
442  // Check bounding box (bbox)
443  //
444  BoundingLimits(bmin,bmax);
445  G4BoundingEnvelope bbox(bmin,bmax);
446 #ifdef G4BBOX_EXTENT
447  if (true) return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
448 #endif
449  if (bbox.BoundingBoxVsVoxelLimits(pAxis,pVoxelLimit,pTransform,pMin,pMax))
450  {
451  return exist = (pMin < pMax) ? true : false;
452  }
453 
454  // To find the extent, RZ contour of the polycone is subdivided
455  // in triangles. The extent is calculated as cumulative extent of
456  // all sub-polycones formed by rotation of triangles around Z
457  //
458  G4TwoVectorList contourRZ;
459  G4TwoVectorList triangles;
460  std::vector<G4int> iout;
461  G4double eminlim = pVoxelLimit.GetMinExtent(pAxis);
462  G4double emaxlim = pVoxelLimit.GetMaxExtent(pAxis);
463 
464  // get RZ contour, ensure anticlockwise order of corners
465  for (G4int i=0; i<GetNumRZCorner(); ++i)
466  {
467  G4PolyconeSideRZ corner = GetCorner(i);
468  contourRZ.push_back(G4TwoVector(corner.r,corner.z));
469  }
471  G4double area = G4GeomTools::PolygonArea(contourRZ);
472  if (area < 0.) std::reverse(contourRZ.begin(),contourRZ.end());
473 
474  // triangulate RZ countour
475  if (!G4GeomTools::TriangulatePolygon(contourRZ,triangles))
476  {
477  std::ostringstream message;
478  message << "Triangulation of RZ contour has failed for solid: "
479  << GetName() << " !"
480  << "\nExtent has been calculated using boundary box";
481  G4Exception("G4UPolycone::CalculateExtent()",
482  "GeomMgt1002", JustWarning, message);
483  return bbox.CalculateExtent(pAxis,pVoxelLimit,pTransform,pMin,pMax);
484  }
485 
486  // set trigonometric values
487  const G4int NSTEPS = 24; // number of steps for whole circle
488  G4double astep = twopi/NSTEPS; // max angle for one step
489 
490  G4double sphi = GetStartPhi();
491  G4double ephi = GetEndPhi();
492  G4double dphi = IsOpen() ? ephi-sphi : twopi;
493  G4int ksteps = (dphi <= astep) ? 1 : (G4int)((dphi-deg)/astep) + 1;
494  G4double ang = dphi/ksteps;
495 
496  G4double sinHalf = std::sin(0.5*ang);
497  G4double cosHalf = std::cos(0.5*ang);
498  G4double sinStep = 2.*sinHalf*cosHalf;
499  G4double cosStep = 1. - 2.*sinHalf*sinHalf;
500 
501  G4double sinStart = GetSinStartPhi();
502  G4double cosStart = GetCosStartPhi();
503  G4double sinEnd = GetSinEndPhi();
504  G4double cosEnd = GetCosEndPhi();
505 
506  // define vectors and arrays
507  std::vector<const G4ThreeVectorList *> polygons;
508  polygons.resize(ksteps+2);
509  G4ThreeVectorList pols[NSTEPS+2];
510  for (G4int k=0; k<ksteps+2; ++k) pols[k].resize(6);
511  for (G4int k=0; k<ksteps+2; ++k) polygons[k] = &pols[k];
512  G4double r0[6],z0[6]; // contour with original edges of triangle
513  G4double r1[6]; // shifted radii of external edges of triangle
514 
515  // main loop along triangles
516  pMin = kInfinity;
517  pMax =-kInfinity;
518  G4int ntria = triangles.size()/3;
519  for (G4int i=0; i<ntria; ++i)
520  {
521  G4int i3 = i*3;
522  for (G4int k=0; k<3; ++k)
523  {
524  G4int e0 = i3+k, e1 = (k<2) ? e0+1 : i3;
525  G4int k2 = k*2;
526  // set contour with original edges of triangle
527  r0[k2+0] = triangles[e0].x(); z0[k2+0] = triangles[e0].y();
528  r0[k2+1] = triangles[e1].x(); z0[k2+1] = triangles[e1].y();
529  // set shifted radii
530  r1[k2+0] = r0[k2+0];
531  r1[k2+1] = r0[k2+1];
532  if (z0[k2+1] - z0[k2+0] <= 0) continue;
533  r1[k2+0] /= cosHalf;
534  r1[k2+1] /= cosHalf;
535  }
536 
537  // rotate countour, set sequence of 6-sided polygons
538  G4double sinCur = sinStart*cosHalf + cosStart*sinHalf;
539  G4double cosCur = cosStart*cosHalf - sinStart*sinHalf;
540  for (G4int j=0; j<6; ++j) pols[0][j].set(r0[j]*cosStart,r0[j]*sinStart,z0[j]);
541  for (G4int k=1; k<ksteps+1; ++k)
542  {
543  for (G4int j=0; j<6; ++j) pols[k][j].set(r1[j]*cosCur,r1[j]*sinCur,z0[j]);
544  G4double sinTmp = sinCur;
545  sinCur = sinCur*cosStep + cosCur*sinStep;
546  cosCur = cosCur*cosStep - sinTmp*sinStep;
547  }
548  for (G4int j=0; j<6; ++j) pols[ksteps+1][j].set(r0[j]*cosEnd,r0[j]*sinEnd,z0[j]);
549 
550  // set sub-envelope and adjust extent
551  G4double emin,emax;
552  G4BoundingEnvelope benv(polygons);
553  if (!benv.CalculateExtent(pAxis,pVoxelLimit,pTransform,emin,emax)) continue;
554  if (emin < pMin) pMin = emin;
555  if (emax > pMax) pMax = emax;
556  if (eminlim > pMin && emaxlim < pMax) return true; // max possible extent
557  }
558  return (pMin < pMax);
559 }
560 
562 //
563 // CreatePolyhedron
564 //
565 G4Polyhedron* G4UPolycone::CreatePolyhedron() const
566 {
568  polyhedron = new G4PolyhedronPcon( fOriginalParameters.Start_angle,
569  fOriginalParameters.Opening_angle,
570  fOriginalParameters.Num_z_planes,
571  fOriginalParameters.Z_values,
572  fOriginalParameters.Rmin,
573  fOriginalParameters.Rmax );
574  return polyhedron;
575 }
576 
577 #endif // G4GEOM_USE_USOLIDS
void set(double x, double y, double z)
const XML_Char * name
Definition: expat.h:151
static G4bool TriangulatePolygon(const G4TwoVectorList &polygon, G4TwoVectorList &result)
Definition: G4GeomTools.cc:199
G4double GetMaxExtent(const EAxis pAxis) const
std::vector< ExP01TrackerHit * > a
Definition: ExP01Classes.hh:33
static const G4double kInfinity
Definition: geomdefs.hh:42
virtual void ComputeDimensions(G4Box &, const G4int, const G4VPhysicalVolume *) const
#define G4endl
Definition: G4ios.hh:61
const char * p
Definition: xmltok.h:285
CLHEP::Hep2Vector G4TwoVector
Definition: G4TwoVector.hh:42
Double_t z
void message(RunManager *runmanager)
Definition: ts_scorers.cc:72
double z() const
static const G4double emax
const G4double kCarTolerance
static G4bool DiskExtent(G4double rmin, G4double rmax, G4double startPhi, G4double delPhi, G4TwoVector &pmin, G4TwoVector &pmax)
Definition: G4GeomTools.cc:396
double G4double
Definition: G4Types.hh:76
bool G4bool
Definition: G4Types.hh:79
std::vector< G4ThreeVector > G4ThreeVectorList
G4double GetMinExtent(const EAxis pAxis) const
double x() const
static constexpr double deg
Definition: G4SIunits.hh:152
ntupleExperimental Reset()
static constexpr double twopi
Definition: G4SIunits.hh:76
#define DBL_EPSILON
Definition: templates.hh:87
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.hh:65
int G4int
Definition: G4Types.hh:78
std::vector< G4TwoVector > G4TwoVectorList
Definition: G4GeomTools.hh:50
EAxis
Definition: geomdefs.hh:54
double y() const
G4GLOB_DLL std::ostream G4cout
double x() const
static void RemoveRedundantVertices(G4TwoVectorList &polygon, std::vector< G4int > &iout, G4double tolerance=0)
Definition: G4GeomTools.cc:311
Char_t n[5]
double y() const
static G4double PolygonArea(const G4TwoVectorList &polygon)
Definition: G4GeomTools.cc:82