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