26911512 |
1 | |
2 | // Flugg tag |
3 | |
4 | //////////////////////////////////////////////////////////////////// |
5 | // |
6 | // WrapNorml.hh - Sara Vanini |
7 | // |
8 | // Wrapper for computing normal unit-vector in global coordinates. |
9 | // |
10 | // Fluka requires normal vector exiting from final position (of |
11 | // particle) volume, that is: entering in volume of initial position. |
12 | // Geant4 always computes the normal vector exiting from the volume. |
13 | // In GetLocalExitNormal() call the volume is the pre-step volume |
14 | // (so G4 normal vector sign is opposite of fluka-required normal). |
15 | // If IsLocalExitNormalValid=false, normal value is computed from |
16 | // init-step volume (in this case sign must change), or from |
17 | // end-step volume (the sign is the same). Normal vector is computed |
18 | // always on boundary between volumes, in global coordinates (to take |
19 | // rotation of parameterised volumes in hierarchy in consideration). |
20 | // So: nrmlwr returns inwards pointing unit normal of the shape for |
21 | // surface closest to the point returned by the navigator (last step |
22 | // end-point). |
23 | // |
24 | // modified 10/III/99 |
25 | // modified 25/V/00 |
26 | // modified 7/VI/00 for boundary-crossing in case of relocation |
27 | // modified 5/VII/00 geometry error on boundary fixed |
28 | // modified 24.10.01: by I. Hrivnacova |
29 | // functions declarations separated from implementation |
30 | // (moved to Wrappers.hh); |
31 | // |
32 | //////////////////////////////////////////////////////////////////// |
33 | |
34 | #include "Wrappers.hh" |
35 | #include "WrapUtils.hh" |
36 | #include "FGeometryInit.hh" |
37 | #include "G4VPhysicalVolume.hh" |
38 | #include "FluggNavigator.hh" |
39 | #include "G4ThreeVector.hh" |
40 | #include "globals.hh" |
41 | |
42 | |
c5a7ed1d |
43 | void nrmlwr(G4double& /*pSx*/, G4double& /*pSy*/, G4double& /*pSz*/, |
26911512 |
44 | G4double& pVx, G4double& pVy, G4double& pVz, |
45 | G4double* norml, const G4int& oldReg, |
c5a7ed1d |
46 | const G4int& /*newReg*/, G4int& flagErr) |
26911512 |
47 | { |
48 | //flag |
49 | #ifdef G4GEOMETRY_DEBUG |
50 | G4cout << "============ NRMLWR-DBG =============" << G4endl; |
51 | #endif |
52 | |
53 | //dummy variables |
54 | flagErr=0; |
55 | |
56 | //navigator pointer |
57 | static FGeometryInit * ptrGeoInit; |
58 | ptrGeoInit = FGeometryInit::GetInstance(); |
59 | FluggNavigator * ptrNavig = ptrGeoInit->getNavigatorForTracking(); |
60 | |
61 | //variables |
62 | G4ThreeVector normalLoc; |
63 | G4ThreeVector normalGlob; |
64 | |
65 | //normal computing |
c5a7ed1d |
66 | G4bool valid; |
67 | normalLoc=ptrNavig->GetLocalExitNormal(&valid); |
0edf14e7 |
68 | if(valid) { |
26911512 |
69 | normalLoc *= -1; |
70 | |
71 | //global cooordinates normal |
72 | normalGlob = ptrNavig->GetLocalToGlobalTransform(). |
73 | TransformAxis(normalLoc); |
74 | } |
75 | else { |
76 | G4VPhysicalVolume *touchvolume; |
77 | G4ThreeVector theLocalPoint; |
78 | |
79 | if(ptrNavig->EnteredDaughterVolume()) { |
80 | //volume from touchable history |
81 | G4TouchableHistory *ptrTouchableHistory=ptrGeoInit-> |
82 | GetTouchableHistory(); |
83 | touchvolume = ptrTouchableHistory->GetVolume(); |
84 | |
85 | //local point from navigator and normal |
86 | theLocalPoint = ptrNavig->GetCurrentLocalCoordinate(); |
87 | normalLoc = touchvolume->GetLogicalVolume()->GetSolid()-> |
88 | SurfaceNormal(theLocalPoint); |
89 | |
90 | //global cooordinates normal |
91 | normalGlob = ptrNavig->GetLocalToGlobalTransform(). |
92 | TransformAxis(normalLoc); |
93 | } |
94 | else { |
95 | //volume from old history |
96 | const G4NavigationHistory * ptrOldNavHist = |
97 | ptrGeoInit->GetOldNavHist()->GetHistory(); |
98 | touchvolume = ptrOldNavHist->GetTopVolume(); |
99 | |
100 | if(!touchvolume) { |
101 | // Old history has been reseted by LOOKZ relocation, |
102 | // so is necessary to track back and forward to find |
103 | // the right histories. |
104 | |
105 | |
106 | //////////// COMPUTE STEP BACKWARD ////////////////// |
107 | G4ThreeVector theGlobalPoint = ptrNavig->GetLocalToGlobalTransform(). |
108 | TransformPoint(ptrNavig->GetCurrentLocalCoordinate()); |
109 | |
110 | //compute step and new location |
111 | G4ThreeVector pVec(pVx,pVy,pVz); |
112 | pVec=-pVec; |
113 | G4double appStep = 0; |
114 | G4double safety = 0; |
115 | G4bool onBoundary = false; |
116 | G4double physStep = 1000000000; |
117 | G4int newRegStep; |
118 | G4ThreeVector partLoc = theGlobalPoint; |
119 | G4bool fErr=false; |
120 | |
121 | #ifdef G4GEOMETRY_DEBUG |
122 | G4cout << "Old history not found" << G4endl; |
123 | G4cout << "* NRML needs boundary-crossing: computing step backward..." |
124 | << G4endl; |
125 | #endif |
126 | |
127 | //compute step and location |
128 | newRegStep=StepAndLocation(partLoc,pVec,physStep, |
129 | appStep,safety,onBoundary, |
130 | fErr,oldReg); |
131 | |
132 | G4PhysicalVolumeStore * pVolStore = G4PhysicalVolumeStore:: |
133 | GetInstance(); |
134 | |
135 | if(appStep<physStep && newRegStep!=G4int(pVolStore->size())+1) { |
136 | //end-step point is on boundary between volumes; |
137 | //==> update step-histories |
138 | |
139 | #ifdef G4GEOMETRY_DEBUG |
140 | G4cout << "* updating step-histories" << G4endl; |
141 | #endif |
142 | |
143 | G4TouchableHistory * ptrTouchHist = |
144 | ptrGeoInit->GetTouchableHistory(); |
145 | ptrGeoInit->UpdateHistories(ptrTouchHist->GetHistory(),2); |
146 | } |
147 | else { |
148 | #ifdef G4GEOMETRY_DEBUG |
149 | G4cout << "ERROR! Boundary not found" << G4endl; |
150 | #endif |
151 | } |
152 | |
153 | #ifdef G4GEOMETRY_DEBUG |
154 | G4cout << "* computing step forward..." << G4endl; |
155 | #endif |
156 | pVec=-pVec; |
157 | safety = 0; |
158 | onBoundary = false; |
159 | |
160 | //compute step and location for boundary crossing |
161 | newRegStep=StepAndLocation(partLoc,pVec,physStep, |
162 | appStep,safety,onBoundary,fErr,oldReg); |
163 | if(appStep<physStep) { |
164 | //end-step point is on boundary between volumes; |
165 | //==> update step-histories |
166 | |
167 | #ifdef G4GEOMETRY_DEBUG |
168 | G4cout << "* updating step-histories" << G4endl; |
169 | #endif |
170 | |
171 | G4TouchableHistory * ptrTouchHist = |
172 | ptrGeoInit->GetTouchableHistory(); |
173 | ptrGeoInit->UpdateHistories(ptrTouchHist->GetHistory(),2); |
174 | } |
175 | } |
176 | |
177 | // now touchvolume exist. |
178 | // local point from navigator and global point |
179 | // N.B. if particle has exited world volume, |
180 | // FluggNavigator doesn't update lastLocatedPoint. |
181 | // So be carefull in building geometry always to have a |
182 | // big world volume that fluka won't exit. |
183 | |
184 | touchvolume = ptrOldNavHist->GetTopVolume(); |
185 | |
186 | G4ThreeVector theGlobalPoint = ptrNavig->GetLocalToGlobalTransform(). |
187 | TransformPoint(ptrNavig->GetCurrentLocalCoordinate()); |
188 | theLocalPoint = ptrOldNavHist->GetTopTransform(). |
189 | TransformPoint(theGlobalPoint); |
190 | normalLoc = (touchvolume->GetLogicalVolume()->GetSolid()-> |
191 | SurfaceNormal(theLocalPoint)); |
192 | normalLoc *= -1; |
193 | |
194 | //global cooordinates normal |
195 | normalGlob = ptrOldNavHist->GetTopTransform(). |
196 | Inverse().TransformAxis(normalLoc); |
197 | } |
198 | } |
199 | |
200 | //return normal: |
201 | norml[0]=G4double(normalGlob.x()); |
202 | norml[1]=G4double(normalGlob.y()); |
203 | norml[2]=G4double(normalGlob.z()); |
204 | |
205 | //for debugging |
206 | #ifdef G4GEOMETRY_DEBUG |
207 | G4cout << "Normal: " << normalGlob << G4endl; |
208 | #endif |
209 | } |
210 | |
211 | |