File indexing completed on 2025-02-23 09:20:58
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 #include "DetectorConstruction.hh"
0034
0035 #include "DetectorMessenger.hh"
0036
0037 #include "G4Box.hh"
0038 #include "G4GeometryManager.hh"
0039 #include "G4LogicalVolume.hh"
0040 #include "G4LogicalVolumeStore.hh"
0041 #include "G4Material.hh"
0042 #include "G4NistManager.hh"
0043 #include "G4PVPlacement.hh"
0044 #include "G4PVReplica.hh"
0045 #include "G4PhysicalConstants.hh"
0046 #include "G4PhysicalVolumeStore.hh"
0047 #include "G4RunManager.hh"
0048 #include "G4SolidStore.hh"
0049 #include "G4SystemOfUnits.hh"
0050 #include "G4UnitsTable.hh"
0051
0052 #include <iomanip>
0053
0054
0055
0056 DetectorConstruction::DetectorConstruction()
0057 {
0058 for (G4int i = 0; i < kMaxAbsor; ++i) {
0059 fAbsorMaterial[i] = nullptr;
0060 fAbsorThickness[i] = 0.0;
0061 fSolidAbsor[i] = nullptr;
0062 fLogicAbsor[i] = nullptr;
0063 fPhysiAbsor[i] = nullptr;
0064 }
0065
0066
0067 fNbOfAbsor = 2;
0068 fAbsorThickness[1] = 2.3 * mm;
0069 fAbsorThickness[2] = 5.7 * mm;
0070 fNbOfLayers = 50;
0071 fCalorSizeYZ = 40. * cm;
0072 ComputeCalorParameters();
0073
0074
0075 DefineMaterials();
0076 SetWorldMaterial("Galactic");
0077 SetAbsorMaterial(1, "G4_Pb");
0078 SetAbsorMaterial(2, "G4_lAr");
0079
0080
0081 fDetectorMessenger = new DetectorMessenger(this);
0082 }
0083
0084
0085
0086 DetectorConstruction::~DetectorConstruction()
0087 {
0088 delete fDetectorMessenger;
0089 }
0090
0091
0092
0093 void DetectorConstruction::DefineMaterials()
0094 {
0095
0096
0097 G4NistManager* manager = G4NistManager::Instance();
0098 manager->SetVerbose(0);
0099
0100
0101
0102 G4double z, a;
0103
0104 G4Element* H = manager->FindOrBuildElement(1);
0105 G4Element* C = manager->FindOrBuildElement(6);
0106 G4Element* N = manager->FindOrBuildElement(7);
0107 G4Element* O = manager->FindOrBuildElement(8);
0108 G4Element* Si = manager->FindOrBuildElement(14);
0109 G4Element* Ge = manager->FindOrBuildElement(32);
0110 G4Element* Sb = manager->FindOrBuildElement(51);
0111 G4Element* I = manager->FindOrBuildElement(53);
0112 G4Element* Cs = manager->FindOrBuildElement(55);
0113 G4Element* Pb = manager->FindOrBuildElement(82);
0114 G4Element* Bi = manager->FindOrBuildElement(83);
0115
0116
0117
0118
0119 G4int iz, n;
0120
0121 G4int ncomponents;
0122 G4double abundance;
0123
0124 G4Isotope* U5 = new G4Isotope("U235", iz = 92, n = 235, a = 235.01 * g / mole);
0125 G4Isotope* U8 = new G4Isotope("U238", iz = 92, n = 238, a = 238.03 * g / mole);
0126
0127 G4Element* U = new G4Element("enriched Uranium", "U", ncomponents = 2);
0128 U->AddIsotope(U5, abundance = 90. * perCent);
0129 U->AddIsotope(U8, abundance = 10. * perCent);
0130
0131
0132
0133
0134 G4double density;
0135
0136 new G4Material("liquidH2", z = 1., a = 1.008 * g / mole, density = 70.8 * mg / cm3);
0137 new G4Material("Aluminium", z = 13., a = 26.98 * g / mole, density = 2.700 * g / cm3);
0138 new G4Material("Titanium", z = 22., a = 47.867 * g / mole, density = 4.54 * g / cm3);
0139 new G4Material("Iron", z = 26., a = 55.85 * g / mole, density = 7.870 * g / cm3);
0140 new G4Material("Copper", z = 29., a = 63.55 * g / mole, density = 8.960 * g / cm3);
0141 new G4Material("Tungsten", z = 74., a = 183.85 * g / mole, density = 19.30 * g / cm3);
0142 new G4Material("Gold", z = 79., a = 196.97 * g / mole, density = 19.32 * g / cm3);
0143 new G4Material("Uranium", z = 92., a = 238.03 * g / mole, density = 18.95 * g / cm3);
0144
0145
0146
0147
0148 G4int natoms;
0149
0150 G4Material* H2O = new G4Material("Water", density = 1.000 * g / cm3, ncomponents = 2);
0151 H2O->AddElement(H, natoms = 2);
0152 H2O->AddElement(O, natoms = 1);
0153 H2O->GetIonisation()->SetMeanExcitationEnergy(78.0 * eV);
0154 H2O->SetChemicalFormula("H_2O");
0155
0156 G4Material* CH = new G4Material("Polystyrene", density = 1.032 * g / cm3, ncomponents = 2);
0157 CH->AddElement(C, natoms = 1);
0158 CH->AddElement(H, natoms = 1);
0159
0160 G4Material* Sci = new G4Material("Scintillator", density = 1.032 * g / cm3, ncomponents = 2);
0161 Sci->AddElement(C, natoms = 9);
0162 Sci->AddElement(H, natoms = 10);
0163
0164 Sci->GetIonisation()->SetBirksConstant(0.126 * mm / MeV);
0165
0166 G4Material* Lct = new G4Material("Lucite", density = 1.185 * g / cm3, ncomponents = 3);
0167 Lct->AddElement(C, 59.97 * perCent);
0168 Lct->AddElement(H, 8.07 * perCent);
0169 Lct->AddElement(O, 31.96 * perCent);
0170
0171 G4Material* Sili = new G4Material("Silicon", density = 2.330 * g / cm3, ncomponents = 1);
0172 Sili->AddElement(Si, natoms = 1);
0173
0174 G4Material* SiO2 = new G4Material("quartz", density = 2.200 * g / cm3, ncomponents = 2);
0175 SiO2->AddElement(Si, natoms = 1);
0176 SiO2->AddElement(O, natoms = 2);
0177
0178 G4Material* G10 = new G4Material("NemaG10", density = 1.700 * g / cm3, ncomponents = 4);
0179 G10->AddElement(Si, natoms = 1);
0180 G10->AddElement(O, natoms = 2);
0181 G10->AddElement(C, natoms = 3);
0182 G10->AddElement(H, natoms = 3);
0183
0184 G4Material* CsI = new G4Material("CsI", density = 4.534 * g / cm3, ncomponents = 2);
0185 CsI->AddElement(Cs, natoms = 1);
0186 CsI->AddElement(I, natoms = 1);
0187 CsI->GetIonisation()->SetMeanExcitationEnergy(553.1 * eV);
0188
0189 G4Material* BGO = new G4Material("BGO", density = 7.10 * g / cm3, ncomponents = 3);
0190 BGO->AddElement(O, natoms = 12);
0191 BGO->AddElement(Ge, natoms = 3);
0192 BGO->AddElement(Bi, natoms = 4);
0193
0194
0195 density = 3.1 * g / cm3;
0196 G4Material* SiNx = new G4Material("SiNx", density, ncomponents = 3);
0197 SiNx->AddElement(Si, 300);
0198 SiNx->AddElement(N, 310);
0199 SiNx->AddElement(H, 6);
0200
0201
0202
0203
0204 G4double fractionmass;
0205
0206 G4Material* Air = manager->FindOrBuildMaterial("G4_AIR");
0207 manager->ConstructNewGasMaterial("Air20", "G4_AIR", 293. * kelvin, 1. * atmosphere);
0208
0209 G4Material* lAr = manager->FindOrBuildMaterial("G4_lAr");
0210 G4Material* lArEm3 = new G4Material("liquidArgon", density = 1.390 * g / cm3, ncomponents = 1);
0211 lArEm3->AddMaterial(lAr, fractionmass = 1.0);
0212
0213
0214
0215
0216
0217 G4Material* Lead = new G4Material("Lead", density = 11.35 * g / cm3, ncomponents = 1);
0218 Lead->AddElement(Pb, fractionmass = 1.0);
0219
0220 G4Material* LeadSb = new G4Material("LeadSb", density = 11.35 * g / cm3, ncomponents = 2);
0221 LeadSb->AddElement(Sb, fractionmass = 4. * perCent);
0222 LeadSb->AddElement(Pb, fractionmass = 96. * perCent);
0223
0224 G4Material* Aerog = new G4Material("Aerogel", density = 0.200 * g / cm3, ncomponents = 3);
0225 Aerog->AddMaterial(SiO2, fractionmass = 62.5 * perCent);
0226 Aerog->AddMaterial(H2O, fractionmass = 37.4 * perCent);
0227 Aerog->AddElement(C, fractionmass = 0.1 * perCent);
0228
0229
0230
0231
0232 G4double temperature, pressure;
0233
0234 G4Material* CO2 =
0235 new G4Material("CarbonicGas", density = 27. * mg / cm3, ncomponents = 2, kStateGas,
0236 temperature = 325. * kelvin, pressure = 50. * atmosphere);
0237 CO2->AddElement(C, natoms = 1);
0238 CO2->AddElement(O, natoms = 2);
0239
0240 G4Material* steam =
0241 new G4Material("WaterSteam", density = 1.0 * mg / cm3, ncomponents = 1, kStateGas,
0242 temperature = 273 * kelvin, pressure = 1 * atmosphere);
0243 steam->AddMaterial(H2O, fractionmass = 1.);
0244
0245 new G4Material("ArgonGas", z = 18, a = 39.948 * g / mole, density = 1.782 * mg / cm3, kStateGas,
0246 273.15 * kelvin, 1 * atmosphere);
0247
0248
0249
0250
0251 density = universe_mean_density;
0252 pressure = 3.e-18 * pascal;
0253 temperature = 2.73 * kelvin;
0254 new G4Material("Galactic", z = 1., a = 1.008 * g / mole, density, kStateGas, temperature,
0255 pressure);
0256
0257 density = 1.e-5 * g / cm3;
0258 pressure = 2.e-2 * bar;
0259 temperature = STP_Temperature;
0260 G4Material* beam =
0261 new G4Material("Beam", density, ncomponents = 1, kStateGas, temperature, pressure);
0262 beam->AddMaterial(Air, fractionmass = 1.);
0263
0264
0265 }
0266
0267
0268
0269 void DetectorConstruction::ComputeCalorParameters()
0270 {
0271
0272 fLayerThickness = 0.;
0273 for (G4int iAbs = 1; iAbs <= fNbOfAbsor; iAbs++) {
0274 fLayerThickness += fAbsorThickness[iAbs];
0275 }
0276 fCalorThickness = fNbOfLayers * fLayerThickness;
0277 fWorldSizeX = 1.2 * fCalorThickness;
0278 fWorldSizeYZ = 1.2 * fCalorSizeYZ;
0279 }
0280
0281
0282
0283 G4VPhysicalVolume* DetectorConstruction::Construct()
0284 {
0285 if (fPhysiWorld) {
0286 return fPhysiWorld;
0287 }
0288
0289 ComputeCalorParameters();
0290
0291
0292
0293
0294 fSolidWorld = new G4Box("World",
0295 fWorldSizeX / 2, fWorldSizeYZ / 2, fWorldSizeYZ / 2);
0296
0297 fLogicWorld = new G4LogicalVolume(fSolidWorld,
0298 fWorldMaterial,
0299 "World");
0300
0301 fPhysiWorld = new G4PVPlacement(0,
0302 G4ThreeVector(),
0303 fLogicWorld,
0304 "World",
0305 0,
0306 false,
0307 0);
0308
0309
0310
0311
0312 fSolidCalor = new G4Box("Calorimeter", fCalorThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2);
0313
0314 fLogicCalor = new G4LogicalVolume(fSolidCalor, fWorldMaterial, "Calorimeter");
0315
0316 fPhysiCalor = new G4PVPlacement(0,
0317 G4ThreeVector(),
0318 fLogicCalor,
0319 "Calorimeter",
0320 fLogicWorld,
0321 false,
0322 0);
0323
0324
0325
0326
0327
0328 fSolidLayer = new G4Box("Layer", fLayerThickness / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2);
0329
0330 fLogicLayer = new G4LogicalVolume(fSolidLayer, fWorldMaterial, "Layer");
0331 if (fNbOfLayers > 1) {
0332 fPhysiLayer =
0333 new G4PVReplica("Layer", fLogicLayer, fLogicCalor, kXAxis, fNbOfLayers, fLayerThickness);
0334 }
0335 else {
0336 fPhysiLayer =
0337 new G4PVPlacement(0, G4ThreeVector(), fLogicLayer, "Layer", fLogicCalor, false, 0);
0338 }
0339
0340
0341
0342
0343 G4double xfront = -0.5 * fLayerThickness;
0344 for (G4int k = 1; k <= fNbOfAbsor; ++k) {
0345 fSolidAbsor[k] = new G4Box("Absorber",
0346 fAbsorThickness[k] / 2, fCalorSizeYZ / 2, fCalorSizeYZ / 2);
0347
0348 fLogicAbsor[k] = new G4LogicalVolume(fSolidAbsor[k],
0349 fAbsorMaterial[k],
0350 fAbsorMaterial[k]->GetName());
0351
0352 G4double xcenter = xfront + 0.5 * fAbsorThickness[k];
0353 xfront += fAbsorThickness[k];
0354 fPhysiAbsor[k] = new G4PVPlacement(0, G4ThreeVector(xcenter, 0., 0.), fLogicAbsor[k],
0355 fAbsorMaterial[k]->GetName(), fLogicLayer, false,
0356 k);
0357 }
0358
0359 PrintCalorParameters();
0360
0361
0362
0363 return fPhysiWorld;
0364 }
0365
0366
0367
0368 void DetectorConstruction::PrintCalorParameters()
0369 {
0370 G4cout << "\n-------------------------------------------------------------"
0371 << "\n ---> The calorimeter is " << fNbOfLayers << " layers of:";
0372 for (G4int i = 1; i <= fNbOfAbsor; ++i) {
0373 G4cout << "\n \t" << std::setw(12) << fAbsorMaterial[i]->GetName() << ": " << std::setw(6)
0374 << G4BestUnit(fAbsorThickness[i], "Length");
0375 }
0376 G4cout << "\n-------------------------------------------------------------\n";
0377
0378 G4cout << "\n" << fWorldMaterial << G4endl;
0379 for (G4int j = 1; j <= fNbOfAbsor; ++j) {
0380 G4cout << "\n" << fAbsorMaterial[j] << G4endl;
0381 }
0382 G4cout << "\n-------------------------------------------------------------\n";
0383 }
0384
0385
0386
0387 void DetectorConstruction::SetWorldMaterial(const G4String& material)
0388 {
0389
0390 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(material);
0391 if (pttoMaterial) {
0392 fWorldMaterial = pttoMaterial;
0393 if (fLogicWorld) {
0394 fLogicWorld->SetMaterial(fWorldMaterial);
0395 fLogicLayer->SetMaterial(fWorldMaterial);
0396 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0397 }
0398 }
0399 }
0400
0401
0402
0403 void DetectorConstruction::SetNbOfLayers(G4int ival)
0404 {
0405
0406
0407 if (ival < 1) {
0408 G4cout << "\n --->warning from SetfNbOfLayers: " << ival
0409 << " must be at least 1. Command refused" << G4endl;
0410 return;
0411 }
0412 fNbOfLayers = ival;
0413 }
0414
0415
0416
0417 void DetectorConstruction::SetNbOfAbsor(G4int ival)
0418 {
0419
0420
0421 if (ival < 1 || ival > (kMaxAbsor - 1)) {
0422 G4cout << "\n ---> warning from SetfNbOfAbsor: " << ival << " must be at least 1 and and most "
0423 << kMaxAbsor - 1 << ". Command refused" << G4endl;
0424 return;
0425 }
0426 fNbOfAbsor = ival;
0427 }
0428
0429
0430
0431 void DetectorConstruction::SetAbsorMaterial(G4int ival, const G4String& material)
0432 {
0433
0434
0435 if (ival > fNbOfAbsor || ival <= 0) {
0436 G4cout << "\n --->warning from SetAbsorMaterial: absor number " << ival
0437 << " out of range. Command refused" << G4endl;
0438 return;
0439 }
0440
0441 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(material);
0442 if (pttoMaterial) {
0443 fAbsorMaterial[ival] = pttoMaterial;
0444 if (fLogicAbsor[ival]) {
0445 fLogicAbsor[ival]->SetMaterial(pttoMaterial);
0446 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0447 }
0448 }
0449 }
0450
0451
0452
0453 void DetectorConstruction::SetAbsorThickness(G4int ival, G4double val)
0454 {
0455
0456
0457 if (ival > fNbOfAbsor || ival <= 0) {
0458 G4cout << "\n --->warning from SetAbsorThickness: absor number " << ival
0459 << " out of range. Command refused" << G4endl;
0460 return;
0461 }
0462 if (val <= DBL_MIN) {
0463 G4cout << "\n --->warning from SetAbsorThickness: thickness " << val
0464 << " out of range. Command refused" << G4endl;
0465 return;
0466 }
0467 fAbsorThickness[ival] = val;
0468 }
0469
0470
0471
0472 void DetectorConstruction::SetCalorSizeYZ(G4double val)
0473 {
0474
0475
0476 if (val <= DBL_MIN) {
0477 G4cout << "\n --->warning from SetfCalorSizeYZ: thickness " << val
0478 << " out of range. Command refused" << G4endl;
0479 return;
0480 }
0481 fCalorSizeYZ = val;
0482 }
0483
0484
0485
0486 #include "G4AutoDelete.hh"
0487 #include "G4GlobalMagFieldMessenger.hh"
0488
0489 void DetectorConstruction::ConstructSDandField()
0490 {
0491 if (fFieldMessenger.Get() == nullptr) {
0492
0493
0494
0495 G4ThreeVector fieldValue = G4ThreeVector();
0496 G4GlobalMagFieldMessenger* msg = new G4GlobalMagFieldMessenger(fieldValue);
0497
0498 G4AutoDelete::Register(msg);
0499 fFieldMessenger.Put(msg);
0500 }
0501 }
0502
0503