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