Geant4 Cross Reference |
1 // 1 2 // ******************************************* 3 // * License and Disclaimer 4 // * 5 // * The Geant4 software is copyright of th 6 // * the Geant4 Collaboration. It is provided 7 // * conditions of the Geant4 Software License 8 // * LICENSE and available at http://cern.ch/ 9 // * include a list of copyright holders. 10 // * 11 // * Neither the authors of this software syst 12 // * institutes,nor the agencies providing fin 13 // * work make any representation or warran 14 // * regarding this software system or assum 15 // * use. Please see the license in the file 16 // * for the full disclaimer and the limitatio 17 // * 18 // * This code implementation is the result 19 // * technical work of the GEANT4 collaboratio 20 // * By using, copying, modifying or distri 21 // * any work based on the software) you ag 22 // * use in resulting scientific publicati 23 // * acceptance of all terms of the Geant4 Sof 24 // ******************************************* 25 // 26 // G4GeometryWorkspace - implementation 27 // 28 // Authors: John Apostolakis (CERN), Andrea Do 29 // ------------------------------------------- 30 31 #include "G4GeometryWorkspace.hh" 32 #include "G4PhysicalVolumeStore.hh" 33 #include "G4AutoLock.hh" 34 35 namespace 36 { 37 G4Mutex mutex_init = G4MUTEX_INITIALIZER; 38 G4GeometryWorkspace::pool_type thePool; 39 } 40 41 // ------------------------------------------- 42 // 43 G4GeometryWorkspace::pool_type* G4GeometryWork 44 { 45 return &thePool; 46 } 47 48 // ------------------------------------------- 49 // 50 G4GeometryWorkspace::G4GeometryWorkspace() 51 { 52 fpLogicalVolumeSIM= 53 &const_cast<G4LVManager&>(G4LogicalVolum 54 fpPhysicalVolumeSIM= 55 &const_cast<G4PVManager&>( G4VPhysicalVo 56 fpReplicaSIM= 57 &const_cast<G4PVRManager&>(G4PVReplica:: 58 fpRegionSIM= 59 &const_cast<G4RegionManager&>(G4Region:: 60 61 // Create a work area for Logical Volumes in 62 // then capture its address 63 // 64 InitialiseWorkspace(); 65 66 fLogicalVolumeOffset = fpLogicalVolumeSIM->G 67 68 fPhysicalVolumeOffset = fpPhysicalVolumeSIM- 69 70 fReplicaOffset = fpReplicaSIM->GetOffset(); 71 72 fRegionOffset = fpRegionSIM->GetOffset(); 73 } 74 75 // ------------------------------------------- 76 // 77 void 78 G4GeometryWorkspace::UseWorkspace() 79 { 80 // Geometry related, split classes mechanism 81 // for this thread 82 // 83 fpLogicalVolumeSIM->UseWorkArea(fLogicalVolu 84 fpPhysicalVolumeSIM->UseWorkArea(fPhysicalVo 85 86 fpReplicaSIM->UseWorkArea(fReplicaOffset); 87 fpRegionSIM->UseWorkArea(fRegionOffset); 88 89 // When recycling a workspace 90 // - it must be a lightweight operation, t 91 // - so it must NOT Initialise anything! 92 // Do not call InitialisePhysicalVolumes(); 93 } 94 95 // ------------------------------------------- 96 // 97 void G4GeometryWorkspace::ReleaseWorkspace() 98 { 99 fpLogicalVolumeSIM->UseWorkArea(nullptr); 100 fpPhysicalVolumeSIM->UseWorkArea(nullptr); 101 102 fpReplicaSIM->UseWorkArea(nullptr); 103 fpRegionSIM->UseWorkArea(nullptr); 104 } 105 106 // ------------------------------------------- 107 // 108 void G4GeometryWorkspace::InitialisePhysicalVo 109 { 110 G4PhysicalVolumeStore* physVolStore = G4Phys 111 for (auto physVol : *physVolStore) 112 { 113 G4LogicalVolume *logicalVol = physVol->Get 114 115 // Use shadow pointer 116 // 117 G4VSolid* solid = logicalVol->GetMasterSol 118 auto g4PVReplica = dynamic_cast<G4PVReplic 119 if (g4PVReplica == nullptr) 120 { 121 // Placement volume 122 // 123 logicalVol->InitialiseWorker(logicalVol, 124 } 125 else 126 { 127 g4PVReplica->InitialiseWorker(g4PVReplic 128 logicalVol->InitialiseWorker(logicalVol, 129 130 // If the replica's solid (in LV) is cha 131 // it must be thread-private 132 // 133 CloneReplicaSolid( g4PVReplica ); 134 } 135 } 136 } 137 138 // ------------------------------------------- 139 // Create a clone of the solid for this replic 140 // 141 G4bool G4GeometryWorkspace::CloneReplicaSolid( 142 { 143 G4LogicalVolume* logicalV = replicaPV->GetLo 144 G4VSolid* solid = logicalV->GetSolid(); 145 146 G4AutoLock aLock(&mutex_init); 147 G4VSolid* workerSolid = solid->Clone(); 148 aLock.unlock(); 149 150 if( workerSolid != nullptr ) 151 { 152 logicalV->InitialiseWorker(logicalV,worker 153 } 154 else 155 { 156 // In the case that not all solids support 157 // method, we do similar thing here to dyn 158 // and then get the clone method 159 // 160 G4ExceptionDescription ed; 161 ed << "ERROR - Unable to initialise geomet 162 << "A solid lacks the Clone() method - 163 << " Type of solid: " << solid->GetEn 164 << " Parameters: " << *solid; 165 G4Exception("G4GeometryWorkspace::CloneRep 166 "GeomVol0003", FatalException, 167 return false; 168 } 169 return true; // It Worked 170 } 171 172 // ------------------------------------------- 173 // 174 void G4GeometryWorkspace::InitialiseWorkspace( 175 { 176 // Geometry related, split classes mechanism 177 // Do *NOT* instantiate sub-instance for thi 178 // 179 fpLogicalVolumeSIM->SlaveCopySubInstanceArra 180 fpPhysicalVolumeSIM->SlaveCopySubInstanceArr 181 fpReplicaSIM->SlaveCopySubInstanceArray(); 182 fpRegionSIM->SlaveInitializeSubInstance(); 183 184 InitialisePhysicalVolumes(); 185 } 186 187 // ------------------------------------------- 188 // 189 void G4GeometryWorkspace::DestroyWorkspace() 190 { 191 G4PhysicalVolumeStore* physVolStore = G4Phys 192 for (auto physVol : *physVolStore) 193 { 194 G4LogicalVolume* logicalVol = physVol->Get 195 auto g4PVReplica = dynamic_cast<G4PVReplic 196 if (g4PVReplica != nullptr) 197 { 198 g4PVReplica->TerminateWorker(g4PVReplica 199 } 200 logicalVol->TerminateWorker(logicalVol); 201 } 202 203 // Threads may attempt to free memory simult 204 // Need a lock to guarantee thread safety 205 // 206 G4AutoLock aLock(&mutex_init); 207 fpLogicalVolumeSIM->FreeSlave(); 208 fpPhysicalVolumeSIM->FreeSlave(); 209 fpReplicaSIM->FreeSlave(); 210 fpRegionSIM->FreeSlave(); 211 aLock.unlock(); 212 } 213