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