Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
GarfieldDetectorConstruction.cc
Go to the documentation of this file.
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// $Id: GarfieldDetectorConstruction.cc 999992 2015-12-11 14:47:43Z dpfeiffe $
27//
28/// \file GarfieldDetectorConstruction.cc
29/// \brief Implementation of the GarfieldDetectorConstruction class
30
33#include "GarfieldMessenger.hh"
34#include "G4Material.hh"
35#include "G4NistManager.hh"
36
37#include "G4Box.hh"
38#include "G4Tubs.hh"
39#include "G4LogicalVolume.hh"
40#include "G4PVPlacement.hh"
41#include "G4PVReplica.hh"
42#include "G4GlobalMagFieldMessenger.hh"
43#include "G4AutoDelete.hh"
44
45#include "G4GeometryManager.hh"
46#include "G4PhysicalVolumeStore.hh"
47#include "G4LogicalVolumeStore.hh"
48#include "G4SolidStore.hh"
49
50#include "G4VisAttributes.hh"
51#include "G4Colour.hh"
52
53#include "G4PhysicalConstants.hh"
54#include "G4SystemOfUnits.hh"
55#include "G4RunManager.hh"
56
57//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
58
60 G4VUserDetectorConstruction(), fAbsorberPV(0), fTubePV(0), fGasPV(0), fWirePV(
61 0), fAbsorberMaterial(0), fAbsorberLV(0), fCheckOverlaps(true), fGarfieldG4FastSimulationModel(
62 0), fGarfieldMessenger(0) {
63 fGarfieldMessenger = new GarfieldMessenger(this);
64}
65
66//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
67
69 delete fGarfieldMessenger;
70}
71
72//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
73
75 // Define materials
76 DefineMaterials();
77
78 // Define volumes
79 return DefineVolumes();
80}
81
82//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
83
84void GarfieldDetectorConstruction::DefineMaterials() {
85 G4bool isotopes = false;
86 G4String name, symbol;
87 G4int ncomponents, natoms;
88 G4double density, fractionmass;
89
90 // Lead material defined using NIST Manager
91 G4NistManager* nistManager = G4NistManager::Instance();
92
93 nistManager->FindOrBuildMaterial("G4_Pb");
94 nistManager->FindOrBuildMaterial("G4_Cu");
95 nistManager->FindOrBuildMaterial("G4_Al");
96 nistManager->FindOrBuildMaterial("G4_Au");
97 nistManager->FindOrBuildMaterial("G4_W");
98
99 nistManager->FindOrBuildMaterial("G4_AIR");
100
101 G4Element* H = nistManager->FindOrBuildElement("H", isotopes);
102 G4Element* N = nistManager->FindOrBuildElement("N", isotopes);
103 G4Element* C = nistManager->FindOrBuildElement("C", isotopes);
104 G4Element* O = nistManager->FindOrBuildElement("O", isotopes);
105 G4Element* Ar = nistManager->FindOrBuildElement("Ar", isotopes);
106
107 G4Material* CO2 = new G4Material("CO2",
108 density = 1.977 * CLHEP::mg / CLHEP::cm3, ncomponents = 2);
109 CO2->AddElement(C, natoms = 1);
110 CO2->AddElement(O, natoms = 2);
111
112 G4Material* ArCO2_70_30 = new G4Material("ArCO2_70_30",
113 density = 1.8223 * CLHEP::mg / CLHEP::cm3, ncomponents = 2,
114 kStateGas);
115
116 ArCO2_70_30->AddElement(Ar, fractionmass = 0.70);
117 ArCO2_70_30->AddMaterial(CO2, fractionmass = 0.30);
118
119 G4Material* ArCO2_93_7 = new G4Material("ArCO2_93_7",
120 density = 1.8223 * CLHEP::mg / CLHEP::cm3, ncomponents = 2);
121 ArCO2_93_7->AddElement(Ar, fractionmass = 0.93);
122 ArCO2_93_7->AddMaterial(CO2, fractionmass = 0.07);
123
124 density = 1.413 * CLHEP::g / CLHEP::cm3;
125 G4Material* Kapton = new G4Material(name = "Kapton", density, ncomponents =
126 4);
127 Kapton->AddElement(O, 5);
128 Kapton->AddElement(C, 22);
129 Kapton->AddElement(N, 2);
130 Kapton->AddElement(H, 10);
131
132 // Print materials
133 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
134}
135
136//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
137
138G4VPhysicalVolume* GarfieldDetectorConstruction::DefineVolumes() {
139 // Geometry parameters
140 G4double worldSizeXYZ = 1000 * mm;
141 G4double absorberThicknessZ = 10. * mm;
142 G4double absorberThicknessXY = 100. * mm;
143 G4double wireRadius = 0.025 * mm;
144 G4double tubeRadius = 15 * mm;
145 G4double tubeHalfLength = 100 * mm;
146 G4double tubeThickness = 500 * um;
147
148 // Get materials
149 G4Material* defaultMaterial = G4Material::GetMaterial("G4_AIR");
150 fAbsorberMaterial = G4Material::GetMaterial("G4_Pb");
151
152 G4Material* gasMaterial = G4Material::GetMaterial("ArCO2_70_30");
153 G4Material* cathodeMaterial = G4Material::GetMaterial("G4_Al");
154 G4Material* wireMaterial = G4Material::GetMaterial("G4_W");
155
156 if (!defaultMaterial || !fAbsorberMaterial || !gasMaterial
157 || !cathodeMaterial || !wireMaterial) {
158 G4ExceptionDescription msg;
159 msg << "Cannot retrieve materials already defined.";
160 G4Exception("GarfieldDetectorConstruction::DefineVolumes()",
161 "exampleGarfield", FatalException, msg);
162 }
163
164 //
165 // World
166 //
167 G4VSolid* worldS = new G4Box("World", // its name
168 0.5 * worldSizeXYZ, 0.5 * worldSizeXYZ, 0.5 * worldSizeXYZ); // its size
169
170 G4LogicalVolume* worldLV = new G4LogicalVolume(worldS, // its solid
171 defaultMaterial, // its material
172 "World"); // its name
173
174 G4VPhysicalVolume* worldPV = new G4PVPlacement(0, // no rotation
175 G4ThreeVector(), // at (0,0,0)
176 worldLV, // its logical volume
177 "World", // its name
178 0, // its mother volume
179 false, // no boolean operation
180 0, // copy number
181 fCheckOverlaps); // checking overlaps
182 //
183 // Absorber
184 //
185 G4VSolid* absorberS = new G4Box(
186 "Absorber", // its name
187 0.5 * absorberThicknessXY, 0.5 * absorberThicknessXY,
188 0.5 * absorberThicknessZ); // its size
189
190 fAbsorberLV = new G4LogicalVolume(absorberS, // its solid
191 fAbsorberMaterial, // its material
192 "Absorber"); // its name
193
194 fAbsorberPV = new G4PVPlacement(0, // no rotation
195 G4ThreeVector(0., 0., absorberThicknessZ / 2), // its position
196 fAbsorberLV, // its logical volume
197 "Absorber", // its name
198 worldLV, // its mother volume
199 false, // no boolean operation
200 0, // copy number
201 fCheckOverlaps); // checking overlaps
202
203 //
204 // Drift tube
205 //
206 G4VSolid* tubeS = new G4Tubs("Tube", // its name
207 0, tubeRadius, tubeHalfLength + tubeThickness, 0, 2 * pi); // its size
208
209 G4LogicalVolume* tubeLV = new G4LogicalVolume(tubeS, // its solid
210 cathodeMaterial, // its material
211 "Tube"); // its name
212
213 G4RotationMatrix* rotY = new G4RotationMatrix();
214 rotY->rotateY(90. * CLHEP::degree);
215
216 fTubePV = new G4PVPlacement(rotY,
217 G4ThreeVector(0., -0.2 * tubeRadius,
218 absorberThicknessZ + tubeRadius), // its position
219 tubeLV, // its logical volume
220 "Tube", // its name
221 worldLV, // its mother volume
222 false, // no boolean operation
223 0, // copy number
224 fCheckOverlaps); // checking overlaps
225
226 //
227 // Drift Tube Gas
228 //
229 G4VSolid* gasS = new G4Tubs("Gas", // its name
230 wireRadius, tubeRadius - tubeThickness, tubeHalfLength, 0, 2 * pi); // its size
231
232 G4LogicalVolume* gasLV = new G4LogicalVolume(gasS, // its solid
233 gasMaterial, // its material
234 "Gas"); // its name
235
236 fGasPV = new G4PVPlacement(0, // no rotation
237 G4ThreeVector(0., 0., 0.), // its position
238 gasLV, // its logical volume
239 "Gas", // its name
240 tubeLV, // its mother volume
241 false, // no boolean operation
242 0, // copy number
243 fCheckOverlaps); // checking overlaps
244
245 //
246 // Wire
247 //
248 G4VSolid* wireS = new G4Tubs("Wire", // its name
249 0, wireRadius, tubeHalfLength, 0, 2 * pi); // its size
250
251 G4LogicalVolume* wireLV = new G4LogicalVolume(wireS, // its solid
252 wireMaterial, // its material
253 "Wire"); // its name
254
255 fWirePV = new G4PVPlacement(0, // no rotation
256 G4ThreeVector(0., 0., 0.), // its position
257 wireLV, // its logical volume
258 "Wire", // its name
259 tubeLV, // its mother volume
260 false, // no boolean operation
261 0, // copy number
262 fCheckOverlaps); // checking overlaps
263
264 //
265 // Visualization attributes
266 //
267 worldLV->SetVisAttributes(G4VisAttributes::Invisible);
268
269 G4VisAttributes* VisAttBlue = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0));
270 G4VisAttributes* VisAttGreen = new G4VisAttributes(G4Colour(0.0, 1.0, 0.0));
271 G4VisAttributes* VisAttRed = new G4VisAttributes(G4Colour(1.0, 0.0, 0.0));
272 G4VisAttributes* VisAttWhite = new G4VisAttributes(G4Colour(1.0, 1.0, 1.0));
273
274 wireLV->SetVisAttributes(VisAttRed);
275 tubeLV->SetVisAttributes(VisAttGreen);
276 gasLV->SetVisAttributes(VisAttWhite);
277 fAbsorberLV->SetVisAttributes(VisAttBlue);
278
279 G4Region* regionGarfield = new G4Region("RegionGarfield");
280 regionGarfield->AddRootLogicalVolume(gasLV);
281
282 G4Region* regionWire = new G4Region("RegionWire");
283 regionWire->AddRootLogicalVolume(wireLV);
284
285 fGarfieldG4FastSimulationModel = new GarfieldG4FastSimulationModel(
286 "GarfieldG4FastSimulationModel", regionGarfield);
287
288 fGarfieldG4FastSimulationModel->WriteGeometryToGDML(fGasPV);
289
290 //
291 // Always return the physical World
292 //
293 return worldPV;
294}
295
296//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
297
299 G4String name, G4String symbol, G4double density, G4int Z, G4int A) {
300 // define a material from an isotope
301 //
302 G4int ncomponents;
303 G4double abundance, massfraction;
304
305 G4Isotope* isotope = new G4Isotope(symbol, Z, A);
306
307 G4Element* element = new G4Element(name, symbol, ncomponents = 1);
308 element->AddIsotope(isotope, abundance = 100. * perCent);
309
310 G4Material* material = new G4Material(name, density, ncomponents = 1);
311 material->AddElement(element, massfraction = 100. * perCent);
312
313 return material;
314}
315
316//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
317
319 G4String materialChoice) {
320 // search the material by its name
321 G4Material* newMaterial = G4NistManager::Instance()->FindOrBuildMaterial(
322 materialChoice);
323
324 if (newMaterial) {
325 if (fAbsorberMaterial != newMaterial) {
326 fAbsorberMaterial = newMaterial;
327 if (fAbsorberLV) {
328 fAbsorberLV->SetMaterial(fAbsorberMaterial);
329 }
330 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
331 }
332 } else {
333 G4cout
334 << "\n--> warning from GarfieldDetectorConstruction::SetMaterial : "
335 << materialChoice << " not found" << G4endl;
336 }
337}
338
339//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Definition of the GarfieldDetectorConstruction class.
Definition of the GarfieldMessenger class.
void SetAbsorberMaterial(G4String materialChoice)
G4Material * AbsorberMaterialWithSingleIsotope(G4String name, G4String symbol, G4double density, G4int Z, G4int A)
virtual G4VPhysicalVolume * Construct()
void WriteGeometryToGDML(G4VPhysicalVolume *physicalVolume)