File indexing completed on 2025-02-23 09:21:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 #include "F01DetectorConstruction.hh"
0036
0037 #include "F01CalorimeterSD.hh"
0038 #include "F01DetectorMessenger.hh"
0039
0040 #include "G4AutoDelete.hh"
0041 #include "G4GeometryManager.hh"
0042 #include "G4FieldBuilder.hh"
0043 #include "G4LogicalVolume.hh"
0044 #include "G4LogicalVolumeStore.hh"
0045 #include "G4Material.hh"
0046 #include "G4PVPlacement.hh"
0047 #include "G4PhysicalConstants.hh"
0048 #include "G4PhysicalVolumeStore.hh"
0049 #include "G4RunManager.hh"
0050 #include "G4SDManager.hh"
0051 #include "G4SolidStore.hh"
0052 #include "G4SystemOfUnits.hh"
0053 #include "G4Tubs.hh"
0054 #include "G4UniformMagField.hh"
0055
0056
0057
0058 F01DetectorConstruction::F01DetectorConstruction()
0059 {
0060
0061
0062 G4cout << "F01DetectorConstruction::F01DetectorConstruction()" << G4endl;
0063
0064 fDetectorMessenger = new F01DetectorMessenger(this);
0065
0066
0067
0068 G4FieldBuilder::Instance();
0069
0070
0071
0072
0073 DefineMaterials();
0074 }
0075
0076
0077
0078 F01DetectorConstruction::~F01DetectorConstruction()
0079 {
0080
0081 }
0082
0083
0084
0085 G4VPhysicalVolume* F01DetectorConstruction::Construct()
0086 {
0087 return ConstructCalorimeter();
0088 }
0089
0090
0091
0092 void F01DetectorConstruction::DefineMaterials()
0093 {
0094
0095
0096 G4String name, symbol;
0097 G4double a, z, density;
0098 G4int nel;
0099 G4int ncomponents;
0100 G4double fractionmass, pressure, temperature;
0101
0102
0103
0104
0105
0106 a = 1.01 * g / mole;
0107 auto elH = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a);
0108
0109 a = 12.01 * g / mole;
0110 auto elC = new G4Element(name = "Carbon", symbol = "C", z = 6., a);
0111
0112 a = 14.01 * g / mole;
0113 auto elN = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a);
0114
0115 a = 16.00 * g / mole;
0116 auto elO = new G4Element(name = "Oxygen", symbol = "O", z = 8., a);
0117
0118 a = 39.948 * g / mole;
0119 auto elAr = new G4Element(name = "Argon", symbol = "Ar", z = 18., a);
0120
0121
0122
0123
0124
0125
0126
0127 density = 1.39 * g / cm3;
0128 auto mylar = new G4Material(name = "Mylar", density, nel = 3);
0129 mylar->AddElement(elO, 2);
0130 mylar->AddElement(elC, 5);
0131 mylar->AddElement(elH, 4);
0132
0133
0134
0135 auto CH2 = new G4Material("Polypropelene", 0.91 * g / cm3, 2);
0136 CH2->AddElement(elH, 2);
0137 CH2->AddElement(elC, 1);
0138
0139
0140
0141 density = 3.700 * mg / cm3;
0142 a = 83.80 * g / mole;
0143 auto Kr = new G4Material(name = "Kr", z = 36., a, density);
0144
0145
0146
0147 density = 1.7836 * mg / cm3;
0148 auto argon = new G4Material(name = "Argon", density, ncomponents = 1);
0149 argon->AddElement(elAr, 1);
0150
0151 density = 1.25053 * mg / cm3;
0152 auto nitrogen = new G4Material(name = "N2", density, ncomponents = 1);
0153 nitrogen->AddElement(elN, 2);
0154
0155 density = 1.4289 * mg / cm3;
0156 auto oxygen = new G4Material(name = "O2", density, ncomponents = 1);
0157 oxygen->AddElement(elO, 2);
0158
0159 density = 1.2928 * mg / cm3;
0160 density *= 1.0e-8;
0161
0162 temperature = STP_Temperature;
0163 pressure = 1.0e-8 * STP_Pressure;
0164
0165 auto air =
0166 new G4Material(name = "Air", density, ncomponents = 3, kStateGas, temperature, pressure);
0167 air->AddMaterial(nitrogen, fractionmass = 0.7557);
0168 air->AddMaterial(oxygen, fractionmass = 0.2315);
0169
0170 air->AddMaterial(argon, fractionmass = 0.0128);
0171
0172
0173
0174 density = 5.858 * mg / cm3;
0175 a = 131.29 * g / mole;
0176 auto Xe = new G4Material(name = "Xenon", z = 54., a, density);
0177
0178
0179
0180 density = 1.842 * mg / cm3;
0181 auto CarbonDioxide = new G4Material(name = "CO2", density, nel = 2);
0182 CarbonDioxide->AddElement(elC, 1);
0183 CarbonDioxide->AddElement(elO, 2);
0184
0185
0186
0187 density = 5.0818 * mg / cm3;
0188 auto Xe20CO2 = new G4Material(name = "Xe20CO2", density, ncomponents = 2);
0189 Xe20CO2->AddMaterial(Xe, fractionmass = 0.922);
0190 Xe20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.078);
0191
0192
0193
0194 density = 3.601 * mg / cm3;
0195 auto Kr20CO2 = new G4Material(name = "Kr20CO2", density, ncomponents = 2);
0196 Kr20CO2->AddMaterial(Kr, fractionmass = 0.89);
0197 Kr20CO2->AddMaterial(CarbonDioxide, fractionmass = 0.11);
0198
0199
0200
0201 G4cout << "F01DetectorConstruction: not printing material table - to see it edit the source."
0202 << G4endl;
0203
0204
0205
0206 fAbsorberMaterial = air;
0207
0208 fWorldMaterial = air;
0209 }
0210
0211
0212
0213 G4VPhysicalVolume* F01DetectorConstruction::ConstructCalorimeter()
0214 {
0215
0216
0217 if (fPhysiWorld) {
0218 G4GeometryManager::GetInstance()->OpenGeometry();
0219 G4PhysicalVolumeStore::GetInstance()->Clean();
0220 G4LogicalVolumeStore::GetInstance()->Clean();
0221 G4SolidStore::GetInstance()->Clean();
0222 }
0223
0224
0225
0226 ComputeCalorParameters();
0227 PrintCalorParameters();
0228
0229
0230
0231 fSolidWorld = new G4Tubs("World",
0232 0., fWorldSizeR, fWorldSizeZ / 2., 0., twopi);
0233
0234 fLogicWorld = new G4LogicalVolume(fSolidWorld,
0235 fWorldMaterial,
0236 "World");
0237
0238 fPhysiWorld = new G4PVPlacement(nullptr,
0239 G4ThreeVector(),
0240 "World",
0241 fLogicWorld,
0242 nullptr,
0243 false,
0244 0);
0245
0246
0247 fSolidAbsorber =
0248 new G4Tubs("Absorber", 1.0 * mm, fAbsorberRadius, fAbsorberThickness / 2., 0.0, twopi);
0249
0250 fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, fAbsorberMaterial, "Absorber");
0251
0252 fPhysiAbsorber = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fZAbsorber), "Absorber",
0253 fLogicAbsorber, fPhysiWorld, false, 0);
0254
0255 return fPhysiWorld;
0256 }
0257
0258
0259
0260 void F01DetectorConstruction::PrintCalorParameters()
0261 {
0262 G4cout << "\n The WORLD is made of " << fWorldSizeZ / mm << "mm of "
0263 << fWorldMaterial->GetName();
0264 G4cout << ", the transverse size (R) of the world is " << fWorldSizeR / mm << " mm. " << G4endl;
0265 G4cout << " The ABSORBER is made of " << fAbsorberThickness / mm << "mm of "
0266 << fAbsorberMaterial->GetName();
0267 G4cout << ", the transverse size (R) is " << fAbsorberRadius / mm << " mm. " << G4endl;
0268 G4cout << " Z position of the (middle of the) absorber " << fZAbsorber / mm << " mm." << G4endl;
0269 G4cout << G4endl;
0270 }
0271
0272
0273
0274 void F01DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
0275 {
0276
0277 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0278
0279
0280 G4Material* material;
0281 for (size_t j = 0; j < theMaterialTable->size(); j++) {
0282 material = (*theMaterialTable)[j];
0283 if (material->GetName() == materialChoice) {
0284 fAbsorberMaterial = material;
0285 fLogicAbsorber->SetMaterial(material);
0286 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0287 }
0288 }
0289 }
0290
0291
0292
0293 void F01DetectorConstruction::SetWorldMaterial(G4String materialChoice)
0294 {
0295
0296 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0297
0298
0299 G4Material* material;
0300 for (size_t j = 0; j < theMaterialTable->size(); j++) {
0301 material = (*theMaterialTable)[j];
0302 if (material->GetName() == materialChoice) {
0303 fWorldMaterial = material;
0304 fLogicWorld->SetMaterial(material);
0305 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0306 }
0307 }
0308 }
0309
0310
0311
0312 void F01DetectorConstruction::SetAbsorberThickness(G4double val)
0313 {
0314
0315 fAbsorberThickness = val;
0316 ComputeCalorParameters();
0317 G4RunManager::GetRunManager()->ReinitializeGeometry();
0318 }
0319
0320
0321
0322 void F01DetectorConstruction::SetAbsorberRadius(G4double val)
0323 {
0324
0325 fAbsorberRadius = val;
0326 ComputeCalorParameters();
0327 G4RunManager::GetRunManager()->ReinitializeGeometry();
0328 }
0329
0330
0331
0332 void F01DetectorConstruction::SetWorldSizeZ(G4double val)
0333 {
0334 fWorldSizeZ = val;
0335 ComputeCalorParameters();
0336 G4RunManager::GetRunManager()->ReinitializeGeometry();
0337 }
0338
0339
0340
0341 void F01DetectorConstruction::SetWorldSizeR(G4double val)
0342 {
0343 fWorldSizeR = val;
0344 ComputeCalorParameters();
0345 G4RunManager::GetRunManager()->ReinitializeGeometry();
0346 }
0347
0348
0349
0350 void F01DetectorConstruction::SetAbsorberZpos(G4double val)
0351 {
0352 fZAbsorber = val;
0353 ComputeCalorParameters();
0354 G4RunManager::GetRunManager()->ReinitializeGeometry();
0355 }
0356
0357
0358
0359 void F01DetectorConstruction::SetFieldValue(G4ThreeVector value)
0360 {
0361 fFieldVector = value;
0362
0363 G4UniformMagField* magField = nullptr;
0364 if (fFieldVector != G4ThreeVector(0.,0.,0.)) {
0365 magField = new G4UniformMagField(fFieldVector);
0366 }
0367
0368
0369 auto fieldBuilder = G4FieldBuilder::Instance();
0370 fieldBuilder->SetGlobalField(magField);
0371 }
0372
0373
0374 #include "G4FieldManager.hh"
0375
0376 void F01DetectorConstruction::ConstructSDandField()
0377 {
0378
0379
0380 if (!fCalorimeterSD.Get()) {
0381 auto calorimeterSD = new F01CalorimeterSD("CalorSD", this);
0382 fCalorimeterSD.Put(calorimeterSD);
0383 }
0384 G4SDManager::GetSDMpointer()->AddNewDetector(fCalorimeterSD.Get());
0385 SetSensitiveDetector(fLogicAbsorber, fCalorimeterSD.Get());
0386
0387
0388 SetFieldValue(fFieldVector);
0389
0390
0391 auto fieldBuilder = G4FieldBuilder::Instance();
0392 fieldBuilder->ConstructFieldSetup();
0393 }
0394
0395