File indexing completed on 2025-02-23 09:21:17
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 "F03DetectorConstruction.hh"
0036
0037 #include "F03CalorimeterSD.hh"
0038 #include "F03DetectorMessenger.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 F03DetectorConstruction::F03DetectorConstruction()
0059 {
0060 fDetectorMessenger = new F03DetectorMessenger(this);
0061
0062
0063
0064 G4FieldBuilder::Instance();
0065
0066
0067 auto globalFieldParameters = G4FieldBuilder::Instance()->GetFieldParameters();
0068 auto localFieldParameters = G4FieldBuilder::Instance()->CreateFieldParameters("Radiator");
0069
0070
0071 globalFieldParameters->SetMinimumStep(0.25 * mm);
0072 localFieldParameters->SetMinimumStep(0.25 * mm);
0073
0074
0075 DefineMaterials();
0076 }
0077
0078
0079
0080 F03DetectorConstruction::~F03DetectorConstruction()
0081 {
0082 delete fDetectorMessenger;
0083 }
0084
0085
0086
0087 G4VPhysicalVolume* F03DetectorConstruction::Construct()
0088 {
0089 return ConstructCalorimeter();
0090 }
0091
0092
0093
0094 void F03DetectorConstruction::DefineMaterials()
0095 {
0096
0097
0098 G4String name, symbol;
0099 G4double a, z, density;
0100 G4int nel;
0101 G4int ncomponents;
0102 G4double fractionmass, pressure, temperature;
0103
0104
0105
0106
0107
0108 a = 1.01 * g / mole;
0109 auto elH = new G4Element(name = "Hydrogen", symbol = "H", z = 1., a);
0110
0111 a = 12.01 * g / mole;
0112 auto elC = new G4Element(name = "Carbon", symbol = "C", z = 6., a);
0113
0114 a = 14.01 * g / mole;
0115 auto elN = new G4Element(name = "Nitrogen", symbol = "N", z = 7., a);
0116
0117 a = 16.00 * g / mole;
0118 auto elO = new G4Element(name = "Oxygen", symbol = "O", z = 8., a);
0119
0120 a = 39.948 * g / mole;
0121 auto elAr = new G4Element(name = "Argon", symbol = "Ar", z = 18., a);
0122
0123
0124
0125
0126
0127
0128
0129 density = 1.39 * g / cm3;
0130 auto mylar = new G4Material(name = "Mylar", density, nel = 3);
0131 mylar->AddElement(elO, 2);
0132 mylar->AddElement(elC, 5);
0133 mylar->AddElement(elH, 4);
0134
0135
0136
0137 auto CH2 = new G4Material("Polypropelene", 0.91 * g / cm3, 2);
0138 CH2->AddElement(elH, 2);
0139 CH2->AddElement(elC, 1);
0140
0141
0142
0143 density = 3.700 * mg / cm3;
0144 a = 83.80 * g / mole;
0145 auto Kr = new G4Material(name = "Kr", z = 36., a, density);
0146
0147
0148
0149 density = 1.7836 * mg / cm3;
0150 auto argon = new G4Material(name = "Argon", density, ncomponents = 1);
0151 argon->AddElement(elAr, 1);
0152
0153 density = 1.25053 * mg / cm3;
0154 auto nitrogen = new G4Material(name = "N2", density, ncomponents = 1);
0155 nitrogen->AddElement(elN, 2);
0156
0157 density = 1.4289 * mg / cm3;
0158 auto oxygen = new G4Material(name = "O2", density, ncomponents = 1);
0159 oxygen->AddElement(elO, 2);
0160
0161 density = 1.2928 * mg / cm3;
0162 density *= 1.0e-8;
0163 temperature = STP_Temperature;
0164 pressure = 1.0e-8 * STP_Pressure;
0165
0166 auto air =
0167 new G4Material(name = "Air", density, ncomponents = 3, kStateGas, temperature, pressure);
0168 air->AddMaterial(nitrogen, fractionmass = 0.7557);
0169 air->AddMaterial(oxygen, fractionmass = 0.2315);
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 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0200
0201
0202
0203 fRadiatorMat = air;
0204
0205 fAbsorberMaterial = air;
0206
0207 fWorldMaterial = air;
0208 }
0209
0210
0211
0212 G4VPhysicalVolume* F03DetectorConstruction::ConstructCalorimeter()
0213 {
0214
0215
0216 if (fPhysiWorld) {
0217 G4GeometryManager::GetInstance()->OpenGeometry();
0218 G4PhysicalVolumeStore::GetInstance()->Clean();
0219 G4LogicalVolumeStore::GetInstance()->Clean();
0220 G4SolidStore::GetInstance()->Clean();
0221 }
0222
0223
0224
0225 ComputeCalorParameters();
0226 PrintCalorParameters();
0227
0228 G4bool checkOverlaps = true;
0229
0230 fSolidWorld = new G4Tubs("World",
0231 0., fWorldSizeR, fWorldSizeZ / 2., 0., twopi);
0232
0233 fLogicWorld = new G4LogicalVolume(fSolidWorld,
0234 fWorldMaterial,
0235 "World");
0236
0237 fPhysiWorld = new G4PVPlacement(nullptr,
0238 G4ThreeVector(),
0239 "World",
0240 fLogicWorld,
0241 nullptr,
0242 false,
0243 0,
0244 checkOverlaps);
0245
0246
0247 G4double radThick = fFoilNumber * (fRadThickness + fGasGap) + fDetGap;
0248 G4double zRad = fZAbsorber - 0.5 * (radThick + fAbsorberThickness);
0249
0250 G4cout << "zRad = " << zRad / mm << " mm" << G4endl;
0251 G4cout << "radThick = " << radThick / mm << " mm" << G4endl;
0252 G4cout << "fFoilNumber = " << fFoilNumber << G4endl;
0253 G4cout << "fRadiatorMat = " << fRadiatorMat->GetName() << G4endl;
0254 G4cout << "WorldMaterial = " << fWorldMaterial->GetName() << G4endl;
0255
0256 fSolidRadiator = new G4Tubs("Radiator", 0.0, fAbsorberRadius, 0.5 * radThick, 0.0, twopi);
0257
0258 fLogicRadiator = new G4LogicalVolume(fSolidRadiator, fWorldMaterial, "Radiator");
0259
0260 fPhysiRadiator = new G4PVPlacement(nullptr, G4ThreeVector(0, 0, zRad), "Radiator", fLogicRadiator,
0261 fPhysiWorld, false, 0, checkOverlaps);
0262
0263 fSolidRadSlice = new G4Tubs("RadSlice", 0.0, fAbsorberRadius, 0.5 * fRadThickness, 0.0, twopi);
0264
0265 fLogicRadSlice = new G4LogicalVolume(fSolidRadSlice, fRadiatorMat, "RadSlice");
0266
0267
0268 G4double radSliceThick = fRadThickness + fGasGap;
0269 G4double zStart = 0.5 * (-radThick + radSliceThick) + fDetGap;
0270
0271
0272 for (G4int j = 0; j < fFoilNumber; j++) {
0273 G4double zSlice = zStart + j * radSliceThick;
0274 G4cout << zSlice / mm << " mm"
0275 << "\t";
0276
0277 fPhysiRadSlice = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., zSlice), "RadSlice",
0278 fLogicRadSlice, fPhysiRadiator, false, j, checkOverlaps);
0279 }
0280 G4cout << G4endl;
0281
0282
0283
0284 fSolidAbsorber =
0285 new G4Tubs("Absorber", 1.0 * mm, fAbsorberRadius, fAbsorberThickness / 2., 0.0, twopi);
0286
0287 fLogicAbsorber = new G4LogicalVolume(fSolidAbsorber, fAbsorberMaterial, "Absorber");
0288
0289 fPhysiAbsorber = new G4PVPlacement(nullptr, G4ThreeVector(0., 0., fZAbsorber), "Absorber",
0290 fLogicAbsorber, fPhysiWorld, false, 0, checkOverlaps);
0291
0292 return fPhysiWorld;
0293 }
0294
0295
0296
0297 void F03DetectorConstruction::PrintCalorParameters()
0298 {
0299 G4cout << "\n The WORLD is made of " << fWorldSizeZ / mm << "mm of "
0300 << fWorldMaterial->GetName();
0301 G4cout << ", the transverse size (R) of the world is " << fWorldSizeR / mm << " mm. " << G4endl;
0302 G4cout << " The ABSORBER is made of " << fAbsorberThickness / mm << "mm of "
0303 << fAbsorberMaterial->GetName();
0304 G4cout << ", the transverse size (R) is " << fAbsorberRadius / mm << " mm. " << G4endl;
0305 G4cout << " Z position of the (middle of the) absorber " << fZAbsorber / mm << " mm." << G4endl;
0306 G4cout << G4endl;
0307 }
0308
0309
0310
0311 void F03DetectorConstruction::SetAbsorberMaterial(G4String materialChoice)
0312 {
0313
0314 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0315
0316
0317 G4Material* material;
0318 for (size_t j = 0; j < theMaterialTable->size(); j++) {
0319 material = (*theMaterialTable)[j];
0320 if (material->GetName() == materialChoice) {
0321 fAbsorberMaterial = material;
0322 fLogicAbsorber->SetMaterial(material);
0323 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0324 }
0325 }
0326 }
0327
0328
0329
0330 void F03DetectorConstruction::SetWorldMaterial(G4String materialChoice)
0331 {
0332
0333 const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
0334
0335
0336 G4Material* material;
0337 for (size_t j = 0; j < theMaterialTable->size(); j++) {
0338 material = (*theMaterialTable)[j];
0339 if (material->GetName() == materialChoice) {
0340 fWorldMaterial = material;
0341 fLogicWorld->SetMaterial(material);
0342 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0343 }
0344 }
0345 }
0346
0347
0348
0349 void F03DetectorConstruction::SetAbsorberThickness(G4double val)
0350 {
0351
0352 fAbsorberThickness = val;
0353 ComputeCalorParameters();
0354 G4RunManager::GetRunManager()->ReinitializeGeometry();
0355 }
0356
0357
0358
0359 void F03DetectorConstruction::SetAbsorberRadius(G4double val)
0360 {
0361
0362 fAbsorberRadius = val;
0363 ComputeCalorParameters();
0364 G4RunManager::GetRunManager()->ReinitializeGeometry();
0365 }
0366
0367
0368
0369 void F03DetectorConstruction::SetWorldSizeZ(G4double val)
0370 {
0371 fWorldSizeZ = val;
0372 ComputeCalorParameters();
0373 G4RunManager::GetRunManager()->ReinitializeGeometry();
0374 }
0375
0376
0377
0378 void F03DetectorConstruction::SetWorldSizeR(G4double val)
0379 {
0380 fWorldSizeR = val;
0381 ComputeCalorParameters();
0382 G4RunManager::GetRunManager()->ReinitializeGeometry();
0383 }
0384
0385
0386
0387 void F03DetectorConstruction::SetAbsorberZpos(G4double val)
0388 {
0389 fZAbsorber = val;
0390 ComputeCalorParameters();
0391 G4RunManager::GetRunManager()->ReinitializeGeometry();
0392 }
0393
0394
0395
0396 void F03DetectorConstruction::SetFieldValue(G4ThreeVector value)
0397 {
0398 fFieldVector = value;
0399
0400 G4UniformMagField* magField = nullptr;
0401 if (fFieldVector != G4ThreeVector(0.,0.,0.)) {
0402 magField = new G4UniformMagField(fFieldVector);
0403 }
0404
0405
0406 auto fieldBuilder = G4FieldBuilder::Instance();
0407 fieldBuilder->SetGlobalField(magField);
0408 }
0409
0410
0411
0412
0413 void F03DetectorConstruction::SetLocalFieldValue(G4ThreeVector value)
0414 {
0415 fLocalFieldVector = value;
0416
0417 G4UniformMagField* magField = nullptr;
0418 if (fLocalFieldVector != G4ThreeVector(0.,0.,0.)) {
0419 magField = new G4UniformMagField(fLocalFieldVector);
0420 }
0421
0422
0423 auto fieldBuilder = G4FieldBuilder::Instance();
0424 fieldBuilder->SetLocalField(magField, fLogicRadiator);
0425 }
0426
0427
0428
0429 void F03DetectorConstruction::ConstructSDandField()
0430 {
0431
0432
0433 if (!fCalorimeterSD.Get()) {
0434 auto calorimeterSD = new F03CalorimeterSD("CalorSD", this);
0435 fCalorimeterSD.Put(calorimeterSD);
0436 }
0437 G4SDManager::GetSDMpointer()->AddNewDetector(fCalorimeterSD.Get());
0438 SetSensitiveDetector(fLogicAbsorber, fCalorimeterSD.Get());
0439
0440
0441 SetFieldValue(fFieldVector);
0442 SetLocalFieldValue(fLocalFieldVector);
0443
0444
0445 auto fieldBuilder = G4FieldBuilder::Instance();
0446 fieldBuilder->ConstructFieldSetup();
0447 }
0448
0449