Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // class G4RegularNavigation implementation 26 // class G4RegularNavigation implementation 27 // 27 // 28 // Author: Pedro Arce, May 2007 28 // Author: Pedro Arce, May 2007 29 // << 30 // ------------------------------------------- 29 // -------------------------------------------------------------------- 31 30 32 #include "G4RegularNavigation.hh" 31 #include "G4RegularNavigation.hh" 33 #include "G4TouchableHistory.hh" 32 #include "G4TouchableHistory.hh" 34 #include "G4PhantomParameterisation.hh" 33 #include "G4PhantomParameterisation.hh" 35 #include "G4Material.hh" 34 #include "G4Material.hh" 36 #include "G4NormalNavigation.hh" 35 #include "G4NormalNavigation.hh" 37 #include "G4Navigator.hh" 36 #include "G4Navigator.hh" 38 #include "G4GeometryTolerance.hh" 37 #include "G4GeometryTolerance.hh" 39 #include "G4RegularNavigationHelper.hh" 38 #include "G4RegularNavigationHelper.hh" 40 39 41 //-------------------------------------------- 40 //------------------------------------------------------------------ 42 G4RegularNavigation::G4RegularNavigation() 41 G4RegularNavigation::G4RegularNavigation() 43 { 42 { 44 kCarTolerance = G4GeometryTolerance::GetInst 43 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); 45 fMinStep = 101*kCarTolerance; << 46 } 44 } 47 45 48 46 49 //-------------------------------------------- 47 //------------------------------------------------------------------ 50 G4RegularNavigation::~G4RegularNavigation() = << 48 G4RegularNavigation::~G4RegularNavigation() >> 49 { >> 50 } 51 51 52 52 53 //-------------------------------------------- 53 //------------------------------------------------------------------ 54 G4double G4RegularNavigation:: 54 G4double G4RegularNavigation:: 55 ComputeStep(const G4ThreeV 55 ComputeStep(const G4ThreeVector& localPoint, 56 const G4ThreeV 56 const G4ThreeVector& localDirection, 57 const G4double 57 const G4double currentProposedStepLength, 58 G4double 58 G4double& newSafety, 59 G4Naviga 59 G4NavigationHistory& history, 60 G4bool& 60 G4bool& validExitNormal, 61 G4ThreeV 61 G4ThreeVector& exitNormal, 62 G4bool& 62 G4bool& exiting, 63 G4bool& 63 G4bool& entering, 64 G4VPhysi 64 G4VPhysicalVolume *(*pBlockedPhysical), 65 G4int& b 65 G4int& blockedReplicaNo) 66 { 66 { 67 // This method is never called because to be 67 // This method is never called because to be called the daughter has to be 68 // a regular structure. This would only happ 68 // a regular structure. This would only happen if the track is in the mother 69 // of voxels volume. But the voxels fill com 69 // of voxels volume. But the voxels fill completely their mother, so when a 70 // track enters the mother it automatically 70 // track enters the mother it automatically enters a voxel. Only precision 71 // problems would make this method to be cal 71 // problems would make this method to be called 72 72 73 G4ThreeVector globalPoint = 73 G4ThreeVector globalPoint = 74 history.GetTopTransform().InverseTransform << 74 history.GetTopTransform().InverseTransformPoint(localPoint); 75 G4ThreeVector globalDirection = 75 G4ThreeVector globalDirection = 76 history.GetTopTransform().InverseTran 76 history.GetTopTransform().InverseTransformAxis(localDirection); 77 77 78 G4ThreeVector localPoint2 = localPoint; // t 78 G4ThreeVector localPoint2 = localPoint; // take away constantness 79 79 80 LevelLocate( history, *pBlockedPhysical, blo 80 LevelLocate( history, *pBlockedPhysical, blockedReplicaNo, 81 globalPoint, &globalDirection, 81 globalPoint, &globalDirection, true, localPoint2 ); 82 82 83 83 84 // Get in which voxel it is 84 // Get in which voxel it is 85 // 85 // 86 G4VPhysicalVolume *motherPhysical, *daughter 86 G4VPhysicalVolume *motherPhysical, *daughterPhysical; 87 G4LogicalVolume *motherLogical; 87 G4LogicalVolume *motherLogical; 88 motherPhysical = history.GetTopVolume(); 88 motherPhysical = history.GetTopVolume(); 89 motherLogical = motherPhysical->GetLogicalVo 89 motherLogical = motherPhysical->GetLogicalVolume(); 90 daughterPhysical = motherLogical->GetDaughte 90 daughterPhysical = motherLogical->GetDaughter(0); 91 91 92 auto daughterParam = << 92 G4PhantomParameterisation * daughterParam = 93 (G4PhantomParameterisation*)(daughterPh << 93 (G4PhantomParameterisation*)(daughterPhysical->GetParameterisation()); 94 G4int copyNo = daughterParam ->GetReplicaNo( 94 G4int copyNo = daughterParam ->GetReplicaNo(localPoint,localDirection); 95 95 96 G4ThreeVector voxelTranslation = daughterPar 96 G4ThreeVector voxelTranslation = daughterParam->GetTranslation( copyNo ); 97 G4ThreeVector daughterPoint = localPoint - v 97 G4ThreeVector daughterPoint = localPoint - voxelTranslation; 98 98 99 99 100 // Compute step in voxel 100 // Compute step in voxel 101 // 101 // 102 return fnormalNav->ComputeStep(daughterPoint 102 return fnormalNav->ComputeStep(daughterPoint, 103 localDirectio 103 localDirection, 104 currentPropos 104 currentProposedStepLength, 105 newSafety, 105 newSafety, 106 history, 106 history, 107 validExitNorm 107 validExitNormal, 108 exitNormal, 108 exitNormal, 109 exiting, 109 exiting, 110 entering, 110 entering, 111 pBlockedPhysi 111 pBlockedPhysical, 112 blockedReplic 112 blockedReplicaNo); 113 } 113 } 114 114 115 115 116 //-------------------------------------------- 116 //------------------------------------------------------------------ 117 G4double G4RegularNavigation::ComputeStepSkipp 117 G4double G4RegularNavigation::ComputeStepSkippingEqualMaterials( 118 G4ThreeV 118 G4ThreeVector& localPoint, 119 const G4ThreeV 119 const G4ThreeVector& localDirection, 120 const G4double 120 const G4double currentProposedStepLength, 121 G4double& newS 121 G4double& newSafety, 122 G4NavigationHi 122 G4NavigationHistory& history, 123 G4bool& validE 123 G4bool& validExitNormal, 124 G4ThreeVector& 124 G4ThreeVector& exitNormal, 125 G4bool& exitin 125 G4bool& exiting, 126 G4bool& enteri 126 G4bool& entering, 127 G4VPhysicalVol 127 G4VPhysicalVolume *(*pBlockedPhysical), 128 G4int& blocked 128 G4int& blockedReplicaNo, 129 G4VPhysicalVol 129 G4VPhysicalVolume* pCurrentPhysical) 130 { 130 { 131 G4RegularNavigationHelper::Instance()->Clear 131 G4RegularNavigationHelper::Instance()->ClearStepLengths(); 132 132 133 auto param = << 133 G4PhantomParameterisation *param = 134 (G4PhantomParameterisation*)(pCurrentPhysi 134 (G4PhantomParameterisation*)(pCurrentPhysical->GetParameterisation()); 135 135 136 if( !param->SkipEqualMaterials() ) 136 if( !param->SkipEqualMaterials() ) 137 { 137 { 138 return fnormalNav->ComputeStep(localPoint, 138 return fnormalNav->ComputeStep(localPoint, 139 localDirect 139 localDirection, 140 currentProp 140 currentProposedStepLength, 141 newSafety, 141 newSafety, 142 history, 142 history, 143 validExitNo 143 validExitNormal, 144 exitNormal, 144 exitNormal, 145 exiting, 145 exiting, 146 entering, 146 entering, 147 pBlockedPhy 147 pBlockedPhysical, 148 blockedRepl 148 blockedReplicaNo); 149 } 149 } 150 150 151 151 152 G4double ourStep = 0.; 152 G4double ourStep = 0.; 153 153 154 // To get replica No: transform local point 154 // To get replica No: transform local point to the reference system of the 155 // param container volume 155 // param container volume 156 // 156 // 157 auto ide = (G4int)history.GetDepth(); << 157 G4int ide = history.GetDepth(); 158 G4ThreeVector containerPoint = history.GetTr 158 G4ThreeVector containerPoint = history.GetTransform(ide) 159 .InverseTrans << 159 .InverseTransformPoint(localPoint); 160 << 161 // Point in global frame 160 // Point in global frame 162 // 161 // 163 containerPoint = history.GetTransform(ide).I 162 containerPoint = history.GetTransform(ide).InverseTransformPoint(localPoint); 164 163 165 // Point in voxel parent volume frame 164 // Point in voxel parent volume frame 166 // 165 // 167 containerPoint = history.GetTransform(ide-1) 166 containerPoint = history.GetTransform(ide-1).TransformPoint(containerPoint); 168 167 169 // Store previous voxel translation to move 168 // Store previous voxel translation to move localPoint by the difference 170 // with the new one 169 // with the new one 171 // 170 // 172 G4ThreeVector prevVoxelTranslation = contain 171 G4ThreeVector prevVoxelTranslation = containerPoint - localPoint; 173 172 174 // Do not use the expression below: There ar 173 // Do not use the expression below: There are cases where the 175 // fLastLocatedPointLocal does not give the 174 // fLastLocatedPointLocal does not give the correct answer 176 // (particle reaching a wall and bounced bac 175 // (particle reaching a wall and bounced back, particle travelling through 177 // the wall that is deviated in an step, ... 176 // the wall that is deviated in an step, ...; these are pathological cases 178 // that give wrong answers in G4PhantomParam 177 // that give wrong answers in G4PhantomParameterisation::GetReplicaNo() 179 // 178 // 180 // G4ThreeVector prevVoxelTranslation = para 179 // G4ThreeVector prevVoxelTranslation = param->GetTranslation( copyNo ); 181 180 182 G4int copyNo = param->GetReplicaNo(container 181 G4int copyNo = param->GetReplicaNo(containerPoint,localDirection); 183 182 184 G4Material* currentMate = param->ComputeMate 183 G4Material* currentMate = param->ComputeMaterial( copyNo, nullptr, nullptr ); 185 G4VSolid* voxelBox = pCurrentPhysical->GetLo 184 G4VSolid* voxelBox = pCurrentPhysical->GetLogicalVolume()->GetSolid(); 186 185 187 G4VSolid* containerSolid = param->GetContain 186 G4VSolid* containerSolid = param->GetContainerSolid(); 188 G4Material* nextMate; 187 G4Material* nextMate; 189 G4bool bFirstStep = true; 188 G4bool bFirstStep = true; 190 G4double newStep; 189 G4double newStep; 191 G4double totalNewStep = 0.; 190 G4double totalNewStep = 0.; 192 191 193 // Loop while same material is found 192 // Loop while same material is found 194 // 193 // 195 // << 194 for( ;; ) 196 fNumberZeroSteps = 0; << 197 for( G4int ii = 0; ii < fNoStepsAllowed+1; + << 198 { 195 { 199 if( ii == fNoStepsAllowed ) { << 200 // Must kill this stuck track << 201 // << 202 G4ThreeVector pGlobalpoint = history.Get << 203 .InverseTra << 204 std::ostringstream message; << 205 message << "G4RegularNavigation::Compute << 206 << "Stuck Track: potential geometry or << 207 << G4endl << 208 << " Track stuck, moving for mo << 209 << ii << " steps" << G4endl << 210 << "- at point " << pGlobalpoint << G4 << 211 << " local direction: " << loca << 212 G4Exception("G4RegularNavigation::Comput << 213 "GeomRegNav1001", << 214 EventMustBeAborted, << 215 message); << 216 } << 217 newStep = voxelBox->DistanceToOut( localPo 196 newStep = voxelBox->DistanceToOut( localPoint, localDirection ); 218 fLastStepWasZero = (newStep<fMinStep); << 197 219 if( fLastStepWasZero ) << 220 { << 221 ++fNumberZeroSteps; << 222 #ifdef G4DEBUG_NAVIGATION << 223 if( fNumberZeroSteps > 1 ) << 224 { << 225 G4ThreeVector pGlobalpoint = history.G << 226 .InverseT << 227 std::ostringstream message; << 228 message.precision(16); << 229 message << "G4RegularNavigation::Compute << 230 << fNumberZeroSteps << 231 << ", at " << pGlobalpoint << 232 << ", nav-comp-step calls # " << i << 233 << ", Step= " << newStep; << 234 G4Exception("G4RegularNavigation:: << 235 "GeomRegNav1002", Just << 236 "Potential overlap in << 237 } << 238 #endif << 239 if( fNumberZeroSteps > fActionThreshold_ << 240 { << 241 // Act to recover this stuck track. Pu << 242 // << 243 newStep = std::min(101*kCarTolerance*s << 244 #ifdef G4DEBUG_NAVIGATION << 245 G4ThreeVector pGlobalpoint = history.G << 246 .Invers << 247 std::ostringstream message; << 248 message.precision(16); << 249 message << "Track stuck or not moving. << 250 << " Track stuc << 251 << fNumberZeroSteps << " << 252 << "- at point " << pGlo << 253 << " (local point " << l << 254 << " local direct << 255 << " Potential << 256 << G4endl << 257 << " Trying pus << 258 G4Exception("G4RegularNavigation << 259 "GeomRegNav1003", Ju << 260 "Potential overlap i << 261 #endif << 262 } << 263 if( fNumberZeroSteps > fAbandonThreshold << 264 { << 265 // Must kill this stuck track << 266 // << 267 G4ThreeVector pGlobalpoint = history.G << 268 .Inv << 269 std::ostringstream message; << 270 message << "G4RegularNavigation::Compu << 271 << "Stuck Track: potential geometry << 272 << G4endl << 273 << " Track stuck, not moving << 274 << fNumberZeroSteps << " steps" << G << 275 << "- at point " << pGlobalpoint << << 276 << " local direction: " << lo << 277 G4Exception("G4RegularNavigation::Comp << 278 "GeomRegNav1004", << 279 EventMustBeAborted, << 280 message); << 281 } << 282 } << 283 else << 284 { << 285 // reset the zero step counter when a no << 286 fNumberZeroSteps = 0; << 287 } << 288 if( (bFirstStep) && (newStep < currentProp 198 if( (bFirstStep) && (newStep < currentProposedStepLength) ) 289 { 199 { 290 exiting = true; 200 exiting = true; 291 } 201 } 292 bFirstStep = false; 202 bFirstStep = false; 293 203 294 newStep += kCarTolerance; // Avoid preci 204 newStep += kCarTolerance; // Avoid precision problems 295 ourStep += newStep; 205 ourStep += newStep; 296 totalNewStep += newStep; 206 totalNewStep += newStep; 297 207 298 // Physical process is limiting the step, 208 // Physical process is limiting the step, don't continue 299 // 209 // 300 if(std::fabs(totalNewStep-currentProposedS 210 if(std::fabs(totalNewStep-currentProposedStepLength) < kCarTolerance) 301 { 211 { 302 return currentProposedStepLength; 212 return currentProposedStepLength; 303 } 213 } 304 if(totalNewStep > currentProposedStepLengt 214 if(totalNewStep > currentProposedStepLength) 305 { 215 { 306 G4RegularNavigationHelper::Instance()-> 216 G4RegularNavigationHelper::Instance()-> 307 AddStepLength(copyNo, newStep-totalNew 217 AddStepLength(copyNo, newStep-totalNewStep+currentProposedStepLength); 308 return currentProposedStepLength; 218 return currentProposedStepLength; 309 } 219 } 310 G4RegularNavigationHelper::Instance()->Add << 220 else >> 221 { >> 222 G4RegularNavigationHelper::Instance()->AddStepLength( copyNo, newStep ); >> 223 } >> 224 311 225 312 // Move container point until wall of voxe 226 // Move container point until wall of voxel 313 // 227 // 314 containerPoint += newStep*localDirection; 228 containerPoint += newStep*localDirection; 315 if( containerSolid->Inside( containerPoint 229 if( containerSolid->Inside( containerPoint ) != kInside ) 316 { 230 { 317 break; 231 break; 318 } 232 } 319 233 320 // Get copyNo and translation of new voxel 234 // Get copyNo and translation of new voxel 321 // 235 // 322 copyNo = param->GetReplicaNo(containerPoin 236 copyNo = param->GetReplicaNo(containerPoint, localDirection); 323 G4ThreeVector voxelTranslation = param->Ge 237 G4ThreeVector voxelTranslation = param->GetTranslation( copyNo ); 324 238 325 // Move local point until wall of voxel an 239 // Move local point until wall of voxel and then put it in the new voxel 326 // local coordinates 240 // local coordinates 327 // 241 // 328 localPoint += newStep*localDirection; 242 localPoint += newStep*localDirection; 329 localPoint += prevVoxelTranslation - voxel 243 localPoint += prevVoxelTranslation - voxelTranslation; 330 244 331 prevVoxelTranslation = voxelTranslation; 245 prevVoxelTranslation = voxelTranslation; 332 246 333 // Check if material of next voxel is the 247 // Check if material of next voxel is the same as that of the current voxel >> 248 // 334 nextMate = param->ComputeMaterial( copyNo, 249 nextMate = param->ComputeMaterial( copyNo, nullptr, nullptr ); 335 250 336 if( currentMate != nextMate ) { break; } 251 if( currentMate != nextMate ) { break; } 337 } 252 } 338 253 339 return ourStep; 254 return ourStep; 340 } 255 } 341 256 342 257 343 //-------------------------------------------- 258 //------------------------------------------------------------------ 344 G4double 259 G4double 345 G4RegularNavigation::ComputeSafety(const G4Thr 260 G4RegularNavigation::ComputeSafety(const G4ThreeVector& localPoint, 346 const G4Nav 261 const G4NavigationHistory& history, 347 const G4dou 262 const G4double pMaxLength) 348 { 263 { 349 // This method is never called because to be 264 // This method is never called because to be called the daughter has to be a 350 // regular structure. This would only happen 265 // regular structure. This would only happen if the track is in the mother of 351 // voxels volume. But the voxels fill comple 266 // voxels volume. But the voxels fill completely their mother, so when a 352 // track enters the mother it automatically 267 // track enters the mother it automatically enters a voxel. Only precision 353 // problems would make this method to be cal 268 // problems would make this method to be called 354 269 355 // Compute step in voxel 270 // Compute step in voxel 356 // 271 // 357 return fnormalNav->ComputeSafety(localPoint, 272 return fnormalNav->ComputeSafety(localPoint, 358 history, 273 history, 359 pMaxLength 274 pMaxLength ); 360 } 275 } 361 276 362 277 363 //-------------------------------------------- 278 //------------------------------------------------------------------ 364 G4bool 279 G4bool 365 G4RegularNavigation::LevelLocate( G4Navigation 280 G4RegularNavigation::LevelLocate( G4NavigationHistory& history, 366 const G4VPhy 281 const G4VPhysicalVolume* , 367 const G4int 282 const G4int , 368 const G4Thre 283 const G4ThreeVector& globalPoint, 369 const G4Thre 284 const G4ThreeVector* globalDirection, 370 const G4bool 285 const G4bool, // pLocatedOnEdge, 371 G4ThreeVecto 286 G4ThreeVector& localPoint ) 372 { 287 { 373 G4VPhysicalVolume *motherPhysical, *pPhysica 288 G4VPhysicalVolume *motherPhysical, *pPhysical; 374 G4PhantomParameterisation *pParam; 289 G4PhantomParameterisation *pParam; 375 G4LogicalVolume *motherLogical; 290 G4LogicalVolume *motherLogical; 376 G4ThreeVector localDir; 291 G4ThreeVector localDir; 377 G4int replicaNo; 292 G4int replicaNo; 378 293 379 motherPhysical = history.GetTopVolume(); 294 motherPhysical = history.GetTopVolume(); 380 motherLogical = motherPhysical->GetLogicalVo 295 motherLogical = motherPhysical->GetLogicalVolume(); 381 296 382 pPhysical = motherLogical->GetDaughter(0); 297 pPhysical = motherLogical->GetDaughter(0); 383 pParam = (G4PhantomParameterisation*)(pPhysi 298 pParam = (G4PhantomParameterisation*)(pPhysical->GetParameterisation()); 384 299 385 // Save parent history in touchable history 300 // Save parent history in touchable history 386 // ... for use as parent t-h in ComputeMater 301 // ... for use as parent t-h in ComputeMaterial method of param 387 // 302 // 388 G4TouchableHistory parentTouchable( history 303 G4TouchableHistory parentTouchable( history ); 389 304 390 // Get local direction 305 // Get local direction 391 // 306 // 392 if( globalDirection != nullptr ) << 307 if( globalDirection ) 393 { 308 { 394 localDir = history.GetTopTransform().Trans 309 localDir = history.GetTopTransform().TransformAxis(*globalDirection); 395 } 310 } 396 else 311 else 397 { 312 { 398 localDir = G4ThreeVector(0.,0.,0.); 313 localDir = G4ThreeVector(0.,0.,0.); 399 } 314 } 400 315 401 // Enter this daughter 316 // Enter this daughter 402 // 317 // 403 replicaNo = pParam->GetReplicaNo( localPoint 318 replicaNo = pParam->GetReplicaNo( localPoint, localDir ); 404 319 405 if( replicaNo < 0 || replicaNo >= G4int(pPar << 320 if( replicaNo < 0 || replicaNo >= G4int(pParam->GetNoVoxel()) ) 406 { 321 { 407 return false; 322 return false; 408 } 323 } 409 324 410 // Set the correct copy number in physical 325 // Set the correct copy number in physical 411 // 326 // 412 pPhysical->SetCopyNo(replicaNo); 327 pPhysical->SetCopyNo(replicaNo); 413 pParam->ComputeTransformation(replicaNo,pPhy 328 pParam->ComputeTransformation(replicaNo,pPhysical); 414 329 415 history.NewLevel(pPhysical, kParameterised, 330 history.NewLevel(pPhysical, kParameterised, replicaNo ); 416 localPoint = history.GetTopTransform().Trans 331 localPoint = history.GetTopTransform().TransformPoint(globalPoint); 417 332 418 // Set the correct solid and material in Log 333 // Set the correct solid and material in Logical Volume 419 // 334 // 420 G4LogicalVolume *pLogical = pPhysical->GetLo 335 G4LogicalVolume *pLogical = pPhysical->GetLogicalVolume(); 421 336 422 pLogical->UpdateMaterial(pParam->ComputeMate 337 pLogical->UpdateMaterial(pParam->ComputeMaterial(replicaNo, 423 pPhysical, &parentT 338 pPhysical, &parentTouchable) ); 424 return true; 339 return true; 425 } 340 } 426 341