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 // 27 /// \brief {Duplicated version of G4TransportationManager. 28 /// This class just contains the pointer to the navigator object of the 29 /// simulation.} 30 // 31 // History: 32 // ----------- 33 // 34 // ------------------------------------------------------------------- 35 36 #include "G4ITTransportationManager.hh" 37 #include "G4TransportationManager.hh" 38 #include "G4ITNavigator.hh" 39 #include "G4ITSafetyHelper.hh" 40 #include "G4PVPlacement.hh" 41 42 G4ThreadLocal G4ITTransportationManager* 43 G4ITTransportationManager::fpInstance(nullptr); 44 45 G4ITTransportationManager::G4ITTransportationManager() 46 { 47 Initialize(); 48 } 49 50 G4ITTransportationManager::~G4ITTransportationManager() 51 { 52 ClearNavigators(); 53 delete fpSafetyHelper; 54 } 55 56 void G4ITTransportationManager::DeleteInstance() 57 { 58 if (fpInstance != nullptr) 59 { 60 delete fpInstance; 61 fpInstance = nullptr; 62 } 63 } 64 65 // ---------------------------------------------------------------------------- 66 // ClearNavigators() 67 // 68 // Clear collection of navigators and delete allocated objects. 69 // Called only by the class destructor. 70 // 71 void G4ITTransportationManager::ClearNavigators() 72 { 73 std::vector<G4ITNavigator*>::iterator pNav; 74 for (pNav = fNavigators.begin(); pNav != fNavigators.end(); pNav++) 75 { 76 delete *pNav; 77 } 78 fNavigators.clear(); 79 fActiveNavigators.clear(); 80 fWorlds.clear(); 81 } 82 83 void G4ITTransportationManager::Initialize() 84 { 85 // Create the navigator for tracking and activate it; add to collections 86 // 87 auto trackingNavigator = new G4ITNavigator(); 88 trackingNavigator->Activate(true); 89 G4Navigator* navForTracking = 90 G4TransportationManager::GetTransportationManager() 91 ->GetNavigatorForTracking(); 92 G4VPhysicalVolume* world = navForTracking->GetWorldVolume(); 93 trackingNavigator->SetWorldVolume(world); 94 fNavigators.push_back(trackingNavigator); 95 fActiveNavigators.push_back(trackingNavigator); 96 //fWorlds.push_back(world); // NULL registered 97 98 size_t n_worlds = G4TransportationManager::GetTransportationManager() 99 ->GetNoWorlds(); 100 auto it = 101 G4TransportationManager::GetTransportationManager()->GetWorldsIterator(); 102 103 for (size_t i = 0; i < n_worlds; i++, it++) 104 { 105 fWorlds.push_back(*it); 106 } 107 fpSafetyHelper = new G4ITSafetyHelper(); 108 } 109 110 G4ITTransportationManager* G4ITTransportationManager::GetTransportationManager() 111 { 112 if (fpInstance == nullptr) fpInstance = new G4ITTransportationManager; 113 return fpInstance; 114 } 115 116 // ---------------------------------------------------------------------------- 117 // GetParallelWorld() 118 // 119 // Provided the name of a world volume, returns the associated world pointer. 120 // If not existing, create (allocate) and register it in the collection. 121 // 122 G4VPhysicalVolume* 123 G4ITTransportationManager::GetParallelWorld(const G4String& worldName) 124 { 125 G4VPhysicalVolume* wPV = IsWorldExisting(worldName); 126 if (wPV == nullptr) 127 { 128 wPV = GetNavigatorForTracking()->GetWorldVolume(); 129 G4LogicalVolume* wLV = wPV->GetLogicalVolume(); 130 wLV = new G4LogicalVolume(wLV->GetSolid(), nullptr, worldName); 131 wPV = new G4PVPlacement(wPV->GetRotation(), wPV->GetTranslation(), wLV, 132 worldName, nullptr, false, 0); 133 RegisterWorld(wPV); 134 } 135 return wPV; 136 } 137 138 // ---------------------------------------------------------------------------- 139 // GetNavigator() 140 // 141 // Provided the name of a world volume, returns the associated navigator. 142 // If not existing, create it and register it in the collection, throw an 143 // exception if the associated parallel world does not exist. 144 // 145 G4ITNavigator* G4ITTransportationManager::GetNavigator(const G4String& worldName) 146 { 147 // If already existing, return the stored pointer to the navigator 148 // 149 std::vector<G4ITNavigator*>::iterator pNav; 150 for (pNav = fNavigators.begin(); pNav != fNavigators.end(); pNav++) 151 { 152 if ((*pNav)->GetWorldVolume()->GetName() == worldName) 153 { 154 return *pNav; 155 } 156 } 157 158 // Check if world of that name already exists, 159 // create a navigator and register it 160 // 161 G4ITNavigator* aNavigator = nullptr; 162 G4VPhysicalVolume* aWorld = IsWorldExisting(worldName); 163 if (aWorld != nullptr) 164 { 165 aNavigator = new G4ITNavigator(); 166 aNavigator->SetWorldVolume(aWorld); 167 fNavigators.push_back(aNavigator); 168 } 169 else 170 { 171 G4String message = "World volume with name -" 172 + worldName 173 + "- does not exist. Create it first by GetParallelWorld() method!"; 174 G4Exception("G4ITTransportationManager::GetNavigator(name)", "GeomNav0002", 175 FatalException, message); 176 } 177 178 return aNavigator; 179 } 180 181 // ---------------------------------------------------------------------------- 182 // GetNavigator() 183 // 184 // Provided a pointer to a world volume, returns the associated navigator. 185 // Create it in case not existing and add it to the collection. 186 // If world volume not existing, issue an exception. 187 // 188 G4ITNavigator* G4ITTransportationManager::GetNavigator(G4VPhysicalVolume* aWorld) 189 { 190 std::vector<G4ITNavigator*>::iterator pNav; 191 for (pNav = fNavigators.begin(); pNav != fNavigators.end(); pNav++) 192 { 193 if ((*pNav)->GetWorldVolume() == aWorld) 194 { 195 return *pNav; 196 } 197 } 198 G4ITNavigator* aNavigator = nullptr; 199 auto pWorld = std::find(fWorlds.begin(), 200 fWorlds.end(), 201 aWorld); 202 if (pWorld != fWorlds.end()) 203 { 204 aNavigator = new G4ITNavigator(); 205 aNavigator->SetWorldVolume(aWorld); 206 fNavigators.push_back(aNavigator); 207 } 208 else 209 { 210 G4String message = "World volume with name -" 211 + aWorld->GetName() 212 + "- does not exist. Create it first by GetParallelWorld() method!"; 213 G4Exception("G4ITTransportationManager::GetNavigator(pointer)", 214 "GeomNav0002", FatalException, message); 215 } 216 217 return aNavigator; 218 } 219 220 // ---------------------------------------------------------------------------- 221 // DeRegisterNavigator() 222 // 223 // Provided a pointer to an already allocated navigator object, removes the 224 // associated entry in the navigators collection (remove pair) but does not 225 // delete the actual pointed object, which is still owned by the caller. 226 // The navigator for tracking -cannot- be deregistered. 227 // 228 void G4ITTransportationManager::DeRegisterNavigator(G4ITNavigator* aNavigator) 229 { 230 if (aNavigator == fNavigators[0]) 231 { 232 G4Exception("G4ITTransportationManager::DeRegisterNavigator()", 233 "GeomNav0003", FatalException, 234 "The navigator for tracking CANNOT be deregistered!"); 235 } 236 auto pNav = std::find(fNavigators.begin(), 237 fNavigators.end(), 238 aNavigator); 239 if (pNav != fNavigators.end()) 240 { 241 // Deregister associated world volume 242 // 243 DeRegisterWorld((*pNav)->GetWorldVolume()); 244 245 // Deregister the navigator 246 // 247 fNavigators.erase(pNav); 248 } 249 else 250 { 251 G4String message = "Navigator for volume -" 252 + aNavigator->GetWorldVolume()->GetName() + "- not found in memory!"; 253 G4Exception("G4ITTransportationManager::DeRegisterNavigator()", 254 "GeomNav1002", JustWarning, message); 255 } 256 } 257 258 // ---------------------------------------------------------------------------- 259 // ActivateNavigator() 260 // 261 // Provided a pointer to an already allocated navigator object, set to 'true' 262 // the associated activation flag for the navigator in the collection. 263 // If the provided navigator is not already registered, issue a warning 264 // Return the index of the activated navigator. This index should be used for 265 // ComputeStep() method of G4PathFinder. 266 // 267 G4int G4ITTransportationManager::ActivateNavigator(G4ITNavigator* aNavigator) 268 { 269 auto pNav = std::find(fNavigators.begin(), 270 fNavigators.end(), 271 aNavigator); 272 if (pNav == fNavigators.end()) 273 { 274 G4String message = "Navigator for volume -" 275 + aNavigator->GetWorldVolume()->GetName() + "- not found in memory!"; 276 G4Exception("G4ITTransportationManager::ActivateNavigator()", "GeomNav1002", 277 JustWarning, message); 278 return -1; 279 } 280 281 aNavigator->Activate(true); 282 G4int id = 0; 283 std::vector<G4ITNavigator*>::iterator pActiveNav; 284 for (pActiveNav = fActiveNavigators.begin(); 285 pActiveNav != fActiveNavigators.end(); pActiveNav++) 286 { 287 if (*pActiveNav == aNavigator) 288 { 289 return id; 290 } 291 id++; 292 } 293 294 fActiveNavigators.push_back(aNavigator); 295 return id; 296 } 297 298 // ---------------------------------------------------------------------------- 299 // DeActivateNavigator() 300 // 301 // Provided a pointer to an already allocated navigator object, set to 'false' 302 // the associated activation flag in the navigators collection. 303 // If the provided navigator is not already registered, issue a warning. 304 // 305 void G4ITTransportationManager::DeActivateNavigator(G4ITNavigator* aNavigator) 306 { 307 auto pNav = std::find(fNavigators.begin(), 308 fNavigators.end(), 309 aNavigator); 310 if (pNav != fNavigators.end()) 311 { 312 (*pNav)->Activate(false); 313 } 314 else 315 { 316 G4String message = "Navigator for volume -" 317 + aNavigator->GetWorldVolume()->GetName() + "- not found in memory!"; 318 G4Exception("G4ITTransportationManager::DeActivateNavigator()", 319 "GeomNav1002", JustWarning, message); 320 } 321 322 auto pActiveNav = std::find( 323 fActiveNavigators.begin(), fActiveNavigators.end(), aNavigator); 324 if (pActiveNav != fActiveNavigators.end()) 325 { 326 fActiveNavigators.erase(pActiveNav); 327 } 328 } 329 330 // ---------------------------------------------------------------------------- 331 // InactivateAll() 332 // 333 // Inactivate all the navigators except for the tracking one, and clear the 334 // store of active navigators. 335 // 336 void G4ITTransportationManager::InactivateAll() 337 { 338 std::vector<G4ITNavigator*>::iterator pNav; 339 for (pNav = fActiveNavigators.begin(); pNav != fActiveNavigators.end(); 340 pNav++) 341 { 342 (*pNav)->Activate(false); 343 } 344 fActiveNavigators.clear(); 345 346 // Restore status for the navigator for tracking 347 // 348 fNavigators[0]->Activate(true); 349 fActiveNavigators.push_back(fNavigators[0]); 350 } 351 352 // ---------------------------------------------------------------------------- 353 // IsWorldExisting() 354 // 355 // Verify existance or not of an istance of the world volume with 356 // same name in the collection. Return the world pointer if existing. 357 // 358 G4VPhysicalVolume* 359 G4ITTransportationManager::IsWorldExisting(const G4String& name) 360 { 361 auto pWorld = fWorlds.begin(); 362 if (*pWorld == 0) 363 { 364 *pWorld = fNavigators[0]->GetWorldVolume(); 365 } 366 367 for (pWorld = fWorlds.begin(); pWorld != fWorlds.end(); pWorld++) 368 { 369 if ((*pWorld)->GetName() == name) 370 { 371 return *pWorld; 372 } 373 } 374 return nullptr; 375 } 376 377 // ---------------------------------------------------------------------------- 378 // RegisterWorld() 379 // 380 // Provided a pointer to an already allocated world object, check and add the 381 // associated entry in the worlds collection. Return 'true' if registration 382 // succeeds and the new entry is created. 383 // 384 G4bool G4ITTransportationManager::RegisterWorld(G4VPhysicalVolume* aWorld) 385 { 386 G4bool done = false; 387 388 auto pWorld = std::find(fWorlds.begin(), 389 fWorlds.end(), 390 aWorld); 391 if (pWorld == fWorlds.end()) 392 { 393 fWorlds.push_back(aWorld); 394 done = true; 395 } 396 return done; 397 } 398 399 // ---------------------------------------------------------------------------- 400 // DeRegisterWorld() 401 // 402 // Provided a pointer to an already allocated world object, removes the 403 // associated entry in the worlds collection but does not delete the actual 404 // pointed object, which is still owned by the caller. 405 // 406 void G4ITTransportationManager::DeRegisterWorld(G4VPhysicalVolume* aWorld) 407 { 408 auto pWorld = std::find(fWorlds.begin(), 409 fWorlds.end(), 410 aWorld); 411 if (pWorld != fWorlds.end()) 412 { 413 fWorlds.erase(pWorld); 414 } 415 else 416 { 417 G4String message = "World volume -" + aWorld->GetName() 418 + "- not found in memory!"; 419 G4Exception("G4ITTransportationManager::DeRegisterWorld()", "GeomNav1002", 420 JustWarning, message); 421 } 422 } 423