Computes the length of a step to the next boundary. Does not test against pBlockedPhysical. Identifies the next candidate volume (if a daughter of the current volume), and returns it in: pBlockedPhysical, blockedReplicaNo.
80{
81 G4VPhysicalVolume *motherPhysical, *samplePhysical;
82 G4VPVParameterisation *sampleParam;
83 G4LogicalVolume *motherLogical;
84 G4VSolid *motherSolid, *sampleSolid;
86 G4double ourStep=currentProposedStepLength, ourSafety;
88 G4bool motherValidExitNormal =
false;
90
92
93 G4bool initialNode, noStep;
94 G4SmartVoxelNode *curVoxelNode;
95 G4long curNoVolumes, contentNo;
97
98
99
104
107 motherSolid = motherLogical->
GetSolid();
108
109
110
111
112
114 ourSafety = motherSafety;
115
116#ifdef G4VERBOSE
118 {
119 if( motherSafety < 0.0 )
120 {
122 std::ostringstream message;
123 message <<
"Negative Safety In Voxel Navigation !" <<
G4endl
124 <<
" Current solid " << motherSolid->
GetName()
125 <<
" gave negative safety: " << motherSafety <<
G4endl
126 << " for the current (local) point " << localPoint;
127 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
129 }
131 {
132 std::ostringstream message;
133 message <<
"Point is outside Current Volume !" <<
G4endl
134 << " Point " << localPoint
135 <<
" is outside current volume " << motherPhysical->
GetName()
138 G4cout <<
" Estimated isotropic distance to solid (distToIn)= "
139 << estDistToSolid;
140 if( estDistToSolid > 100.0 * motherSolid->
GetTolerance() )
141 {
143 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
145 "Point is far outside Current Volume !");
146 }
147 else
148 {
149 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
151 "Point is a little outside Current Volume.");
152 }
153 }
154
155
156
157
158
159
161 localDirection,
162 true,
163 &motherValidExitNormal,
164 &motherExitNormal);
165
166 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
167 {
168
169
170 fLogger->ReportOutsideMother(localPoint, localDirection, motherPhysical);
171
172 ourStep = motherStep = 0.0;
173 exiting = true;
174 entering = false;
175
176
177 validExitNormal = motherValidExitNormal;
178 exitNormal = motherExitNormal;
179
180 *pBlockedPhysical = nullptr;
181 blockedReplicaNo = 0;
182
183 newSafety = 0.0;
184 return ourStep;
185 }
186 }
187#endif
188
189 initialNode = true;
190 noStep = true;
191
192
193
194
197 fBList.Enlarge(nReplicas);
199
200
201
202 if (exiting && (*pBlockedPhysical==samplePhysical) && validExitNormal)
203 {
204 if (localDirection.
dot(exitNormal)>=kMinExitingNormalCosine)
205 {
206
207
208 fBList.BlockVolume(blockedReplicaNo);
209 ourSafety = 0;
210 }
211 }
212 exiting = false;
213 entering = false;
214
216
217
218
219 do
220 {
223
224 for ( contentNo=curNoVolumes-1; contentNo>=0; contentNo-- )
225 {
227 if ( !
fBList.IsBlocked(sampleNo) )
228 {
229 fBList.BlockVolume(sampleNo);
230
231
232
233 sampleSolid = IdentifyAndPlaceSolid( sampleNo, samplePhysical,
234 sampleParam );
235
236 G4AffineTransform sampleTf(samplePhysical->
GetRotation(),
238 sampleTf.Invert();
239 const G4ThreeVector samplePoint = sampleTf.TransformPoint(localPoint);
241 if ( sampleSafety<ourSafety )
242 {
243 ourSafety = sampleSafety;
244 }
245 if ( sampleSafety<=ourStep )
246 {
247 sampleDirection = sampleTf.TransformAxis(localDirection);
249 sampleSolid->
DistanceToIn(samplePoint, sampleDirection);
250 if ( sampleStep<=ourStep )
251 {
252 ourStep = sampleStep;
253 entering = true;
254 exiting = false;
255 *pBlockedPhysical = samplePhysical;
256 blockedReplicaNo = sampleNo;
257#ifdef G4VERBOSE
258
259
260
261
262 if ( (
fCheck ) && ( sampleStep < kInfinity ) )
263 {
265 intersectionPoint = samplePoint + sampleStep * sampleDirection;
266 EInside insideIntPt = sampleSolid->
Inside(intersectionPoint);
268 {
270 std::ostringstream message;
271 message << "Navigator gets conflicting response from Solid."
273 << " Inaccurate solid DistanceToIn"
275 << " Solid gave DistanceToIn = "
276 << sampleStep << " yet returns " ;
278 {
279 message << "-kInside-";
280 }
282 {
283 message << "-kOutside-";
284 }
285 else
286 {
287 message << "-kSurface-";
288 }
289 message <<
" for this point !" <<
G4endl
290 << " Point = " << intersectionPoint
293 {
294 message << " DistanceToIn(p) = "
296 }
298 {
299 message << " DistanceToOut(p) = "
301 }
302 G4Exception(
"G4ParameterisedNavigation::ComputeStep()",
304 G4cout.precision(oldcoutPrec);
305 }
306 }
307#endif
308 }
309 }
310 }
311 }
312
313 if ( initialNode )
314 {
315 initialNode = false;
316 voxelSafety = ComputeVoxelSafety(localPoint,
axis);
317 if ( voxelSafety<ourSafety )
318 {
319 ourSafety = voxelSafety;
320 }
321 if ( currentProposedStepLength<ourSafety )
322 {
323
324
325 noStep = false;
326 entering = false;
327 exiting = false;
328 *pBlockedPhysical = nullptr;
329 ourStep = kInfinity;
330 }
331 else
332 {
333
334
335 if ( motherSafety<=ourStep )
336 {
338 {
340 localDirection,
341 true,
342 &motherValidExitNormal,
343 &motherExitNormal);
344 }
345
346 if( ( motherStep < 0.0 ) || ( motherStep >= kInfinity) )
347 {
348#ifdef G4VERBOSE
349 fLogger->ReportOutsideMother(localPoint, localDirection,
350 motherPhysical);
351#endif
352 ourStep = motherStep = 0.0;
353
354
355
356 }
357#ifdef G4VERBOSE
358 if( motherValidExitNormal && (
fCheck || (motherStep<=ourStep)) )
359 {
360 fLogger->CheckAndReportBadNormal(motherExitNormal,
361 localPoint, localDirection,
362 motherStep, motherSolid,
363 "From motherSolid::DistanceToOut");
364 }
365#endif
366 if ( motherStep<=ourStep )
367 {
368 ourStep = motherStep;
369 exiting = true;
370 entering = false;
371 if ( validExitNormal )
372 {
374 if (rot != nullptr)
375 {
377 }
378 }
379 }
380 else
381 {
382 validExitNormal = false;
383 }
384 }
385 }
386 newSafety = ourSafety;
387 }
388 if (noStep)
389 {
390 noStep = LocateNextVoxel(localPoint, localDirection, ourStep,
axis);
391 }
392 } while (noStep);
393
394 return ourStep;
395}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
CLHEP::HepRotation G4RotationMatrix
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
HepRotation inverse() const
const G4String & GetName() const
G4double GetTolerance() const
virtual EInside Inside(const G4ThreeVector &p) const =0
G4NavigationLogger * fLogger