File indexing completed on 2025-01-18 09:17:15
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 #include "DetectorConstruction.hh"
0031
0032 #include "G4AutoDelete.hh"
0033 #include "G4Box.hh"
0034 #include "G4Colour.hh"
0035 #include "G4GlobalMagFieldMessenger.hh"
0036 #include "G4LogicalVolume.hh"
0037 #include "G4Material.hh"
0038 #include "G4NistManager.hh"
0039 #include "G4PVPlacement.hh"
0040 #include "G4PVReplica.hh"
0041 #include "G4PhysicalConstants.hh"
0042 #include "G4SystemOfUnits.hh"
0043 #include "G4VisAttributes.hh"
0044
0045 namespace B4
0046 {
0047
0048
0049
0050 G4ThreadLocal G4GlobalMagFieldMessenger* DetectorConstruction::fMagFieldMessenger = nullptr;
0051
0052
0053
0054 G4VPhysicalVolume* DetectorConstruction::Construct()
0055 {
0056
0057 DefineMaterials();
0058
0059
0060 return DefineVolumes();
0061 }
0062
0063
0064
0065 void DetectorConstruction::DefineMaterials()
0066 {
0067
0068 auto nistManager = G4NistManager::Instance();
0069 nistManager->FindOrBuildMaterial("G4_Pb");
0070
0071
0072 G4double a;
0073 G4double z;
0074 G4double density;
0075 new G4Material("liquidArgon", z = 18., a = 39.95 * g / mole, density = 1.390 * g / cm3);
0076
0077
0078
0079 new G4Material("Galactic", z = 1., a = 1.01 * g / mole, density = universe_mean_density,
0080 kStateGas, 2.73 * kelvin, 3.e-18 * pascal);
0081
0082
0083 G4cout << *(G4Material::GetMaterialTable()) << G4endl;
0084 }
0085
0086
0087
0088 G4VPhysicalVolume* DetectorConstruction::DefineVolumes()
0089 {
0090
0091 G4int nofLayers = 10;
0092 G4double absoThickness = 10. * mm;
0093 G4double gapThickness = 5. * mm;
0094 G4double calorSizeXY = 10. * cm;
0095
0096 auto layerThickness = absoThickness + gapThickness;
0097 auto calorThickness = nofLayers * layerThickness;
0098 auto worldSizeXY = 1.2 * calorSizeXY;
0099 auto worldSizeZ = 1.2 * calorThickness;
0100
0101
0102 auto defaultMaterial = G4Material::GetMaterial("Galactic");
0103 auto absorberMaterial = G4Material::GetMaterial("G4_Pb");
0104 auto gapMaterial = G4Material::GetMaterial("liquidArgon");
0105
0106 if (!defaultMaterial || !absorberMaterial || !gapMaterial) {
0107 G4ExceptionDescription msg;
0108 msg << "Cannot retrieve materials already defined.";
0109 G4Exception("DetectorConstruction::DefineVolumes()", "MyCode0001", FatalException, msg);
0110 }
0111
0112
0113
0114
0115 auto worldS = new G4Box("World",
0116 worldSizeXY / 2, worldSizeXY / 2, worldSizeZ / 2);
0117
0118 auto worldLV = new G4LogicalVolume(worldS,
0119 defaultMaterial,
0120 "World");
0121
0122 auto worldPV = new G4PVPlacement(nullptr,
0123 G4ThreeVector(),
0124 worldLV,
0125 "World",
0126 nullptr,
0127 false,
0128 0,
0129 fCheckOverlaps);
0130
0131
0132
0133
0134 auto calorimeterS = new G4Box("Calorimeter",
0135 calorSizeXY / 2, calorSizeXY / 2, calorThickness / 2);
0136
0137 auto calorLV = new G4LogicalVolume(calorimeterS,
0138 defaultMaterial,
0139 "Calorimeter");
0140
0141 new G4PVPlacement(nullptr,
0142 G4ThreeVector(),
0143 calorLV,
0144 "Calorimeter",
0145 worldLV,
0146 false,
0147 0,
0148 fCheckOverlaps);
0149
0150
0151
0152
0153 auto layerS = new G4Box("Layer",
0154 calorSizeXY / 2, calorSizeXY / 2, layerThickness / 2);
0155
0156 auto layerLV = new G4LogicalVolume(layerS,
0157 defaultMaterial,
0158 "Layer");
0159
0160 new G4PVReplica("Layer",
0161 layerLV,
0162 calorLV,
0163 kZAxis,
0164 nofLayers,
0165 layerThickness);
0166
0167
0168
0169
0170 auto absorberS = new G4Box("Abso",
0171 calorSizeXY / 2, calorSizeXY / 2, absoThickness / 2);
0172
0173 auto absorberLV = new G4LogicalVolume(absorberS,
0174 absorberMaterial,
0175 "Abso");
0176
0177 fAbsorberPV = new G4PVPlacement(nullptr,
0178 G4ThreeVector(0., 0., -gapThickness / 2),
0179 absorberLV,
0180 "Abso",
0181 layerLV,
0182 false,
0183 0,
0184 fCheckOverlaps);
0185
0186
0187
0188
0189 auto gapS = new G4Box("Gap",
0190 calorSizeXY / 2, calorSizeXY / 2, gapThickness / 2);
0191
0192 auto gapLV = new G4LogicalVolume(gapS,
0193 gapMaterial,
0194 "Gap");
0195
0196 fGapPV = new G4PVPlacement(nullptr,
0197 G4ThreeVector(0., 0., absoThickness / 2),
0198 gapLV,
0199 "Gap",
0200 layerLV,
0201 false,
0202 0,
0203 fCheckOverlaps);
0204
0205
0206
0207
0208 G4cout << G4endl << "------------------------------------------------------------" << G4endl
0209 << "---> The calorimeter is " << nofLayers << " layers of: [ " << absoThickness / mm
0210 << "mm of " << absorberMaterial->GetName() << " + " << gapThickness / mm << "mm of "
0211 << gapMaterial->GetName() << " ] " << G4endl
0212 << "------------------------------------------------------------" << G4endl;
0213
0214
0215
0216
0217 worldLV->SetVisAttributes(G4VisAttributes::GetInvisible());
0218 calorLV->SetVisAttributes(G4VisAttributes(G4Colour::White()));
0219
0220
0221
0222
0223 return worldPV;
0224 }
0225
0226
0227
0228 void DetectorConstruction::ConstructSDandField()
0229 {
0230
0231
0232
0233 G4ThreeVector fieldValue;
0234 fMagFieldMessenger = new G4GlobalMagFieldMessenger(fieldValue);
0235 fMagFieldMessenger->SetVerboseLevel(1);
0236
0237
0238 G4AutoDelete::Register(fMagFieldMessenger);
0239 }
0240
0241
0242
0243 }