Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
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//
27// $Id$
28//
29//
30// class G4NormalNavigation Implementation
31//
32// Author: P.Kent, 1996
33//
34// --------------------------------------------------------------------
35
36#include "G4NormalNavigation.hh"
37#include "G4AffineTransform.hh"
38
39// ********************************************************************
40// Constructor
41// ********************************************************************
42//
44 : fCheck(false)
45{
46 fLogger = new G4NavigationLogger("G4NormalNavigation");
47}
48
49// ********************************************************************
50// Destructor
51// ********************************************************************
52//
54{
55 delete fLogger;
56}
57
58// ********************************************************************
59// ComputeStep
60// ********************************************************************
61//
64 const G4ThreeVector &localDirection,
65 const G4double currentProposedStepLength,
66 G4double &newSafety,
67 G4NavigationHistory &history,
68 G4bool &validExitNormal,
69 G4ThreeVector &exitNormal,
70 G4bool &exiting,
71 G4bool &entering,
72 G4VPhysicalVolume *(*pBlockedPhysical),
73 G4int &blockedReplicaNo)
74{
75 G4VPhysicalVolume *motherPhysical, *samplePhysical, *blockedExitedVol=0;
76 G4LogicalVolume *motherLogical;
77 G4VSolid *motherSolid;
78 G4ThreeVector sampleDirection;
79 G4double ourStep=currentProposedStepLength, motherSafety, ourSafety;
80 G4int localNoDaughters, sampleNo;
81
82 motherPhysical = history.GetTopVolume();
83 motherLogical = motherPhysical->GetLogicalVolume();
84 motherSolid = motherLogical->GetSolid();
85
86 // Compute mother safety
87 //
88 motherSafety = motherSolid->DistanceToOut(localPoint);
89 ourSafety = motherSafety; // Working isotropic safety
90
91#ifdef G4VERBOSE
92 if ( fCheck )
93 {
94 fLogger->PreComputeStepLog(motherPhysical, motherSafety, localPoint);
95 }
96#endif
97
98 //
99 // Compute daughter safeties & intersections
100 //
101
102 // Exiting normal optimisation
103 //
104 if ( exiting&&validExitNormal )
105 {
106 if ( localDirection.dot(exitNormal)>=kMinExitingNormalCosine )
107 {
108 // Block exited daughter volume
109 //
110 blockedExitedVol =* pBlockedPhysical;
111 ourSafety = 0;
112 }
113 }
114 exiting = false;
115 entering = false;
116
117 localNoDaughters = motherLogical->GetNoDaughters();
118 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo--)
119 {
120 samplePhysical = motherLogical->GetDaughter(sampleNo);
121 if ( samplePhysical!=blockedExitedVol )
122 {
123 G4AffineTransform sampleTf(samplePhysical->GetRotation(),
124 samplePhysical->GetTranslation());
125 sampleTf.Invert();
126 const G4ThreeVector samplePoint =
127 sampleTf.TransformPoint(localPoint);
128 const G4VSolid *sampleSolid =
129 samplePhysical->GetLogicalVolume()->GetSolid();
130 const G4double sampleSafety =
131 sampleSolid->DistanceToIn(samplePoint);
132#ifdef G4VERBOSE
133 if( fCheck )
134 {
135 fLogger->PrintDaughterLog(sampleSolid, samplePoint, sampleSafety, 0);
136 }
137#endif
138 if ( sampleSafety<ourSafety )
139 {
140 ourSafety=sampleSafety;
141 }
142 if ( sampleSafety<=ourStep )
143 {
144 sampleDirection = sampleTf.TransformAxis(localDirection);
145 const G4double sampleStep =
146 sampleSolid->DistanceToIn(samplePoint,sampleDirection);
147
148#ifdef G4VERBOSE
149 if( fCheck )
150 {
151 fLogger->PrintDaughterLog(sampleSolid, samplePoint,
152 sampleSafety, sampleStep);
153 }
154#endif
155 if ( sampleStep<=ourStep )
156 {
157 ourStep = sampleStep;
158 entering = true;
159 exiting = false;
160 *pBlockedPhysical = samplePhysical;
161 blockedReplicaNo = -1;
162#ifdef G4VERBOSE
163 if( fCheck )
164 {
165 fLogger->AlongComputeStepLog(sampleSolid, samplePoint,
166 sampleDirection, localDirection, sampleSafety, sampleStep);
167 }
168#endif
169 }
170 }
171 }
172 }
173 if ( currentProposedStepLength<ourSafety )
174 {
175 // Guaranteed physics limited
176 //
177 entering = false;
178 exiting = false;
179 *pBlockedPhysical = 0;
180 ourStep = kInfinity;
181 }
182 else
183 {
184 // Compute mother intersection if required
185 //
186 if ( motherSafety<=ourStep )
187 {
188 G4double motherStep = motherSolid->DistanceToOut(localPoint,
189 localDirection,
190 true,
191 &validExitNormal,
192 &exitNormal);
193#ifdef G4VERBOSE
194 if ( fCheck )
195 {
196 fLogger->PostComputeStepLog(motherSolid, localPoint, localDirection,
197 motherStep, motherSafety);
198 }
199#endif
200
201 if ( motherStep<=ourStep )
202 {
203 ourStep = motherStep;
204 exiting = true;
205 entering = false;
206 if ( validExitNormal )
207 {
208 const G4RotationMatrix *rot = motherPhysical->GetRotation();
209 if (rot)
210 {
211 exitNormal *= rot->inverse();
212 }
213 }
214 }
215 else
216 {
217 validExitNormal = false;
218 }
219 }
220 }
221 newSafety = ourSafety;
222 return ourStep;
223}
224
225// ********************************************************************
226// ComputeSafety
227// ********************************************************************
228//
230 const G4NavigationHistory &history,
231 const G4double)
232{
233 G4VPhysicalVolume *motherPhysical, *samplePhysical;
234 G4LogicalVolume *motherLogical;
235 G4VSolid *motherSolid;
236 G4double motherSafety, ourSafety;
237 G4int localNoDaughters, sampleNo;
238
239 motherPhysical = history.GetTopVolume();
240 motherLogical = motherPhysical->GetLogicalVolume();
241 motherSolid = motherLogical->GetSolid();
242
243 // Compute mother safety
244 //
245 motherSafety = motherSolid->DistanceToOut(localPoint);
246 ourSafety = motherSafety; // Working isotropic safety
247
248#ifdef G4VERBOSE
249 if( fCheck )
250 {
251 fLogger->ComputeSafetyLog(motherSolid, localPoint, motherSafety, true);
252 }
253#endif
254
255 // Compute daughter safeties
256 //
257 localNoDaughters = motherLogical->GetNoDaughters();
258 for ( sampleNo=localNoDaughters-1; sampleNo>=0; sampleNo-- )
259 {
260 samplePhysical = motherLogical->GetDaughter(sampleNo);
261 G4AffineTransform sampleTf(samplePhysical->GetRotation(),
262 samplePhysical->GetTranslation());
263 sampleTf.Invert();
264 const G4ThreeVector samplePoint =
265 sampleTf.TransformPoint(localPoint);
266 const G4VSolid *sampleSolid =
267 samplePhysical->GetLogicalVolume()->GetSolid();
268 const G4double sampleSafety =
269 sampleSolid->DistanceToIn(samplePoint);
270 if ( sampleSafety<ourSafety )
271 {
272 ourSafety = sampleSafety;
273 }
274#ifdef G4VERBOSE
275 if(fCheck)
276 {
277 fLogger->ComputeSafetyLog(sampleSolid, samplePoint, sampleSafety, false);
278 }
279#endif
280 }
281 return ourSafety;
282}
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
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
G4int GetNoDaughters() const
G4VPhysicalVolume * GetDaughter(const G4int i) const
G4VPhysicalVolume * GetTopVolume() const
void PreComputeStepLog(const G4VPhysicalVolume *motherPhysical, G4double motherSafety, const G4ThreeVector &localPoint) const
void PostComputeStepLog(const G4VSolid *motherSolid, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, G4double motherStep, G4double motherSafety) const
void PrintDaughterLog(const G4VSolid *sampleSolid, const G4ThreeVector &samplePoint, G4double sampleSafety, G4double sampleStep) const
void ComputeSafetyLog(const G4VSolid *solid, const G4ThreeVector &point, G4double safety, G4bool banner) 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)
G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4NavigationHistory &history, const G4double pMaxLength=DBL_MAX)
const G4RotationMatrix * GetRotation() const
G4LogicalVolume * GetLogicalVolume() const
const G4ThreeVector & GetTranslation() const
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0