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 G4NormalNavigation Implementation 26 // class G4NormalNavigation Implementation 27 // 27 // 28 // Author: P.Kent, 1996 28 // Author: P.Kent, 1996 29 // 29 // 30 // ------------------------------------------- 30 // -------------------------------------------------------------------- 31 31 32 #include "G4NormalNavigation.hh" 32 #include "G4NormalNavigation.hh" 33 #include "G4NavigationLogger.hh" 33 #include "G4NavigationLogger.hh" 34 #include "G4AffineTransform.hh" 34 #include "G4AffineTransform.hh" 35 35 36 // ******************************************* 36 // ******************************************************************** 37 // Constructor 37 // Constructor 38 // ******************************************* 38 // ******************************************************************** 39 // 39 // 40 G4NormalNavigation::G4NormalNavigation() 40 G4NormalNavigation::G4NormalNavigation() 41 { 41 { 42 fLogger = new G4NavigationLogger("G4NormalNa 42 fLogger = new G4NavigationLogger("G4NormalNavigation"); 43 } 43 } 44 44 45 // ******************************************* 45 // ******************************************************************** 46 // Destructor 46 // Destructor 47 // ******************************************* 47 // ******************************************************************** 48 // 48 // 49 G4NormalNavigation::~G4NormalNavigation() 49 G4NormalNavigation::~G4NormalNavigation() 50 { 50 { 51 delete fLogger; 51 delete fLogger; 52 } 52 } 53 53 54 // ******************************************* 54 // ******************************************************************** 55 // ComputeStep 55 // ComputeStep 56 // ******************************************* 56 // ******************************************************************** 57 // 57 // 58 // On entry 58 // On entry 59 // exitNormal, validExitNormal: for previo 59 // exitNormal, validExitNormal: for previous exited volume (daughter) 60 // 60 // 61 // On exit 61 // On exit 62 // exitNormal, validExitNormal: for mother 62 // exitNormal, validExitNormal: for mother, if exiting it (else unchanged) 63 G4double 63 G4double 64 G4NormalNavigation::ComputeStep(const G4ThreeV 64 G4NormalNavigation::ComputeStep(const G4ThreeVector& localPoint, 65 const G4ThreeV 65 const G4ThreeVector& localDirection, 66 const G4double 66 const G4double currentProposedStepLength, 67 G4double 67 G4double& newSafety, 68 G4Naviga 68 G4NavigationHistory& history, 69 G4bool& 69 G4bool& validExitNormal, 70 G4ThreeV 70 G4ThreeVector& exitNormal, 71 G4bool& 71 G4bool& exiting, 72 G4bool& 72 G4bool& entering, 73 G4VPhysi 73 G4VPhysicalVolume* (*pBlockedPhysical), 74 G4int& b 74 G4int& blockedReplicaNo) 75 { 75 { 76 G4VPhysicalVolume *motherPhysical, *samplePh 76 G4VPhysicalVolume *motherPhysical, *samplePhysical, 77 *blockedExitedVol = nullpt 77 *blockedExitedVol = nullptr; 78 G4LogicalVolume *motherLogical; 78 G4LogicalVolume *motherLogical; 79 G4VSolid *motherSolid; 79 G4VSolid *motherSolid; 80 G4ThreeVector sampleDirection; 80 G4ThreeVector sampleDirection; 81 G4double ourStep = currentProposedStepLength 81 G4double ourStep = currentProposedStepLength, ourSafety; 82 G4double motherSafety, motherStep = DBL_MAX; 82 G4double motherSafety, motherStep = DBL_MAX; 83 G4long localNoDaughters, sampleNo; << 83 G4int localNoDaughters, sampleNo; 84 G4bool motherValidExitNormal = false; 84 G4bool motherValidExitNormal = false; 85 G4ThreeVector motherExitNormal; 85 G4ThreeVector motherExitNormal; 86 86 87 motherPhysical = history.GetTopVolume(); 87 motherPhysical = history.GetTopVolume(); 88 motherLogical = motherPhysical->GetLogicalV 88 motherLogical = motherPhysical->GetLogicalVolume(); 89 motherSolid = motherLogical->GetSolid(); 89 motherSolid = motherLogical->GetSolid(); 90 90 91 // Compute mother safety 91 // Compute mother safety 92 // 92 // 93 motherSafety = motherSolid->DistanceToOut(lo 93 motherSafety = motherSolid->DistanceToOut(localPoint); 94 ourSafety = motherSafety; // Working isotrop 94 ourSafety = motherSafety; // Working isotropic safety 95 95 96 localNoDaughters = motherLogical->GetNoDaugh 96 localNoDaughters = motherLogical->GetNoDaughters(); 97 97 98 #ifdef G4VERBOSE 98 #ifdef G4VERBOSE 99 if ( fCheck && ( (localNoDaughters>0) || (ou 99 if ( fCheck && ( (localNoDaughters>0) || (ourStep < motherSafety) ) ) 100 { 100 { 101 fLogger->PreComputeStepLog(motherPhysical, 101 fLogger->PreComputeStepLog(motherPhysical, motherSafety, localPoint); 102 } 102 } 103 #endif 103 #endif 104 // Compute daughter safeties & intersections 104 // Compute daughter safeties & intersections 105 // 105 // 106 106 107 // Exiting normal optimisation 107 // Exiting normal optimisation 108 // 108 // 109 if ( exiting && validExitNormal ) 109 if ( exiting && validExitNormal ) 110 { 110 { 111 if ( localDirection.dot(exitNormal)>=kMinE 111 if ( localDirection.dot(exitNormal)>=kMinExitingNormalCosine ) 112 { 112 { 113 // Block exited daughter volume 113 // Block exited daughter volume 114 // 114 // 115 blockedExitedVol = (*pBlockedPhysical); 115 blockedExitedVol = (*pBlockedPhysical); 116 ourSafety = 0; 116 ourSafety = 0; 117 } 117 } 118 } 118 } 119 exiting = false; 119 exiting = false; 120 entering = false; 120 entering = false; 121 121 122 #ifdef G4VERBOSE 122 #ifdef G4VERBOSE 123 if ( fCheck ) 123 if ( fCheck ) 124 { 124 { 125 // Compute early: 125 // Compute early: 126 // a) to check whether point is (wrongly) 126 // a) to check whether point is (wrongly) outside 127 // (signaled if step < 0 or 127 // (signaled if step < 0 or step == kInfinity ) 128 // b) to check value against answer of da 128 // b) to check value against answer of daughters! 129 129 130 motherStep = motherSolid->DistanceToOut(lo 130 motherStep = motherSolid->DistanceToOut(localPoint, 131 lo 131 localDirection, 132 tr 132 true, 133 &mo 133 &motherValidExitNormal, 134 &mo 134 &motherExitNormal); 135 135 136 if( (motherStep >= kInfinity) || (motherSt 136 if( (motherStep >= kInfinity) || (motherStep < 0.0) ) 137 { 137 { 138 // Error - indication of being outside s 138 // Error - indication of being outside solid !! 139 fLogger->ReportOutsideMother(localPoint, 139 fLogger->ReportOutsideMother(localPoint, localDirection, motherPhysical); 140 140 141 ourStep = motherStep = 0.0; 141 ourStep = motherStep = 0.0; 142 142 143 exiting = true; 143 exiting = true; 144 entering = false; 144 entering = false; 145 145 146 // If we are outside the solid does the 146 // If we are outside the solid does the normal make sense? 147 validExitNormal = motherValidExitNormal; 147 validExitNormal = motherValidExitNormal; 148 exitNormal = motherExitNormal; 148 exitNormal = motherExitNormal; 149 149 150 *pBlockedPhysical = nullptr; // or mothe 150 *pBlockedPhysical = nullptr; // or motherPhysical ? 151 blockedReplicaNo = 0; // or motherRepli 151 blockedReplicaNo = 0; // or motherReplicaNumber ? 152 152 153 newSafety = 0.0; 153 newSafety = 0.0; 154 return ourStep; 154 return ourStep; 155 } 155 } 156 } 156 } 157 #endif 157 #endif 158 158 159 for ( sampleNo=localNoDaughters-1; sampleNo> 159 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo--) 160 { 160 { 161 samplePhysical = motherLogical->GetDaughte 161 samplePhysical = motherLogical->GetDaughter(sampleNo); 162 if ( samplePhysical!=blockedExitedVol ) 162 if ( samplePhysical!=blockedExitedVol ) 163 { 163 { 164 G4AffineTransform sampleTf(samplePhysica 164 G4AffineTransform sampleTf(samplePhysical->GetRotation(), 165 samplePhysica 165 samplePhysical->GetTranslation()); 166 sampleTf.Invert(); 166 sampleTf.Invert(); 167 const G4ThreeVector samplePoint = sample 167 const G4ThreeVector samplePoint = sampleTf.TransformPoint(localPoint); 168 const G4VSolid *sampleSolid = 168 const G4VSolid *sampleSolid = 169 samplePhysical->GetLogicalVolume 169 samplePhysical->GetLogicalVolume()->GetSolid(); 170 const G4double sampleSafety = 170 const G4double sampleSafety = 171 sampleSolid->DistanceToIn(sample 171 sampleSolid->DistanceToIn(samplePoint); 172 172 173 if ( sampleSafety<ourSafety ) 173 if ( sampleSafety<ourSafety ) 174 { 174 { 175 ourSafety=sampleSafety; 175 ourSafety=sampleSafety; 176 } 176 } 177 177 178 if ( sampleSafety<=ourStep ) 178 if ( sampleSafety<=ourStep ) 179 { 179 { 180 sampleDirection = sampleTf.TransformAx 180 sampleDirection = sampleTf.TransformAxis(localDirection); 181 const G4double sampleStep = 181 const G4double sampleStep = 182 sampleSolid->DistanceToIn(samp 182 sampleSolid->DistanceToIn(samplePoint,sampleDirection); 183 #ifdef G4VERBOSE 183 #ifdef G4VERBOSE 184 if( fCheck ) 184 if( fCheck ) 185 { 185 { 186 fLogger->PrintDaughterLog(sampleSoli 186 fLogger->PrintDaughterLog(sampleSolid, samplePoint, 187 sampleSafe 187 sampleSafety, true, 188 sampleDire 188 sampleDirection, sampleStep); 189 } 189 } 190 #endif 190 #endif 191 if ( sampleStep<=ourStep ) 191 if ( sampleStep<=ourStep ) 192 { 192 { 193 ourStep = sampleStep; 193 ourStep = sampleStep; 194 entering = true; 194 entering = true; 195 exiting = false; 195 exiting = false; 196 *pBlockedPhysical = samplePhysical; 196 *pBlockedPhysical = samplePhysical; 197 blockedReplicaNo = -1; 197 blockedReplicaNo = -1; 198 #ifdef G4VERBOSE 198 #ifdef G4VERBOSE 199 if( fCheck ) 199 if( fCheck ) 200 { 200 { 201 fLogger->AlongComputeStepLog(sampl 201 fLogger->AlongComputeStepLog(sampleSolid, samplePoint, 202 sampl 202 sampleDirection, localDirection, 203 sampl 203 sampleSafety, sampleStep); 204 } 204 } 205 #endif 205 #endif 206 } 206 } 207 207 208 #ifdef G4VERBOSE 208 #ifdef G4VERBOSE 209 if( fCheck && (sampleStep < kInfinity) 209 if( fCheck && (sampleStep < kInfinity) && (sampleStep >= motherStep) ) 210 { 210 { 211 // The intersection point with the 211 // The intersection point with the daughter is at or after the exit 212 // point from the mother volume. D 212 // point from the mother volume. Double check! 213 fLogger->CheckDaughterEntryPoint(sa 213 fLogger->CheckDaughterEntryPoint(sampleSolid, 214 sa 214 samplePoint, sampleDirection, 215 mo 215 motherSolid, 216 lo 216 localPoint, localDirection, 217 mo 217 motherStep, sampleStep); 218 } 218 } 219 #endif 219 #endif 220 } // end of if ( sampleSafety <= ourStep 220 } // end of if ( sampleSafety <= ourStep ) 221 #ifdef G4VERBOSE 221 #ifdef G4VERBOSE 222 else if ( fCheck ) 222 else if ( fCheck ) 223 { 223 { 224 fLogger->PrintDaughterLog(sampleSolid 224 fLogger->PrintDaughterLog(sampleSolid, samplePoint, 225 sampleSafet 225 sampleSafety, false, 226 G4ThreeVect 226 G4ThreeVector(0.,0.,0.), -1.0 ); 227 } 227 } 228 #endif 228 #endif 229 } 229 } 230 } 230 } 231 if ( currentProposedStepLength<ourSafety ) 231 if ( currentProposedStepLength<ourSafety ) 232 { 232 { 233 // Guaranteed physics limited 233 // Guaranteed physics limited 234 // 234 // 235 entering = false; 235 entering = false; 236 exiting = false; 236 exiting = false; 237 *pBlockedPhysical = nullptr; 237 *pBlockedPhysical = nullptr; 238 ourStep = kInfinity; 238 ourStep = kInfinity; 239 } 239 } 240 else 240 else 241 { 241 { 242 // Consider intersection with mother solid 242 // Consider intersection with mother solid 243 // 243 // 244 if ( motherSafety<=ourStep ) 244 if ( motherSafety<=ourStep ) 245 { 245 { 246 if ( !fCheck ) // The call is moved abo 246 if ( !fCheck ) // The call is moved above when running in check_mode 247 { 247 { 248 motherStep = motherSolid->DistanceToOu 248 motherStep = motherSolid->DistanceToOut(localPoint, 249 249 localDirection, 250 250 true, 251 251 &motherValidExitNormal, 252 252 &motherExitNormal); 253 } 253 } 254 #ifdef G4VERBOSE 254 #ifdef G4VERBOSE 255 else // check_mode 255 else // check_mode 256 { 256 { 257 fLogger->PostComputeStepLog(motherSoli 257 fLogger->PostComputeStepLog(motherSolid, localPoint, localDirection, 258 motherStep 258 motherStep, motherSafety); 259 if( motherValidExitNormal ) 259 if( motherValidExitNormal ) 260 { 260 { 261 fLogger->CheckAndReportBadNormal(mot 261 fLogger->CheckAndReportBadNormal(motherExitNormal, 262 loc 262 localPoint, 263 loc 263 localDirection, 264 mot 264 motherStep, 265 mot 265 motherSolid, 266 "Fr 266 "From motherSolid::DistanceToOut" ); 267 } 267 } 268 } 268 } 269 #endif 269 #endif 270 270 271 if( (motherStep >= kInfinity) || (mother 271 if( (motherStep >= kInfinity) || (motherStep < 0.0) ) 272 { 272 { 273 #ifdef G4VERBOSE 273 #ifdef G4VERBOSE 274 if( fCheck ) // Clearly outside the m 274 if( fCheck ) // Clearly outside the mother solid! 275 { 275 { 276 fLogger->ReportOutsideMother(localPo 276 fLogger->ReportOutsideMother(localPoint, localDirection, 277 motherP 277 motherPhysical); 278 } 278 } 279 #endif 279 #endif 280 ourStep = motherStep = 0.0; 280 ourStep = motherStep = 0.0; 281 exiting = true; 281 exiting = true; 282 entering = false; 282 entering = false; 283 // validExitNormal= motherValidExitNor 283 // validExitNormal= motherValidExitNormal; 284 // exitNormal= motherExitNormal; 284 // exitNormal= motherExitNormal; 285 // The normal could be useful - but o 285 // The normal could be useful - but only if near the mother 286 // But it could be unreliable! 286 // But it could be unreliable! 287 validExitNormal = false; 287 validExitNormal = false; 288 *pBlockedPhysical = nullptr; // or mot 288 *pBlockedPhysical = nullptr; // or motherPhysical ? 289 blockedReplicaNo = 0; // or motherRep 289 blockedReplicaNo = 0; // or motherReplicaNumber ? 290 newSafety= 0.0; 290 newSafety= 0.0; 291 return ourStep; 291 return ourStep; 292 } 292 } 293 293 294 if ( motherStep<=ourStep ) 294 if ( motherStep<=ourStep ) 295 { 295 { 296 ourStep = motherStep; 296 ourStep = motherStep; 297 exiting = true; 297 exiting = true; 298 entering = false; 298 entering = false; 299 validExitNormal = motherValidExitNorma 299 validExitNormal = motherValidExitNormal; 300 exitNormal = motherExitNormal; 300 exitNormal = motherExitNormal; 301 301 302 if ( motherValidExitNormal ) 302 if ( motherValidExitNormal ) 303 { 303 { 304 const G4RotationMatrix *rot = mother 304 const G4RotationMatrix *rot = motherPhysical->GetRotation(); 305 if (rot != nullptr) << 305 if (rot) 306 { 306 { 307 exitNormal *= rot->inverse(); 307 exitNormal *= rot->inverse(); 308 #ifdef G4VERBOSE 308 #ifdef G4VERBOSE 309 if( fCheck ) 309 if( fCheck ) 310 { << 311 fLogger->CheckAndReportBadNorma 310 fLogger->CheckAndReportBadNormal(exitNormal, // rotated 312 311 motherExitNormal, // original 313 312 *rot, 314 313 "From RotationMatrix" ); 315 } << 316 #endif 314 #endif 317 } 315 } 318 } 316 } 319 } 317 } 320 else 318 else 321 { 319 { 322 validExitNormal = false; 320 validExitNormal = false; 323 } 321 } 324 } 322 } 325 } 323 } 326 newSafety = ourSafety; 324 newSafety = ourSafety; 327 return ourStep; 325 return ourStep; 328 } 326 } 329 327 330 // ******************************************* 328 // ******************************************************************** 331 // ComputeSafety 329 // ComputeSafety 332 // ******************************************* 330 // ******************************************************************** 333 // 331 // 334 G4double G4NormalNavigation::ComputeSafety(con 332 G4double G4NormalNavigation::ComputeSafety(const G4ThreeVector& localPoint, 335 con 333 const G4NavigationHistory& history, 336 con 334 const G4double) 337 { 335 { 338 G4VPhysicalVolume *motherPhysical, *samplePh 336 G4VPhysicalVolume *motherPhysical, *samplePhysical; 339 G4LogicalVolume *motherLogical; 337 G4LogicalVolume *motherLogical; 340 G4VSolid *motherSolid; 338 G4VSolid *motherSolid; 341 G4double motherSafety, ourSafety; 339 G4double motherSafety, ourSafety; 342 G4long localNoDaughters, sampleNo; << 340 G4int localNoDaughters, sampleNo; 343 341 344 motherPhysical = history.GetTopVolume(); 342 motherPhysical = history.GetTopVolume(); 345 motherLogical = motherPhysical->GetLogicalV 343 motherLogical = motherPhysical->GetLogicalVolume(); 346 motherSolid = motherLogical->GetSolid(); 344 motherSolid = motherLogical->GetSolid(); 347 345 348 // Compute mother safety 346 // Compute mother safety 349 // 347 // 350 motherSafety = motherSolid->DistanceToOut(lo 348 motherSafety = motherSolid->DistanceToOut(localPoint); 351 ourSafety = motherSafety; // Working isotrop 349 ourSafety = motherSafety; // Working isotropic safety 352 350 353 #ifdef G4VERBOSE 351 #ifdef G4VERBOSE 354 if( fCheck ) 352 if( fCheck ) 355 { 353 { 356 fLogger->ComputeSafetyLog(motherSolid,loca << 354 fLogger->ComputeSafetyLog(motherSolid,localPoint,motherSafety,true,true); 357 } 355 } 358 #endif 356 #endif 359 357 360 // Compute daughter safeties 358 // Compute daughter safeties 361 // 359 // 362 localNoDaughters = motherLogical->GetNoDaugh 360 localNoDaughters = motherLogical->GetNoDaughters(); 363 for ( sampleNo=localNoDaughters-1; sampleNo> 361 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- ) 364 { 362 { 365 samplePhysical = motherLogical->GetDaughte 363 samplePhysical = motherLogical->GetDaughter(sampleNo); 366 G4AffineTransform sampleTf(samplePhysical- 364 G4AffineTransform sampleTf(samplePhysical->GetRotation(), 367 samplePhysical- 365 samplePhysical->GetTranslation()); 368 sampleTf.Invert(); 366 sampleTf.Invert(); 369 const G4ThreeVector samplePoint = 367 const G4ThreeVector samplePoint = 370 sampleTf.TransformPoint(localPoint 368 sampleTf.TransformPoint(localPoint); 371 const G4VSolid *sampleSolid = 369 const G4VSolid *sampleSolid = 372 samplePhysical->GetLogicalVolume() 370 samplePhysical->GetLogicalVolume()->GetSolid(); 373 const G4double sampleSafety = 371 const G4double sampleSafety = 374 sampleSolid->DistanceToIn(samplePo 372 sampleSolid->DistanceToIn(samplePoint); 375 if ( sampleSafety<ourSafety ) 373 if ( sampleSafety<ourSafety ) 376 { 374 { 377 ourSafety = sampleSafety; 375 ourSafety = sampleSafety; 378 } 376 } 379 #ifdef G4VERBOSE 377 #ifdef G4VERBOSE 380 if(fCheck) 378 if(fCheck) 381 { 379 { 382 fLogger->ComputeSafetyLog(sampleSolid, s 380 fLogger->ComputeSafetyLog(sampleSolid, samplePoint, 383 sampleSafety, << 381 sampleSafety, false, false); 384 // Not mother, no banner 382 // Not mother, no banner 385 } 383 } 386 #endif 384 #endif 387 } 385 } 388 return ourSafety; 386 return ourSafety; 389 } 387 } 390 388 391 // The following methods have been imported to 389 // The following methods have been imported to this source file 392 // in order to avoid dependency of the header 390 // in order to avoid dependency of the header file on the 393 // header implementation of G4NavigationLogger 391 // header implementation of G4NavigationLogger. 394 392 395 // ******************************************* 393 // ******************************************************************** 396 // GetVerboseLevel 394 // GetVerboseLevel 397 // ******************************************* 395 // ******************************************************************** 398 // 396 // 399 G4int G4NormalNavigation::GetVerboseLevel() co 397 G4int G4NormalNavigation::GetVerboseLevel() const 400 { 398 { 401 return fLogger->GetVerboseLevel(); 399 return fLogger->GetVerboseLevel(); 402 } 400 } 403 401 404 // ******************************************* 402 // ******************************************************************** 405 // SetVerboseLevel 403 // SetVerboseLevel 406 // ******************************************* 404 // ******************************************************************** 407 // 405 // 408 void G4NormalNavigation::SetVerboseLevel(G4int 406 void G4NormalNavigation::SetVerboseLevel(G4int level) 409 { 407 { 410 fLogger->SetVerboseLevel(level); 408 fLogger->SetVerboseLevel(level); 411 } 409 } 412 410