5 * Revision 1.3 1998/02/09 16:48:33 japost
6 * Simone's fix for MANY volumes in gmedia.
8 * Revision 1.2 1996/09/30 14:25:07 ravndal
9 * Windows NT related modifications
11 * Revision 1.1.1.1 1995/10/24 10:20:51 cernlib
15 #include "geant321/pilot.h"
16 #if !defined(CERNLIB_OLD)
17 *CMZ : 3.21/02 29/03/94 15.24.17 by S.Giani
19 SUBROUTINE GMEDIA (X, NUMED)
21 C. ******************************************************************
23 C. * Finds in which volume/medium the point X is, and updates the *
24 C. * common /GCVOLU/ and the structure JGPAR accordingly. *
26 C. * NUMED returns the tracking medium number, or 0 if point is *
27 C. * outside the experimental setup. *
29 C. * Called by : GTREVE, GLTRAC, 'User' *
30 C. * Authors : R.Brun, F.Bruyant, A.McPherson *
33 C. * Modified by S.Giani (1993) to perform the search according *
34 C. * to the new 'virtual divisions' algorithm and to build the *
35 C. * stack of the 'possible overlapping volumes' in the case of *
36 C. * MANY volumes. Any kind of boolean operation is now possible.*
37 C. * Divisions along arbitrary axis are now possible. *
39 C. ******************************************************************
41 #include "geant321/gcflag.inc"
42 #include "geant321/gckine.inc"
43 #include "geant321/gcbank.inc"
44 #include "geant321/gcvolu.inc"
45 #include "geant321/gctrak.inc"
46 #if defined(CERNLIB_USRJMP)
47 #include "geant321/gcjump.inc"
49 #include "geant321/gcvdma.inc"
50 #include "geant321/gchvir.inc"
57 C. ------------------------------------------------------------------
63 IF (NLEVEL.EQ.0) CALL GMEDIN
65 * SECTION I: The /GCVOLU/ table contains the initial guess for a path
66 * in the geometry tree on which X may be found. Look along this
67 * path until X is found inside. This is the starting position.
68 * If this is an ONLY volume with no daughters, we are done;
69 * otherwise reset search record variables, proceed to section II.
71 * The information contained in INFROM has to be invalidated
72 * because it has no meaning for the subsequent tracking. INFR
73 * is a local variable used to optimise the search in the
78 * *** Check if point is in current volume
82 C***** Code Expanded From Routine: GTRNSF
84 100 IF (GRMAT(10,NLEVEL) .EQ. 0.) THEN
85 XC(1) = X(1) - GTRAN(1,NLEVEL)
86 XC(2) = X(2) - GTRAN(2,NLEVEL)
87 XC(3) = X(3) - GTRAN(3,NLEVEL)
90 XL1 = X(1) - GTRAN(1,NLEVEL)
91 XL2 = X(2) - GTRAN(2,NLEVEL)
92 XL3 = X(3) - GTRAN(3,NLEVEL)
93 XC(1) = XL1*GRMAT(1,NLEVEL) + XL2*GRMAT(2,NLEVEL) + XL3*GRMAT(3
95 XC(2) = XL1*GRMAT(4,NLEVEL) + XL2*GRMAT(5,NLEVEL) + XL3*GRMAT(6
97 XC(3) = XL1*GRMAT(7,NLEVEL) + XL2*GRMAT(8,NLEVEL) + XL3*GRMAT(9
104 C***** End of Code Expanded From Routine: GTRNSF
106 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
107 JPAR = LQ(JGPAR-NLEVEL)
108 CALL GINME (XC, Q(JVO+2), Q(JPAR+1), IYES)
111 * ** Point not in current volume, go up the tree
113 IF (NLEVEL.GT.1) THEN
115 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
119 * Do not set INFR whne going up the tree. GMEDIA can be called
120 * by the user and it should not assume that the previous
121 * position has something to do with the current search. INFR
122 * is otherwise useful when searching in a 'MANY' volume
123 * configuration. This statement is commented for the above reason.
125 * INFR =LINDEX(NLEVEL+1)
132 * * Point is outside setup
139 * ** Point is in current volume
143 IQ(JIN) = IBSET(IQ(JIN),4)
146 * To avoid starting from the protuding part of a MANY volume
147 IF(GONLY(NLEVEL).EQ.0.) THEN
154 * SECTION II: X is found inside current node at NLEVEL in /GCVOLU/.
155 * Search all contents recursively for any containing X.
156 * Take the first one found, if any, and continue at that
157 * level, incrementing NLEVEL and extending /GCVOLU/ tables.
158 * This is continued until a level is reached where X is not
159 * found in any of the contents, or there are no contents.
160 * Note: Since Section II is re-entered from Section III, a blocking word
161 * is used to mark those contents already checked. Upon exit from Section
162 * II, these blocking words are cleared at NLEVEL, but may remain set in
163 * levels between NLEVEL-1 and NLMIN, if any. They must be cleared at exit.
165 * ** Check contents, if any
167 200 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
169 if(raytra.eq.1..and.imyse.eq.1)then
170 CALL UHTOC(NAMES(NLEVEL),4,NAME,4)
171 CALL GFIND(NAME,'SEEN',ISSEEN)
172 if(isseen.eq.-2.or.isseen.eq.-1)goto 300
175 * * Case with no contents
180 * * Case with contents defined by division
182 ELSEIF (NIN.LT.0) THEN
183 CALL GMEDIV (JVO, IN, XC, 1)
189 * * Case with contents positioned
193 clmoth=q(jvirt+4*(LVOLUM(NLEVEL)-1)+3)
194 chmoth=q(jvirt+4*(LVOLUM(NLEVEL)-1)+4)
195 ndivto=q(jvirt+4*(LVOLUM(NLEVEL)-1)+2)
196 iaxis =q(jvirt+4*(LVOLUM(NLEVEL)-1)+1)
198 ivdiv=((xc(iaxis)-clmoth)*ndivto/(chmoth-clmoth))+1
201 elseif(ivdiv.gt.ndivto)then
205 call gfcoor(xc,iaxis,cx)
207 if((cx-clmoth).lt.-1.)then
209 elseif((cx-chmoth).gt.1.)then
214 elseif(cx.lt.clmoth)then
218 ivdiv=((cx-clmoth)*ndivto/(chmoth-clmoth))+1
221 elseif(ivdiv.gt.ndivto)then
225 jvdiv=lq(jvirt-LVOLUM(NLEVEL))
226 iofset=iq(jvdiv+ivdiv)
227 ncont=iq(jvdiv+iofset+1)
229 if(ncont.eq.0)goto 260
231 JCONT = LQ(JVO-NIN-1)+1
235 * For each selected content in turn, check if point is inside
245 * If the value IQ(JCONT+ICONT)=0 then we are back in the mother.
246 * So jump to 260, the search is finished. Clean-up should be done
247 * only up to ICONT-1, so we set:
253 IF (.NOT.BTEST(IQ(JIN),4)) THEN
254 CALL GMEPOS (JVO, IN, XC, 1)
257 IF (GONLY(NLEVEL).NE.0.) THEN
265 IQ(JIN) = IBSET(IQ(JIN),4)
271 260 IF(NCONT.EQ.NIN) THEN
274 IQ(JIN) = IBCLR(IQ(JIN),4)
284 IQ(JIN) = IBCLR(IQ(JIN),4)
288 IQ(JIN) = IBCLR(IQ(JIN),4)
294 * SECTION III: X is found at current node (NLEVEL in /GCVOLU) but not in
295 * any of its contents, if any. If this is a MANY volume,
296 * save it as a candidate best-choice, and continue the search
297 * by backing up the tree one node and proceed to Section II.
298 * If this is an ONLY volume, proceed to Section IV.
300 * *** Point is in current volume/medium, and not in any content
302 300 IF (GONLY(NLEVEL).EQ.0.) THEN
304 * ** Lowest level is 'NOT ONLY'
306 IF (NLEVEL.GT.NLMANY) THEN
313 manyle(nvmany)=nlevel
315 manyna(nvmany,i)=names(i)
316 manynu(nvmany,i)=number(i)
320 * * Go up the tree up to a volume with positioned contents
323 310 INFR = LINDEX(NLEVEL)
325 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
327 IF (NIN.LT.0) GO TO 310
329 C***** Code Expanded From Routine: GTRNSF
331 IF (GRMAT(10,NLEVEL) .EQ. 0.) THEN
332 XC(1) = X(1) - GTRAN(1,NLEVEL)
333 XC(2) = X(2) - GTRAN(2,NLEVEL)
334 XC(3) = X(3) - GTRAN(3,NLEVEL)
337 XL1 = X(1) - GTRAN(1,NLEVEL)
338 XL2 = X(2) - GTRAN(2,NLEVEL)
339 XL3 = X(3) - GTRAN(3,NLEVEL)
340 XC(1) = XL1*GRMAT(1,NLEVEL) + XL2*GRMAT(2,NLEVEL) + XL3*
342 XC(2) = XL1*GRMAT(4,NLEVEL) + XL2*GRMAT(5,NLEVEL) + XL3*
344 XC(3) = XL1*GRMAT(7,NLEVEL) + XL2*GRMAT(8,NLEVEL) + XL3*
348 C***** End of Code Expanded From Routine: GTRNSF
351 IQ(JIN) = IBSET(IQ(JIN),4)
352 NLMIN = MIN(NLEVEL,NLMIN)
356 * SECTION IV: This is the end of the search. The current node (NLEVEL
357 * in /GCVOLU/) is the lowest ONLY volume in which X is found.
358 * If X was also found in any of its contents, they are MANY
359 * volumes: the best-choice is the one among them at the greatest
360 * level in the tree, and it is stored. Otherwise the current
361 * volume is the solution. Before exit, all of the blocking
362 * words leftover in the tree must be reset to zero.
363 * Note: A valid structure is assumed, in which no ONLY volumes overlap.
364 * If this rule is violated, or if a daughter is not entirely contained
365 * within the mother volume, the results are unpredictable.
367 DO 419 NL=NLMIN,NLEVEL-1
368 JVO = LQ(JVOLUM-LVOLUM(NL))
372 IQ(JIN) = IBCLR(IQ(JIN),4)
380 IF (NLMANY.GT.0) CALL GFCVOL
381 JVO = LQ(JVOLUM-LVOLUM(NLEVEL))
382 IF(JVIN.NE.0) IQ(JVIN) = IBCLR(IQ(JVIN),4)
385 999 IF(JGSTAT.NE.0) CALL GFSTAT(2)