source: trunk/examples/extended/field/field04/src/F04DetectorConstruction.cc @ 1309

Last change on this file since 1309 was 807, checked in by garnier, 16 years ago

update

File size: 14.6 KB
Line 
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//
28
29#include "G4ios.hh"
30#include "globals.hh"
31
32#include "F04DetectorConstruction.hh"
33#include "F04DetectorMessenger.hh"
34
35#include "F04GlobalField.hh"
36
37#include "G4Tubs.hh"
38#include "G4LogicalVolume.hh"
39#include "G4PVPlacement.hh"
40
41#include "G4Material.hh"
42#include "G4NistManager.hh"
43
44#include "G4FieldManager.hh"
45#include "G4UniformMagField.hh"
46#include "G4TransportationManager.hh"
47
48#include "G4GeometryManager.hh"
49
50#include "G4SolidStore.hh"
51#include "G4RegionStore.hh"
52#include "G4LogicalVolumeStore.hh"
53#include "G4PhysicalVolumeStore.hh"
54
55#include "G4RunManager.hh"
56
57#include "F04DetectorConstruction.hh"
58#include "F04DetectorMessenger.hh"
59#include "F04Materials.hh"
60
61#include "G4RotationMatrix.hh"
62
63#include "F04SimpleSolenoid.hh"
64#include "F04FocusSolenoid.hh"
65
66F04DetectorConstruction::F04DetectorConstruction()
67 : solidWorld(0), logicWorld(0), physiWorld(0),
68   solidTarget(0), logicTarget(0), physiTarget(0),
69   solidDegrader(0),logicDegrader(0), physiDegrader(0),
70   solidCaptureMgnt(0), logicCaptureMgnt(0), physiCaptureMgnt(0),
71   solidTransferMgnt(0), logicTransferMgnt(0), physiTransferMgnt(0),
72   WorldMaterial(0), TargetMaterial(0), DegraderMaterial(0),
73   focusSolenoid(0), simpleSolenoid(0)
74{
75  WorldSizeZ = 50.*m;
76  WorldSizeR =  5.*m;
77
78  TargetRadius       =   0.4*cm;
79  TargetThickness    =  16.0*cm;
80
81  SetTargetAngle(170);
82
83  DegraderRadius     =  30.0*cm;
84  DegraderThickness  =   0.1*cm;
85
86  CaptureMgntRadius  =  0.6*m;
87  CaptureMgntLength  =  4.0*m;
88
89  SetCaptureMgntB1(2.5*tesla);
90  SetCaptureMgntB2(5.0*tesla);
91
92  TransferMgntRadius =  0.3*m;
93  TransferMgntLength = 15.0*m;
94
95  SetTransferMgntB(5.0*tesla);
96
97  DegraderPos = -TransferMgntLength/2. + DegraderThickness/2.;
98
99  // ensure the global field is initialized
100  (void)F04GlobalField::getObject();
101
102  detectorMessenger = new F04DetectorMessenger(this);
103}
104
105F04DetectorConstruction::~F04DetectorConstruction()
106{ 
107  delete detectorMessenger;
108}
109
110G4VPhysicalVolume* F04DetectorConstruction::Construct()
111{
112  materials = F04Materials::GetInstance();
113
114  DefineMaterials();
115
116  return ConstructDetector();
117}
118
119void F04DetectorConstruction::DefineMaterials()
120{
121  //define materials for the experiment
122
123  Vacuum = materials->GetMaterial("G4_Galactic");
124
125  WorldMaterial    = materials->GetMaterial("G4_AIR");
126  DegraderMaterial = materials->GetMaterial("G4_Pb");
127  TargetMaterial   = materials->GetMaterial("G4_W");
128}
129
130G4VPhysicalVolume* F04DetectorConstruction::ConstructDetector()
131{
132  solidWorld = new G4Tubs("World",
133               0.,GetWorldSizeR(),GetWorldSizeZ()/2.,0.,twopi);
134                         
135  logicWorld = new G4LogicalVolume(solidWorld,
136                                   GetWorldMaterial(),
137                                   "World");
138                                   
139  physiWorld = new G4PVPlacement(0,
140                                 G4ThreeVector(),
141                                 "World",
142                                 logicWorld,
143                                 0,
144                                 false,
145                                 0);
146
147  // Capture Magnet
148
149  solidCaptureMgnt = new G4Tubs("CaptureMgnt",
150                     0.,GetCaptureMgntRadius(),
151                     GetCaptureMgntLength()/2.,0.,twopi);
152
153  logicCaptureMgnt = new G4LogicalVolume(solidCaptureMgnt,
154                                         Vacuum,
155                                         "CaptureMgnt");
156
157  G4ThreeVector CaptureMgntCenter = G4ThreeVector();
158
159  physiCaptureMgnt = new G4PVPlacement(0,
160                                       CaptureMgntCenter,
161                                       "CaptureMgnt",
162                                       logicCaptureMgnt,
163                                       physiWorld,
164                                       false,
165                                       0);
166
167  // Transfer Magnet
168
169  solidTransferMgnt = new G4Tubs("TransferMgnt",
170                      0.,GetTransferMgntRadius(),
171                      GetTransferMgntLength()/2.,0.,twopi);
172
173  logicTransferMgnt = new G4LogicalVolume(solidTransferMgnt,
174                                          Vacuum,
175                                          "TransferMgnt");
176
177  G4double z  = GetCaptureMgntLength()/2. + GetTransferMgntLength()/2.
178                              + GetTransferMgntPos();
179  G4double x =  GetTransferMgntPos()/2.;
180
181  G4ThreeVector TransferMgntCenter = G4ThreeVector(x,0.,z);
182
183  G4RotationMatrix* g4rot = new G4RotationMatrix();
184  *g4rot = stringToRotationMatrix("Y30,X10");
185  *g4rot = g4rot->inverse();
186  if (*g4rot == G4RotationMatrix()) g4rot = NULL;
187
188  physiTransferMgnt = new G4PVPlacement(g4rot,
189                                        TransferMgntCenter,
190                                        "TransferMgnt",
191                                        logicTransferMgnt,
192                                        physiWorld,
193                                        false,
194                                        0);
195
196  // Test Plane
197
198  G4Tubs* solidTestPlane = new G4Tubs("TestPlane",
199                                      0.,GetTransferMgntRadius(),
200                                      1.*mm,0.,twopi);
201
202  G4LogicalVolume* logicTestPlane = new G4LogicalVolume(solidTestPlane,
203                                                        Vacuum,
204                                                        "TestPlane");
205
206
207  z = GetTransferMgntLength()/2. - 1.*mm;
208
209  G4ThreeVector TestPlaneCenter = G4ThreeVector(0.,0.,z);
210
211  new G4PVPlacement(0,
212                    TestPlaneCenter,
213                    "TestPlane",
214                    logicTestPlane,
215                    physiTransferMgnt,
216                    false,
217                    0);
218
219  // Target
220
221  if (GetTargetThickness() > 0.)
222  {
223      solidTarget = new G4Tubs("Target", 
224                    0.,GetTargetRadius(),
225                    GetTargetThickness()/2.,0.,twopi);
226
227      logicTarget = new G4LogicalVolume(solidTarget,
228                                        GetTargetMaterial(),
229                                        "Target");
230
231      G4int i =  GetTargetAngle();
232
233      char c[4];
234      sprintf(c,"%d",i);
235      G4String Angle = c;
236      Angle = Angle.strip(G4String::both,' ');
237      Angle = "Y" + Angle;
238
239      g4rot = new G4RotationMatrix();
240      *g4rot = stringToRotationMatrix(Angle);
241      *g4rot = g4rot->inverse();
242      if (*g4rot == G4RotationMatrix()) g4rot = NULL;
243
244      G4ThreeVector TargetCenter(0.,0.,GetTargetPos());
245
246      physiTarget = new G4PVPlacement(g4rot,
247                                      TargetCenter,
248                                      "Target",
249                                      logicTarget,
250                                      physiCaptureMgnt,
251                                      false,
252                                      0);
253  }
254
255  // Degrader
256
257  if (GetDegraderThickness() > 0.) 
258  { 
259      solidDegrader = new G4Tubs("Degrader",
260                      0., GetDegraderRadius(),
261                      GetDegraderThickness()/2., 0.,twopi); 
262                         
263      logicDegrader = new G4LogicalVolume(solidDegrader,   
264                                          GetDegraderMaterial(), 
265                                          "Degrader");     
266
267      G4ThreeVector DegraderCenter = G4ThreeVector(0.,0.,GetDegraderPos());
268
269      physiDegrader = new G4PVPlacement(0,                 
270                                        DegraderCenter,
271                                        "Degrader",       
272                                        logicDegrader,     
273                                        physiTransferMgnt,       
274                                        false,             
275                                        0);
276  }
277
278  G4double l = 0.0;
279  G4double B1 = GetCaptureMgntB1();
280  G4double B2 = GetCaptureMgntB2();
281
282  if (focusSolenoid) delete focusSolenoid;
283  focusSolenoid = new F04FocusSolenoid(B1, B2, l,
284                                    logicCaptureMgnt,CaptureMgntCenter);
285  focusSolenoid -> SetHalf(true);
286
287           l = 0.0;
288  G4double B = GetTransferMgntB();
289
290  if (simpleSolenoid) delete simpleSolenoid;
291  simpleSolenoid = new F04SimpleSolenoid(B, l,
292                                      logicTransferMgnt,TransferMgntCenter);
293
294  simpleSolenoid->setColor("1,0,1");
295  simpleSolenoid->setColor("0,1,1");
296  simpleSolenoid->setMaxStep(1.5*mm);
297  simpleSolenoid->setMaxStep(2.5*mm);
298
299  return physiWorld;
300}
301
302void F04DetectorConstruction::SetWorldMaterial(const G4String materialChoice)
303{
304  G4Material* pttoMaterial =
305      G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
306
307  if (pttoMaterial != WorldMaterial) {
308     if ( pttoMaterial ) {
309        WorldMaterial = pttoMaterial;
310     } else {
311        G4cout << "\n--> WARNING from SetWorldMaterial : "
312               << materialChoice << " not found" << G4endl;
313     }
314  }
315}
316
317void F04DetectorConstruction::SetTargetMaterial(const G4String materialChoice)
318{
319  G4Material* pttoMaterial =
320      G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
321
322  if (pttoMaterial != TargetMaterial) {
323     if ( pttoMaterial ) {
324        TargetMaterial = pttoMaterial;
325     } else {
326        G4cout << "\n-->  WARNING from SetTargetMaterial : "
327               << materialChoice << " not found" << G4endl;
328     }
329  }
330}
331
332void F04DetectorConstruction::SetDegraderMaterial(const G4String materialChoice)
333
334{
335  G4Material* pttoMaterial =
336      G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
337
338  if (pttoMaterial != DegraderMaterial) {
339     if ( pttoMaterial ) {
340        DegraderMaterial = pttoMaterial;
341     } else {
342        G4cout << "\n--> WARNING from SetDegraderMaterial : "
343               << materialChoice << " not found" << G4endl;
344     }
345  }
346}
347
348void F04DetectorConstruction::SetWorldSizeZ(G4double val)
349{
350  WorldSizeZ = val;
351}
352
353void F04DetectorConstruction::SetWorldSizeR(G4double val)
354{
355  WorldSizeR = val;
356}
357
358void F04DetectorConstruction::SetCaptureMgntRadius(G4double val)
359{
360  CaptureMgntRadius = val;
361}
362
363void F04DetectorConstruction::SetCaptureMgntLength(G4double val)
364{
365  CaptureMgntLength = val;
366}
367
368void F04DetectorConstruction::SetCaptureMgntB1(G4double val)
369{
370  CaptureMgntB1 = val;
371}
372
373void F04DetectorConstruction::SetCaptureMgntB2(G4double val)
374{
375  CaptureMgntB2 = val;
376}
377
378void F04DetectorConstruction::SetTransferMgntRadius(G4double val)
379{
380  TransferMgntRadius = val;
381}
382
383void F04DetectorConstruction::SetTransferMgntLength(G4double val)
384{
385  TransferMgntLength = val;
386}
387
388void F04DetectorConstruction::SetTransferMgntB(G4double val)
389{
390  TransferMgntB = val;
391}
392
393void F04DetectorConstruction::SetTransferMgntPos(G4double val)
394{
395  TransferMgntPos = val;
396}
397
398void F04DetectorConstruction::SetTargetRadius(G4double val)
399{
400  TargetRadius = val;
401}
402
403void F04DetectorConstruction::SetTargetThickness(G4double val)
404{
405  TargetThickness = val;
406}
407
408void F04DetectorConstruction::SetTargetPos(G4double val)
409{
410  TargetPos = val;
411}
412
413void F04DetectorConstruction::SetTargetAngle(G4int val)
414{
415  TargetAngle = val;
416}
417
418void F04DetectorConstruction::SetDegraderRadius(G4double val)
419{
420  DegraderRadius = val;
421}
422
423void F04DetectorConstruction::SetDegraderThickness(G4double val)
424{
425  DegraderThickness = val;
426} 
427
428void F04DetectorConstruction::SetDegraderPos(G4double val)
429{
430  DegraderPos = val;
431} 
432
433void F04DetectorConstruction::UpdateGeometry()
434{
435  if (!physiWorld) return;
436
437  // clean-up previous geometry
438  G4GeometryManager::GetInstance()->OpenGeometry();
439
440  G4PhysicalVolumeStore::GetInstance()->Clean();
441  G4LogicalVolumeStore::GetInstance()->Clean();
442  G4SolidStore::GetInstance()->Clean();
443
444  //define new one
445  G4RunManager::GetRunManager()->DefineWorldVolume(ConstructDetector());
446
447  G4RunManager::GetRunManager()->GeometryHasBeenModified();
448  G4RunManager::GetRunManager()->PhysicsHasBeenModified();
449
450  G4RegionStore::GetInstance()->UpdateMaterialList(physiWorld);
451
452}
453
454G4RotationMatrix
455            F04DetectorConstruction::stringToRotationMatrix(G4String rotation)
456{
457  // We apply successive rotations OF THE OBJECT around the FIXED
458  // axes of the parent's local coordinates; rotations are applied
459  // left-to-right (rotation="r1,r2,r3" => r1 then r2 then r3).
460
461  G4RotationMatrix rot;
462
463  unsigned int place = 0;
464
465  while (place < rotation.size()) {
466
467        G4double angle;
468        char* p(0);
469        G4String current=rotation.substr(place+1);
470        angle = strtod(current.c_str(),&p) * deg;
471             
472        if (!p || (*p != ',' && *p != '\0')) {
473          G4cerr << "Invalid rotation specification: " << 
474                                                  rotation.c_str() << G4endl;
475
476           return rot;
477        }
478
479        G4RotationMatrix thisRotation;
480
481        switch(rotation.substr(place,1).c_str()[0]) {
482              case 'X': case 'x':
483                thisRotation = G4RotationMatrix(CLHEP::HepRotationX(angle));
484                break;
485              case 'Y': case 'y':
486                thisRotation = G4RotationMatrix(CLHEP::HepRotationY(angle));
487                break;
488              case 'Z': case 'z':
489                thisRotation = G4RotationMatrix(CLHEP::HepRotationZ(angle));
490                break;
491              default:
492                G4cerr << " Invalid rotation specification: "
493                       << rotation << G4endl;
494                return rot;
495        }
496
497       rot = thisRotation * rot;
498       place = rotation.find(',',place);
499       if (place > rotation.size()) break;
500       ++place;
501  }
502
503  return rot;
504
505}
Note: See TracBrowser for help on using the repository browser.