Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4NormalNavigation.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// class G4NormalNavigation Implementation
27//
28// Author: P.Kent, 1996
29//
30// --------------------------------------------------------------------
31
32#include "G4NormalNavigation.hh"
33#include "G4NavigationLogger.hh"
34#include "G4AffineTransform.hh"
35
36// ********************************************************************
37// Constructor
38// ********************************************************************
39//
41{
42 fLogger = new G4NavigationLogger("G4NormalNavigation");
43}
44
45// ********************************************************************
46// Destructor
47// ********************************************************************
48//
50{
51 delete fLogger;
52}
53
54// ********************************************************************
55// ComputeStep
56// ********************************************************************
57//
58// On entry
59// exitNormal, validExitNormal: for previous exited volume (daughter)
60//
61// On exit
62// exitNormal, validExitNormal: for mother, if exiting it (else unchanged)
65 const G4ThreeVector& localDirection,
66 const G4double currentProposedStepLength,
67 G4double& newSafety,
68 G4NavigationHistory& history,
69 G4bool& validExitNormal,
70 G4ThreeVector& exitNormal,
71 G4bool& exiting,
72 G4bool& entering,
73 G4VPhysicalVolume* (*pBlockedPhysical),
74 G4int& blockedReplicaNo)
75{
76 G4VPhysicalVolume *motherPhysical, *samplePhysical,
77 *blockedExitedVol = nullptr;
78 G4LogicalVolume *motherLogical;
79 G4VSolid *motherSolid;
80 G4ThreeVector sampleDirection;
81 G4double ourStep = currentProposedStepLength, ourSafety;
82 G4double motherSafety, motherStep = DBL_MAX;
83 G4long localNoDaughters, sampleNo;
84 G4bool motherValidExitNormal = false;
85 G4ThreeVector motherExitNormal;
86
87 motherPhysical = history.GetTopVolume();
88 motherLogical = motherPhysical->GetLogicalVolume();
89 motherSolid = motherLogical->GetSolid();
90
91 // Compute mother safety
92 //
93 motherSafety = motherSolid->DistanceToOut(localPoint);
94 ourSafety = motherSafety; // Working isotropic safety
95
96 localNoDaughters = motherLogical->GetNoDaughters();
97
98#ifdef G4VERBOSE
99 if ( fCheck && ( (localNoDaughters>0) || (ourStep < motherSafety) ) )
100 {
101 fLogger->PreComputeStepLog(motherPhysical, motherSafety, localPoint);
102 }
103#endif
104 // Compute daughter safeties & intersections
105 //
106
107 // Exiting normal optimisation
108 //
109 if ( exiting && validExitNormal )
110 {
111 if ( localDirection.dot(exitNormal)>=kMinExitingNormalCosine )
112 {
113 // Block exited daughter volume
114 //
115 blockedExitedVol = (*pBlockedPhysical);
116 ourSafety = 0;
117 }
118 }
119 exiting = false;
120 entering = false;
121
122#ifdef G4VERBOSE
123 if ( fCheck )
124 {
125 // Compute early:
126 // a) to check whether point is (wrongly) outside
127 // (signaled if step < 0 or step == kInfinity )
128 // b) to check value against answer of daughters!
129
130 motherStep = motherSolid->DistanceToOut(localPoint,
131 localDirection,
132 true,
133 &motherValidExitNormal,
134 &motherExitNormal);
135
136 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
137 {
138 // Error - indication of being outside solid !!
139 fLogger->ReportOutsideMother(localPoint, localDirection, motherPhysical);
140
141 ourStep = motherStep = 0.0;
142
143 exiting = true;
144 entering = false;
145
146 // If we are outside the solid does the normal make sense?
147 validExitNormal = motherValidExitNormal;
148 exitNormal = motherExitNormal;
149
150 *pBlockedPhysical = nullptr; // or motherPhysical ?
151 blockedReplicaNo = 0; // or motherReplicaNumber ?
152
153 newSafety = 0.0;
154 return ourStep;
155 }
156 }
157#endif
158
159 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo--)
160 {
161 samplePhysical = motherLogical->GetDaughter(sampleNo);
162 if ( samplePhysical!=blockedExitedVol )
163 {
164 G4AffineTransform sampleTf(samplePhysical->GetRotation(),
165 samplePhysical->GetTranslation());
166 sampleTf.Invert();
167 const G4ThreeVector samplePoint = sampleTf.TransformPoint(localPoint);
168 const G4VSolid *sampleSolid =
169 samplePhysical->GetLogicalVolume()->GetSolid();
170 const G4double sampleSafety =
171 sampleSolid->DistanceToIn(samplePoint);
172
173 if ( sampleSafety<ourSafety )
174 {
175 ourSafety=sampleSafety;
176 }
177
178 if ( sampleSafety<=ourStep )
179 {
180 sampleDirection = sampleTf.TransformAxis(localDirection);
181 const G4double sampleStep =
182 sampleSolid->DistanceToIn(samplePoint,sampleDirection);
183#ifdef G4VERBOSE
184 if( fCheck )
185 {
186 fLogger->PrintDaughterLog(sampleSolid, samplePoint,
187 sampleSafety, true,
188 sampleDirection, sampleStep);
189 }
190#endif
191 if ( sampleStep<=ourStep )
192 {
193 ourStep = sampleStep;
194 entering = true;
195 exiting = false;
196 *pBlockedPhysical = samplePhysical;
197 blockedReplicaNo = -1;
198#ifdef G4VERBOSE
199 if( fCheck )
200 {
201 fLogger->AlongComputeStepLog(sampleSolid, samplePoint,
202 sampleDirection, localDirection,
203 sampleSafety, sampleStep);
204 }
205#endif
206 }
207
208#ifdef G4VERBOSE
209 if( fCheck && (sampleStep < kInfinity) && (sampleStep >= motherStep) )
210 {
211 // The intersection point with the daughter is at or after the exit
212 // point from the mother volume. Double check!
213 fLogger->CheckDaughterEntryPoint(sampleSolid,
214 samplePoint, sampleDirection,
215 motherSolid,
216 localPoint, localDirection,
217 motherStep, sampleStep);
218 }
219#endif
220 } // end of if ( sampleSafety <= ourStep )
221#ifdef G4VERBOSE
222 else if ( fCheck )
223 {
224 fLogger->PrintDaughterLog(sampleSolid, samplePoint,
225 sampleSafety, false,
226 G4ThreeVector(0.,0.,0.), -1.0 );
227 }
228#endif
229 }
230 }
231 if ( currentProposedStepLength<ourSafety )
232 {
233 // Guaranteed physics limited
234 //
235 entering = false;
236 exiting = false;
237 *pBlockedPhysical = nullptr;
238 ourStep = kInfinity;
239 }
240 else
241 {
242 // Consider intersection with mother solid
243 //
244 if ( motherSafety<=ourStep )
245 {
246 if ( !fCheck ) // The call is moved above when running in check_mode
247 {
248 motherStep = motherSolid->DistanceToOut(localPoint,
249 localDirection,
250 true,
251 &motherValidExitNormal,
252 &motherExitNormal);
253 }
254#ifdef G4VERBOSE
255 else // check_mode
256 {
257 fLogger->PostComputeStepLog(motherSolid, localPoint, localDirection,
258 motherStep, motherSafety);
259 if( motherValidExitNormal )
260 {
261 fLogger->CheckAndReportBadNormal(motherExitNormal,
262 localPoint,
263 localDirection,
264 motherStep,
265 motherSolid,
266 "From motherSolid::DistanceToOut" );
267 }
268 }
269#endif
270
271 if( (motherStep >= kInfinity) || (motherStep < 0.0) )
272 {
273#ifdef G4VERBOSE
274 if( fCheck ) // Clearly outside the mother solid!
275 {
276 fLogger->ReportOutsideMother(localPoint, localDirection,
277 motherPhysical);
278 }
279#endif
280 ourStep = motherStep = 0.0;
281 exiting = true;
282 entering = false;
283 // validExitNormal= motherValidExitNormal;
284 // exitNormal= motherExitNormal;
285 // The normal could be useful - but only if near the mother
286 // But it could be unreliable!
287 validExitNormal = false;
288 *pBlockedPhysical = nullptr; // or motherPhysical ?
289 blockedReplicaNo = 0; // or motherReplicaNumber ?
290 newSafety= 0.0;
291 return ourStep;
292 }
293
294 if ( motherStep<=ourStep )
295 {
296 ourStep = motherStep;
297 exiting = true;
298 entering = false;
299 validExitNormal = motherValidExitNormal;
300 exitNormal = motherExitNormal;
301
302 if ( motherValidExitNormal )
303 {
304 const G4RotationMatrix *rot = motherPhysical->GetRotation();
305 if (rot)
306 {
307 exitNormal *= rot->inverse();
308#ifdef G4VERBOSE
309 if( fCheck )
310 fLogger->CheckAndReportBadNormal(exitNormal, // rotated
311 motherExitNormal, // original
312 *rot,
313 "From RotationMatrix" );
314#endif
315 }
316 }
317 }
318 else
319 {
320 validExitNormal = false;
321 }
322 }
323 }
324 newSafety = ourSafety;
325 return ourStep;
326}
327
328// ********************************************************************
329// ComputeSafety
330// ********************************************************************
331//
333 const G4NavigationHistory& history,
334 const G4double)
335{
336 G4VPhysicalVolume *motherPhysical, *samplePhysical;
337 G4LogicalVolume *motherLogical;
338 G4VSolid *motherSolid;
339 G4double motherSafety, ourSafety;
340 G4long localNoDaughters, sampleNo;
341
342 motherPhysical = history.GetTopVolume();
343 motherLogical = motherPhysical->GetLogicalVolume();
344 motherSolid = motherLogical->GetSolid();
345
346 // Compute mother safety
347 //
348 motherSafety = motherSolid->DistanceToOut(localPoint);
349 ourSafety = motherSafety; // Working isotropic safety
350
351#ifdef G4VERBOSE
352 if( fCheck )
353 {
354 fLogger->ComputeSafetyLog(motherSolid,localPoint,motherSafety,true,true);
355 }
356#endif
357
358 // Compute daughter safeties
359 //
360 localNoDaughters = motherLogical->GetNoDaughters();
361 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
362 {
363 samplePhysical = motherLogical->GetDaughter(sampleNo);
364 G4AffineTransform sampleTf(samplePhysical->GetRotation(),
365 samplePhysical->GetTranslation());
366 sampleTf.Invert();
367 const G4ThreeVector samplePoint =
368 sampleTf.TransformPoint(localPoint);
369 const G4VSolid *sampleSolid =
370 samplePhysical->GetLogicalVolume()->GetSolid();
371 const G4double sampleSafety =
372 sampleSolid->DistanceToIn(samplePoint);
373 if ( sampleSafety<ourSafety )
374 {
375 ourSafety = sampleSafety;
376 }
377#ifdef G4VERBOSE
378 if(fCheck)
379 {
380 fLogger->ComputeSafetyLog(sampleSolid, samplePoint,
381 sampleSafety, false, false);
382 // Not mother, no banner
383 }
384#endif
385 }
386 return ourSafety;
387}
388
389// The following methods have been imported to this source file
390// in order to avoid dependency of the header file on the
391// header implementation of G4NavigationLogger.
392
393// ********************************************************************
394// GetVerboseLevel
395// ********************************************************************
396//
398{
399 return fLogger->GetVerboseLevel();
400}
401
402// ********************************************************************
403// SetVerboseLevel
404// ********************************************************************
405//
407{
408 fLogger->SetVerboseLevel(level);
409}
CLHEP::Hep3Vector G4ThreeVector
double G4double
Definition: G4Types.hh:83
long G4long
Definition: G4Types.hh:87
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
double dot(const Hep3Vector &) const
HepRotation inverse() const
G4AffineTransform & Invert()
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
G4VSolid * GetSolid() const
std::size_t GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const std::size_t i) const
G4VPhysicalVolume * GetTopVolume() const
void SetVerboseLevel(G4int level)
void PreComputeStepLog(const G4VPhysicalVolume *motherPhysical, G4double motherSafety, const G4ThreeVector &localPoint) const
void CheckDaughterEntryPoint(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, const G4ThreeVector &sampleDirection, const G4VSolid *motherSolid, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double motherStep, G4double sampleStep) const
G4int GetVerboseLevel() const
void PrintDaughterLog(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, G4double sampleSafety, G4bool onlySafety, const G4ThreeVector &sampleDirection, G4double sampleStep) const
G4bool CheckAndReportBadNormal(const G4ThreeVector &unitNormal, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double step, const G4VSolid *solid, const char *msg) const
void ComputeSafetyLog(const G4VSolid *solid, const G4ThreeVector &point, G4double safety, G4bool isMotherVolume, G4int banner=-1) const
void PostComputeStepLog(const G4VSolid *motherSolid, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double motherStep, G4double motherSafety) const
void ReportOutsideMother(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4VPhysicalVolume *motherPV, G4double tDist=30.0 *CLHEP::cm) const
void AlongComputeStepLog(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, const G4ThreeVector &sampleDirection, const G4ThreeVector &localDirection, G4double sampleSafety, G4double sampleStep) const
G4double ComputeStep(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4int GetVerboseLevel() const
G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4NavigationHistory &history, const G4double pMaxLength=DBL_MAX)
void SetVerboseLevel(G4int level)
const G4RotationMatrix * GetRotation() const
const G4ThreeVector GetTranslation() const
G4LogicalVolume * GetLogicalVolume() const
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=nullptr, G4ThreeVector *n=nullptr) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
#define DBL_MAX
Definition: templates.hh:62