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 // $Id: G4VIntersectionLocator.cc,v 1.7 2009/11/27 15:21:59 japost Exp $ >> 27 // GEANT4 tag $Name: geant4-09-03-patch-01 $ >> 28 // 26 // Class G4VIntersectionLocator implementation 29 // Class G4VIntersectionLocator implementation 27 // 30 // 28 // 27.10.08 - John Apostolakis, Tatiana Nikiti 31 // 27.10.08 - John Apostolakis, Tatiana Nikitina. 29 // ------------------------------------------- 32 // --------------------------------------------------------------------------- 30 33 31 #include <iomanip> 34 #include <iomanip> 32 #include <sstream> << 33 35 34 #include "globals.hh" 36 #include "globals.hh" 35 #include "G4ios.hh" 37 #include "G4ios.hh" 36 #include "G4AutoDelete.hh" << 37 #include "G4SystemOfUnits.hh" << 38 #include "G4VIntersectionLocator.hh" 38 #include "G4VIntersectionLocator.hh" 39 #include "G4TouchableHandle.hh" << 40 #include "G4GeometryTolerance.hh" 39 #include "G4GeometryTolerance.hh" 41 40 42 ////////////////////////////////////////////// 41 /////////////////////////////////////////////////////////////////////////// 43 // 42 // 44 // Constructor 43 // Constructor 45 // 44 // 46 G4VIntersectionLocator::G4VIntersectionLocator << 45 G4VIntersectionLocator:: G4VIntersectionLocator(G4Navigator *theNavigator): 47 : fiNavigator(theNavigator) << 46 fUseNormalCorrection(false), >> 47 fiNavigator( theNavigator ), >> 48 fiChordFinder( 0 ), // Not set - overridden at each step >> 49 fiEpsilonStep( -1.0 ), // Out of range - overridden at each step >> 50 fiDeltaIntersection( -1.0 ), // Out of range - overridden at each step >> 51 fiUseSafety(false) // Default - overridden at each step 48 { 52 { 49 kCarTolerance = G4GeometryTolerance::GetInst 53 kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); 50 << 54 fVerboseLevel = 0; 51 if( fiNavigator->GetExternalNavigation() == << 55 fHelpingNavigator = new G4Navigator(); 52 { << 53 fHelpingNavigator = new G4Navigator(); << 54 } << 55 else // Must clone the navigator, together w << 56 { << 57 fHelpingNavigator = fiNavigator->Clone(); << 58 } << 59 } 56 } 60 57 61 ////////////////////////////////////////////// 58 /////////////////////////////////////////////////////////////////////////// 62 // 59 // 63 // Destructor. 60 // Destructor. 64 // 61 // 65 G4VIntersectionLocator::~G4VIntersectionLocato 62 G4VIntersectionLocator::~G4VIntersectionLocator() 66 { 63 { 67 delete fHelpingNavigator; 64 delete fHelpingNavigator; 68 delete fpTouchable; << 69 } << 70 << 71 ////////////////////////////////////////////// << 72 // << 73 // Dump status of propagator to cout (old meth << 74 // << 75 void << 76 G4VIntersectionLocator::printStatus( const G4F << 77 const G4F << 78 G4d << 79 G4d << 80 G4i << 81 { << 82 std::ostringstream os; << 83 printStatus( StartFT,CurrentFT,requestStep,s << 84 G4cout << os.str(); << 85 } 65 } 86 66 87 ////////////////////////////////////////////// 67 /////////////////////////////////////////////////////////////////////////// 88 // 68 // 89 // Dumps status of propagator. 69 // Dumps status of propagator. 90 // 70 // 91 void 71 void 92 G4VIntersectionLocator::printStatus( const G4F << 72 G4VIntersectionLocator::printStatus( const G4FieldTrack& StartFT, 93 const G4F << 73 const G4FieldTrack& CurrentFT, 94 G4d << 74 G4double requestStep, 95 G4d << 75 G4double safety, 96 G4i << 76 G4int stepNo) 97 std << 98 G4i << 99 { 77 { 100 // const G4int verboseLevel= fVerboseLevel; << 78 const G4int verboseLevel= fVerboseLevel; 101 const G4ThreeVector StartPosition = St 79 const G4ThreeVector StartPosition = StartFT.GetPosition(); 102 const G4ThreeVector StartUnitVelocity = St 80 const G4ThreeVector StartUnitVelocity = StartFT.GetMomentumDir(); 103 const G4ThreeVector CurrentPosition = Cu 81 const G4ThreeVector CurrentPosition = CurrentFT.GetPosition(); 104 const G4ThreeVector CurrentUnitVelocity = Cu 82 const G4ThreeVector CurrentUnitVelocity = CurrentFT.GetMomentumDir(); 105 83 106 G4double step_len = CurrentFT.GetCurveLength 84 G4double step_len = CurrentFT.GetCurveLength() - StartFT.GetCurveLength(); 107 G4long oldprc; // cout/cerr precision setti << 85 108 << 109 if( ((stepNo == 0) && (verboseLevel <3)) || 86 if( ((stepNo == 0) && (verboseLevel <3)) || (verboseLevel >= 3) ) 110 { 87 { 111 oldprc = os.precision(4); << 88 static G4int noPrecision= 4; 112 os << std::setw( 6) << " " << 89 G4cout.precision(noPrecision); >> 90 // G4cout.setf(ios_base::fixed,ios_base::floatfield); >> 91 G4cout << std::setw( 6) << " " 113 << std::setw( 25) << " Current Posi 92 << std::setw( 25) << " Current Position and Direction" << " " 114 << G4endl; 93 << G4endl; 115 os << std::setw( 5) << "Step#" << 94 G4cout << std::setw( 5) << "Step#" 116 << std::setw(10) << " s " << " " 95 << std::setw(10) << " s " << " " 117 << std::setw(10) << "X(mm)" << " " 96 << std::setw(10) << "X(mm)" << " " 118 << std::setw(10) << "Y(mm)" << " " 97 << std::setw(10) << "Y(mm)" << " " 119 << std::setw(10) << "Z(mm)" << " " 98 << std::setw(10) << "Z(mm)" << " " 120 << std::setw( 7) << " N_x " << " " 99 << std::setw( 7) << " N_x " << " " 121 << std::setw( 7) << " N_y " << " " 100 << std::setw( 7) << " N_y " << " " 122 << std::setw( 7) << " N_z " << " " 101 << std::setw( 7) << " N_z " << " " ; 123 os << std::setw( 7) << " Delta|N|" << " " << 102 // << G4endl; >> 103 G4cout // << " >>> " >> 104 << std::setw( 7) << " Delta|N|" << " " >> 105 // << std::setw( 7) << " Delta(N_z) " << " " 124 << std::setw( 9) << "StepLen" << " 106 << std::setw( 9) << "StepLen" << " " 125 << std::setw(12) << "StartSafety" < 107 << std::setw(12) << "StartSafety" << " " 126 << std::setw( 9) << "PhsStep" << " 108 << std::setw( 9) << "PhsStep" << " "; 127 os << G4endl; << 109 128 os.precision(oldprc); << 110 G4cout << G4endl; 129 } 111 } 130 if((stepNo == 0) && (verboseLevel <=3)) 112 if((stepNo == 0) && (verboseLevel <=3)) 131 { 113 { 132 // Recurse to print the start values 114 // Recurse to print the start values 133 // 115 // 134 printStatus( StartFT, StartFT, -1.0, safet << 116 printStatus( StartFT, StartFT, -1.0, safety, -1); 135 } 117 } 136 if( verboseLevel <= 3 ) 118 if( verboseLevel <= 3 ) 137 { 119 { 138 if( stepNo >= 0) 120 if( stepNo >= 0) 139 { 121 { 140 os << std::setw( 4) << stepNo << " "; << 122 G4cout << std::setw( 4) << stepNo << " "; 141 } 123 } 142 else 124 else 143 { 125 { 144 os << std::setw( 5) << "Start" ; << 126 G4cout << std::setw( 5) << "Start" ; 145 } 127 } 146 oldprc = os.precision(8); << 128 G4cout.precision(8); 147 os << std::setw(10) << CurrentFT.GetCurveL << 129 G4cout << std::setw(10) << CurrentFT.GetCurveLength() << " "; 148 os << std::setw(10) << CurrentPosition.x() << 130 G4cout.precision(8); >> 131 G4cout << std::setw(10) << CurrentPosition.x() << " " 149 << std::setw(10) << CurrentPosition 132 << std::setw(10) << CurrentPosition.y() << " " 150 << std::setw(10) << CurrentPosition 133 << std::setw(10) << CurrentPosition.z() << " "; 151 os.precision(4); << 134 G4cout.precision(4); 152 os << std::setw( 7) << CurrentUnitVelocity << 135 G4cout << std::setw( 7) << CurrentUnitVelocity.x() << " " 153 << std::setw( 7) << CurrentUnitVelo 136 << std::setw( 7) << CurrentUnitVelocity.y() << " " 154 << std::setw( 7) << CurrentUnitVelo 137 << std::setw( 7) << CurrentUnitVelocity.z() << " "; 155 os.precision(3); << 138 // G4cout << G4endl; 156 os << std::setw( 7) << 139 // G4cout << " >>> " ; 157 << CurrentFT.GetMomentum().mag()- S << 140 G4cout.precision(3); 158 << " "; << 141 G4cout << std::setw( 7) 159 os << std::setw( 9) << step_len << " "; << 142 << CurrentFT.GetMomentum().mag()- StartFT.GetMomentum().mag() 160 os << std::setw(12) << safety << " "; << 143 << " "; 161 if( requestStep != -1.0 ) << 144 // << std::setw( 7) 162 { << 145 // << CurrentUnitVelocity.z() - InitialUnitVelocity.z() << " "; 163 os << std::setw( 9) << requestStep << " << 146 G4cout << std::setw( 9) << step_len << " "; 164 } << 147 G4cout << std::setw(12) << safety << " "; 165 else << 148 if( requestStep != -1.0 ) 166 { << 149 { 167 os << std::setw( 9) << "Init/NotKnown" < << 150 G4cout << std::setw( 9) << requestStep << " "; 168 } << 151 } 169 os << G4endl; << 152 else 170 os.precision(oldprc); << 153 { 171 } << 154 G4cout << std::setw( 9) << "Init/NotKnown" << " "; 172 else // if( verboseLevel > 3 ) << 155 } 173 { << 156 G4cout << G4endl; 174 // Multi-line output << 157 } >> 158 else // if( verboseLevel > 3 ) >> 159 { >> 160 // Multi-line output 175 161 176 os << "Step taken was " << step_len << 162 G4cout << "Step taken was " << step_len 177 << " out of PhysicalStep= " << req << 163 << " out of PhysicalStep= " << requestStep << G4endl; 178 os << "Final safety is: " << safety << G4e << 164 G4cout << "Final safety is: " << safety << G4endl; 179 os << "Chord length = " << (CurrentPositio << 165 180 << G4endl; << 166 G4cout << "Chord length = " << (CurrentPosition-StartPosition).mag() 181 os << G4endl; << 167 << G4endl; 182 } << 168 G4cout << G4endl; >> 169 } 183 } 170 } 184 171 185 ////////////////////////////////////////////// 172 /////////////////////////////////////////////////////////////////////////// 186 // 173 // 187 // ReEstimateEndPoint. 174 // ReEstimateEndPoint. 188 // 175 // 189 G4FieldTrack G4VIntersectionLocator:: 176 G4FieldTrack G4VIntersectionLocator:: 190 ReEstimateEndpoint( const G4FieldTrack& Curren << 177 ReEstimateEndpoint( const G4FieldTrack &CurrentStateA, 191 const G4FieldTrack& Estima << 178 const G4FieldTrack &EstimatedEndStateB, 192 G4double , // l << 179 G4double linearDistSq, 193 G4double << 180 G4double curveDist ) 194 #ifdef G4DEBUG_FIELD << 195 curveDist << 196 #endif << 197 ) << 198 { 181 { 199 G4FieldTrack newEndPoint( CurrentStateA ); 182 G4FieldTrack newEndPoint( CurrentStateA ); 200 auto integrDriver = GetChordFinderFor()->Get << 183 G4MagInt_Driver* integrDriver= GetChordFinderFor()->GetIntegrationDriver(); 201 184 202 G4FieldTrack retEndPoint( CurrentStateA ); 185 G4FieldTrack retEndPoint( CurrentStateA ); 203 G4bool goodAdvance; 186 G4bool goodAdvance; 204 G4int itrial = 0; << 187 G4int itrial=0; 205 const G4int no_trials = 20; << 188 const G4int no_trials= 20; 206 << 207 189 208 G4double endCurveLen= EstimatedEndStateB.Get 190 G4double endCurveLen= EstimatedEndStateB.GetCurveLength(); 209 << 191 do 210 do // Loop checking, 07.10.2016, JA << 211 { 192 { 212 G4double currentCurveLen = newEndPoint.Get << 193 G4double currentCurveLen= newEndPoint.GetCurveLength(); 213 G4double advanceLength = endCurveLen - cur << 194 G4double advanceLength= endCurveLen - currentCurveLen ; 214 if (std::abs(advanceLength)<kCarTolerance) << 195 if (std::abs(advanceLength)<kCarTolerance) 215 { << 196 { 216 goodAdvance=true; << 197 goodAdvance=true; 217 } << 198 } 218 else << 199 else{ 219 { << 200 goodAdvance= 220 goodAdvance = integrDriver->AccurateAdva << 201 integrDriver->AccurateAdvance(newEndPoint, advanceLength, 221 << 202 GetEpsilonStepFor()); 222 } << 203 } 223 } 204 } 224 while( !goodAdvance && (++itrial < no_trials 205 while( !goodAdvance && (++itrial < no_trials) ); 225 206 226 if( goodAdvance ) 207 if( goodAdvance ) 227 { 208 { 228 retEndPoint = newEndPoint; << 209 retEndPoint= newEndPoint; 229 } 210 } 230 else 211 else 231 { 212 { 232 retEndPoint = EstimatedEndStateB; // Could << 213 retEndPoint= EstimatedEndStateB; // Could not improve without major work !! 233 } 214 } 234 215 235 // All the work is done 216 // All the work is done 236 // below are some diagnostics only -- befor 217 // below are some diagnostics only -- before the return! 237 // 218 // 238 const G4String MethodName("G4VIntersectionLo << 219 static const G4String MethodName("G4VIntersectionLocator::ReEstimateEndpoint"); 239 220 240 #ifdef G4VERBOSE 221 #ifdef G4VERBOSE 241 G4int latest_good_trials = 0; << 222 G4int latest_good_trials=0; 242 if( itrial > 1) 223 if( itrial > 1) 243 { 224 { 244 if( fVerboseLevel > 0 ) 225 if( fVerboseLevel > 0 ) 245 { 226 { 246 G4cout << MethodName << " called - goodA 227 G4cout << MethodName << " called - goodAdv= " << goodAdvance 247 << " trials = " << itrial 228 << " trials = " << itrial 248 << " previous good= " << latest_g 229 << " previous good= " << latest_good_trials 249 << G4endl; 230 << G4endl; 250 } 231 } 251 latest_good_trials = 0; << 232 latest_good_trials=0; 252 } 233 } 253 else 234 else 254 { 235 { 255 ++latest_good_trials; << 236 latest_good_trials++; 256 } 237 } 257 #endif 238 #endif 258 239 259 #ifdef G4DEBUG_FIELD 240 #ifdef G4DEBUG_FIELD 260 G4double lengthDone = newEndPoint.GetCurveLe 241 G4double lengthDone = newEndPoint.GetCurveLength() 261 - CurrentStateA.GetCurve 242 - CurrentStateA.GetCurveLength(); 262 if( !goodAdvance ) 243 if( !goodAdvance ) 263 { 244 { 264 if( fVerboseLevel >= 3 ) 245 if( fVerboseLevel >= 3 ) 265 { 246 { 266 G4cout << MethodName << "> AccurateAdvan 247 G4cout << MethodName << "> AccurateAdvance failed " ; 267 G4cout << " in " << itrial << " integrat 248 G4cout << " in " << itrial << " integration trials/steps. " << G4endl; 268 G4cout << " It went only " << lengthDone 249 G4cout << " It went only " << lengthDone << " instead of " << curveDist 269 << " -- a difference of " << curv 250 << " -- a difference of " << curveDist - lengthDone << G4endl; 270 G4cout << " ReEstimateEndpoint> Reset en 251 G4cout << " ReEstimateEndpoint> Reset endPoint to original value!" 271 << G4endl; 252 << G4endl; 272 } 253 } 273 } 254 } 274 G4double linearDist = ( EstimatedEndStateB.G << 255 275 - CurrentStateA.GetPosit << 276 static G4int noInaccuracyWarnings = 0; 256 static G4int noInaccuracyWarnings = 0; 277 G4int maxNoWarnings = 10; 257 G4int maxNoWarnings = 10; 278 if ( (noInaccuracyWarnings < maxNoWarnings 258 if ( (noInaccuracyWarnings < maxNoWarnings ) 279 || (fVerboseLevel > 1) ) 259 || (fVerboseLevel > 1) ) 280 { 260 { 281 G4ThreeVector move = newEndPoint.GetPosi << 261 G4cerr << "G4PropagatorInField::LocateIntersectionPoint():" 282 - EstimatedEndStateB. << 262 << G4endl 283 std::ostringstream message; << 263 << " Warning: Integration inaccuracy requires" 284 message.precision(12); << 264 << " an adjustment in the step's endpoint." << G4endl 285 message << " Integration inaccuracy requ << 265 << " Two mid-points are further apart than their" 286 << " an adjustment in the step's << 266 << " curve length difference" << G4endl 287 << " Two mid-points are furthe << 267 << " Dist = " << std::sqrt(linearDistSq) 288 << " curve length difference" << 268 << " curve length = " << curveDist << G4endl; 289 << " Dist = " << linearD << 269 G4cerr << " Correction applied is " 290 << " curve length = " << curveDi << 270 << (newEndPoint.GetPosition()-EstimatedEndStateB.GetPosition()).mag() 291 message << " Correction applied is " << << 271 << G4endl; 292 << " Old Estimated B position= << 293 << EstimatedEndStateB.GetPositio << 294 << " Recalculated Position= << 295 << newEndPoint.GetPosition() << << 296 << " Change ( new - old ) = << 297 G4Exception("G4VIntersectionLocator::ReE << 298 "GeomNav1002", JustWarning, << 299 } 272 } 300 /* << 301 #else 273 #else 302 // Statistics on the RMS value of the correc 274 // Statistics on the RMS value of the corrections 303 275 304 static G4ThreadLocal G4int noCorrections = 0 << 276 static G4int noCorrections=0; 305 ++noCorrections; << 277 static G4double sumCorrectionsSq = 0; >> 278 noCorrections++; 306 if( goodAdvance ) 279 if( goodAdvance ) 307 { 280 { 308 static G4ThreadLocal G4double sumCorrectio << 309 sumCorrectionsSq += (EstimatedEndStateB.Ge 281 sumCorrectionsSq += (EstimatedEndStateB.GetPosition() - 310 newEndPoint.GetPositi 282 newEndPoint.GetPosition()).mag2(); 311 } 283 } 312 */ << 284 linearDistSq -= curveDist; // To use linearDistSq ... ! 313 #endif 285 #endif 314 286 315 return retEndPoint; 287 return retEndPoint; 316 } 288 } 317 289 318 << 319 ////////////////////////////////////////////// << 320 // << 321 // ReEstimateEndPoint. << 322 // << 323 // The following values are returned in curv << 324 // 0: Normal - no problem << 325 // 1: Unexpected co-incidence - milder m << 326 // 2: Real mixup - EndB is NOT past Star << 327 // ( ie. StartA's curve-lengh is bi << 328 << 329 << 330 G4bool G4VIntersectionLocator:: << 331 CheckAndReEstimateEndpoint( const G4FieldTrack << 332 const G4FieldTrack << 333 G4FieldTrack << 334 G4int& << 335 { << 336 G4double linDistSq, curveDist; << 337 << 338 G4bool recalculated = false; << 339 curveError= 0; << 340 << 341 linDistSq = ( EstimatedEndB.GetPosition() << 342 - CurrentStartA.GetPosition() ). << 343 curveDist = EstimatedEndB.GetCurveLength() << 344 - CurrentStartA.GetCurveLength(); << 345 if( (curveDist>=0.0) << 346 && (curveDist*curveDist *(1.0+2.0*fiEpsil << 347 { << 348 G4FieldTrack newEndPointFT = EstimatedEndB << 349 << 350 if (curveDist>0.0) << 351 { << 352 // Re-integrate to obtain a new B << 353 RevisedEndPoint = ReEstimateEndpoint( C << 354 E << 355 l << 356 c << 357 recalculated = true; << 358 } << 359 else << 360 { << 361 // Zero length -> no advance! << 362 newEndPointFT = CurrentStartA; << 363 recalculated = true; << 364 curveError = 1; // Unexpected co-incid << 365 << 366 G4Exception("G4MultiLevelLocator::Estim << 367 "GeomNav1002", JustWarning, << 368 "A & B are at equal distance in 2nd << 369 } << 370 } << 371 << 372 // Sanity check << 373 // << 374 if( curveDist < 0.0 ) << 375 { << 376 curveError = 2; // Real mixup << 377 } << 378 return recalculated; << 379 } << 380 << 381 ////////////////////////////////////////////// 290 /////////////////////////////////////////////////////////////////////////// 382 // 291 // 383 // Method for finding SurfaceNormal of Interse 292 // Method for finding SurfaceNormal of Intersecting Solid 384 // 293 // 385 G4ThreeVector G4VIntersectionLocator:: 294 G4ThreeVector G4VIntersectionLocator:: 386 GetLocalSurfaceNormal(const G4ThreeVector& Cur << 295 GetLocalSurfaceNormal(const G4ThreeVector &CurrentE_Point, G4bool &validNormal) 387 { 296 { 388 G4ThreeVector Normal(G4ThreeVector(0.0,0.0,0 << 297 G4ThreeVector Normal(G4ThreeVector(0,0,0)); 389 G4VPhysicalVolume* located; 298 G4VPhysicalVolume* located; 390 299 391 validNormal = false; 300 validNormal = false; 392 fHelpingNavigator->SetWorldVolume(GetNavigat 301 fHelpingNavigator->SetWorldVolume(GetNavigatorFor()->GetWorldVolume()); 393 located = fHelpingNavigator->LocateGlobalPoi 302 located = fHelpingNavigator->LocateGlobalPointAndSetup( CurrentE_Point ); 394 << 303 G4TouchableHistoryHandle aTouchable = fHelpingNavigator 395 delete fpTouchable; << 304 ->CreateTouchableHistoryHandle(); 396 fpTouchable = fHelpingNavigator->CreateTouch << 305 G4ThreeVector localPosition = aTouchable->GetHistory() 397 << 398 // To check if we can use GetGlobalExitNorma << 399 // << 400 G4ThreeVector localPosition = fpTouchable->G << 401 ->GetTopTransform().TransformP 306 ->GetTopTransform().TransformPoint(CurrentE_Point); 402 307 403 // Issue: in the case of coincident surfaces << 308 if( located != 0) 404 // which side you are located onto (c << 405 // TO-DO: use direction (of chord) to identi << 406 << 407 if( located != nullptr) << 408 { 309 { 409 G4LogicalVolume* pLogical= located->GetLog << 310 if (located->GetLogicalVolume() 410 G4VSolid* pSolid; << 311 ->GetSolid()->Inside(localPosition)==kSurface) 411 << 412 if( (pLogical != nullptr) && ( (pSolid=pLo << 413 { 312 { 414 if ( ( pSolid->Inside(localPosition)==kS << 313 Normal = located->GetLogicalVolume() 415 || ( pSolid->DistanceToOut(localPositi << 314 ->GetSolid()->SurfaceNormal(localPosition); 416 { << 315 validNormal = true; 417 Normal = pSolid->SurfaceNormal(localPo << 418 validNormal = true; << 419 << 420 #ifdef G4DEBUG_FIELD << 421 if( std::fabs(Normal.mag2() - 1.0 ) > << 422 { << 423 G4cerr << "PROBLEM in G4VIntersectio << 424 << G4endl; << 425 G4cerr << " Normal is not unit - ma << 426 G4cerr << " at trial local point " << 427 G4cerr << " Solid is " << *pSolid << 428 } << 429 #endif << 430 } << 431 } 316 } 432 } 317 } >> 318 433 return Normal; 319 return Normal; 434 } 320 } 435 321 436 ////////////////////////////////////////////// 322 /////////////////////////////////////////////////////////////////////////// 437 // 323 // 438 // Adjustment of Found Intersection 324 // Adjustment of Found Intersection 439 // 325 // 440 G4bool G4VIntersectionLocator:: 326 G4bool G4VIntersectionLocator:: 441 AdjustmentOfFoundIntersection( const G4ThreeVe << 327 AdjustmentOfFoundIntersection( const G4ThreeVector &CurrentA_Point, 442 const G4ThreeVe << 328 const G4ThreeVector &CurrentE_Point, 443 const G4ThreeVe << 329 const G4ThreeVector &CurrentF_Point, 444 const G4ThreeVe << 330 const G4ThreeVector &MomentumDir, 445 const G4bool 331 const G4bool IntersectAF, 446 G4ThreeVe << 332 G4ThreeVector &IntersectionPoint, // I/O 447 G4double& << 333 G4double &NewSafety, // I/O 448 G4double& << 334 G4double &fPreviousSafety, // I/O 449 G4ThreeVe << 335 G4ThreeVector &fPreviousSftOrigin )// I/O 450 { 336 { 451 G4double dist,lambda; 337 G4double dist,lambda; 452 G4ThreeVector Normal, NewPoint, Point_G; 338 G4ThreeVector Normal, NewPoint, Point_G; 453 G4bool goodAdjust = false, Intersects_FP = f << 339 G4bool goodAdjust=false, Intersects_FP=false, validNormal=false; 454 340 455 // Get SurfaceNormal of Intersecting Solid 341 // Get SurfaceNormal of Intersecting Solid 456 // 342 // 457 Normal = GetGlobalSurfaceNormal(CurrentE_Poi << 343 Normal=GetLocalSurfaceNormal(CurrentE_Point,validNormal); 458 if(!validNormal) { return false; } 344 if(!validNormal) { return false; } 459 345 460 // Intersection between Line and Plane 346 // Intersection between Line and Plane 461 // 347 // 462 G4double n_d_m = Normal.dot(MomentumDir); 348 G4double n_d_m = Normal.dot(MomentumDir); 463 if ( std::abs(n_d_m)>kCarTolerance ) 349 if ( std::abs(n_d_m)>kCarTolerance ) 464 { 350 { 465 #ifdef G4VERBOSE << 466 if ( fVerboseLevel>1 ) 351 if ( fVerboseLevel>1 ) 467 { 352 { 468 G4Exception("G4VIntersectionLocator::Adj << 353 G4cerr << "WARNING - " 469 "GeomNav0003", JustWarning, << 354 << "G4VIntersectionLocator::AdjustementOfFoundIntersection()" 470 "No intersection. Parallels << 355 << G4endl >> 356 << " No intersection. Parallels lines!" << G4endl; >> 357 return false; 471 } 358 } 472 #endif << 473 lambda =- Normal.dot(CurrentF_Point-Curren 359 lambda =- Normal.dot(CurrentF_Point-CurrentE_Point)/n_d_m; 474 360 475 // New candidate for Intersection 361 // New candidate for Intersection 476 // 362 // 477 NewPoint = CurrentF_Point+lambda*MomentumD 363 NewPoint = CurrentF_Point+lambda*MomentumDir; 478 364 479 // Distance from CurrentF to Calculated In 365 // Distance from CurrentF to Calculated Intersection 480 // 366 // 481 dist = std::abs(lambda); 367 dist = std::abs(lambda); 482 368 483 if ( dist<kCarTolerance*0.001 ) { return 369 if ( dist<kCarTolerance*0.001 ) { return false; } 484 370 485 // Calculation of new intersection point o 371 // Calculation of new intersection point on the path. 486 // 372 // 487 if ( IntersectAF ) // First part interse 373 if ( IntersectAF ) // First part intersects 488 { 374 { 489 G4double stepLengthFP; 375 G4double stepLengthFP; 490 G4ThreeVector Point_P = CurrentA_Point; 376 G4ThreeVector Point_P = CurrentA_Point; 491 GetNavigatorFor()->LocateGlobalPointWith 377 GetNavigatorFor()->LocateGlobalPointWithinVolume(Point_P); 492 Intersects_FP = IntersectChord( Point_P, 378 Intersects_FP = IntersectChord( Point_P, NewPoint, NewSafety, 493 fPreviou 379 fPreviousSafety, fPreviousSftOrigin, 494 stepLeng 380 stepLengthFP, Point_G ); 495 381 496 } 382 } 497 else // Second part intersects 383 else // Second part intersects 498 { 384 { 499 G4double stepLengthFP; 385 G4double stepLengthFP; 500 GetNavigatorFor()->LocateGlobalPointWith 386 GetNavigatorFor()->LocateGlobalPointWithinVolume(CurrentF_Point ); 501 Intersects_FP = IntersectChord( CurrentF 387 Intersects_FP = IntersectChord( CurrentF_Point, NewPoint, NewSafety, 502 fPreviou 388 fPreviousSafety, fPreviousSftOrigin, 503 stepLeng 389 stepLengthFP, Point_G ); 504 } 390 } 505 if ( Intersects_FP ) 391 if ( Intersects_FP ) 506 { 392 { 507 goodAdjust = true; 393 goodAdjust = true; 508 IntersectionPoint = Point_G; 394 IntersectionPoint = Point_G; 509 } 395 } 510 } 396 } 511 397 512 return goodAdjust; 398 return goodAdjust; 513 } 399 } 514 << 515 ////////////////////////////////////////////// << 516 // << 517 // GetSurfaceNormal. << 518 // << 519 G4ThreeVector G4VIntersectionLocator:: << 520 GetSurfaceNormal(const G4ThreeVector& CurrentI << 521 G4bool& validNormal) << 522 { << 523 G4ThreeVector NormalAtEntry; // ( -10. , -10 << 524 << 525 G4ThreeVector NormalAtEntryLast, NormalAtEnt << 526 G4bool validNormalLast; << 527 << 528 // Relies on a call to Navigator::ComputeSte << 529 // this call << 530 // << 531 NormalAtEntryLast = GetLastSurfaceNormal( Cu << 532 // May return valid=false in cases, includ << 533 // - if the candidate volume was not foun << 534 // - a replica was involved -- determined << 535 // (This list is not complete.) << 536 << 537 #ifdef G4DEBUG_FIELD << 538 if ( validNormalLast << 539 && ( std::fabs(NormalAtEntryLast.mag2() - 1 << 540 { << 541 std::ostringstream message; << 542 message << "PROBLEM: Normal is not unit - << 543 << NormalAtEntryLast.mag() << G4en << 544 message << " at trial intersection point << 545 message << " Obtained from Get *Last* Su << 546 G4Exception("G4VIntersectionLocator::GetSu << 547 "GeomNav1002", JustWarning, me << 548 } << 549 #endif << 550 << 551 if( validNormalLast ) << 552 { << 553 NormalAtEntry = NormalAtEntryLast; << 554 } << 555 validNormal = validNormalLast; << 556 << 557 return NormalAtEntry; << 558 } << 559 << 560 ////////////////////////////////////////////// << 561 // << 562 // GetGlobalSurfaceNormal. << 563 // << 564 G4ThreeVector G4VIntersectionLocator:: << 565 GetGlobalSurfaceNormal(const G4ThreeVector& Cu << 566 G4bool& validNorm << 567 { << 568 G4ThreeVector localNormal = GetLocalSurfaceN << 569 G4AffineTransform localToGlobal = / << 570 fHelpingNavigator->GetLocalToGlobalTrans << 571 G4ThreeVector globalNormal = localToGlobal.T << 572 << 573 #ifdef G4DEBUG_FIELD << 574 if( validNormal && ( std::fabs(globalNormal. << 575 { << 576 std::ostringstream message; << 577 message << "****************************** << 578 << G4endl; << 579 message << " Bad Normal in G4VIntersection << 580 << G4endl; << 581 message << " * Constituents: " << G4endl; << 582 message << " Local Normal= " << localN << 583 message << " Transform: " << G4endl << 584 << " Net Translation= " << lo << 585 << G4endl << 586 << " Net Rotation = " << lo << 587 << G4endl; << 588 message << " * Result: " << G4endl; << 589 message << " Global Normal= " << local << 590 message << "****************************** << 591 G4Exception("G4VIntersectionLocator::GetGl << 592 "GeomNav1002", JustWarning, me << 593 } << 594 #endif << 595 << 596 return globalNormal; << 597 } << 598 << 599 ////////////////////////////////////////////// << 600 // << 601 // GetLastSurfaceNormal. << 602 // << 603 G4ThreeVector G4VIntersectionLocator:: << 604 GetLastSurfaceNormal( const G4ThreeVector& int << 605 G4bool& normalIsVa << 606 { << 607 G4ThreeVector normalVec; << 608 G4bool validNorm; << 609 normalVec = fiNavigator->GetGlobalExitNormal << 610 normalIsValid = validNorm; << 611 << 612 return normalVec; << 613 } << 614 << 615 ////////////////////////////////////////////// << 616 // << 617 // ReportTrialStep. << 618 // << 619 void G4VIntersectionLocator::ReportTrialStep( << 620 const << 621 const << 622 const << 623 const << 624 << 625 { << 626 G4double ABchord_length = ChordAB_v.mag(); << 627 G4double MomDir_dot_Norm = NewMomentumDir.do << 628 G4double MomDir_dot_ABchord; << 629 MomDir_dot_ABchord = (1.0 / ABchord_length) << 630 << 631 std::ostringstream outStream; << 632 outStream << std::setw(6) << " Step# " << 633 << std::setw(17) << " |ChordEF|(mag)" << " << 634 << std::setw(18) << " uMomentum.Normal" << << 635 << std::setw(18) << " uMomentum.ABdir " << << 636 << std::setw(16) << " AB-dist " << << 637 << " Chord Vector (EF) " << 638 << G4endl; << 639 outStream.precision(7); << 640 outStream << " " << std::setw(5) << step_no << 641 << " " << std::setw(18) << ChordEF_v.mag() << 642 << " " << std::setw(18) << MomDir_dot_Norm << 643 << " " << std::setw(18) << MomDir_dot_ABch << 644 << " " << std::setw(12) << ABchord_length << 645 << " " << ChordEF_v << 646 << G4endl; << 647 outStream << " MomentumDir= " << " " << NewM << 648 << " Normal at Entry E= " << NormalAtEntry << 649 << " AB chord = " << ChordAB_v << 650 << G4endl; << 651 G4cout << outStream.str(); << 652 << 653 if( ( std::fabs(NormalAtEntry.mag2() - 1.0) << 654 { << 655 std::ostringstream message; << 656 message << "Normal is not unit - mag= " << << 657 << " ValidNormalAtE = " << << 658 G4Exception("G4VIntersectionLocator::Repor << 659 "GeomNav1002", JustWarning, me << 660 } << 661 return; << 662 } << 663 << 664 ////////////////////////////////////////////// << 665 // << 666 // LocateGlobalPointWithinVolumeAndCheck. << 667 // << 668 // Locate point using navigator: updates state << 669 // By default, it assumes that the point is in << 670 // and returns true. << 671 // In check mode, checks whether the point is << 672 // If it is inside, it returns true << 673 // If not, issues a warning and returns fals << 674 // << 675 G4bool G4VIntersectionLocator:: << 676 LocateGlobalPointWithinVolumeAndCheck( const G << 677 { << 678 G4bool good = true; << 679 G4Navigator* nav = GetNavigatorFor(); << 680 const G4String << 681 MethodName("G4VIntersectionLocator::LocateGl << 682 << 683 if( fCheckMode ) << 684 { << 685 G4bool navCheck= nav->IsCheckModeActive(); << 686 nav->CheckMode(true); << 687 << 688 // Identify the current volume << 689 << 690 G4TouchableHandle startTH= nav->CreateTouc << 691 G4VPhysicalVolume* motherPhys = startTH->G << 692 G4VSolid* motherSolid = startTH-> << 693 G4AffineTransform transform = nav->GetGlob << 694 G4int motherCopyNo = motherPhys->GetCopyNo << 695 << 696 // Let's check that the point is inside th << 697 G4ThreeVector localPosition = transform.T << 698 EInside inMother = motherSolid->Ins << 699 if( inMother != kInside ) << 700 { << 701 std::ostringstream message; << 702 message << "Position located " << 703 << ( inMother == kSurface ? " on << 704 << "expected volume" << G4endl << 705 << " Safety (from Outside) = " << 706 << motherSolid->DistanceToIn(loc << 707 G4Exception("G4VIntersectionLocator::Loc << 708 "GeomNav1002", JustWarning, << 709 } << 710 << 711 // 1. Simple next step - quick relocation << 712 // nav->LocateGlobalPointWithinVolume( pos << 713 << 714 // 2. Full relocation - to cross-check ans << 715 G4VPhysicalVolume* nextPhysical= nav->Loca << 716 if( (nextPhysical != motherPhys) << 717 || (nextPhysical->GetCopyNo() != mothe << 718 ) << 719 { << 720 G4Exception("G4VIntersectionLocator::Loc << 721 "GeomNav1002", JustWarning, << 722 "Position located outside ex << 723 } << 724 nav->CheckMode(navCheck); // Recover orig << 725 } << 726 else << 727 { << 728 nav->LocateGlobalPointWithinVolume( positi << 729 } << 730 return good; << 731 } << 732 << 733 ////////////////////////////////////////////// << 734 // << 735 // LocateGlobalPointWithinVolumeCheckAndReport << 736 // << 737 void G4VIntersectionLocator:: << 738 LocateGlobalPointWithinVolumeCheckAndReport( c << 739 c << 740 G << 741 { << 742 // Save value of Check mode first << 743 G4bool oldCheck = GetCheckMode(); << 744 << 745 G4bool ok = LocateGlobalPointWithinVolumeAnd << 746 if( !ok ) << 747 { << 748 std::ostringstream message; << 749 message << "Failed point location." << G4e << 750 << " Code Location info: " << Co << 751 G4Exception("G4VIntersectionLocator::Locat << 752 "GeomNav1002", JustWarning, me << 753 } << 754 << 755 SetCheckMode( oldCheck ); << 756 } << 757 << 758 ////////////////////////////////////////////// << 759 // << 760 // ReportReversedPoints. << 761 // << 762 void G4VIntersectionLocator:: << 763 ReportReversedPoints( std::ostringstream& msg, << 764 const G4FieldTrack& Star << 765 const G4FieldTrack& EndP << 766 G4double NewSafety << 767 const G4FieldTrack& A_Pt << 768 const G4FieldTrack& B_Pt << 769 const G4FieldTrack& SubS << 770 const G4ThreeVector& E_P << 771 const G4FieldTrack& Appr << 772 G4int substep_no, << 773 { << 774 // Expect that 'msg' can hold the name of t << 775 << 776 // FieldTrack 'points' A and B have been ta << 777 // Whereas A should be before B, it is foun << 778 G4int verboseLevel= 5; << 779 G4double curveDist = B_PtVel.GetCurveLength << 780 G4VIntersectionLocator::printStatus( A_PtVe << 781 -1.0, NewSafety, s << 782 msg << "Error in advancing propagation." << << 783 << " The final curve point is NOT fur << 784 << " than the original!" << G4endl << 785 << " Going *backwards* from len(A) = << 786 << " to len(B) = " << B_PtVel.GetCurve << 787 << " Curve distance is " << curveD << 788 << G4endl << 789 << " Point A' (start) is " << A_Pt << 790 << " Point B' (end) is " << B_Pt << 791 msg << " fEpsStep= " << epsStep << G4e << 792 << 793 G4long oldprc = msg.precision(20); << 794 msg << " In full precision, the position, m << 795 << " ... are: " << G4endl; << 796 msg << " Point A[0] (Curve start) is " << << 797 << " Point S (Sub start) is " << << 798 << " Point A' (Current start) is " << << 799 << " Point E (Trial Point) is " << << 800 << " Point F (Intersection) is " << << 801 << " Point B' (Current end) is " << << 802 << " Point B[0] (Curve end) is " << << 803 << G4endl << 804 << " LocateIntersection parameters are << 805 << " Substep no (total) = " << su << 806 << " Substep no = " << su << 807 msg.precision(oldprc); << 808 } << 809 << 810 ////////////////////////////////////////////// << 811 // << 812 // ReportProgress. << 813 // << 814 void G4VIntersectionLocator::ReportProgress( s << 815 const G4Fi << 816 const G4Fi << 817 G4in << 818 const G4Fi << 819 const G4Fi << 820 G4do << 821 G4in << 822 << 823 { << 824 oss << "ReportProgress: Current status of in << 825 if( depth > 0 ) { oss << " Depth= " << depth << 826 oss << " Substep no = " << substep_no << G4e << 827 G4int verboseLevel = 5; << 828 G4double safetyPrev = -1.0; // Add as argum << 829 << 830 printStatus( StartPointVel, EndPointVel, -1. << 831 oss, verboseLevel); << 832 oss << " * Start and end-point of requested << 833 oss << " ** State of point A: "; << 834 printStatus( A_PtVel, A_PtVel, -1.0, safetyP << 835 oss, verboseLevel); << 836 oss << " ** State of point B: "; << 837 printStatus( A_PtVel, B_PtVel, -1.0, safetyL << 838 oss, verboseLevel); << 839 } << 840 << 841 ////////////////////////////////////////////// << 842 // << 843 // ReportImmediateHit. << 844 // << 845 void << 846 G4VIntersectionLocator::ReportImmediateHit( co << 847 co << 848 co << 849 << 850 un << 851 { << 852 static G4ThreadLocal unsigned int occurredOn << 853 static G4ThreadLocal G4ThreeVector* ptrLast << 854 if( ptrLast == nullptr ) << 855 { << 856 ptrLast= new G4ThreeVector( DBL_MAX, DBL_ << 857 G4AutoDelete::Register(ptrLast); << 858 } << 859 G4ThreeVector &lastStart= *ptrLast; << 860 << 861 if( (TrialPoint - StartPosition).mag2() < to << 862 { << 863 static G4ThreadLocal unsigned int numUnmo << 864 static G4ThreadLocal unsigned int numStil << 865 << 866 G4cout << "Intersection F == start A in " << 867 G4cout << "Start Point: " << StartPositio << 868 G4cout << " Start-Trial: " << TrialPoint << 869 G4cout << " Start-last: " << StartPositio << 870 << 871 if( (StartPosition - lastStart).mag() < t << 872 { << 873 // We are at position of last 'Start' << 874 ++numUnmoved; << 875 ++numStill; << 876 G4cout << " { Unmoved: " << " still#= << 877 << " total # = " << numUnmoved << 878 } << 879 else << 880 { << 881 numStill = 0; << 882 } << 883 G4cout << " Occurred: " << ++occurredOnTo << 884 G4cout << " out of total calls= " << num << 885 G4cout << G4endl; << 886 lastStart = StartPosition; << 887 } << 888 } // End of ReportImmediateHit() << 889 400