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 G4BrentLocator implementation << 26 // $Id: G4BrentLocator.cc,v 1.9 2010-07-13 15:59:42 gcosmo Exp $ >> 27 // GEANT4 tag $Name: not supported by cvs2svn $ >> 28 // >> 29 // Class G4BrentLocator implementation 27 // 30 // 28 // 27.10.08 - Tatiana Nikitina. 31 // 27.10.08 - Tatiana Nikitina. 29 // 04.10.11 - John Apostolakis, revised conver 32 // 04.10.11 - John Apostolakis, revised convergence to use Surface Normal 30 // ------------------------------------------- 33 // --------------------------------------------------------------------------- 31 34 32 #include <iomanip> << 33 << 34 #include "G4BrentLocator.hh" 35 #include "G4BrentLocator.hh" 35 #include "G4ios.hh" 36 #include "G4ios.hh" >> 37 #include <iomanip> 36 38 37 G4BrentLocator::G4BrentLocator(G4Navigator *th 39 G4BrentLocator::G4BrentLocator(G4Navigator *theNavigator) 38 : G4VIntersectionLocator(theNavigator) << 40 : G4VIntersectionLocator(theNavigator) 39 { 41 { 40 // In case of too slow progress in finding I 42 // In case of too slow progress in finding Intersection Point 41 // intermediates Points on the Track must be 43 // intermediates Points on the Track must be stored. 42 // Initialise the array of Pointers [max_dep 44 // Initialise the array of Pointers [max_depth+1] to do this 43 45 44 G4ThreeVector zeroV(0.0,0.0,0.0); 46 G4ThreeVector zeroV(0.0,0.0,0.0); 45 for (auto & idepth : ptrInterMedFT) << 47 for (G4int idepth=0; idepth<max_depth+1; idepth++ ) 46 { 48 { 47 idepth = new G4FieldTrack( zeroV, zeroV, 0 << 49 ptrInterMedFT[ idepth ] = new G4FieldTrack( zeroV, zeroV, 0., 0., 0., 0.); 48 } 50 } >> 51 >> 52 // Counters for Locator >> 53 >> 54 // Counter for Maximum Number Of Trial before Intersection Found >> 55 // >> 56 maxNumberOfStepsForIntersection=0; >> 57 >> 58 // Counter for Number Of Calls to ReIntegrationEndPoint Method >> 59 // >> 60 maxNumberOfCallsToReIntegration=0; >> 61 maxNumberOfCallsToReIntegration_depth=0; 49 } 62 } 50 63 51 G4BrentLocator::~G4BrentLocator() 64 G4BrentLocator::~G4BrentLocator() 52 { 65 { 53 for (auto & idepth : ptrInterMedFT) << 66 for ( G4int idepth=0; idepth<max_depth+1; idepth++) 54 { 67 { 55 delete idepth; << 68 delete ptrInterMedFT[idepth]; 56 } 69 } >> 70 #ifdef G4DEBUG_FIELD >> 71 if(fVerboseLevel>0) >> 72 { >> 73 G4cout << "G4BrentLocator::Location with Max Number of Steps=" >> 74 << maxNumberOfStepsForIntersection<<G4endl; >> 75 G4cout << "G4BrentLocator::ReIntegrateEndPoint was called " >> 76 << maxNumberOfCallsToReIntegration >> 77 << " times and for depth algorithm " >> 78 << maxNumberOfCallsToReIntegration_depth << " times." << G4endl; >> 79 } >> 80 #endif 57 } 81 } 58 82 59 // ------------------------------------------- 83 // -------------------------------------------------------------------------- 60 // G4bool G4PropagatorInField::LocateIntersect 84 // G4bool G4PropagatorInField::LocateIntersectionPoint( 61 // const G4FieldTrack& CurveStart 85 // const G4FieldTrack& CurveStartPointVelocity, // A 62 // const G4FieldTrack& CurveEndPo 86 // const G4FieldTrack& CurveEndPointVelocity, // B 63 // const G4ThreeVector& TrialPoint 87 // const G4ThreeVector& TrialPoint, // E 64 // G4FieldTrack& Intersecte 88 // G4FieldTrack& IntersectedOrRecalculated // Output 65 // G4bool& recalculat 89 // G4bool& recalculated) // Out 66 // ------------------------------------------- 90 // -------------------------------------------------------------------------- 67 // 91 // 68 // Function that returns the intersection of t 92 // Function that returns the intersection of the true path with the surface 69 // of the current volume (either the external 93 // of the current volume (either the external one or the inner one with one 70 // of the daughters: 94 // of the daughters: 71 // 95 // 72 // A = Initial point 96 // A = Initial point 73 // B = another point 97 // B = another point 74 // 98 // 75 // Both A and B are assumed to be on the true 99 // Both A and B are assumed to be on the true path: 76 // 100 // 77 // E is the first point of intersection of 101 // E is the first point of intersection of the chord AB with 78 // a volume other than A (on the surface 102 // a volume other than A (on the surface of A or of a daughter) 79 // 103 // 80 // Convention of Use : 104 // Convention of Use : 81 // i) If it returns "true", then Intersect 105 // i) If it returns "true", then IntersectionPointVelocity is set 82 // to the approximate intersection poin 106 // to the approximate intersection point. 83 // ii) If it returns "false", no intersecti 107 // ii) If it returns "false", no intersection was found. 84 // The validity of IntersectedOrRecalcu 108 // The validity of IntersectedOrRecalculated depends on 'recalculated' 85 // a) if latter is false, then Intersec 109 // a) if latter is false, then IntersectedOrRecalculated is invalid. 86 // b) if latter is true, then Intersec 110 // b) if latter is true, then IntersectedOrRecalculated is 87 // the new endpoint, due to a re-int 111 // the new endpoint, due to a re-integration. 88 // ------------------------------------------- 112 // -------------------------------------------------------------------------- 89 // NOTE: implementation taken from G4Propagato 113 // NOTE: implementation taken from G4PropagatorInField 90 // New second order locator is added 114 // New second order locator is added 91 // 115 // 92 G4bool G4BrentLocator::EstimateIntersectionPoi 116 G4bool G4BrentLocator::EstimateIntersectionPoint( 93 const G4FieldTrack& CurveStart 117 const G4FieldTrack& CurveStartPointVelocity, // A 94 const G4FieldTrack& CurveEndPo 118 const G4FieldTrack& CurveEndPointVelocity, // B 95 const G4ThreeVector& TrialPoint 119 const G4ThreeVector& TrialPoint, // E 96 G4FieldTrack& Intersecte 120 G4FieldTrack& IntersectedOrRecalculatedFT, // Output 97 G4bool& recalculat 121 G4bool& recalculatedEndPoint, // Out 98 G4double& fPreviousS 122 G4double& fPreviousSafety, // In/Out 99 G4ThreeVector& fPreviousS 123 G4ThreeVector& fPreviousSftOrigin) // In/Out 100 124 101 { 125 { 102 // Find Intersection Point ( A, B, E ) of t 126 // Find Intersection Point ( A, B, E ) of true path AB - start at E. 103 127 104 G4bool found_approximate_intersection = fals 128 G4bool found_approximate_intersection = false; 105 G4bool there_is_no_intersection = fals 129 G4bool there_is_no_intersection = false; 106 130 107 G4FieldTrack CurrentA_PointVelocity = Curve 131 G4FieldTrack CurrentA_PointVelocity = CurveStartPointVelocity; 108 G4FieldTrack CurrentB_PointVelocity = Curve 132 G4FieldTrack CurrentB_PointVelocity = CurveEndPointVelocity; 109 G4ThreeVector CurrentE_Point = TrialPoint; 133 G4ThreeVector CurrentE_Point = TrialPoint; 110 G4bool validNormalAtE = false; 134 G4bool validNormalAtE = false; 111 G4ThreeVector NormalAtEntry; 135 G4ThreeVector NormalAtEntry; 112 136 113 G4FieldTrack ApproxIntersecPointV(CurveEndP 137 G4FieldTrack ApproxIntersecPointV(CurveEndPointVelocity); // FT-Def-Construct 114 G4double NewSafety = 0.0; 138 G4double NewSafety = 0.0; 115 G4bool last_AF_intersection = false; 139 G4bool last_AF_intersection = false; 116 140 117 // G4bool final_section= true; // Shows whe 141 // G4bool final_section= true; // Shows whether current section is last 118 // (i.e. B=f 142 // (i.e. B=full end) 119 G4bool first_section = true; 143 G4bool first_section = true; 120 recalculatedEndPoint = false; 144 recalculatedEndPoint = false; 121 145 122 G4bool restoredFullEndpoint = false; 146 G4bool restoredFullEndpoint = false; 123 147 124 G4long oldprc; // cout, cerr precision << 148 G4int oldprc; // cout, cerr precision 125 G4int substep_no = 0; 149 G4int substep_no = 0; 126 150 127 // Limits for substep number 151 // Limits for substep number 128 // 152 // 129 const G4int max_substeps= 10000; // Test 153 const G4int max_substeps= 10000; // Test 120 (old value 100 ) 130 const G4int warn_substeps= 1000; // 154 const G4int warn_substeps= 1000; // 100 131 155 132 // Statistics for substeps 156 // Statistics for substeps 133 // 157 // 134 static G4ThreadLocal G4int max_no_seen= -1; << 158 static G4int max_no_seen= -1; 135 159 136 // Counter for restarting Bintermed 160 // Counter for restarting Bintermed 137 // 161 // 138 G4int restartB = 0; 162 G4int restartB = 0; 139 163 140 //------------------------------------------ 164 //-------------------------------------------------------------------------- 141 // Algorithm for the case if progress in fo 165 // Algorithm for the case if progress in founding intersection is too slow. 142 // Process is defined too slow if after N=p 166 // Process is defined too slow if after N=param_substeps advances on the 143 // path, it will be only 'fraction_done' of 167 // path, it will be only 'fraction_done' of the total length. 144 // In this case the remaining length is div 168 // In this case the remaining length is divided in two half and 145 // the loop is restarted for each half. 169 // the loop is restarted for each half. 146 // If progress is still too slow, the divis 170 // If progress is still too slow, the division in two halfs continue 147 // until 'max_depth'. 171 // until 'max_depth'. 148 //------------------------------------------ 172 //-------------------------------------------------------------------------- 149 173 150 const G4int param_substeps = 50; // Test val << 174 const G4int param_substeps=50; // Test value for the maximum number 151 // of subst << 175 // of substeps 152 const G4double fraction_done = 0.3; << 176 const G4double fraction_done=0.3; 153 177 154 G4bool Second_half = false; // First hal 178 G4bool Second_half = false; // First half or second half of divided step 155 179 156 NormalAtEntry = GetSurfaceNormal(CurrentE_Po 180 NormalAtEntry = GetSurfaceNormal(CurrentE_Point, validNormalAtE); 157 181 158 // We need to know this for the 'final_secti 182 // We need to know this for the 'final_section': 159 // real 'final_section' or first half 'final 183 // real 'final_section' or first half 'final_section' 160 // In algorithm it is considered that the 'S 184 // In algorithm it is considered that the 'Second_half' is true 161 // and it becomes false only if we are in th 185 // and it becomes false only if we are in the first-half of level 162 // depthness or if we are in the first secti 186 // depthness or if we are in the first section 163 187 164 G4int depth = 0; // Depth counts how many su << 188 G4int depth=0; // Depth counts how many subdivisions of initial step made 165 189 166 #ifdef G4DEBUG_FIELD 190 #ifdef G4DEBUG_FIELD 167 const G4double tolerance = 1.0e-8; << 191 static G4double tolerance= 1.0e-8; 168 G4ThreeVector StartPosition = CurveStartPoi << 192 G4ThreeVector StartPosition= CurveStartPointVelocity.GetPosition(); 169 if( (TrialPoint - StartPosition).mag() < tol << 193 if( (TrialPoint - StartPosition).mag() < tolerance * mm ) 170 { 194 { 171 G4Exception("G4BrentLocator::EstimateInte 195 G4Exception("G4BrentLocator::EstimateIntersectionPoint()", 172 "GeomNav1002", JustWarning, 196 "GeomNav1002", JustWarning, 173 "Intersection point F is exac 197 "Intersection point F is exactly at start point A." ); 174 } 198 } 175 #endif 199 #endif 176 200 177 // Intermediates Points on the Track = Subdi 201 // Intermediates Points on the Track = Subdivided Points must be stored. 178 // Give the initial values to 'InterMedFt' 202 // Give the initial values to 'InterMedFt' 179 // Important is 'ptrInterMedFT[0]', it saves 203 // Important is 'ptrInterMedFT[0]', it saves the 'EndCurvePoint' 180 // 204 // 181 *ptrInterMedFT[0] = CurveEndPointVelocity; 205 *ptrInterMedFT[0] = CurveEndPointVelocity; 182 for (auto idepth=1; idepth<max_depth+1; ++id << 206 for (G4int idepth=1; idepth<max_depth+1; idepth++ ) 183 { 207 { 184 *ptrInterMedFT[idepth] = CurveStartPointVe << 208 *ptrInterMedFT[idepth]=CurveStartPointVelocity; 185 } 209 } 186 210 187 //Final_section boolean store 211 //Final_section boolean store 188 G4bool fin_section_depth[max_depth]; 212 G4bool fin_section_depth[max_depth]; 189 for (bool & idepth : fin_section_depth) << 213 for (G4int idepth=0; idepth<max_depth; idepth++ ) 190 { 214 { 191 idepth = true; << 215 fin_section_depth[idepth]=true; 192 } 216 } 193 217 194 // 'SubStartPoint' is needed to calculate th 218 // 'SubStartPoint' is needed to calculate the length of the divided step 195 // 219 // 196 G4FieldTrack SubStart_PointVelocity = CurveS 220 G4FieldTrack SubStart_PointVelocity = CurveStartPointVelocity; 197 221 198 do // Loop checking, 07.10.2016, J.Apostol << 222 do 199 { 223 { 200 G4int substep_no_p = 0; 224 G4int substep_no_p = 0; 201 G4bool sub_final_section = false; // the s 225 G4bool sub_final_section = false; // the same as final_section, 202 // but f 226 // but for 'sub_section' 203 SubStart_PointVelocity = CurrentA_PointVel 227 SubStart_PointVelocity = CurrentA_PointVelocity; 204 << 228 do // REPEAT param 205 do // Loop checking, 07.10.2016, J.Apost << 229 { 206 { // REPEAT param << 207 G4ThreeVector Point_A = CurrentA_PointVe 230 G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition(); 208 G4ThreeVector Point_B = CurrentB_PointVe 231 G4ThreeVector Point_B = CurrentB_PointVelocity.GetPosition(); 209 232 210 // F = a point on true AB path close to 233 // F = a point on true AB path close to point E 211 // (the closest if possible) 234 // (the closest if possible) 212 // 235 // 213 if(substep_no_p==0) 236 if(substep_no_p==0) 214 { 237 { 215 ApproxIntersecPointV = GetChordFinderF 238 ApproxIntersecPointV = GetChordFinderFor() 216 ->ApproxCurvePo 239 ->ApproxCurvePointV( CurrentA_PointVelocity, 217 240 CurrentB_PointVelocity, 218 241 CurrentE_Point, 219 242 GetEpsilonStepFor()); 220 // The above method is the key & mo 243 // The above method is the key & most intuitive part ... 221 } 244 } 222 #ifdef G4DEBUG_FIELD 245 #ifdef G4DEBUG_FIELD 223 if( ApproxIntersecPointV.GetCurveLength( 246 if( ApproxIntersecPointV.GetCurveLength() > 224 CurrentB_PointVelocity.GetCurveLengt 247 CurrentB_PointVelocity.GetCurveLength() * (1.0 + tolerance) ) 225 { 248 { 226 G4Exception("G4BrentLocator::EstimateI 249 G4Exception("G4BrentLocator::EstimateIntersectionPoint()", 227 "GeomNav0003", FatalExcept 250 "GeomNav0003", FatalException, 228 "Intermediate F point is p 251 "Intermediate F point is past end B point" ); 229 } 252 } 230 #endif 253 #endif 231 254 232 G4ThreeVector CurrentF_Point = ApproxInt << 255 G4ThreeVector CurrentF_Point= ApproxIntersecPointV.GetPosition(); 233 256 234 // First check whether EF is small - the 257 // First check whether EF is small - then F is a good approx. point 235 // Calculate the length and direction of 258 // Calculate the length and direction of the chord AF 236 // 259 // 237 G4ThreeVector ChordEF_Vector = CurrentF 260 G4ThreeVector ChordEF_Vector = CurrentF_Point - CurrentE_Point; 238 G4ThreeVector NewMomentumDir = ApproxIn << 261 G4ThreeVector NewMomentumDir= ApproxIntersecPointV.GetMomentumDir(); 239 G4double MomDir_dot_Norm = NewMome << 262 G4double MomDir_dot_Norm= NewMomentumDir.dot( NormalAtEntry ) ; 240 263 241 #ifdef G4DEBUG_FIELD 264 #ifdef G4DEBUG_FIELD 242 G4ThreeVector ChordAB = Point_B - Point 265 G4ThreeVector ChordAB = Point_B - Point_A; 243 266 244 G4VIntersectionLocator::ReportTrialStep( 267 G4VIntersectionLocator::ReportTrialStep( substep_no, ChordAB, 245 ChordEF_Vector, NewMomentumDir, 268 ChordEF_Vector, NewMomentumDir, NormalAtEntry, validNormalAtE ); 246 #endif 269 #endif 247 270 248 G4bool adequate_angle; 271 G4bool adequate_angle; 249 adequate_angle = ( MomDir_dot_Norm >= 0 272 adequate_angle = ( MomDir_dot_Norm >= 0.0 ) // Can use -epsilon instead. 250 || (! validNormalAtE ); 273 || (! validNormalAtE ); // Makes criterion invalid 251 G4double EF_dist2 = ChordEF_Vector.mag2( 274 G4double EF_dist2 = ChordEF_Vector.mag2(); 252 if ( ( EF_dist2 <= sqr(fiDeltaIntersecti 275 if ( ( EF_dist2 <= sqr(fiDeltaIntersection) && ( adequate_angle ) ) 253 || ( EF_dist2 <= kCarTolerance*kCarTol 276 || ( EF_dist2 <= kCarTolerance*kCarTolerance ) ) 254 { 277 { 255 found_approximate_intersection = true; 278 found_approximate_intersection = true; 256 279 257 // Create the "point" return value 280 // Create the "point" return value 258 // 281 // 259 IntersectedOrRecalculatedFT = ApproxIn 282 IntersectedOrRecalculatedFT = ApproxIntersecPointV; 260 IntersectedOrRecalculatedFT.SetPositio 283 IntersectedOrRecalculatedFT.SetPosition( CurrentE_Point ); 261 284 262 if ( GetAdjustementOfFoundIntersection 285 if ( GetAdjustementOfFoundIntersection() ) 263 { 286 { 264 // Try to Get Correction of Intersec 287 // Try to Get Correction of IntersectionPoint using SurfaceNormal() 265 // 288 // 266 G4ThreeVector IP; 289 G4ThreeVector IP; 267 G4ThreeVector MomentumDir=ApproxInte 290 G4ThreeVector MomentumDir=ApproxIntersecPointV.GetMomentumDirection(); 268 G4bool goodCorrection = AdjustmentOf 291 G4bool goodCorrection = AdjustmentOfFoundIntersection( Point_A, 269 CurrentE_P 292 CurrentE_Point, CurrentF_Point, MomentumDir, 270 last_AF_in 293 last_AF_intersection, IP, NewSafety, 271 fPreviousS 294 fPreviousSafety, fPreviousSftOrigin ); 272 if ( goodCorrection ) 295 if ( goodCorrection ) 273 { 296 { 274 IntersectedOrRecalculatedFT = Appr 297 IntersectedOrRecalculatedFT = ApproxIntersecPointV; 275 IntersectedOrRecalculatedFT.SetPos 298 IntersectedOrRecalculatedFT.SetPosition(IP); 276 } 299 } 277 } 300 } 278 301 279 // Note: in order to return a point on 302 // Note: in order to return a point on the boundary, 280 // we must return E. But it is F 303 // we must return E. But it is F on the curve. 281 // So we must "cheat": we are us 304 // So we must "cheat": we are using the position at point E 282 // and the velocity at point F ! 305 // and the velocity at point F !!! 283 // 306 // 284 // This must limit the length we can a 307 // This must limit the length we can allow for displacement! 285 } 308 } 286 else // E is NOT close enough to the cu 309 else // E is NOT close enough to the curve (ie point F) 287 { 310 { 288 // Check whether any volumes are encou 311 // Check whether any volumes are encountered by the chord AF 289 // ----------------------------------- 312 // --------------------------------------------------------- 290 // First relocate to restore any Voxel 313 // First relocate to restore any Voxel etc information 291 // in the Navigator before calling Com 314 // in the Navigator before calling ComputeStep() 292 // 315 // 293 GetNavigatorFor()->LocateGlobalPointWi 316 GetNavigatorFor()->LocateGlobalPointWithinVolume( Point_A ); 294 317 295 G4ThreeVector PointG; // Candidate i 318 G4ThreeVector PointG; // Candidate intersection point 296 G4double stepLengthAF; 319 G4double stepLengthAF; 297 G4bool usedNavigatorAF = false; 320 G4bool usedNavigatorAF = false; 298 G4bool Intersects_AF = IntersectChord( 321 G4bool Intersects_AF = IntersectChord( Point_A, CurrentF_Point, 299 322 NewSafety,fPreviousSafety, 300 323 fPreviousSftOrigin, 301 324 stepLengthAF, 302 325 PointG, 303 326 &usedNavigatorAF); 304 last_AF_intersection = Intersects_AF; 327 last_AF_intersection = Intersects_AF; 305 if( Intersects_AF ) 328 if( Intersects_AF ) 306 { 329 { 307 // G is our new Candidate for the in 330 // G is our new Candidate for the intersection point. 308 // It replaces "E" and we will repe 331 // It replaces "E" and we will repeat the test to see if 309 // it is a good enough approximate p 332 // it is a good enough approximate point for us. 310 // B <- F 333 // B <- F 311 // E <- G 334 // E <- G 312 // 335 // 313 G4FieldTrack EndPoint = ApproxInters 336 G4FieldTrack EndPoint = ApproxIntersecPointV; 314 ApproxIntersecPointV = GetChordFinde 337 ApproxIntersecPointV = GetChordFinderFor()->ApproxCurvePointS( 315 CurrentA_Poin 338 CurrentA_PointVelocity, CurrentB_PointVelocity, 316 EndPoint,Curr 339 EndPoint,CurrentE_Point, CurrentF_Point,PointG, 317 true, GetEpsi 340 true, GetEpsilonStepFor() ); 318 CurrentB_PointVelocity = EndPoint; 341 CurrentB_PointVelocity = EndPoint; 319 CurrentE_Point = PointG; 342 CurrentE_Point = PointG; 320 343 321 // Need to recalculate the Exit Norm 344 // Need to recalculate the Exit Normal at the new PointG 322 // Know that a call was made to Navi 345 // Know that a call was made to Navigator::ComputeStep in 323 // IntersectChord above. 346 // IntersectChord above. 324 // 347 // 325 G4bool validNormalLast; 348 G4bool validNormalLast; 326 NormalAtEntry = GetSurfaceNormal( P 349 NormalAtEntry = GetSurfaceNormal( PointG, validNormalLast ); 327 validNormalAtE = validNormalLast; 350 validNormalAtE = validNormalLast; 328 351 329 // By moving point B, must take care 352 // By moving point B, must take care if current 330 // AF has no intersection to try cur 353 // AF has no intersection to try current FB!! 331 // 354 // 332 fin_section_depth[depth] = false; 355 fin_section_depth[depth] = false; 333 #ifdef G4VERBOSE 356 #ifdef G4VERBOSE 334 if( fVerboseLevel > 3 ) 357 if( fVerboseLevel > 3 ) 335 { 358 { 336 G4cout << "G4PiF::LI> Investigatin 359 G4cout << "G4PiF::LI> Investigating intermediate point" 337 << " at s=" << ApproxInters 360 << " at s=" << ApproxIntersecPointV.GetCurveLength() 338 << " on way to full s=" 361 << " on way to full s=" 339 << CurveEndPointVelocity.Ge 362 << CurveEndPointVelocity.GetCurveLength() << G4endl; 340 } 363 } 341 #endif 364 #endif 342 } 365 } 343 else // not Intersects_AF 366 else // not Intersects_AF 344 { 367 { 345 // In this case: 368 // In this case: 346 // There is NO intersection of AF wi 369 // There is NO intersection of AF with a volume boundary. 347 // We must continue the search in th 370 // We must continue the search in the segment FB! 348 // 371 // 349 GetNavigatorFor()->LocateGlobalPoint 372 GetNavigatorFor()->LocateGlobalPointWithinVolume( CurrentF_Point ); 350 373 351 G4double stepLengthFB; 374 G4double stepLengthFB; 352 G4ThreeVector PointH; 375 G4ThreeVector PointH; 353 G4bool usedNavigatorFB = false; 376 G4bool usedNavigatorFB = false; 354 377 355 // Check whether any volumes are enc 378 // Check whether any volumes are encountered by the chord FB 356 // --------------------------------- 379 // --------------------------------------------------------- 357 380 358 G4bool Intersects_FB = IntersectChor 381 G4bool Intersects_FB = IntersectChord( CurrentF_Point, Point_B, 359 382 NewSafety,fPreviousSafety, 360 383 fPreviousSftOrigin, 361 384 stepLengthFB, 362 385 PointH, 363 386 &usedNavigatorFB); 364 if( Intersects_FB ) 387 if( Intersects_FB ) 365 { 388 { 366 // There is an intersection of FB 389 // There is an intersection of FB with a volume boundary 367 // H <- First Intersection of Chor 390 // H <- First Intersection of Chord FB 368 391 369 // H is our new Candidate for the 392 // H is our new Candidate for the intersection point. 370 // It replaces "E" and we will re 393 // It replaces "E" and we will repeat the test to see if 371 // it is a good enough approximate 394 // it is a good enough approximate point for us. 372 395 373 // Note that F must be in volume v 396 // Note that F must be in volume volA (the same as A) 374 // (otherwise AF would meet a volu 397 // (otherwise AF would meet a volume boundary!) 375 // A <- F 398 // A <- F 376 // E <- H 399 // E <- H 377 // 400 // 378 G4FieldTrack InterMed = ApproxInte << 401 G4FieldTrack InterMed=ApproxIntersecPointV; 379 ApproxIntersecPointV = GetChordFin 402 ApproxIntersecPointV = GetChordFinderFor()->ApproxCurvePointS( 380 CurrentA_PointVeloci 403 CurrentA_PointVelocity,CurrentB_PointVelocity, 381 InterMed,CurrentE_Po 404 InterMed,CurrentE_Point,CurrentF_Point,PointH, 382 false,GetEpsilonStep 405 false,GetEpsilonStepFor()); 383 CurrentA_PointVelocity = InterMed; 406 CurrentA_PointVelocity = InterMed; 384 CurrentE_Point = PointH; 407 CurrentE_Point = PointH; 385 408 386 // Need to recalculate the Exit No 409 // Need to recalculate the Exit Normal at the new PointG 387 // 410 // 388 G4bool validNormalLast; 411 G4bool validNormalLast; 389 NormalAtEntry = GetSurfaceNormal( 412 NormalAtEntry = GetSurfaceNormal( PointH, validNormalLast ); 390 validNormalAtE = validNormalLast; << 413 validNormalAtE= validNormalLast; 391 } 414 } 392 else // not Intersects_FB 415 else // not Intersects_FB 393 { 416 { 394 // There is NO intersection of FB 417 // There is NO intersection of FB with a volume boundary 395 418 396 if( fin_section_depth[depth] ) 419 if( fin_section_depth[depth] ) 397 { 420 { 398 // If B is the original endpoint 421 // If B is the original endpoint, this means that whatever 399 // volume(s) intersected the ori 422 // volume(s) intersected the original chord, none touch the 400 // smaller chords we have used. 423 // smaller chords we have used. 401 // The value of 'IntersectedOrRe 424 // The value of 'IntersectedOrRecalculatedFT' returned is 402 // likely not valid 425 // likely not valid 403 426 404 // Check on real final_section o 427 // Check on real final_section or SubEndSection 405 // 428 // 406 if( ((Second_half)&&(depth==0)) 429 if( ((Second_half)&&(depth==0)) || (first_section) ) 407 { 430 { 408 there_is_no_intersection = tru 431 there_is_no_intersection = true; // real final_section 409 } 432 } 410 else 433 else 411 { 434 { 412 // end of subsection, not real 435 // end of subsection, not real final section 413 // exit from the and go to the 436 // exit from the and go to the depth-1 level 414 437 415 substep_no_p = param_substeps+ 438 substep_no_p = param_substeps+2; // exit from the loop 416 439 417 // but 'Second_half' is still 440 // but 'Second_half' is still true because we need to find 418 // the 'CurrentE_point' for th 441 // the 'CurrentE_point' for the next loop 419 // 442 // 420 Second_half = true; 443 Second_half = true; 421 sub_final_section = true; 444 sub_final_section = true; 422 } 445 } 423 } 446 } 424 else 447 else 425 { 448 { 426 if( depth==0 ) << 449 if(depth==0) 427 { 450 { 428 // We must restore the origina 451 // We must restore the original endpoint 429 // 452 // 430 CurrentA_PointVelocity = Curre 453 CurrentA_PointVelocity = CurrentB_PointVelocity; // Got to B 431 CurrentB_PointVelocity = Curve 454 CurrentB_PointVelocity = CurveEndPointVelocity; 432 SubStart_PointVelocity = Curre 455 SubStart_PointVelocity = CurrentA_PointVelocity; 433 ApproxIntersecPointV = GetChor 456 ApproxIntersecPointV = GetChordFinderFor() 434 ->ApproxCurvePo 457 ->ApproxCurvePointV( CurrentA_PointVelocity, 435 458 CurrentB_PointVelocity, 436 459 CurrentE_Point, 437 460 GetEpsilonStepFor()); 438 461 439 restoredFullEndpoint = true; 462 restoredFullEndpoint = true; 440 ++restartB; // counter << 463 restartB++; // counter 441 } 464 } 442 else 465 else 443 { 466 { 444 // We must restore the depth e 467 // We must restore the depth endpoint 445 // 468 // 446 CurrentA_PointVelocity = Curre 469 CurrentA_PointVelocity = CurrentB_PointVelocity; // Got to B 447 CurrentB_PointVelocity = *ptr 470 CurrentB_PointVelocity = *ptrInterMedFT[depth]; 448 SubStart_PointVelocity = Curre 471 SubStart_PointVelocity = CurrentA_PointVelocity; 449 ApproxIntersecPointV = GetChor 472 ApproxIntersecPointV = GetChordFinderFor() 450 ->ApproxCurvePo 473 ->ApproxCurvePointV( CurrentA_PointVelocity, 451 474 CurrentB_PointVelocity, 452 475 CurrentE_Point, 453 476 GetEpsilonStepFor()); 454 restoredFullEndpoint = true; 477 restoredFullEndpoint = true; 455 ++restartB; // counter << 478 restartB++; // counter 456 } 479 } 457 } 480 } 458 } // Endif (Intersects_FB) 481 } // Endif (Intersects_FB) 459 } // Endif (Intersects_AF) 482 } // Endif (Intersects_AF) 460 483 461 // Ensure that the new endpoints are n 484 // Ensure that the new endpoints are not further apart in space 462 // than on the curve due to different 485 // than on the curve due to different errors in the integration 463 // 486 // 464 G4double linDistSq, curveDist; 487 G4double linDistSq, curveDist; 465 linDistSq = ( CurrentB_PointVelocity.G 488 linDistSq = ( CurrentB_PointVelocity.GetPosition() 466 - CurrentA_PointVelocity.G 489 - CurrentA_PointVelocity.GetPosition() ).mag2(); 467 curveDist = CurrentB_PointVelocity.Get 490 curveDist = CurrentB_PointVelocity.GetCurveLength() 468 - CurrentA_PointVelocity.G 491 - CurrentA_PointVelocity.GetCurveLength(); 469 492 470 // Change this condition for very stri 493 // Change this condition for very strict parameters of propagation 471 // 494 // 472 if( curveDist*curveDist*(1+2* GetEpsil 495 if( curveDist*curveDist*(1+2* GetEpsilonStepFor()) < linDistSq ) 473 { 496 { 474 // Re-integrate to obtain a new B 497 // Re-integrate to obtain a new B 475 // 498 // 476 G4FieldTrack newEndPointFT= 499 G4FieldTrack newEndPointFT= 477 ReEstimateEndpoint( CurrentA 500 ReEstimateEndpoint( CurrentA_PointVelocity, 478 CurrentB 501 CurrentB_PointVelocity, 479 linDistS 502 linDistSq, // to avoid recalculation 480 curveDis 503 curveDist ); 481 G4FieldTrack oldPointVelB = CurrentB 504 G4FieldTrack oldPointVelB = CurrentB_PointVelocity; 482 CurrentB_PointVelocity = newEndPoint 505 CurrentB_PointVelocity = newEndPointFT; 483 506 484 if ( (fin_section_depth[depth]) 507 if ( (fin_section_depth[depth]) // real final section 485 &&( first_section || ((Second_ha 508 &&( first_section || ((Second_half)&&(depth==0)) ) ) 486 { 509 { 487 recalculatedEndPoint = true; 510 recalculatedEndPoint = true; 488 IntersectedOrRecalculatedFT = newE 511 IntersectedOrRecalculatedFT = newEndPointFT; 489 // So that we can return it, if 512 // So that we can return it, if it is the endpoint! 490 } 513 } 491 } 514 } 492 if( curveDist < 0.0 ) 515 if( curveDist < 0.0 ) 493 { 516 { 494 fVerboseLevel = 5; // Print out a ma 517 fVerboseLevel = 5; // Print out a maximum of information 495 printStatus( CurrentA_PointVelocity, 518 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity, 496 -1.0, NewSafety, subst 519 -1.0, NewSafety, substep_no ); 497 std::ostringstream message; 520 std::ostringstream message; 498 message << "Error in advancing propa 521 message << "Error in advancing propagation." << G4endl 499 << " Error in advanci 522 << " Error in advancing propagation." << G4endl 500 << " Point A (start) 523 << " Point A (start) is " << CurrentA_PointVelocity 501 << G4endl 524 << G4endl 502 << " Point B (end) 525 << " Point B (end) is " << CurrentB_PointVelocity 503 << G4endl 526 << G4endl 504 << " Curve distance i 527 << " Curve distance is " << curveDist << G4endl 505 << G4endl 528 << G4endl 506 << "The final curve point is 529 << "The final curve point is not further along" 507 << " than the original!" << 530 << " than the original!" << G4endl; 508 531 509 if( recalculatedEndPoint ) 532 if( recalculatedEndPoint ) 510 { 533 { 511 message << "Recalculation of EndPo 534 message << "Recalculation of EndPoint was called with fEpsStep= " 512 << GetEpsilonStepFor() << 535 << GetEpsilonStepFor() << G4endl; 513 } 536 } 514 oldprc = G4cerr.precision(20); 537 oldprc = G4cerr.precision(20); 515 message << " Point A (Curve start) 538 message << " Point A (Curve start) is " << CurveStartPointVelocity 516 << G4endl 539 << G4endl 517 << " Point B (Curve end) 540 << " Point B (Curve end) is " << CurveEndPointVelocity 518 << G4endl 541 << G4endl 519 << " Point A (Current start) 542 << " Point A (Current start) is " << CurrentA_PointVelocity 520 << G4endl 543 << G4endl 521 << " Point B (Current end) 544 << " Point B (Current end) is " << CurrentB_PointVelocity 522 << G4endl 545 << G4endl 523 << " Point S (Sub start) 546 << " Point S (Sub start) is " << SubStart_PointVelocity 524 << G4endl 547 << G4endl 525 << " Point E (Trial Point) 548 << " Point E (Trial Point) is " << CurrentE_Point 526 << G4endl 549 << G4endl 527 << " Old Point F(Intersectio 550 << " Old Point F(Intersection) is " << CurrentF_Point 528 << G4endl 551 << G4endl 529 << " New Point F(Intersectio 552 << " New Point F(Intersection) is " << ApproxIntersecPointV 530 << G4endl 553 << G4endl 531 << " LocateIntersecti 554 << " LocateIntersection parameters are : Substep no= " 532 << substep_no << G4endl 555 << substep_no << G4endl 533 << " Substep depth no 556 << " Substep depth no= "<< substep_no_p << " Depth= " 534 << depth << G4endl 557 << depth << G4endl 535 << " Restarted no= "< 558 << " Restarted no= "<< restartB << " Epsilon= " 536 << GetEpsilonStepFor() <<" D 559 << GetEpsilonStepFor() <<" DeltaInters= " 537 << GetDeltaIntersectionFor() 560 << GetDeltaIntersectionFor(); 538 G4cerr.precision( oldprc ); 561 G4cerr.precision( oldprc ); 539 562 540 G4Exception("G4BrentLocator::Estimat 563 G4Exception("G4BrentLocator::EstimateIntersectionPoint()", 541 "GeomNav0003", FatalExce 564 "GeomNav0003", FatalException, message); 542 } 565 } 543 566 544 if( restoredFullEndpoint ) << 567 if(restoredFullEndpoint) 545 { 568 { 546 fin_section_depth[depth] = restoredF 569 fin_section_depth[depth] = restoredFullEndpoint; 547 restoredFullEndpoint = false; 570 restoredFullEndpoint = false; 548 } 571 } 549 } // EndIf ( E is close enough to the cu 572 } // EndIf ( E is close enough to the curve, ie point F. ) 550 // tests ChordAF_Vector.mag() <= maxim 573 // tests ChordAF_Vector.mag() <= maximum_lateral_displacement 551 574 552 #ifdef G4DEBUG_LOCATE_INTERSECTION 575 #ifdef G4DEBUG_LOCATE_INTERSECTION 553 G4int trigger_substepno_print= warn_subs << 576 static G4int trigger_substepno_print= warn_substeps - 20 ; 554 577 555 if( substep_no >= trigger_substepno_prin 578 if( substep_no >= trigger_substepno_print ) 556 { 579 { 557 G4cout << "Difficulty in converging in 580 G4cout << "Difficulty in converging in " 558 << "G4BrentLocator::EstimateInt 581 << "G4BrentLocator::EstimateIntersectionPoint()" 559 << G4endl 582 << G4endl 560 << " Substep no = " << subst 583 << " Substep no = " << substep_no << G4endl; 561 if( substep_no == trigger_substepno_pr 584 if( substep_no == trigger_substepno_print ) 562 { 585 { 563 printStatus( CurveStartPointVelocity 586 printStatus( CurveStartPointVelocity, CurveEndPointVelocity, 564 -1.0, NewSafety, 0); 587 -1.0, NewSafety, 0); 565 } 588 } 566 G4cout << " State of point A: "; 589 G4cout << " State of point A: "; 567 printStatus( CurrentA_PointVelocity, C 590 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity, 568 -1.0, NewSafety, substep_ 591 -1.0, NewSafety, substep_no-1, 0); 569 G4cout << " State of point B: "; 592 G4cout << " State of point B: "; 570 printStatus( CurrentA_PointVelocity, C 593 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity, 571 -1.0, NewSafety, substep_ 594 -1.0, NewSafety, substep_no); 572 } 595 } 573 #endif 596 #endif 574 ++substep_no; << 597 substep_no++; 575 ++substep_no_p; << 598 substep_no_p++; 576 599 577 } while ( ( ! found_approximate_intersect 600 } while ( ( ! found_approximate_intersection ) 578 && ( ! there_is_no_intersection ) 601 && ( ! there_is_no_intersection ) 579 && ( substep_no_p <= param_substep 602 && ( substep_no_p <= param_substeps) ); // UNTIL found or 580 603 // failed param substep 581 first_section = false; 604 first_section = false; 582 605 583 if( (!found_approximate_intersection) && ( 606 if( (!found_approximate_intersection) && (!there_is_no_intersection) ) 584 { 607 { 585 G4double did_len = std::abs( CurrentA_Po 608 G4double did_len = std::abs( CurrentA_PointVelocity.GetCurveLength() 586 - SubStart_PointVelocit 609 - SubStart_PointVelocity.GetCurveLength()); 587 G4double all_len = std::abs( CurrentB_Po 610 G4double all_len = std::abs( CurrentB_PointVelocity.GetCurveLength() 588 - SubStart_PointVelocit 611 - SubStart_PointVelocity.GetCurveLength()); 589 612 590 G4double stepLengthAB; 613 G4double stepLengthAB; 591 G4ThreeVector PointGe; 614 G4ThreeVector PointGe; 592 615 593 // Check if progress is too slow and if 616 // Check if progress is too slow and if it possible to go deeper, 594 // then halve the step if so 617 // then halve the step if so 595 // 618 // 596 if ( ( did_len < fraction_done*all_len ) 619 if ( ( did_len < fraction_done*all_len ) 597 && (depth < max_depth) && (!sub_final_ << 620 && (depth<max_depth) && (!sub_final_section) ) 598 { 621 { 599 Second_half=false; 622 Second_half=false; 600 ++depth; << 623 depth++; 601 624 602 G4double Sub_len = (all_len-did_len)/( 625 G4double Sub_len = (all_len-did_len)/(2.); 603 G4FieldTrack start = CurrentA_PointVel 626 G4FieldTrack start = CurrentA_PointVelocity; 604 auto integrDriver = << 627 G4MagInt_Driver* integrDriver = 605 GetChordFinderFor()-> 628 GetChordFinderFor()->GetIntegrationDriver(); 606 integrDriver->AccurateAdvance(start, S 629 integrDriver->AccurateAdvance(start, Sub_len, GetEpsilonStepFor()); 607 *ptrInterMedFT[depth] = start; 630 *ptrInterMedFT[depth] = start; 608 CurrentB_PointVelocity = *ptrInterMedF 631 CurrentB_PointVelocity = *ptrInterMedFT[depth]; 609 632 610 // Adjust 'SubStartPoint' to calculate 633 // Adjust 'SubStartPoint' to calculate the 'did_length' in next loop 611 // 634 // 612 SubStart_PointVelocity = CurrentA_Poin 635 SubStart_PointVelocity = CurrentA_PointVelocity; 613 636 614 // Find new trial intersection point n 637 // Find new trial intersection point needed at start of the loop 615 // 638 // 616 G4ThreeVector Point_A = CurrentA_Point 639 G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition(); 617 G4ThreeVector SubE_point = CurrentB_Po 640 G4ThreeVector SubE_point = CurrentB_PointVelocity.GetPosition(); 618 641 619 GetNavigatorFor()->LocateGlobalPointWi 642 GetNavigatorFor()->LocateGlobalPointWithinVolume(Point_A); 620 G4bool Intersects_AB = IntersectChord( 643 G4bool Intersects_AB = IntersectChord(Point_A, SubE_point, 621 644 NewSafety, fPreviousSafety, 622 645 fPreviousSftOrigin,stepLengthAB, 623 646 PointGe); 624 if( Intersects_AB ) 647 if( Intersects_AB ) 625 { 648 { 626 last_AF_intersection = Intersects_AB 649 last_AF_intersection = Intersects_AB; 627 CurrentE_Point = PointGe; 650 CurrentE_Point = PointGe; 628 fin_section_depth[depth] = true; << 651 fin_section_depth[depth]=true; 629 652 630 // Need to recalculate the Exit Norm 653 // Need to recalculate the Exit Normal at the new PointG 631 // 654 // 632 G4bool validNormalAB; 655 G4bool validNormalAB; 633 NormalAtEntry = GetSurfaceNormal( Po 656 NormalAtEntry = GetSurfaceNormal( PointGe, validNormalAB ); 634 validNormalAtE = validNormalAB; << 657 validNormalAtE= validNormalAB; 635 } 658 } 636 else 659 else 637 { 660 { 638 // No intersection found for first p 661 // No intersection found for first part of curve 639 // (CurrentA,InterMedPoint[depth]). 662 // (CurrentA,InterMedPoint[depth]). Go to the second part 640 // 663 // 641 Second_half = true; 664 Second_half = true; 642 } 665 } 643 } // if did_len 666 } // if did_len 644 667 645 if( (Second_half)&&(depth!=0) ) 668 if( (Second_half)&&(depth!=0) ) 646 { 669 { 647 // Second part of curve (InterMed[dept 670 // Second part of curve (InterMed[depth],Intermed[depth-1]) ) 648 // On the depth-1 level normally we ar 671 // On the depth-1 level normally we are on the 'second_half' 649 672 650 Second_half = true; 673 Second_half = true; 651 674 652 // Find new trial intersection point 675 // Find new trial intersection point needed at start of the loop 653 // 676 // 654 SubStart_PointVelocity = *ptrInterMedF 677 SubStart_PointVelocity = *ptrInterMedFT[depth]; 655 CurrentA_PointVelocity = *ptrInterMedF 678 CurrentA_PointVelocity = *ptrInterMedFT[depth]; 656 CurrentB_PointVelocity = *ptrInterMedF 679 CurrentB_PointVelocity = *ptrInterMedFT[depth-1]; 657 // Ensure that the new endpoints are 680 // Ensure that the new endpoints are not further apart in space 658 // than on the curve due to different 681 // than on the curve due to different errors in the integration 659 // 682 // 660 G4double linDistSq, curveDist; 683 G4double linDistSq, curveDist; 661 linDistSq = ( CurrentB_PointVelocity.G 684 linDistSq = ( CurrentB_PointVelocity.GetPosition() 662 - CurrentA_PointVelocity.G 685 - CurrentA_PointVelocity.GetPosition() ).mag2(); 663 curveDist = CurrentB_PointVelocity.Get 686 curveDist = CurrentB_PointVelocity.GetCurveLength() 664 - CurrentA_PointVelocity.G 687 - CurrentA_PointVelocity.GetCurveLength(); 665 if( curveDist*curveDist*(1+2*GetEpsilo 688 if( curveDist*curveDist*(1+2*GetEpsilonStepFor() ) < linDistSq ) 666 { 689 { 667 // Re-integrate to obtain a new B 690 // Re-integrate to obtain a new B 668 // 691 // 669 G4FieldTrack newEndPointFT = << 692 G4FieldTrack newEndPointFT= 670 ReEstimateEndpoint( CurrentA 693 ReEstimateEndpoint( CurrentA_PointVelocity, 671 CurrentB 694 CurrentB_PointVelocity, 672 linDistS 695 linDistSq, // to avoid recalculation 673 curveDis 696 curveDist ); 674 G4FieldTrack oldPointVelB = CurrentB 697 G4FieldTrack oldPointVelB = CurrentB_PointVelocity; 675 CurrentB_PointVelocity = newEndPoint 698 CurrentB_PointVelocity = newEndPointFT; 676 if ( depth==1 ) << 699 if (depth==1) 677 { 700 { 678 recalculatedEndPoint = true; 701 recalculatedEndPoint = true; 679 IntersectedOrRecalculatedFT = newE 702 IntersectedOrRecalculatedFT = newEndPointFT; 680 // So that we can return it, if it 703 // So that we can return it, if it is the endpoint! 681 } 704 } 682 } 705 } 683 706 684 707 685 G4ThreeVector Point_A = CurrentA_Po 708 G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition(); 686 G4ThreeVector SubE_point = CurrentB_Po 709 G4ThreeVector SubE_point = CurrentB_PointVelocity.GetPosition(); 687 GetNavigatorFor()->LocateGlobalPointWi 710 GetNavigatorFor()->LocateGlobalPointWithinVolume(Point_A); 688 G4bool Intersects_AB = IntersectChord( 711 G4bool Intersects_AB = IntersectChord(Point_A, SubE_point, NewSafety, 689 712 fPreviousSafety, 690 713 fPreviousSftOrigin,stepLengthAB, PointGe); 691 if( Intersects_AB ) 714 if( Intersects_AB ) 692 { 715 { 693 last_AF_intersection = Intersects_AB 716 last_AF_intersection = Intersects_AB; 694 CurrentE_Point = PointGe; 717 CurrentE_Point = PointGe; 695 718 696 G4bool validNormalAB; 719 G4bool validNormalAB; 697 NormalAtEntry = GetSurfaceNormal( P 720 NormalAtEntry = GetSurfaceNormal( PointGe, validNormalAB ); 698 validNormalAtE = validNormalAB; 721 validNormalAtE = validNormalAB; 699 } 722 } 700 723 701 depth--; 724 depth--; 702 fin_section_depth[depth]=true; 725 fin_section_depth[depth]=true; 703 } 726 } 704 } // if(!found_aproximate_intersection) 727 } // if(!found_aproximate_intersection) 705 728 706 } while ( ( ! found_approximate_intersection 729 } while ( ( ! found_approximate_intersection ) 707 && ( ! there_is_no_intersection ) 730 && ( ! there_is_no_intersection ) 708 && ( substep_no <= max_substeps) ) 731 && ( substep_no <= max_substeps) ); // UNTIL found or failed 709 732 710 if( substep_no > max_no_seen ) 733 if( substep_no > max_no_seen ) 711 { 734 { 712 max_no_seen = substep_no; 735 max_no_seen = substep_no; 713 #ifdef G4DEBUG_LOCATE_INTERSECTION 736 #ifdef G4DEBUG_LOCATE_INTERSECTION 714 if( max_no_seen > warn_substeps ) 737 if( max_no_seen > warn_substeps ) 715 { 738 { 716 trigger_substepno_print = max_no_seen-20 739 trigger_substepno_print = max_no_seen-20; // Want to see last 20 steps 717 } 740 } 718 #endif 741 #endif 719 } 742 } 720 743 721 if( ( substep_no >= max_substeps) 744 if( ( substep_no >= max_substeps) 722 && !there_is_no_intersection 745 && !there_is_no_intersection 723 && !found_approximate_intersection ) 746 && !found_approximate_intersection ) 724 { 747 { 725 G4cout << "ERROR - G4BrentLocator::Estimat 748 G4cout << "ERROR - G4BrentLocator::EstimateIntersectionPoint()" << G4endl 726 << " Start and end-point of 749 << " Start and end-point of requested Step:" << G4endl; 727 printStatus( CurveStartPointVelocity, Curv 750 printStatus( CurveStartPointVelocity, CurveEndPointVelocity, 728 -1.0, NewSafety, 0); 751 -1.0, NewSafety, 0); 729 G4cout << " Start and end-point of 752 G4cout << " Start and end-point of current Sub-Step:" << G4endl; 730 printStatus( CurrentA_PointVelocity, Curre 753 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity, 731 -1.0, NewSafety, substep_no-1 754 -1.0, NewSafety, substep_no-1); 732 printStatus( CurrentA_PointVelocity, Curre 755 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity, 733 -1.0, NewSafety, substep_no); 756 -1.0, NewSafety, substep_no); 734 std::ostringstream message; 757 std::ostringstream message; 735 message << "Too many substeps!" << G4endl 758 message << "Too many substeps!" << G4endl 736 << " Convergence is requi 759 << " Convergence is requiring too many substeps: " 737 << substep_no << G4endl 760 << substep_no << G4endl 738 << " Abandoning effort to 761 << " Abandoning effort to intersect. " << G4endl 739 << " Found intersection = 762 << " Found intersection = " 740 << found_approximate_intersection 763 << found_approximate_intersection << G4endl 741 << " Intersection exists 764 << " Intersection exists = " 742 << !there_is_no_intersection << G4 765 << !there_is_no_intersection << G4endl; 743 oldprc = G4cout.precision( 10 ); 766 oldprc = G4cout.precision( 10 ); 744 G4double done_len = CurrentA_PointVelocity 767 G4double done_len = CurrentA_PointVelocity.GetCurveLength(); 745 G4double full_len = CurveEndPointVelocity. 768 G4double full_len = CurveEndPointVelocity.GetCurveLength(); 746 message << " Undertaken only length 769 message << " Undertaken only length: " << done_len 747 << " out of " << full_len << " req 770 << " out of " << full_len << " required." << G4endl 748 << " Remaining length = " < 771 << " Remaining length = " << full_len - done_len; 749 G4cout.precision( oldprc ); 772 G4cout.precision( oldprc ); 750 773 751 G4Exception("G4BrentLocator::EstimateInter 774 G4Exception("G4BrentLocator::EstimateIntersectionPoint()", 752 "GeomNav0003", FatalException, 775 "GeomNav0003", FatalException, message); 753 } 776 } 754 else if( substep_no >= warn_substeps ) 777 else if( substep_no >= warn_substeps ) 755 { 778 { 756 oldprc = G4cout.precision( 10 ); << 779 oldprc= G4cout.precision( 10 ); 757 std::ostringstream message; 780 std::ostringstream message; 758 message << "Many substeps while trying to 781 message << "Many substeps while trying to locate intersection." 759 << G4endl 782 << G4endl 760 << " Undertaken length: " 783 << " Undertaken length: " 761 << CurrentB_PointVelocity.GetCurve 784 << CurrentB_PointVelocity.GetCurveLength() 762 << " - Needed: " << substep_no << 785 << " - Needed: " << substep_no << " substeps." << G4endl 763 << " Warning level = " << 786 << " Warning level = " << warn_substeps 764 << " and maximum substeps = " << m 787 << " and maximum substeps = " << max_substeps; 765 G4Exception("G4BrentLocator::EstimateInter 788 G4Exception("G4BrentLocator::EstimateIntersectionPoint()", 766 "GeomNav1002", JustWarning, me 789 "GeomNav1002", JustWarning, message); 767 G4cout.precision( oldprc ); 790 G4cout.precision( oldprc ); 768 } 791 } 769 return !there_is_no_intersection; // Succe 792 return !there_is_no_intersection; // Success or failure 770 } 793 } 771 794