File indexing completed on 2025-02-23 09:21:18
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 #include "F04DetectorConstruction.hh"
0034
0035 #include "F04DetectorMessenger.hh"
0036 #include "F04FocusSolenoid.hh"
0037 #include "F04GlobalField.hh"
0038 #include "F04Materials.hh"
0039 #include "F04SimpleSolenoid.hh"
0040
0041 #include "G4AutoDelete.hh"
0042 #include "G4GeometryManager.hh"
0043 #include "G4LogicalVolume.hh"
0044 #include "G4LogicalVolumeStore.hh"
0045 #include "G4Material.hh"
0046 #include "G4NistManager.hh"
0047 #include "G4PVPlacement.hh"
0048 #include "G4PhysicalConstants.hh"
0049 #include "G4PhysicalVolumeStore.hh"
0050 #include "G4RotationMatrix.hh"
0051 #include "G4RunManager.hh"
0052 #include "G4SolidStore.hh"
0053 #include "G4StateManager.hh"
0054 #include "G4SystemOfUnits.hh"
0055 #include "G4Tubs.hh"
0056 #include "globals.hh"
0057
0058
0059
0060 F04DetectorConstruction::F04DetectorConstruction()
0061 {
0062 SetTargetAngle(170);
0063 SetCaptureMgntB1(2.5 * tesla);
0064 SetCaptureMgntB2(5.0 * tesla);
0065 SetTransferMgntB(5.0 * tesla);
0066
0067 fDegraderPos = -fTransferMgntLength / 2. + fDegraderThickness / 2.;
0068
0069 fDetectorMessenger = new F04DetectorMessenger(this);
0070 }
0071
0072
0073
0074 F04DetectorConstruction::~F04DetectorConstruction()
0075 {
0076 delete fDetectorMessenger;
0077 }
0078
0079
0080
0081 G4VPhysicalVolume* F04DetectorConstruction::Construct()
0082 {
0083 if (fPhysiWorld) {
0084 G4GeometryManager::GetInstance()->OpenGeometry();
0085 G4PhysicalVolumeStore::GetInstance()->Clean();
0086 G4LogicalVolumeStore::GetInstance()->Clean();
0087 G4SolidStore::GetInstance()->Clean();
0088 }
0089
0090 fMaterials = F04Materials::GetInstance();
0091
0092 DefineMaterials();
0093
0094 return ConstructDetector();
0095 }
0096
0097
0098
0099 void F04DetectorConstruction::DefineMaterials()
0100 {
0101
0102
0103 fVacuum = fMaterials->GetMaterial("G4_Galactic");
0104
0105 fWorldMaterial = fMaterials->GetMaterial("G4_AIR");
0106 fDegraderMaterial = fMaterials->GetMaterial("G4_Pb");
0107 fTargetMaterial = fMaterials->GetMaterial("G4_W");
0108 }
0109
0110
0111
0112 G4VPhysicalVolume* F04DetectorConstruction::ConstructDetector()
0113 {
0114 fSolidWorld = new G4Tubs("World", 0., GetWorldSizeR(), GetWorldSizeZ() / 2., 0., twopi);
0115
0116 fLogicWorld = new G4LogicalVolume(fSolidWorld, GetWorldMaterial(), "World");
0117
0118 fPhysiWorld =
0119 new G4PVPlacement(nullptr, G4ThreeVector(), "World", fLogicWorld, nullptr, false, 0);
0120
0121
0122
0123 fSolidCaptureMgnt =
0124 new G4Tubs("CaptureMgnt", 0., GetCaptureMgntRadius(), GetCaptureMgntLength() / 2., 0., twopi);
0125
0126 fLogicCaptureMgnt = new G4LogicalVolume(fSolidCaptureMgnt, fVacuum, "CaptureMgnt");
0127
0128 fCaptureMgntCenter = G4ThreeVector();
0129
0130 fPhysiCaptureMgnt = new G4PVPlacement(nullptr, fCaptureMgntCenter, "CaptureMgnt",
0131 fLogicCaptureMgnt, fPhysiWorld, false, 0);
0132
0133
0134
0135 fSolidTransferMgnt = new G4Tubs("TransferMgnt", 0., GetTransferMgntRadius(),
0136 GetTransferMgntLength() / 2., 0., twopi);
0137
0138 fLogicTransferMgnt = new G4LogicalVolume(fSolidTransferMgnt, fVacuum, "TransferMgnt");
0139
0140 G4double z = GetCaptureMgntLength() / 2. + GetTransferMgntLength() / 2. + GetTransferMgntPos();
0141 G4double x = GetTransferMgntPos() / 2.;
0142
0143 fTransferMgntCenter = G4ThreeVector(x, 0., z);
0144
0145 auto g4rot = new G4RotationMatrix();
0146 *g4rot = StringToRotationMatrix("Y30,X10");
0147 *g4rot = g4rot->inverse();
0148 if (*g4rot == G4RotationMatrix()) g4rot = nullptr;
0149
0150 fPhysiTransferMgnt = new G4PVPlacement(g4rot, fTransferMgntCenter, "TransferMgnt",
0151 fLogicTransferMgnt, fPhysiWorld, false, 0);
0152
0153
0154
0155 auto solidTestPlane = new G4Tubs("TestPlane", 0., GetTransferMgntRadius(), 1. * mm, 0., twopi);
0156
0157 auto logicTestPlane = new G4LogicalVolume(solidTestPlane, fVacuum, "TestPlane");
0158
0159 z = GetTransferMgntLength() / 2. - 1. * mm;
0160
0161 G4ThreeVector testPlaneCenter = G4ThreeVector(0., 0., z);
0162
0163 new G4PVPlacement(nullptr, testPlaneCenter, "TestPlane", logicTestPlane, fPhysiTransferMgnt,
0164 false, 0);
0165
0166
0167
0168 if (GetTargetThickness() > 0.) {
0169 fSolidTarget =
0170 new G4Tubs("Target", 0., GetTargetRadius(), GetTargetThickness() / 2., 0., twopi);
0171
0172 fLogicTarget = new G4LogicalVolume(fSolidTarget, GetTargetMaterial(), "Target");
0173
0174 G4int i = GetTargetAngle();
0175
0176 G4String angle = std::to_string(i);
0177 G4StrUtil::strip(angle);
0178 angle = "Y" + angle;
0179
0180 g4rot = new G4RotationMatrix();
0181 *g4rot = StringToRotationMatrix(angle);
0182 *g4rot = g4rot->inverse();
0183 if (*g4rot == G4RotationMatrix()) g4rot = nullptr;
0184
0185 G4ThreeVector targetCenter(0., 0., GetTargetPos());
0186
0187 fPhysiTarget =
0188 new G4PVPlacement(g4rot, targetCenter, "Target", fLogicTarget, fPhysiCaptureMgnt, false, 0);
0189 }
0190
0191
0192
0193 if (GetDegraderThickness() > 0.) {
0194 fSolidDegrader =
0195 new G4Tubs("Degrader", 0., GetDegraderRadius(), GetDegraderThickness() / 2., 0., twopi);
0196
0197 fLogicDegrader = new G4LogicalVolume(fSolidDegrader, GetDegraderMaterial(), "Degrader");
0198
0199 G4ThreeVector degraderCenter = G4ThreeVector(0., 0., GetDegraderPos());
0200
0201 fPhysiDegrader = new G4PVPlacement(nullptr, degraderCenter, "Degrader", fLogicDegrader,
0202 fPhysiTransferMgnt, false, 0);
0203 }
0204
0205 return fPhysiWorld;
0206 }
0207
0208
0209
0210 void F04DetectorConstruction::SetWorldMaterial(const G4String materialChoice)
0211 {
0212 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0213
0214 if (pttoMaterial != fWorldMaterial) {
0215 if (pttoMaterial) {
0216 fWorldMaterial = pttoMaterial;
0217 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0218 }
0219 else {
0220 G4cout << "\n--> WARNING from SetWorldMaterial : " << materialChoice << " not found"
0221 << G4endl;
0222 }
0223 }
0224 }
0225
0226
0227
0228 void F04DetectorConstruction::SetTargetMaterial(const G4String materialChoice)
0229 {
0230 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0231
0232 if (pttoMaterial != fTargetMaterial) {
0233 if (pttoMaterial) {
0234 fTargetMaterial = pttoMaterial;
0235 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0236 }
0237 else {
0238 G4cout << "\n--> WARNING from SetTargetMaterial : " << materialChoice << " not found"
0239 << G4endl;
0240 }
0241 }
0242 }
0243
0244
0245
0246 void F04DetectorConstruction::SetDegraderMaterial(const G4String materialChoice)
0247
0248 {
0249 G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0250
0251 if (pttoMaterial != fDegraderMaterial) {
0252 if (pttoMaterial) {
0253 fDegraderMaterial = pttoMaterial;
0254 G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0255 }
0256 else {
0257 G4cout << "\n--> WARNING from SetDegraderMaterial : " << materialChoice << " not found"
0258 << G4endl;
0259 }
0260 }
0261 }
0262
0263
0264
0265 void F04DetectorConstruction::SetWorldSizeZ(G4double val)
0266 {
0267 fWorldSizeZ = val;
0268
0269 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0270 G4RunManager::GetRunManager()->ReinitializeGeometry();
0271 }
0272 }
0273
0274
0275
0276 void F04DetectorConstruction::SetWorldSizeR(G4double val)
0277 {
0278 fWorldSizeR = val;
0279 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0280 G4RunManager::GetRunManager()->ReinitializeGeometry();
0281 }
0282 }
0283
0284
0285
0286 void F04DetectorConstruction::SetCaptureMgntRadius(G4double val)
0287 {
0288 fCaptureMgntRadius = val;
0289 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0290 G4RunManager::GetRunManager()->ReinitializeGeometry();
0291 }
0292 }
0293
0294
0295
0296 void F04DetectorConstruction::SetCaptureMgntLength(G4double val)
0297 {
0298 fCaptureMgntLength = val;
0299 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0300 G4RunManager::GetRunManager()->ReinitializeGeometry();
0301 }
0302 }
0303
0304
0305
0306 void F04DetectorConstruction::SetCaptureMgntB1(G4double val)
0307 {
0308 fCaptureMgntB1 = val;
0309 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0310 G4RunManager::GetRunManager()->ReinitializeGeometry();
0311 }
0312 }
0313
0314
0315
0316 void F04DetectorConstruction::SetCaptureMgntB2(G4double val)
0317 {
0318 fCaptureMgntB2 = val;
0319 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0320 G4RunManager::GetRunManager()->ReinitializeGeometry();
0321 }
0322 }
0323
0324
0325
0326 void F04DetectorConstruction::SetTransferMgntRadius(G4double val)
0327 {
0328 fTransferMgntRadius = val;
0329 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0330 G4RunManager::GetRunManager()->ReinitializeGeometry();
0331 }
0332 }
0333
0334
0335
0336 void F04DetectorConstruction::SetTransferMgntLength(G4double val)
0337 {
0338 fTransferMgntLength = val;
0339 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0340 G4RunManager::GetRunManager()->ReinitializeGeometry();
0341 }
0342 }
0343
0344
0345
0346 void F04DetectorConstruction::SetTransferMgntB(G4double val)
0347 {
0348 fTransferMgntB = val;
0349 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0350 G4RunManager::GetRunManager()->ReinitializeGeometry();
0351 }
0352 }
0353
0354
0355
0356 void F04DetectorConstruction::SetTransferMgntPos(G4double val)
0357 {
0358 fTransferMgntPos = val;
0359 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0360 G4RunManager::GetRunManager()->ReinitializeGeometry();
0361 }
0362 }
0363
0364
0365
0366 void F04DetectorConstruction::SetTargetRadius(G4double val)
0367 {
0368 fTargetRadius = val;
0369 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0370 G4RunManager::GetRunManager()->ReinitializeGeometry();
0371 }
0372 }
0373
0374
0375
0376 void F04DetectorConstruction::SetTargetThickness(G4double val)
0377 {
0378 fTargetThickness = val;
0379 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0380 G4RunManager::GetRunManager()->ReinitializeGeometry();
0381 }
0382 }
0383
0384
0385
0386 void F04DetectorConstruction::SetTargetPos(G4double val)
0387 {
0388 fTargetPos = val;
0389 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0390 G4RunManager::GetRunManager()->ReinitializeGeometry();
0391 }
0392 }
0393
0394
0395
0396 void F04DetectorConstruction::SetTargetAngle(G4int val)
0397 {
0398 fTargetAngle = val;
0399 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0400 G4RunManager::GetRunManager()->ReinitializeGeometry();
0401 }
0402 }
0403
0404
0405
0406 void F04DetectorConstruction::SetDegraderRadius(G4double val)
0407 {
0408 fDegraderRadius = val;
0409 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0410 G4RunManager::GetRunManager()->ReinitializeGeometry();
0411 }
0412 }
0413
0414
0415
0416 void F04DetectorConstruction::SetDegraderThickness(G4double val)
0417 {
0418 fDegraderThickness = val;
0419 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0420 G4RunManager::GetRunManager()->ReinitializeGeometry();
0421 }
0422 }
0423
0424
0425
0426 void F04DetectorConstruction::SetDegraderPos(G4double val)
0427 {
0428 fDegraderPos = val;
0429 if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit) {
0430 G4RunManager::GetRunManager()->ReinitializeGeometry();
0431 }
0432 }
0433
0434
0435
0436 void F04DetectorConstruction::ConstructSDandField()
0437 {
0438 if (!fFieldSetUp.Get()) {
0439 F04GlobalField* field = F04GlobalField::GetObject(this);
0440 G4AutoDelete::Register(field);
0441 fFieldSetUp.Put(field);
0442 }
0443 }
0444
0445
0446
0447 G4RotationMatrix F04DetectorConstruction::StringToRotationMatrix(G4String rotation)
0448 {
0449
0450
0451
0452
0453 G4RotationMatrix rot;
0454
0455 unsigned int place = 0;
0456
0457 while (place < rotation.size()) {
0458 G4double angle;
0459 char* p(nullptr);
0460 G4String current = rotation.substr(place + 1);
0461 angle = strtod(current.c_str(), &p) * deg;
0462
0463 if (!p || (*p != ',' && *p != '\0')) {
0464 G4cerr << "Invalid rotation specification: " << rotation.c_str() << G4endl;
0465
0466 return rot;
0467 }
0468
0469 G4RotationMatrix thisRotation;
0470
0471 switch (rotation.substr(place, 1).c_str()[0]) {
0472 case 'X':
0473 case 'x':
0474 thisRotation = G4RotationMatrix(CLHEP::HepRotationX(angle));
0475 break;
0476 case 'Y':
0477 case 'y':
0478 thisRotation = G4RotationMatrix(CLHEP::HepRotationY(angle));
0479 break;
0480 case 'Z':
0481 case 'z':
0482 thisRotation = G4RotationMatrix(CLHEP::HepRotationZ(angle));
0483 break;
0484 default:
0485 G4cerr << " Invalid rotation specification: " << rotation << G4endl;
0486 return rot;
0487 }
0488
0489 rot = thisRotation * rot;
0490 place = rotation.find(',', place);
0491 if (place > rotation.size()) break;
0492 ++place;
0493 }
0494
0495 return rot;
0496 }