Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-17 07:41:18

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file F04DetectorConstruction.cc
0027 /// \brief Implementation of the F04DetectorConstruction class
0028 
0029 #include "F04DetectorConstruction.hh"
0030 
0031 #include "F04DetectorMessenger.hh"
0032 #include "F04FocusSolenoid.hh"
0033 #include "F04GlobalField.hh"
0034 #include "F04Materials.hh"
0035 #include "F04SimpleSolenoid.hh"
0036 
0037 #include "G4AutoDelete.hh"
0038 #include "G4GeometryManager.hh"
0039 #include "G4LogicalVolume.hh"
0040 #include "G4LogicalVolumeStore.hh"
0041 #include "G4Material.hh"
0042 #include "G4NistManager.hh"
0043 #include "G4PVPlacement.hh"
0044 #include "G4PhysicalConstants.hh"
0045 #include "G4PhysicalVolumeStore.hh"
0046 #include "G4RotationMatrix.hh"
0047 #include "G4RunManager.hh"
0048 #include "G4SolidStore.hh"
0049 #include "G4StateManager.hh"
0050 #include "G4SystemOfUnits.hh"
0051 #include "G4Tubs.hh"
0052 #include "globals.hh"
0053 
0054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0055 
0056 F04DetectorConstruction::F04DetectorConstruction()
0057 {
0058   SetTargetAngle(170);
0059   SetCaptureMgntB1(2.5 * tesla);
0060   SetCaptureMgntB2(5.0 * tesla);
0061   SetTransferMgntB(5.0 * tesla);
0062 
0063   fDegraderPos = -fTransferMgntLength / 2. + fDegraderThickness / 2.;
0064 
0065   fDetectorMessenger = new F04DetectorMessenger(this);
0066 }
0067 
0068 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0069 
0070 F04DetectorConstruction::~F04DetectorConstruction()
0071 {
0072   delete fDetectorMessenger;
0073 }
0074 
0075 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0076 
0077 G4VPhysicalVolume* F04DetectorConstruction::Construct()
0078 {
0079   if (fPhysiWorld) {
0080     G4GeometryManager::GetInstance()->OpenGeometry();
0081     G4PhysicalVolumeStore::GetInstance()->Clean();
0082     G4LogicalVolumeStore::GetInstance()->Clean();
0083     G4SolidStore::GetInstance()->Clean();
0084   }
0085 
0086   fMaterials = F04Materials::GetInstance();
0087 
0088   DefineMaterials();
0089 
0090   return ConstructDetector();
0091 }
0092 
0093 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0094 
0095 void F04DetectorConstruction::DefineMaterials()
0096 {
0097   // define materials for the experiment
0098 
0099   fVacuum = fMaterials->GetMaterial("G4_Galactic");
0100 
0101   fWorldMaterial = fMaterials->GetMaterial("G4_AIR");
0102   fDegraderMaterial = fMaterials->GetMaterial("G4_Pb");
0103   fTargetMaterial = fMaterials->GetMaterial("G4_W");
0104 }
0105 
0106 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0107 
0108 G4VPhysicalVolume* F04DetectorConstruction::ConstructDetector()
0109 {
0110   fSolidWorld = new G4Tubs("World", 0., GetWorldSizeR(), GetWorldSizeZ() / 2., 0., twopi);
0111 
0112   fLogicWorld = new G4LogicalVolume(fSolidWorld, GetWorldMaterial(), "World");
0113 
0114   fPhysiWorld =
0115     new G4PVPlacement(nullptr, G4ThreeVector(), "World", fLogicWorld, nullptr, false, 0);
0116 
0117   // Capture Magnet
0118 
0119   fSolidCaptureMgnt =
0120     new G4Tubs("CaptureMgnt", 0., GetCaptureMgntRadius(), GetCaptureMgntLength() / 2., 0., twopi);
0121 
0122   fLogicCaptureMgnt = new G4LogicalVolume(fSolidCaptureMgnt, fVacuum, "CaptureMgnt");
0123 
0124   fCaptureMgntCenter = G4ThreeVector();
0125 
0126   fPhysiCaptureMgnt = new G4PVPlacement(nullptr, fCaptureMgntCenter, "CaptureMgnt",
0127                                         fLogicCaptureMgnt, fPhysiWorld, false, 0);
0128 
0129   // Transfer Magnet
0130 
0131   fSolidTransferMgnt = new G4Tubs("TransferMgnt", 0., GetTransferMgntRadius(),
0132                                   GetTransferMgntLength() / 2., 0., twopi);
0133 
0134   fLogicTransferMgnt = new G4LogicalVolume(fSolidTransferMgnt, fVacuum, "TransferMgnt");
0135 
0136   G4double z = GetCaptureMgntLength() / 2. + GetTransferMgntLength() / 2. + GetTransferMgntPos();
0137   G4double x = GetTransferMgntPos() / 2.;
0138 
0139   fTransferMgntCenter = G4ThreeVector(x, 0., z);
0140 
0141   auto g4rot = new G4RotationMatrix();
0142   *g4rot = StringToRotationMatrix("Y30,X10");
0143   *g4rot = g4rot->inverse();
0144   if (*g4rot == G4RotationMatrix()) g4rot = nullptr;
0145 
0146   fPhysiTransferMgnt = new G4PVPlacement(g4rot, fTransferMgntCenter, "TransferMgnt",
0147                                          fLogicTransferMgnt, fPhysiWorld, false, 0);
0148 
0149   // Test Plane
0150 
0151   auto solidTestPlane = new G4Tubs("TestPlane", 0., GetTransferMgntRadius(), 1. * mm, 0., twopi);
0152 
0153   auto logicTestPlane = new G4LogicalVolume(solidTestPlane, fVacuum, "TestPlane");
0154 
0155   z = GetTransferMgntLength() / 2. - 1. * mm;
0156 
0157   G4ThreeVector testPlaneCenter = G4ThreeVector(0., 0., z);
0158 
0159   new G4PVPlacement(nullptr, testPlaneCenter, "TestPlane", logicTestPlane, fPhysiTransferMgnt,
0160                     false, 0);
0161 
0162   // Target
0163 
0164   if (GetTargetThickness() > 0.) {
0165     fSolidTarget =
0166       new G4Tubs("Target", 0., GetTargetRadius(), GetTargetThickness() / 2., 0., twopi);
0167 
0168     fLogicTarget = new G4LogicalVolume(fSolidTarget, GetTargetMaterial(), "Target");
0169 
0170     G4int i = GetTargetAngle();
0171 
0172     G4String angle = std::to_string(i);
0173     G4StrUtil::strip(angle);
0174     angle = "Y" + angle;
0175 
0176     g4rot = new G4RotationMatrix();
0177     *g4rot = StringToRotationMatrix(angle);
0178     *g4rot = g4rot->inverse();
0179     if (*g4rot == G4RotationMatrix()) g4rot = nullptr;
0180 
0181     G4ThreeVector targetCenter(0., 0., GetTargetPos());
0182 
0183     fPhysiTarget =
0184       new G4PVPlacement(g4rot, targetCenter, "Target", fLogicTarget, fPhysiCaptureMgnt, false, 0);
0185   }
0186 
0187   // Degrader
0188 
0189   if (GetDegraderThickness() > 0.) {
0190     fSolidDegrader =
0191       new G4Tubs("Degrader", 0., GetDegraderRadius(), GetDegraderThickness() / 2., 0., twopi);
0192 
0193     fLogicDegrader = new G4LogicalVolume(fSolidDegrader, GetDegraderMaterial(), "Degrader");
0194 
0195     G4ThreeVector degraderCenter = G4ThreeVector(0., 0., GetDegraderPos());
0196 
0197     fPhysiDegrader = new G4PVPlacement(nullptr, degraderCenter, "Degrader", fLogicDegrader,
0198                                        fPhysiTransferMgnt, false, 0);
0199   }
0200 
0201   return fPhysiWorld;
0202 }
0203 
0204 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0205 
0206 void F04DetectorConstruction::SetWorldMaterial(const G4String materialChoice)
0207 {
0208   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0209 
0210   if (pttoMaterial != fWorldMaterial) {
0211     if (pttoMaterial) {
0212       fWorldMaterial = pttoMaterial;
0213       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0214     }
0215     else {
0216       G4cout << "\n--> WARNING from SetWorldMaterial : " << materialChoice << " not found"
0217              << G4endl;
0218     }
0219   }
0220 }
0221 
0222 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0223 
0224 void F04DetectorConstruction::SetTargetMaterial(const G4String materialChoice)
0225 {
0226   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0227 
0228   if (pttoMaterial != fTargetMaterial) {
0229     if (pttoMaterial) {
0230       fTargetMaterial = pttoMaterial;
0231       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0232     }
0233     else {
0234       G4cout << "\n-->  WARNING from SetTargetMaterial : " << materialChoice << " not found"
0235              << G4endl;
0236     }
0237   }
0238 }
0239 
0240 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0241 
0242 void F04DetectorConstruction::SetDegraderMaterial(const G4String materialChoice)
0243 
0244 {
0245   G4Material* pttoMaterial = G4NistManager::Instance()->FindOrBuildMaterial(materialChoice);
0246 
0247   if (pttoMaterial != fDegraderMaterial) {
0248     if (pttoMaterial) {
0249       fDegraderMaterial = pttoMaterial;
0250       G4RunManager::GetRunManager()->PhysicsHasBeenModified();
0251     }
0252     else {
0253       G4cout << "\n--> WARNING from SetDegraderMaterial : " << materialChoice << " not found"
0254              << G4endl;
0255     }
0256   }
0257 }
0258 
0259 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0260 
0261 void F04DetectorConstruction::SetWorldSizeZ(G4double val)
0262 {
0263   fWorldSizeZ = val;
0264   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0265     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0266 }
0267 
0268 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0269 
0270 void F04DetectorConstruction::SetWorldSizeR(G4double val)
0271 {
0272   fWorldSizeR = val;
0273   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0274     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0275 }
0276 
0277 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0278 
0279 void F04DetectorConstruction::SetCaptureMgntRadius(G4double val)
0280 {
0281   fCaptureMgntRadius = val;
0282   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0283     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0284 }
0285 
0286 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0287 
0288 void F04DetectorConstruction::SetCaptureMgntLength(G4double val)
0289 {
0290   fCaptureMgntLength = val;
0291   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0292     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0293 }
0294 
0295 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0296 
0297 void F04DetectorConstruction::SetCaptureMgntB1(G4double val)
0298 {
0299   fCaptureMgntB1 = val;
0300   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0301     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0302 }
0303 
0304 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0305 
0306 void F04DetectorConstruction::SetCaptureMgntB2(G4double val)
0307 {
0308   fCaptureMgntB2 = val;
0309   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0310     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0311 }
0312 
0313 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0314 
0315 void F04DetectorConstruction::SetTransferMgntRadius(G4double val)
0316 {
0317   fTransferMgntRadius = val;
0318   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0319     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0320 }
0321 
0322 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0323 
0324 void F04DetectorConstruction::SetTransferMgntLength(G4double val)
0325 {
0326   fTransferMgntLength = val;
0327   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0328     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0329 }
0330 
0331 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0332 
0333 void F04DetectorConstruction::SetTransferMgntB(G4double val)
0334 {
0335   fTransferMgntB = val;
0336   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0337     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0338 }
0339 
0340 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0341 
0342 void F04DetectorConstruction::SetTransferMgntPos(G4double val)
0343 {
0344   fTransferMgntPos = val;
0345   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0346     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0347 }
0348 
0349 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0350 
0351 void F04DetectorConstruction::SetTargetRadius(G4double val)
0352 {
0353   fTargetRadius = val;
0354   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0355     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0356 }
0357 
0358 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0359 
0360 void F04DetectorConstruction::SetTargetThickness(G4double val)
0361 {
0362   fTargetThickness = val;
0363   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0364     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0365 }
0366 
0367 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0368 
0369 void F04DetectorConstruction::SetTargetPos(G4double val)
0370 {
0371   fTargetPos = val;
0372   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0373     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0374 }
0375 
0376 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0377 
0378 void F04DetectorConstruction::SetTargetAngle(G4int val)
0379 {
0380   fTargetAngle = val;
0381   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0382     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0383 }
0384 
0385 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0386 
0387 void F04DetectorConstruction::SetDegraderRadius(G4double val)
0388 {
0389   fDegraderRadius = val;
0390   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0391     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0392 }
0393 
0394 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0395 
0396 void F04DetectorConstruction::SetDegraderThickness(G4double val)
0397 {
0398   fDegraderThickness = val;
0399   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0400     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0401 }
0402 
0403 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0404 
0405 void F04DetectorConstruction::SetDegraderPos(G4double val)
0406 {
0407   fDegraderPos = val;
0408   if (G4StateManager::GetStateManager()->GetCurrentState() != G4State_PreInit)
0409     G4RunManager::GetRunManager()->GeometryHasBeenModified();
0410 }
0411 
0412 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0413 
0414 void F04DetectorConstruction::ConstructSDandField()
0415 {
0416   if (!fFieldSetUp.Get()) {
0417     F04GlobalField* field = F04GlobalField::GetObject(this);
0418     G4AutoDelete::Register(field);  // Kernel will delete the F04GlobalField
0419     fFieldSetUp.Put(field);
0420   }
0421 }
0422 
0423 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0424 
0425 G4RotationMatrix F04DetectorConstruction::StringToRotationMatrix(G4String rotation)
0426 {
0427   // We apply successive rotations OF THE OBJECT around the FIXED
0428   // axes of the parent's local coordinates; rotations are applied
0429   // left-to-right (rotation="r1,r2,r3" => r1 then r2 then r3).
0430 
0431   G4RotationMatrix rot;
0432 
0433   unsigned int place = 0;
0434 
0435   while (place < rotation.size()) {
0436     G4double angle;
0437     char* p(nullptr);
0438     G4String current = rotation.substr(place + 1);
0439     angle = strtod(current.c_str(), &p) * deg;
0440 
0441     if (!p || (*p != ',' && *p != '\0')) {
0442       G4cerr << "Invalid rotation specification: " << rotation.c_str() << G4endl;
0443 
0444       return rot;
0445     }
0446 
0447     G4RotationMatrix thisRotation;
0448 
0449     switch (rotation.substr(place, 1).c_str()[0]) {
0450       case 'X':
0451       case 'x':
0452         thisRotation = G4RotationMatrix(CLHEP::HepRotationX(angle));
0453         break;
0454       case 'Y':
0455       case 'y':
0456         thisRotation = G4RotationMatrix(CLHEP::HepRotationY(angle));
0457         break;
0458       case 'Z':
0459       case 'z':
0460         thisRotation = G4RotationMatrix(CLHEP::HepRotationZ(angle));
0461         break;
0462       default:
0463         G4cerr << " Invalid rotation specification: " << rotation << G4endl;
0464         return rot;
0465     }
0466 
0467     rot = thisRotation * rot;
0468     place = rotation.find(',', place);
0469     if (place > rotation.size()) break;
0470     ++place;
0471   }
0472 
0473   return rot;
0474 }