ATLAS Offline Software
Loading...
Searching...
No Matches
LArWheelSolidInit.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <cassert>
6#include <stdexcept>
7#include <iostream>
8
9
11
12#include "CLHEP/Units/PhysicalConstants.h"
13#include "G4GeometryTolerance.hh"
14#include "G4Polycone.hh"
15
17#include "LArWheelSolid.h"
18#include "LArFanSection.h"
19#include "G4ShiftedCone.h"
20
21#ifdef DEBUG_LARWHEELSOLID
22G4int LArWheelSolid::Verbose = 0;
23#endif
24
25// these are internal technical constants, should not go in DB
26const unsigned int LArWheelSolid::s_IterationsLimit = 50; // That's enough even for 10e-15 IterationPrecision
27const G4double LArWheelSolid::s_Tolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance() / 2;
28const G4double LArWheelSolid::s_AngularTolerance = G4GeometryTolerance::GetInstance()->GetAngularTolerance() / 2;
29const G4double LArWheelSolid::s_IterationPrecision = 0.001*CLHEP::mm;
30const G4double LArWheelSolid::s_IterationPrecision2 = s_IterationPrecision * s_IterationPrecision;
31
33 G4int zside,
35 const EMECData *emecData
36 )
37 : G4VSolid(name)
38#ifndef PORTABLE_LAR_SHAPE
39 , AthMessaging("LArWheelSolid")
40#endif
41 , m_Type(type), m_Calculator(calc), m_PhiPosition(CLHEP::halfpi), m_fs(0)
42{
43#ifndef PORTABLE_LAR_SHAPE
44#ifdef LARWHEELSOLID_USE_FANBOUND
45 ATH_MSG_INFO ( "compiled with G4 FanBound" );
46#else
47 ATH_MSG_INFO ( "compiled with private find_exit_point" );
48#endif
49#endif
50
52 switch(m_Type){
54 calc_type = LArG4::InnerAbsorberWheel;
55 break;
57 calc_type = LArG4::OuterAbsorberWheel;
58 break;
60 calc_type = LArG4::InnerElectrodWheel;
61 break;
63 calc_type = LArG4::OuterElectrodWheel;
64 break;
67 break;
70 break;
73 break;
76 break;
77 case InnerGlueWheel:
78 calc_type = LArG4::InnerGlueWheel;
79 break;
80 case OuterGlueWheel:
81 calc_type = LArG4::OuterGlueWheel;
82 break;
83 case InnerLeadWheel:
84 calc_type = LArG4::InnerLeadWheel;
85 break;
86 case OuterLeadWheel:
87 calc_type = LArG4::OuterLeadWheel;
88 break;
90 calc_type = LArG4::InnerAbsorberWheel;
91 break;
93 calc_type = LArG4::InnerElectrodWheel;
94 break;
95 case InnerGlueCone:
96 calc_type = LArG4::InnerGlueWheel;
97 break;
98 case InnerLeadCone:
99 calc_type = LArG4::InnerLeadWheel;
100 break;
102 calc_type = LArG4::OuterAbsorberWheel;
103 break;
105 calc_type = LArG4::OuterElectrodWheel;
106 break;
108 calc_type = LArG4::OuterGlueWheel;
109 break;
111 calc_type = LArG4::OuterLeadWheel;
112 break;
114 calc_type = LArG4::OuterAbsorberWheel;
115 break;
117 calc_type = LArG4::OuterElectrodWheel;
118 break;
120 calc_type = LArG4::OuterGlueWheel;
121 break;
123 calc_type = LArG4::OuterLeadWheel;
124 break;
125 default:
126 G4Exception("LArWheelSolid", "UnknownSolidType", FatalException,
127 "Constructor: unknown LArWheelSolid_t");
128 }
129
130 if(m_Calculator == 0) m_Calculator = new LArWheelCalculator(*emecData,calc_type, zside);
131
132 const G4String bs_name = name + "-Bounding";
133#ifdef DEBUG_LARWHEELSOLID
134 const char *venv = getenv("LARWHEELSOLID_VERBOSE");
135 if(venv) Verbose = atoi(venv);
136 std::cout << "The LArWheelSolid build " << __DATE__ << " " << __TIME__
137 << std::endl;
138 std::cout << "LArWheelSolid verbosity level is " << Verbose << std::endl;
139#endif
140
141 // Initialize code that depends on wheel type:
145 switch(m_Type){
150 case InnerGlueWheel:
151 case InnerLeadWheel:
154 case InnerGlueCone:
155 case InnerLeadCone:
156 inner_solid_init(bs_name);
157 break;
162 case OuterGlueWheel:
163 case OuterLeadWheel:
172 outer_solid_init(bs_name);
173 break;
174 default:
175 G4Exception("LArWheelSolid", "UnknownSolidType", FatalException,
176 "Constructor: unknown LArWheelSolid_t");
177 }
178
179 m_Zsect_start_search = (m_Zsect.size() - 1) - 1;
180#ifndef PORTABLE_LAR_SHAPE
181 init_tests();
182 test(); // activated by env. variable
183 clean_tests();
184#endif
185
186#ifdef DEBUG_LARWHEELSOLID
187 m_fs->print();
188 std::cout << "Limits: (" << m_Zsect.size() << ")" << std::endl;
189 for(size_t i = 0; i < m_Zsect.size(); ++ i){
190 std::cout << i << " " << m_Zsect[i] << std::endl;
191 }
192#endif
193#ifndef PORTABLE_LAR_SHAPE
194 ATH_MSG_DEBUG ( "solid of type "
196 << " initialized" );
197#endif
198}
199
201{
202 if(m_fs) delete m_fs;
203}
204
205// initialization of inner Absorber or Electrod wheels
206void LArWheelSolid::inner_solid_init(const G4String &bs_name)
207{
208 m_IsOuter = false;
209 m_FanPhiAmplitude = 0.065; // internal technical constant, should not go in DB
210 set_phi_size();
211
212 std::array<G4double,2> zPlane{}, rInner{}, rOuter{};
213 zPlane[1] = GetCalculator()->GetWheelThickness();
214 G4double wheel_thickness = zPlane[1] - zPlane[0];
217 const G4double phi_min = m_PhiPosition - m_FanPhiAmplitude
219
220 m_Zmin = zPlane[0]; m_Zmax = zPlane[1];
221 m_Rmin = rInner[0]; m_Rmax = rOuter[1];
222 m_Ymin = m_Rmin * 0.9;
223 m_Zmid = zPlane[1];
224 m_Ymid = (rInner[0] + rOuter[1]) * 0.5;
225
230 ){
232 bs_name + "Cone", zPlane[0], zPlane[1],
233 rInner[0], rOuter[0], rInner[1], rOuter[1]
234 );
235 } else {
236 m_BoundingShape = new G4Polycone(
237 bs_name + "Polycone", m_MinPhi, m_MaxPhi - m_MinPhi,
238 2, zPlane.data(), rInner.data(), rOuter.data()
239 );
240 }
241#ifdef LARWHEELSOLID_USE_FANBOUND
242 const G4double phi_size = (m_FanPhiAmplitude + GetCalculator()->GetFanStepOnPhi() * 2) * 2;
243 FanBound = new G4Polycone(bs_name + "ofFan", phi_min, phi_size,
244 2, zPlane, rInner, rOuter);
245#endif
246#ifndef PORTABLE_LAR_SHAPE
247 ATH_MSG_INFO(m_BoundingShape->GetName() + " is the m_BoundingShape");
248#endif
249
250 const G4double half_wave_length = GetCalculator()->GetHalfWaveLength();
251 const G4double sss = GetCalculator()->GetStraightStartSection();
252 m_Zsect.push_back(0.);
253 m_Zsect.push_back(sss + half_wave_length * 0.25);
254 const G4int num_fs = GetCalculator()->GetNumberOfHalfWaves() + 1;
255 for(G4int i = 2; i < num_fs; i ++){
256 const G4double zi = half_wave_length * (i - 1) + sss;
257#if LARWHEELSOLID_ZSECT_MULT > 1
258 for(G4int j = LARWHEELSOLID_ZSECT_MULT - 1; j > 0; -- j){
259 m_Zsect.push_back(zi - half_wave_length * j / LARWHEELSOLID_ZSECT_MULT);
260 }
261#endif
262 m_Zsect.push_back(zi);
263 }
264 m_Zsect.push_back(wheel_thickness - m_Zsect[1]);
265 m_Zsect.push_back(wheel_thickness - m_Zsect[0]);
266
267 m_fs = new LArFanSections(
268 rInner[0], rInner[1], rOuter[0], rOuter[1],
269 m_Rmax*cos(phi_min), m_Zsect.front(), m_Zsect.back()
270 );
271}
272
273// initialization of outer Absorber or Electrod wheels
274void LArWheelSolid::outer_solid_init(const G4String &bs_name)
275{
276 m_IsOuter = true;
277 m_FanPhiAmplitude = 0.02; // internal technical constant, should not go in DB
278 set_phi_size();
279
280 std::array<G4double,3> zPlane{}, rInner{}, rOuter{};
281 zPlane[2] = GetCalculator()->GetWheelThickness();
282 G4double wheel_thickness = zPlane[2] - zPlane[0];
283 zPlane[1] = GetCalculator()->GetWheelInnerRadius(rInner);
285 const G4double phi_min =
288
289 m_Zmid = zPlane[1];
290 m_Ymid = (rInner[0] + rOuter[2]) * 0.5;
291
292 bool hasFrontSections = false;
293 bool hasBackSections = false;
298 ){
299 m_Zmin = zPlane[0]; m_Zmax = zPlane[1];
300 m_Rmin = rInner[0]; m_Rmax = rOuter[1];
302 bs_name + "FrontCone", zPlane[0], zPlane[1],
303 rInner[0], rOuter[0], rInner[1], rOuter[1]
304 );
305 hasFrontSections = true;
306 } else if(m_Type == OuterAbsorberBackCone
310 ){
311 m_Zmin = zPlane[1]; m_Zmax = zPlane[2];
312 m_Rmin = rInner[1]; m_Rmax = rOuter[2];
314 bs_name + "BackCone", zPlane[1], zPlane[2],
315 rInner[1], rOuter[1], rInner[2], rOuter[2]
316 );
317 hasBackSections = true;
318 } else {
319 m_Zmin = zPlane[0]; m_Zmax = zPlane[2];
320 m_Rmin = rInner[0]; m_Rmax = rOuter[2];
321 m_BoundingShape = new G4Polycone(
322 bs_name + "Polycone", m_MinPhi, m_MaxPhi - m_MinPhi,
323 3, zPlane.data(), rInner.data(), rOuter.data()
324 );
325 hasFrontSections = true;
326 hasBackSections = true;
327 }
328
329 m_Ymin = m_Rmin * 0.9;
330
331#ifdef LARWHEELSOLID_USE_FANBOUND
332 const G4double phi_size = (m_FanPhiAmplitude + GetCalculator()->GetFanStepOnPhi() * 2) * 2;
333 FanBound = new G4Polycone(bs_name + "ofFan", phi_min, phi_size,
334 3, zPlane, rInner, rOuter);
335#endif
336#ifndef PORTABLE_LAR_SHAPE
337 ATH_MSG_INFO(m_BoundingShape->GetName() + " is the m_BoundingShape");
338#endif
339 const G4double half_wave_length = GetCalculator()->GetHalfWaveLength();
340 const G4double sss = GetCalculator()->GetStraightStartSection();
341
342 if(hasFrontSections){
343 m_Zsect.push_back(0.);
344 m_Zsect.push_back(sss + half_wave_length * 0.25);
345 } else {
346 m_Zsect.push_back(m_Zmid);
347 }
348 const G4int num_fs = GetCalculator()->GetNumberOfHalfWaves() + 1;
349
350 for(G4int i = 2; i < num_fs; i ++){
351 const G4double zi = half_wave_length * (i - 1) + sss;
352#if LARWHEELSOLID_ZSECT_MULT > 1
353 for(G4int j = LARWHEELSOLID_ZSECT_MULT - 1; j > 0; -- j){
354 G4double zj = zi - half_wave_length * j / LARWHEELSOLID_ZSECT_MULT;
355 if(hasFrontSections && hasBackSections
356 && m_Zsect.back() < m_Zmid && zj >= m_Zmid){
357 m_Zsect.push_back(m_Zmid);
358 }
359 if((zj < m_Zmid && hasFrontSections)
360 || (zj > m_Zmid && hasBackSections)){
361 m_Zsect.push_back(zj);
362 }
363 }
364#endif
365 if(hasFrontSections && hasBackSections
366 && m_Zsect.back() < m_Zmid && zi >= m_Zmid){
367 m_Zsect.push_back(m_Zmid);
368 }
369 if((zi < m_Zmid && hasFrontSections)
370 || (zi > m_Zmid && hasBackSections)){
371 m_Zsect.push_back(zi);
372 }
373 }
374 if(hasBackSections){
375 m_Zsect.push_back(wheel_thickness - sss - half_wave_length * 0.25);
376 m_Zsect.push_back(wheel_thickness);
377 } else {
378 m_Zsect.push_back(m_Zmid);
379 }
380
381 m_fs = new LArFanSections(
382 rInner[0], rInner[1], rOuter[0], rOuter[1],
383 m_Rmax*cos(phi_min), m_Zsect.front(), m_Zmid
384 );
385}
386
387// it should be called after m_FanPhiAmplitude has been set
388// and before m_BoundingShape creation
390{
391 if(GetCalculator()->GetisModule()){
392 m_MinPhi = m_PhiPosition - CLHEP::pi * (1. / 8.) - m_FanPhiAmplitude;
393 m_MaxPhi = m_PhiPosition + CLHEP::pi * (1. / 8.) + m_FanPhiAmplitude;
394 } else {
395 m_MinPhi = 0.;
396 m_MaxPhi = CLHEP::twopi;
397 }
398}
#define ATH_MSG_INFO(x)
#define ATH_MSG_DEBUG(x)
#define LARWHEELSOLID_ZSECT_MULT
LArWheelSolid_t
@ OuterGlueWheel
@ OuterElectrodFrontCone
@ OuterLeadBackCone
@ OuterElectrodBackCone
@ OuterAbsorberFrontCone
@ OuterElectrodModule
@ OuterElectrodWheel
@ InnerAbsorberCone
@ OuterAbsorberWheel
@ OuterLeadFrontCone
@ InnerGlueWheel
@ InnerGlueCone
@ OuterGlueBackCone
@ InnerAbsorberWheel
@ InnerElectrodCone
@ InnerLeadCone
@ InnerAbsorberModule
@ OuterAbsorberModule
@ InnerLeadWheel
@ OuterLeadWheel
@ InnerElectrodModule
@ OuterAbsorberBackCone
@ OuterGlueFrontCone
@ InnerElectrodWheel
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
This class separates some of the geometry details of the LAr endcap.
double GetFanStepOnPhi() const
int GetNumberOfHalfWaves() const
double GetFanHalfThickness(LArG4::LArWheelCalculator_t) const
double GetHalfWaveLength() const
double GetStraightStartSection() const
double GetWheelThickness() const
double GetWheelInnerRadius(std::array< double, 2 > &rInner) const
static const char * LArWheelCalculatorTypeString(LArG4::LArWheelCalculator_t)
void GetWheelOuterRadius(std::array< double, 2 > &rOuter) const
LArWheelCalculator * m_Calculator
void outer_solid_init(const G4String &)
static const G4double s_IterationPrecision2
const LArWheelSolid_t m_Type
static const G4double s_IterationPrecision
static const G4double s_Tolerance
LArWheelSolid(const G4String &name, LArWheelSolid_t type, G4int zside=1, LArWheelCalculator *calc=0, const EMECData *emecData=0)
std::vector< G4double > m_Zsect
G4double m_MinPhi
G4VSolid * m_BoundingShape
static const unsigned int s_IterationsLimit
G4int m_Zsect_start_search
static const G4double s_AngularTolerance
G4double m_FanPhiAmplitude
G4double m_MaxPhi
const G4double m_PhiPosition
LArFanSections * m_fs
void inner_solid_init(const G4String &)
G4double m_FHTminusT
G4double m_FanHalfThickness
const LArWheelCalculator * GetCalculator(void) const
G4double m_FHTplusT