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

Last change on this file since 1337 was 807, checked in by garnier, 17 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.