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