Geant4  10.01.p03
UTubs.icc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * This Software is part of the AIDA Unified Solids Library package *
4 // * See: https://aidasoft.web.cern.ch/USolids *
5 // ********************************************************************
6 //
7 // $Id:$
8 //
9 // --------------------------------------------------------------------
10 //
11 // UTubs.icc
12 //
13 // Implementation of inline methods of UTubs
14 //
15 // 19.10.12 Marek Gayer
16 // Created from original implementation in Geant4
17 // --------------------------------------------------------------------
18 
19 inline
20 double UTubs::GetInnerRadius() const
21 {
22  return fRMin;
23 }
24 
25 inline
26 double UTubs::GetOuterRadius() const
27 {
28  return fRMax;
29 }
30 
31 inline
32 double UTubs::GetZHalfLength() const
33 {
34  return fDz;
35 }
36 
37 inline
38 double UTubs::GetStartPhiAngle() const
39 {
40  return fSPhi;
41 }
42 
43 inline
44 double UTubs::GetDeltaPhiAngle() const
45 {
46  return fDPhi;
47 }
48 
49 inline
50 void UTubs::Initialize()
51 {
52  fCubicVolume = 0.;
53  fSurfaceArea = 0.;
54 }
55 
56 inline
57 void UTubs::InitializeTrigonometry()
58 {
59  double hDPhi = 0.5 * fDPhi; // half delta phi
60  double cPhi = fSPhi + hDPhi;
61  double ePhi = fSPhi + fDPhi;
62 
63  fSinCPhi = std::sin(cPhi);
64  fCosCPhi = std::cos(cPhi);
65  fCosHDPhiIT = std::cos(hDPhi - 0.5 * kAngTolerance); // inner/outer tol half dphi
66  fCosHDPhiOT = std::cos(hDPhi + 0.5 * kAngTolerance);
67  fSinSPhi = std::sin(fSPhi);
68  fCosSPhi = std::cos(fSPhi);
69  fSinEPhi = std::sin(ePhi);
70  fCosEPhi = std::cos(ePhi);
71 
72  fSinSPhiDPhi = std::sin(fSPhi + fDPhi);
73  fCosSPhiDPhi = std::cos(fSPhi + fDPhi);
74 }
75 
76 inline void UTubs::CheckSPhiAngle(double sPhi)
77 {
78  // Ensure fSphi in 0-2PI or -2PI-0 range if shape crosses 0
79 
80  if (sPhi < 0)
81  {
82  fSPhi = 2 * UUtils::kPi - std::fmod(std::fabs(sPhi), 2 * UUtils::kPi);
83  }
84  else
85  {
86  fSPhi = std::fmod(sPhi, 2 * UUtils::kPi) ;
87  }
88  if (fSPhi + fDPhi > 2 * UUtils::kPi)
89  {
90  fSPhi -= 2 * UUtils::kPi ;
91  }
92 }
93 
94 inline void UTubs::CheckDPhiAngle(double dPhi)
95 {
96  fPhiFullTube = true;
97  if (dPhi >= 2 * UUtils::kPi - kAngTolerance * 0.5)
98  {
99  fDPhi = 2 * UUtils::kPi;
100  fSPhi = 0;
101  }
102  else
103  {
104  fPhiFullTube = false;
105  if (dPhi > 0)
106  {
107  fDPhi = dPhi;
108  }
109  else
110  {
111  std::ostringstream message;
112  message << "Invalid dphi." << std::endl
113  << "Negative or zero delta-Phi (" << dPhi << "), for solid: "
114  << GetName();
115  UUtils::Exception("UTubs::CheckDPhiAngle()", "GeomSolids0002",
116  UFatalError, 1, message.str().c_str());
117  }
118  }
119 }
120 
121 inline void UTubs::CheckPhiAngles(double sPhi, double dPhi)
122 {
123  CheckDPhiAngle(dPhi);
124  if ((fDPhi < 2 * UUtils::kPi) && (sPhi))
125  {
126  CheckSPhiAngle(sPhi);
127  }
128  InitializeTrigonometry();
129 }
130 
131 inline
132 void UTubs::SetInnerRadius(double newRMin)
133 {
134  if (newRMin < 0) // Check radii
135  {
136  std::ostringstream message;
137  message << "Invalid radii." << std::endl
138  << "Invalid values for radii in solid " << GetName() << std::endl
139  << " newRMin = " << newRMin
140  << ", fRMax = " << fRMax << std::endl
141  << " Negative inner radius!";
142  UUtils::Exception("UTubs::SetInnerRadius()", "GeomSolids0002",
143  UFatalError, 1, message.str().c_str());
144  }
145  fRMin = newRMin;
146  Initialize();
147 }
148 
149 inline
150 void UTubs::SetOuterRadius(double newRMax)
151 {
152  if (newRMax <= 0) // Check radii
153  {
154  std::ostringstream message;
155  message << "Invalid radii." << std::endl
156  << "Invalid values for radii in solid " << GetName() << std::endl
157  << " fRMin = " << fRMin
158  << ", newRMax = " << newRMax << std::endl
159  << " Invalid outer radius!";
160  UUtils::Exception("UTubs::SetOuterRadius()", "GeomSolids0002",
161  UFatalError, 1, message.str().c_str());
162  }
163  fRMax = newRMax;
164  Initialize();
165 }
166 
167 inline
168 void UTubs::SetZHalfLength(double newDz)
169 {
170  if (newDz <= 0) // Check z-len
171  {
172  std::ostringstream message;
173  message << "Invalid Z half-length." << std::endl
174  << "Negative Z half-length (" << newDz << "), for solid: "
175  << GetName();
176  UUtils::Exception("UTubs::SetZHalfLength()", "GeomSolids0002",
177  UFatalError, 1, message.str().c_str());
178  }
179  fDz = newDz;
180  Initialize();
181 }
182 
183 inline
184 void UTubs::SetStartPhiAngle(double newSPhi, bool compute)
185 {
186  // Flag 'compute' can be used to explicitely avoid recomputation of
187  // trigonometry in case SetDeltaPhiAngle() is invoked afterwards
188 
189  CheckSPhiAngle(newSPhi);
190  fPhiFullTube = false;
191  if (compute)
192  {
193  InitializeTrigonometry();
194  }
195  Initialize();
196 }
197 
198 inline
199 void UTubs::SetDeltaPhiAngle(double newDPhi)
200 {
201  CheckPhiAngles(fSPhi, newDPhi);
202  Initialize();
203 }
204 
205 // Older names for access functions
206 
207 inline
208 double UTubs::GetRMin() const
209 {
210  return GetInnerRadius();
211 }
212 
213 inline
214 double UTubs::GetRMax() const
215 {
216  return GetOuterRadius();
217 }
218 
219 inline
220 double UTubs::GetDz() const
221 {
222  return GetZHalfLength() ;
223 }
224 
225 inline
226 double UTubs::GetSPhi() const
227 {
228  return GetStartPhiAngle();
229 }
230 
231 inline
232 double UTubs::GetDPhi() const
233 {
234  return GetDeltaPhiAngle();
235 }
236 
237 inline
238 double UTubs::Capacity()
239 {
240  if (fCubicVolume != 0.)
241  {
242  ;
243  }
244  else
245  {
246  fCubicVolume = fDPhi * fDz * (fRMax * fRMax - fRMin * fRMin);
247  }
248  return fCubicVolume;
249 }
250 
251 inline
252 double UTubs::SurfaceArea()
253 {
254  if (fSurfaceArea != 0.)
255  {
256  ;
257  }
258  else
259  {
260  fSurfaceArea = fDPhi * (fRMin + fRMax) * (2 * fDz + fRMax - fRMin);
261  if (!fPhiFullTube)
262  {
263  fSurfaceArea = fSurfaceArea + 4 * fDz * (fRMax - fRMin);
264  }
265  }
266  return fSurfaceArea;
267 }
268 
269 inline
270 double UTubs::SafetyFromInsideR(const UVector3& p,
271  const double rho, bool) const
272 {
273  // Safety From Inside R, used for UPolycone Section
274 
275  double safe = 0.0, safeR1, safeR2, safePhi;
276 
277  if (fRMin)
278  {
279  safeR1 = rho - fRMin;
280  safeR2 = fRMax - rho;
281 
282  if (safeR1 < safeR2)
283  {
284  safe = safeR1;
285  }
286  else
287  {
288  safe = safeR2;
289  }
290  }
291  else
292  {
293  safe = fRMax - rho;
294  }
295 
296  // Check if phi divided, Calc distances closest phi plane
297  //
298  if (!fPhiFullTube)
299  {
300  if (p.y() * fCosCPhi - p.x() * fSinCPhi <= 0)
301  {
302  safePhi = -(p.x() * fSinSPhi - p.y() * fCosSPhi);
303  }
304  else
305  {
306  safePhi = (p.x() * fSinEPhi - p.y() * fCosEPhi);
307  }
308  if (safePhi < safe)
309  {
310  safe = safePhi;
311  }
312  }
313 
314  return safe;
315 }
316 
317 inline
318 double UTubs::SafetyFromOutsideR(const UVector3& p,
319  const double rho, bool) const
320 {
321  // Safety for R ,used in UPolycone for sections
322 
323  double safe = 0.0, safe1, safe2;
324  double safePhi;
325  bool outside;
326  safe1 = rho-fRMin; //fRMin - rho;
327  safe2 = fRMax - rho;
328 
329  if (safe1 < safe2)
330  {
331  safe = safe1;
332  }
333  else
334  {
335  safe = safe2;
336  }
337 
338  if ((!fPhiFullTube) && (rho))
339  {
340  safePhi = SafetyToPhi(p,rho,outside);
341  if ((outside) && (safePhi > safe))
342  {
343  safe = safePhi;
344  }
345  }
346 
347  return safe; // not accurate safety
348 }
349 
350 inline
351 double UTubs::SafetyToPhi(const UVector3& p,
352  const double rho, bool& outside) const
353 {
354  double cosPsi, safePhi = 0.0;
355 
356  // Psi=angle from central phi to point
357  //
358  cosPsi = (p.x() * fCosCPhi + p.y() * fSinCPhi) / rho;
359  outside = false;
360  if (cosPsi < std::cos(fDPhi * 0.5))
361  {
362  // Point lies outside phi range
363  //
364  outside=true;
365  if ((p.y() * fCosCPhi - p.x() * fSinCPhi) <= 0)
366  {
367  safePhi = std::fabs(p.x() * fSinSPhi - p.y() * fCosSPhi);
368  }
369  else
370  {
371  safePhi = std::fabs(p.x() * fSinEPhi - p.y() * fCosEPhi);
372  }
373  }
374 
375  return safePhi;
376 }