Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 /// \file GB06/src/GB06ParallelWorldForSlices.cc 27 /// \brief Implementation of the GB06ParallelWorldForSlices class 28 // 29 // 30 #include "GB06ParallelWorldForSlices.hh" 31 32 #include "GB06BOptrSplitAndKillByImportance.hh" 33 34 #include "G4Box.hh" 35 #include "G4LogicalVolume.hh" 36 #include "G4LogicalVolumeStore.hh" 37 #include "G4PVPlacement.hh" 38 #include "G4PVReplica.hh" 39 #include "G4PhysicalVolumeStore.hh" 40 #include "G4SystemOfUnits.hh" 41 #include "G4ThreeVector.hh" 42 43 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 44 45 GB06ParallelWorldForSlices::GB06ParallelWorldForSlices(G4String worldName) 46 : G4VUserParallelWorld(worldName) 47 { 48 ; 49 } 50 51 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 52 53 GB06ParallelWorldForSlices::~GB06ParallelWorldForSlices() 54 { 55 ; 56 } 57 58 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 59 60 void GB06ParallelWorldForSlices::Construct() 61 { 62 // -- Inform about construction: 63 // -- (fWorldName is a protected data member of the base parallel world class) 64 G4cout << "Parallel World `" << fWorldName << "' constructed." << G4endl; 65 66 // ------------------------- 67 // Build parallel geometry: 68 // ------------------------- 69 70 // -- Obtain clone of mass geometry world from GetWorld() base class utility: 71 G4VPhysicalVolume* physicalParallelWorld = GetWorld(); 72 G4LogicalVolume* logicalParallelWorld = physicalParallelWorld->GetLogicalVolume(); 73 74 // -- We overlay a sliced geometry on top of the block of concrete in the mass geometry 75 // -- (ie, in the detector construction class), using the same dimensions. 76 // -- [Note that this is a choice : we can use different dimensions and shapes, creating 77 // -- a new solid for that.] 78 // -- For this we: 79 // -- - 1) get back the solid used to create the concrete shield; 80 // -- - 2) create a new logical volume of same shape than the shield and we place 81 // -- inside the slices 82 // -- - 3) place the sliced structure, using the placement of the physical volume of 83 // -- the concrete shield 84 // -- In all this construction, no materials are used, as only the volumes boundaries 85 // -- are of interest. Note that the absence of materials is only possible in parallel 86 // -- geometries. 87 88 // -- 1) get back the solid used to create the concrete shield: 89 // ------------------------------------------------------ 90 91 // -- get back the logical volume of the shield, using its name: 92 G4LogicalVolume* shieldLogical = G4LogicalVolumeStore::GetInstance()->GetVolume("shield.logical"); 93 94 // -- get back the solid, a G4box in this case. We cast the pointer to access later on 95 // -- the G4Box class specific methods: 96 auto shieldSolid = (G4Box*)shieldLogical->GetSolid(); 97 98 // -- we now re-create a logical volume for the mother volume of the slices: 99 G4LogicalVolume* motherForSlicesLogical = 100 new G4LogicalVolume(shieldSolid, // its solid 101 nullptr, // no material 102 "motherForSlices.logical"); // its name 103 104 // -- 2) new logical volume of same shape than the shield and place inside the slices: 105 // ----------------------------------------------------------------------------- 106 107 // -- We create now the slices; we choose 20 slices: 108 const G4int nSlices(20); 109 // -- the solid for slices: 110 G4double halfSliceZ = shieldSolid->GetZHalfLength() / nSlices; 111 G4Box* sliceSolid = new G4Box("slice.solid", shieldSolid->GetXHalfLength(), 112 shieldSolid->GetYHalfLength(), halfSliceZ); 113 114 // -- the logical volume for slices: 115 sliceLogical = new G4LogicalVolume(sliceSolid, // its solid 116 nullptr, // no material 117 "slice.logical"); // its name 118 119 // -- we use a replica, to place the 20 slices in one go, along the Z axis: 120 slicePhysical = new G4PVReplica("slice.physical", // its name 121 sliceLogical, // its logical volume 122 motherForSlicesLogical, // its mother volume 123 kZAxis, // axis of replication 124 nSlices, // number of replica 125 2 * halfSliceZ); // width of replica 126 127 // -- 3) place the sliced structure, using the concrete shield placement: 128 // ---------------------------------------------------------------- 129 130 // -- get back the physical volume of the shield, using its name: 131 // -- (note that we know we have only one physical volume with this name. If we had 132 // -- several, we should loop by ourselves on the store which is of 133 // -- std::vector<G4VPhysicalVolume*> type.) 134 G4VPhysicalVolume* shieldPhysical = 135 G4PhysicalVolumeStore::GetInstance()->GetVolume("shield.physical"); 136 137 // -- get back the translation 138 // -- (we don't try to get back the rotation, we know we used nullptr): 139 G4ThreeVector translation = shieldPhysical->GetObjectTranslation(); 140 141 // -- finally, we place the sliced structure: 142 new G4PVPlacement(nullptr, // no rotation 143 translation, // translate as for the shield 144 motherForSlicesLogical, // its logical volume 145 "motherForSlices.physical", // its name 146 logicalParallelWorld, // its mother volume 147 false, // no boolean operation 148 0); // copy number 149 } 150 151 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... 152 153 void GB06ParallelWorldForSlices::ConstructSD() 154 { 155 // -- Create the biasing operator: 156 auto biasingOperator = new GB06BOptrSplitAndKillByImportance("neutron", "parallelOptr"); 157 // -- Tell it it is active for this parallel geometry, passing the world 158 // -- volume of this geometry : 159 biasingOperator->SetParallelWorld(GetWorld()); 160 161 // -- Attach to the logical volume where the biasing has to be applied: 162 biasingOperator->AttachTo(sliceLogical); 163 164 // -- Create a simple "volume importance" map, linking replica numbers to importances: 165 // -------------------------------------------------------------------------------- 166 // -- we define the map as going from an importance to 2*importance when going from 167 // -- a slice to the next one, in the Z direction. 168 // -- Get back the replica of slices: 169 G4int nReplica = slicePhysical->GetMultiplicity(); 170 // -- We use and fill the map we defined in the biasing operator: 171 G4int importance = 1; 172 for (G4int iReplica = 0; iReplica < nReplica; ++iReplica) { 173 (biasingOperator->GetImportanceMap())[iReplica] = importance; 174 importance *= 2; 175 } 176 } 177