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