File indexing completed on 2026-09-21 08:28:44
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 "B01DetectorConstruction.hh"
0030
0031 #include "G4Box.hh"
0032 #include "G4Colour.hh"
0033 #include "G4LogicalVolume.hh"
0034 #include "G4Material.hh"
0035 #include "G4PVPlacement.hh"
0036 #include "G4PhysicalConstants.hh"
0037 #include "G4SystemOfUnits.hh"
0038 #include "G4ThreeVector.hh"
0039 #include "G4Tubs.hh"
0040 #include "G4Types.hh"
0041 #include "G4VisAttributes.hh"
0042 #include "globals.hh"
0043
0044 #include <set>
0045 #include <sstream>
0046
0047
0048 #include "G4MultiFunctionalDetector.hh"
0049 #include "G4PSNofCollision.hh"
0050 #include "G4PSPopulation.hh"
0051 #include "G4PSTrackCounter.hh"
0052 #include "G4PSTrackLength.hh"
0053 #include "G4SDManager.hh"
0054 #include "G4SDParticleFilter.hh"
0055
0056
0057 #include "G4IStore.hh"
0058
0059
0060 #include "G4WeightWindowStore.hh"
0061
0062
0063
0064 B01DetectorConstruction::B01DetectorConstruction()
0065 : G4VUserDetectorConstruction(), fLogicalVolumeVector(), fPhysicalVolumeVector()
0066 {
0067 ;
0068 }
0069
0070
0071
0072 B01DetectorConstruction::~B01DetectorConstruction()
0073 {
0074 fLogicalVolumeVector.clear();
0075 fPhysicalVolumeVector.clear();
0076 }
0077
0078
0079
0080 G4VPhysicalVolume* B01DetectorConstruction::Construct()
0081 {
0082 G4double pos_x;
0083 G4double pos_y;
0084 G4double pos_z;
0085
0086 G4double density, pressure, temperature;
0087 G4double A;
0088 G4int Z;
0089
0090 G4String name, symbol;
0091 G4double z;
0092 G4double fractionmass;
0093
0094 A = 1.01 * g / mole;
0095 G4Element* elH = new G4Element(name = "Hydrogen", symbol = "H", Z = 1, A);
0096
0097 A = 12.01 * g / mole;
0098 G4Element* elC = new G4Element(name = "Carbon", symbol = "C", Z = 6, A);
0099
0100 A = 16.00 * g / mole;
0101 G4Element* elO = new G4Element(name = "Oxygen", symbol = "O", Z = 8, A);
0102
0103 A = 22.99 * g / mole;
0104 G4Element* elNa = new G4Element(name = "Natrium", symbol = "Na", Z = 11, A);
0105
0106 A = 200.59 * g / mole;
0107 G4Element* elHg = new G4Element(name = "Hg", symbol = "Hg", Z = 80, A);
0108
0109 A = 26.98 * g / mole;
0110 G4Element* elAl = new G4Element(name = "Aluminium", symbol = "Al", Z = 13, A);
0111
0112 A = 28.09 * g / mole;
0113 G4Element* elSi = new G4Element(name = "Silicon", symbol = "Si", Z = 14, A);
0114
0115 A = 39.1 * g / mole;
0116 G4Element* elK = new G4Element(name = "K", symbol = "K", Z = 19, A);
0117
0118 A = 69.72 * g / mole;
0119 G4Element* elCa = new G4Element(name = "Calzium", symbol = "Ca", Z = 31, A);
0120
0121 A = 55.85 * g / mole;
0122 G4Element* elFe = new G4Element(name = "Iron", symbol = "Fe", Z = 26, A);
0123
0124 density = universe_mean_density;
0125 pressure = 3.e-18 * pascal;
0126 temperature = 2.73 * kelvin;
0127 G4Material* Galactic = new G4Material(name = "Galactic", z = 1., A = 1.01 * g / mole, density,
0128 kStateGas, temperature, pressure);
0129
0130 density = 2.03 * g / cm3;
0131 G4Material* Concrete = new G4Material("Concrete", density, 10);
0132 Concrete->AddElement(elH, fractionmass = 0.01);
0133 Concrete->AddElement(elO, fractionmass = 0.529);
0134 Concrete->AddElement(elNa, fractionmass = 0.016);
0135 Concrete->AddElement(elHg, fractionmass = 0.002);
0136 Concrete->AddElement(elAl, fractionmass = 0.034);
0137 Concrete->AddElement(elSi, fractionmass = 0.337);
0138 Concrete->AddElement(elK, fractionmass = 0.013);
0139 Concrete->AddElement(elCa, fractionmass = 0.044);
0140 Concrete->AddElement(elFe, fractionmass = 0.014);
0141 Concrete->AddElement(elC, fractionmass = 0.001);
0142
0143
0144
0145
0146
0147
0148
0149 G4double innerRadiusCylinder = 0 * cm;
0150 G4double outerRadiusCylinder = 100 * cm;
0151 G4double heightCylinder = 100 * cm;
0152 G4double startAngleCylinder = 0 * deg;
0153 G4double spanningAngleCylinder = 360 * deg;
0154
0155 G4Tubs* worldCylinder = new G4Tubs("worldCylinder", innerRadiusCylinder, outerRadiusCylinder,
0156 heightCylinder, startAngleCylinder, spanningAngleCylinder);
0157
0158
0159
0160 G4LogicalVolume* worldCylinder_log =
0161 new G4LogicalVolume(worldCylinder, Galactic, "worldCylinder_log");
0162 fLogicalVolumeVector.push_back(worldCylinder_log);
0163
0164 name = "shieldWorld";
0165 fWorldVolume = new G4PVPlacement(0, G4ThreeVector(0, 0, 0), worldCylinder_log, name, 0, false, 0);
0166
0167 fPhysicalVolumeVector.push_back(fWorldVolume);
0168
0169
0170
0171 G4double innerRadiusShield = 0 * cm;
0172 G4double outerRadiusShield = 100 * cm;
0173 G4double heightShield = 5 * cm;
0174 G4double startAngleShield = 0 * deg;
0175 G4double spanningAngleShield = 360 * deg;
0176
0177 G4Tubs* aShield = new G4Tubs("aShield", innerRadiusShield, outerRadiusShield, heightShield,
0178 startAngleShield, spanningAngleShield);
0179
0180
0181
0182 G4LogicalVolume* aShield_log = new G4LogicalVolume(aShield, Concrete, "aShield_log");
0183 fLogicalVolumeVector.push_back(aShield_log);
0184
0185 G4VisAttributes* pShieldVis = new G4VisAttributes(G4Colour(0.0, 0.0, 1.0));
0186 pShieldVis->SetForceSolid(true);
0187 aShield_log->SetVisAttributes(pShieldVis);
0188
0189
0190
0191 G4int i;
0192 G4double startz = -85 * cm;
0193 for (i = 1; i <= 18; i++) {
0194 name = GetCellName(i);
0195 pos_x = 0 * cm;
0196 pos_y = 0 * cm;
0197 pos_z = startz + (i - 1) * (2 * heightShield);
0198 G4VPhysicalVolume* pvol = new G4PVPlacement(0, G4ThreeVector(pos_x, pos_y, pos_z), aShield_log,
0199 name, worldCylinder_log, false, i);
0200 fPhysicalVolumeVector.push_back(pvol);
0201 }
0202
0203
0204
0205
0206
0207 innerRadiusShield = 0 * cm;
0208 outerRadiusShield = 100 * cm;
0209 heightShield = 5 * cm;
0210 startAngleShield = 0 * deg;
0211 spanningAngleShield = 360 * deg;
0212
0213 G4Tubs* aRest = new G4Tubs("Rest", innerRadiusShield, outerRadiusShield, heightShield,
0214 startAngleShield, spanningAngleShield);
0215
0216 G4LogicalVolume* aRest_log = new G4LogicalVolume(aRest, Galactic, "aRest_log");
0217 fLogicalVolumeVector.push_back(aRest_log);
0218 name = "rest";
0219
0220 pos_x = 0 * cm;
0221 pos_y = 0 * cm;
0222 pos_z = 95 * cm;
0223 G4VPhysicalVolume* pvol_rest = new G4PVPlacement(0, G4ThreeVector(pos_x, pos_y, pos_z), aRest_log,
0224 name, worldCylinder_log, false,
0225 19);
0226
0227 fPhysicalVolumeVector.push_back(pvol_rest);
0228
0229 SetSensitive();
0230 return fWorldVolume;
0231 }
0232
0233
0234
0235 G4VIStore* B01DetectorConstruction::CreateImportanceStore()
0236 {
0237 G4cout << " B01DetectorConstruction:: Creating Importance Store " << G4endl;
0238 if (!fPhysicalVolumeVector.size()) {
0239 G4Exception("B01DetectorConstruction::CreateImportanceStore", "exampleB01_0001",
0240 RunMustBeAborted, "no physical volumes created yet!");
0241 }
0242
0243 fWorldVolume = fPhysicalVolumeVector[0];
0244
0245
0246
0247 G4IStore* istore = G4IStore::GetInstance();
0248
0249 G4int n = 0;
0250 G4double imp = 1;
0251 istore->AddImportanceGeometryCell(1, *fWorldVolume);
0252 for (std::vector<G4VPhysicalVolume*>::iterator it = fPhysicalVolumeVector.begin();
0253 it != fPhysicalVolumeVector.end() - 1; it++)
0254 {
0255 if (*it != fWorldVolume) {
0256 imp = std::pow(2., n++);
0257 G4cout << "Going to assign importance: " << imp << ", to volume: " << (*it)->GetName()
0258 << G4endl;
0259 istore->AddImportanceGeometryCell(imp, *(*it), n);
0260 }
0261 }
0262
0263
0264
0265
0266 istore->AddImportanceGeometryCell(imp, *(fPhysicalVolumeVector[fPhysicalVolumeVector.size() - 1]),
0267 ++n);
0268
0269 return istore;
0270 }
0271
0272
0273
0274 G4VWeightWindowStore* B01DetectorConstruction::CreateWeightWindowStore()
0275 {
0276 if (!fPhysicalVolumeVector.size()) {
0277 G4Exception("B01DetectorConstruction::CreateWeightWindowStore", "exampleB01_0002",
0278 RunMustBeAborted, "no physical volumes created yet!");
0279 }
0280
0281 fWorldVolume = fPhysicalVolumeVector[0];
0282
0283
0284
0285 G4WeightWindowStore* wwstore = G4WeightWindowStore::GetInstance();
0286
0287
0288
0289 std::set<G4double, std::less<G4double>> enBounds;
0290 enBounds.insert(1 * GeV);
0291 wwstore->SetGeneralUpperEnergyBounds(enBounds);
0292
0293 G4int n = 0;
0294 G4double lowerWeight = 1;
0295 std::vector<G4double> lowerWeights;
0296
0297 lowerWeights.push_back(1);
0298 G4GeometryCell gWorldCell(*fWorldVolume, 0);
0299 wwstore->AddLowerWeights(gWorldCell, lowerWeights);
0300
0301 for (std::vector<G4VPhysicalVolume*>::iterator it = fPhysicalVolumeVector.begin();
0302 it != fPhysicalVolumeVector.end() - 1; it++)
0303 {
0304 if (*it != fWorldVolume) {
0305 lowerWeight = 1. / std::pow(2., n++);
0306 G4cout << "Going to assign lower weight: " << lowerWeight
0307 << ", to volume: " << (*it)->GetName() << G4endl;
0308 G4GeometryCell gCell(*(*it), n);
0309 lowerWeights.clear();
0310 lowerWeights.push_back(lowerWeight);
0311 wwstore->AddLowerWeights(gCell, lowerWeights);
0312 }
0313 }
0314
0315
0316
0317
0318 G4GeometryCell gRestCell(*(fPhysicalVolumeVector[fPhysicalVolumeVector.size() - 1]), ++n);
0319 wwstore->AddLowerWeights(gRestCell, lowerWeights);
0320
0321 return wwstore;
0322 }
0323
0324
0325
0326 G4String B01DetectorConstruction::GetCellName(G4int i)
0327 {
0328 std::ostringstream os;
0329 os << "cell_";
0330 if (i < 10) {
0331 os << "0";
0332 }
0333 os << i;
0334 G4String name = os.str();
0335 return name;
0336 }
0337
0338 G4VPhysicalVolume* B01DetectorConstruction::GetWorldVolume()
0339 {
0340 return fWorldVolume;
0341 }
0342
0343
0344
0345 void B01DetectorConstruction::SetSensitive()
0346 {
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 }
0362
0363
0364
0365 void B01DetectorConstruction::ConstructSDandField()
0366 {
0367
0368 G4SDManager* SDman = G4SDManager::GetSDMpointer();
0369
0370 G4String concreteSDname = "ConcreteSD";
0371
0372
0373
0374
0375
0376
0377 G4MultiFunctionalDetector* MFDet = new G4MultiFunctionalDetector(concreteSDname);
0378 SDman->AddNewDetector(MFDet);
0379
0380 G4String fltName, particleName;
0381 G4SDParticleFilter* neutronFilter =
0382 new G4SDParticleFilter(fltName = "neutronFilter", particleName = "neutron");
0383
0384 MFDet->SetFilter(neutronFilter);
0385
0386 for (std::vector<G4LogicalVolume*>::iterator it = fLogicalVolumeVector.begin();
0387 it != fLogicalVolumeVector.end(); it++)
0388 {
0389
0390 SetSensitiveDetector((*it)->GetName(), MFDet);
0391 }
0392
0393 G4String psName;
0394 G4PSNofCollision* scorer0 = new G4PSNofCollision(psName = "Collisions");
0395 MFDet->RegisterPrimitive(scorer0);
0396
0397 G4PSNofCollision* scorer1 = new G4PSNofCollision(psName = "CollWeight");
0398 scorer1->Weighted(true);
0399 MFDet->RegisterPrimitive(scorer1);
0400
0401 G4PSPopulation* scorer2 = new G4PSPopulation(psName = "Population");
0402 MFDet->RegisterPrimitive(scorer2);
0403
0404 G4PSTrackCounter* scorer3 = new G4PSTrackCounter(psName = "TrackEnter", fCurrent_In);
0405 MFDet->RegisterPrimitive(scorer3);
0406
0407 G4PSTrackLength* scorer4 = new G4PSTrackLength(psName = "SL");
0408 MFDet->RegisterPrimitive(scorer4);
0409
0410 G4PSTrackLength* scorer5 = new G4PSTrackLength(psName = "SLW");
0411 scorer5->Weighted(true);
0412 MFDet->RegisterPrimitive(scorer5);
0413
0414 G4PSTrackLength* scorer6 = new G4PSTrackLength(psName = "SLWE");
0415 scorer6->Weighted(true);
0416 scorer6->MultiplyKineticEnergy(true);
0417 MFDet->RegisterPrimitive(scorer6);
0418
0419 G4PSTrackLength* scorer7 = new G4PSTrackLength(psName = "SLW_V");
0420 scorer7->Weighted(true);
0421 scorer7->DivideByVelocity(true);
0422 MFDet->RegisterPrimitive(scorer7);
0423
0424 G4PSTrackLength* scorer8 = new G4PSTrackLength(psName = "SLWE_V");
0425 scorer8->Weighted(true);
0426 scorer8->MultiplyKineticEnergy(true);
0427 scorer8->DivideByVelocity(true);
0428 MFDet->RegisterPrimitive(scorer8);
0429 }
0430
0431