COSMOS v7.655  COSMOSv7655
(AirShowerMC)
cinteraction.f
Go to the documentation of this file.
1 #include "ZsubstRec.h"
2 ! treat interaction of MovedTrack
3 !
4  subroutine cinteraction
5  use modxsecmedia
6  implicit none
7 
8 #include "Zcode.h"
9 #include "Ztrack.h"
10 #include "Ztrackp.h"
11 #include "Ztrackv.h"
12 #include "Zevhnv.h"
13 #include "Zincidentv.h"
14 #include "Zmass.h"
15 
16 
17  integer i
18  real*8 Ein1, Ein2, Eout, dEabs1, deabs2, dErel1, dErel2
19  real*8 dErel, dEabs, Ein
20 
21 !
22 ! used to judge if user hook should be called
23 ! after MovedTrack interacted.
24 !
25  integer neverNEP/0/, neverE/0/, neverG/0/
26  save nevernep, nevere, neverg
27  integer never
28  integer stackpos
29  save never
30  integer icon
31  integer,parameter::loopmax=100
32  integer:: loopc
33 
34 
35 
36 !c record /ptcl/ fragA(maxHeavyMassN), nonIntNucA(maxHeavyMassN)
37 !c integer noOfFrag, noOfNonIntN
38 !
39 ! record /track/aTrack
40 !
41 ! ** ptcl stacking is done in each subroutine; should be changed
42 ! (except for hadronic interactions)
43 ! logic of employing events satisfying some conditions only
44 !
45 ! generate 1 event ; data is in PWork(:)
46 ! call chookNEPInt(neverNEP) ! the user may give 5 to neverNEP
47 ! ! to discard the current event
48 ! never = neverNEP
49 !
50 !
51 !
52 
53  loopc = 0
54  do while (loopc < loopmax )
55 ! try until desired event is generated
56 ! (mainly for multiple production)
57  loopc = loopc + 1
58  nproduced = 0
59 
60 !
61 !c assume MovedTrack is not changed in interaction routine
62 ! but may be added asflag by chookEing if it is elec.
63 ! (in the case of Job ='newskel' )
64 !
65 !
66  if(movedtrack%p%code .eq. kelec) then
67  call cinteelec
68  elseif(movedtrack%p%code .eq. kphoton) then
69  call cintephoton
70  else
71  call cintenep
72  if(intinfarray(processno)%process .eq. 'coll') then
73  movedtrack%pos%colheight = movedtrack%pos%height
74  endif
75  endif
76 
77  if(movedtrack%p%code .eq. kelec) then
78  if(nevere .ne. 1) then
79  call chookeint(nevere)
80  never = nevere
81  endif
82  elseif(movedtrack%p%code .eq. kphoton) then
83  if(neverg .ne. 1) then
84  call chookgint(neverg)
85  never = neverg
86  endif
87  else
88  if(nevernep .ne. 1) then
89  call chooknepint(nevernep)
90  never = nevernep
91  endif
92  endif
93  if( never /= 5) exit
94  never = 0
95  enddo ! end of while;
96  if(btest(eabsorb(1), biteconsv-1) ) then
97  if(intinfarray(processno)%process .eq. 'coll' .or.
98  * intinfarray(processno)%process .eq. 'photop' .or.
99  * intinfarray(processno)%process .eq. 'munuci' ) then
100 
101 ! last one not used yet
102  call chookeabsorbc( movedtrack, nproduced, pwork, 0)
103 ! what is being done below is almost the same as
104 ! done above call.
105  ein1 = movedtrack%p%fm%p(4)
106  * + masn*(targetnucleonno-targetprotonno) +
107  * masp*targetprotonno
108  ein2 = movedtrack%p%fm%p(4) + masp
109  eout = 0.
110  do i = 1, nproduced
111  eout = eout + pwork(i)%fm%p(4)
112  enddo
113 
114  deabs1 = eout- ein1
115  derel1 = eout/ein1 -1.0
116  deabs2 = eout- ein2
117  derel2 = eout/ein2 -1.0
118  if( abs(derel1) .lt. abs(derel2)) then
119  derel=derel1
120  deabs =deabs1
121  ein = ein1
122  else
123  derel=derel2
124  deabs =deabs2
125  ein = ein2
126 ! no mass case in Eout
127  ein1 = movedtrack%p%fm%p(4)
128  deabs1 = eout- ein1
129  derel1 = eout/ein1 -1.0
130  if(abs(deabs1) .lt. abs(deabs) ) then
131  derel = derel1
132  ein = ein1
133  deabs = deabs1
134  endif
135  endif
136  if( abs(derel) .gt. 0.1 .or.
137  * abs(deabs) .gt. 1.e5 ) then
138  write(0,*) " code=",movedtrack%p%code
139  write(0,*) " chg=",movedtrack%p%charge
140  write(0,*) ' Moved E=',movedtrack%p%fm%p(4)
141  write(0,*) ' Ein =', ein, ' Eout=',eout
142  write(0,*) ' Rerr =', eout/ein -1.0
143  write(0,*) ' dEabscol= ',deabs
144  write(0,*) 'ActiveModel=', activemdl
145  endif
146  else
147 ! possible process; compton, mscat, bscat,
148 ! anihi, decay, photoe, brems, pair cohs
149  ein = movedtrack%p%fm%p(4)
150  if(intinfarray(processno)%process .ne. 'decay' .and.
151  * intinfarray(processno)%process .ne. 'brems' .and.
152  * intinfarray(processno)%process .ne. 'pair' .and.
153  * intinfarray(processno)%process .ne. 'cohs' ) then
154  ein = ein + masele
155  endif
156  if(ein .gt. movedtrack%p%mass) then
157  eout = 0.
158  do i = 1, nproduced
159  eout = eout + pwork(i)%fm%p(4)
160  enddo
161  deabs = eout- ein
162  derel = eout/ein -1.0
163  if( abs(derel) .gt. 0.2 ) then
164 ! if( abs(dEabs) .gt. 1.e5) then
165  if( abs(deabs) .gt. 1.e5 ) then
166  write(0,*) '****************************'
167  else
168  write(0,*) '----------------------------'
169  endif
170  write(0,*) 'proc=', intinfarray(processno)%process
171  write(0,*) 'code=',movedtrack%p%code, ' charge=',
172  * movedtrack%p%charge, ' E=',ein
173  write(0,*) 'dEabs= ', deabs, derel, nproduced
174  do i = 1, nproduced
175  write(0,*) i, pwork(i)%code, pwork(i)%fm%p(4)
176  enddo
177  endif
178  endif
179  endif
180  endif
181 !///////////////////////
182 
183  if(onedim .eq. 0) then
184 ! 3 dimensional
185 ! stack the leading ptcl first (to save stack area)
186  call cmoveptcl3(movedtrack, pwork, nproduced, nstacked)
187  else
188  movedtrack%vec = incidentcopy%vec
189  call cmoveptcl1(movedtrack, pwork, nproduced, nstacked)
190  endif
191 
192 
193  if(never .eq. 0 .or. never .eq. 1 ) then
194 ! user may set never=3
195  elseif(never .eq. 3) then
196 ! don't follow this and child; reset stackpos
197  call cgetcurrentstackpos(stackpos)
198  stackpos=stackpos-nstacked
199  call cresetstackpos(stackpos)
200  elseif(never .eq. 4) then
201 ! discard this event generated by the current primary
202 ! clear stack
203  call cinitstack
204  else
205  call cerrormsg('return value from chookE,G,NEPInt wrong', 1)
206  write(0,*) ' never=', never
207  stop
208  endif
209 
210  end
211 ! following is remnant of never=2 and ad-hoc model
212 ! when chookNEPInt is called before push is called.
213 ! The reason that we put chookNEPInt interface after push
214 ! is to have easy interface for skeleton making
215 !
216 ! elseif(never .eq. 2) then
217 ! save only fragments and non interacting nucleons
218 ! if(MovedTrack.p.code .eq. kgnuc ) then
219 !c get fragment and non interacting nuc.
220 ! call cqHvyIntF(fragA, noOfFrag)
221 ! call cqHvyIntNIN(nonIntNucA, noOfNonIntN)
222 !c
223 ! if(OneDim .eq. 0) then
224 ! call cmovePtcl3(MovedTrack, fragA, noOfFrag)
225 ! call cmovePtcl3(MovedTrack, nonIntNucA, noOfNonIntN)
226 ! else
227 ! MovedTrack.vec = IncidentCopy.vec
228 ! call cmovePtcl1(MovedTrack, fragA, noOfFrag)
229 ! call cmovePtcl1(MovedTrack, nonIntNucA, noOfNonIntN)
230 ! endif
231 ! endif
232 !
233 ! ************************************
234 ! move partcles in a given array to stack
235 ! 3 dimensional case.
236 
237  subroutine cmoveptcl3(iTrack, pw, n, npush)
238  implicit none
239 ! put n ptcls in pw into stack.
240 ! if ThinSampling,
241 #include "Zcode.h"
242 #include "Ztrackp.h"
243 #include "Ztrack.h"
244 #include "Ztrackv.h"
245 !
246  integer n
247  type(track)::iTrack ! input. incident ptcl.
248  type(ptcl)::pw(n)
249  integer npush ! output. actual number of ptcls put in stack.
250  ! in case of ThinSampling, this may be <= Nproduced.
251 
252  type(track)::aTrack
253  integer i
254  integer loc1
255  integer nact
256 
257 
258  atrack = itrack
259  npush = 0
260  call cgetcurrentstackpos(loc1) ! upto loc1 is already filled
261 
262  do i = n, 1, -1 ! move leading ptcl first
263 #ifdef SUBSTREC
264  atrack%p = pw(i)
265 #else
266  atrack%p%fm%p = pw(i)%fm%p
267  atrack%p%mass = pw(i)%mass
268  atrack%p%code = pw(i)%code
269  atrack%p%subcode = pw(i)%subcode
270  atrack%p%charge = pw(i)%charge
271 #endif
272 
273 ! reset direction cos and related stuffs
274  call cresetdirec(atrack)
275 
276 
277 #if LABELING == 1
278 !
279 ! whennever an interaction occur, update labelcounter
280 ! if info>0, clear the timer and infor counters.
281 !
282  if(atrack%info .gt. 0) then
283 !cc aTrack.info = 0
284 !cc aTrack.t = 0.
285  endif
286  labelcounter = labelcounter + 1
287  atrack%label = labelcounter
288 #elif LABELING == 2
289 ! the above simple counter may be replaced by the
290 ! next sophisticated one.
291 ! the same one is in the 1dim mode move routine below.
292 !
293  call ctrickycount(itrack, atrack, pw, i)
294 !
295 #endif
296  npush = npush + 1
297  call cpush(atrack)
298  enddo
299  if(thinsampling .and. npush .ge. 2 ) then
300 ! if(ThinSampling .and. npush .ge. 2 .and.
301 ! * IntInfArray(ProcessNo).process .ne. 'photop') then
302  call cthinstack(loc1+1, npush, itrack, nact)
303 ! among npush from loc1+1, nact is accepted
304 ! adjust npush
305  npush = nact
306  endif
307  end
308  subroutine cthinstack(stackloc, n, iTrack, nout)
309 #include "Zcode.h"
310 #include "Ztrackp.h"
311 #include "Ztrack.h"
312 #include "Ztrackv.h"
313 #include "Zstackv.h"
314 !
315  integer stackloc ! first loc of stack where tracks of current int.
316  integer n
317  type(track)::iTrack ! input. incident ptcl. of the interaction
318  integer nout
319 
320  call cthinning(stack(stackloc), n, itrack, nout)
321  call cresetstackpos(stackloc-1+nout)
322  end
323 
324 
325 
326 
327 #if LABELING == 2
328 ! ************************************
329 ! This routine updates label counters.
330 ! but for the survival particle form brems and knock-on
331 ! the label counter is not updated.
332 ! For those ptcl with info > 0, timer and info counters
333 ! are cleared.
334  subroutine ctrickycount(iTrack, aTrack, pw, i)
335  implicit none
336 #include "Zcode.h"
337 #include "Ztrackp.h"
338 #include "Ztrack.h"
339 #include "Ztrackv.h"
340 !
341  integer n
342  type(track)::iTrack ! input. incident ptcl.
343  type(track)::aTrack ! input/output. i-th secondary track
344  type(ptcl)::pw(*) ! input. secondary pool
345  integer i ! input. i-th secondary (index)
346 
347  logical reset
348 
349  reset = .true.
350 
351  if( itrack%pos%height .gt. 40.d3 ) then
352  if(intinfarray(processno)%process .eq. 'brems' ) then
353 ! for brem, electron has the same label as the incident
354  if( atrack%p%fm%p(4) .lt. itrack%p%fm%p(4)*0.8) then
355  atrack%label = itrack%label
356  reset = .false.
357  endif
358  elseif(intinfarray(processno)%process .eq. 'knock' .or.
359  * intinfarray(processno)%process .eq. 'mscat' .or.
360  * intinfarray(processno)%process .eq. 'bscat' ) then
361 ! for the knock-on, survival particle has the same
362 ! label.
363  if(itrack%p%code .ne. kelec .or.
364  * itrack%p%charge .ne. -1) then
365 ! knockon by p,mu,pi..e+ (not by e-)
366  if(atrack%p%code .ne. kelec) then
367 ! survival one has the same label
368  atrack%label = itrack%label
369  reset = .false.
370  endif
371  else
372 ! electron; make the higher one has the same label
373  if(pw(1)%fm%p(4) .gt. pw(2)%fm%p(4)) then
374  if(i .eq. 1) then
375  atrack%label = itrack%label
376  reset = .false.
377  endif
378  else
379  if(i .eq. 2) then
380  atrack%label = itrack%label
381  reset = .false.
382  endif
383  endif
384  endif
385  endif
386  endif
387  if(reset) then
388  labelcounter = labelcounter +1
389  atrack%label = labelcounter
390 !c aTrack.t = 0. ! timer reset
391 !c aTrack.info = 0 ! cross counter reset
392  endif
393  end
394 #endif
395 ! ************************************
396 ! move partcles in a given array to stack
397 ! 1 dimensional case.
398 
399  subroutine cmoveptcl1(iTrack, pw, n, npush)
400  implicit none
401 
402 #include "Zcode.h"
403 #include "Ztrack.h"
404 #include "Ztrackp.h"
405 #include "Ztrackv.h"
406 #include "Zincidentv.h"
407 
408 
409  integer n
410  type(track)::iTrack ! input. incident track
411  type(ptcl)::pw(n)
412  integer npush ! output. actuall number of ptcls put in stack.
413  real*8 temp, p
414 
415  integer i
416 
417  type(track)::aTrack
418  integer loc1
419  integer nact
420 
421  atrack = itrack
422 
423  call cgetcurrentstackpos(loc1)
424 
425  do i = n, 1, -1 ! move leading ptcl last
426 #ifdef SUBSTREC
427  atrack%p = pw(i)
428 #else
429  atrack%p%fm%p = pw(i)%fm%p
430  atrack%p%mass = pw(i)%mass
431  atrack%p%code = pw(i)%code
432  atrack%p%subcode = pw(i)%subcode
433  atrack%p%charge = pw(i)%charge
434 #endif
435 ! see if angle of particle is larger than a lmit
436  call cscalerprod(atrack%p%fm%p, dcatobsxyz, temp)
437  call cpxyzp(atrack%p%fm, p)
438  if(p .gt. 0.) then
439  temp = temp/p
440  else
441  temp = 1.
442  endif
443  if(temp .gt. backanglimit) then
444 ! only take some limitted angle particles
445 ! call cresetMom(aTrack) which is
446  atrack%p%fm%p(1) = p * atrack%vec%w%r(1)
447  atrack%p%fm%p(2) = p * atrack%vec%w%r(2)
448  atrack%p%fm%p(3) = p * atrack%vec%w%r(3)
449 
450  call cgetzenith(atrack, atrack%vec%coszenith)
451 
452 
453 #if LABELING == 1
454 ! whennever secondary particles are generated,
455 ! each of them get an updated label cocunter
456 ! if the particle has crossed the highest level
457 ! (info > 0), timer and info counter is cleared
458 !
459  if( atrack%info .gt. 0) then
460 !cc aTrack.info = 0
461 !c aTrack.t = 0.
462  endif
463  labelcounter = labelcounter + 1
464  atrack%label = labelcounter
465 #elif LABELING == 2
466 ! this may be used if a tricky count is needed
467 ! in stead of above counting
468  call ctrickycount(itrack, atrack, pw, i)
469 #endif
470  npush = npush + 1
471  call cpush(atrack)
472  endif
473  enddo
474  if(thinsampling .and. npush .gt. 0 ) then
475  call cthinstack(loc1+1, npush, itrack, nact)
476  npush = nact
477  endif
478  end
479 
480 ! ****************************************************************
481  subroutine cqinteptcl(ptclA, num)
482  implicit none
483 ! inquire the particle information that made interactions
484 ! to produce secondary particles.
485 ! If "MovedTrack" is a heavy, ptclA will get interacting nucleons
486 ! otherwise, ptclA will have MovedTrack.p itself.
487 !
488 !
489 #include "Zcode.h"
490 #include "Ztrack.h"
491 #include "Ztrackp.h"
492 #include "Ztrackv.h"
493 
494  type(ptcl)::ptclA(*) ! output. interacted particles. max size
495  ! should be maxHeavyMassN (= 56 =Fe)
496  integer num ! output. number of ptcls in ptclA
497 !
498 !
499 !c if(MovedTrack.p.code .ge. kdeut .and.
500 !c * MovedTrack.p.code .le. khvymax ) then
501  if( movedtrack%p%code .eq. kgnuc ) then
502  call cqhvyintin(ptcla, num)
503  else
504  num = 1
505 #ifdef SUBSTREC
506  ptcla(1) = movedtrack%p
507 #else
508  ptcla(1)%fm%p = movedtrack%p%fm%p
509  ptcla(1)%mass = movedtrack%p%mass
510  ptcla(1)%code = movedtrack%p%code
511  ptcla(1)%subcode = movedtrack%p%subcode
512  ptcla(1)%charge = movedtrack%p%charge
513 #endif
514  endif
515  end
516 
subroutine cerrormsg(msg, needrtn)
Definition: cerrorMsg.f:4
subroutine chookgint(never)
Definition: chook.f:191
subroutine cqinteptcl(ptclA, num)
Definition: cinteraction.f:482
subroutine ctrickycount(iTrack, aTrack, pw, i)
Definition: cinteraction.f:335
max ptcl codes in the kgnuc
Definition: Zcode.h:2
masn
Definition: Zmass.h:5
block data cblkIncident data *Za1ry *HeightOfInj d3
Definition: cblkIncident.h:7
const int kphoton
Definition: Zcode.h:6
subroutine cpxyzp(po, pabs)
Definition: cpxyzp.f:3
Definition: Ztrack.h:44
max ptcl codes in the kelec
Definition: Zcode.h:2
subroutine chooknepint(never)
Definition: chook.f:219
subroutine cgetzenith(aTrack, cosz)
Definition: cgetZenith.f:20
subroutine cmoveptcl3(iTrack, pw, n, npush)
Definition: cinteraction.f:238
block data cblkElemag data *AnihiE ! Eposi< 1 TeV, anihilation considered *X0/365.667/, ! radiation length of air in kg/m2 *Ecrit/81.e-3/, ! critical energy of air in GeV *MaxComptonE/1./, ! compton is considered below 1 GeV *MaxPhotoE/1.e-3/, ! above this, PhotoElectric effect neg. *MinPhotoProdE/153.e-3/, ! below 153 MeV, no gp --> hadrons ! scattering const not MeV *Knockon true
Definition: cblkElemag.h:7
subroutine cinitstack
Definition: cstack.f:76
subroutine cmoveptcl1(iTrack, pw, n, npush)
Definition: cinteraction.f:400
subroutine cresetdirec(aTrack)
Definition: cresetDirec.f:5
subroutine cintenep
Definition: cinteNEP.f:4
const double masele
Definition: Zmass.h:2
subroutine cinteraction
Definition: cinteraction.f:5
subroutine cinteelec
Definition: cinteElec.f:2
block data cblkElemag data *AnihiE ! Eposi< 1 TeV, anihilation considered *X0/365.667/, ! radiation length of air in kg/m2 *Ecrit/81.e-3/, ! critical energy of air in GeV *MaxComptonE/1./, ! compton is considered below 1 GeV *MaxPhotoE/1.e-3/, ! above this, PhotoElectric effect neg. *MinPhotoProdE/153.e-3/, ! below 153 MeV, no gp --> hadrons ! scattering const not MeV *Knockon ! knockon is considered Obsolete *PhotoProd false
Definition: cblkElemag.h:7
masp
Definition: Zmass.h:5
subroutine cthinning(Tracks, n, iTrack, nout)
Definition: cthinning.f:2
Definition: Zptcl.h:75
subroutine cintephoton
Definition: cintePhoton.f:2
subroutine cresetstackpos(stackpos)
Definition: cstack.f:92
subroutine cpush(a)
Definition: cstack.f:4
subroutine chookeabsorbc(a, n, p, info)
Definition: chookEabsorb.f:209
subroutine cgetcurrentstackpos(stackpos)
Definition: cstack.f:84
subroutine cthinstack(stackloc, n, iTrack, nout)
Definition: cinteraction.f:309
subroutine chookeint(never)
Definition: chook.f:162
subroutine cscalerprod(a, b, c)
Definition: cscalerProd.f:4