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