1
SUBROUTINE SBORN(P,ANS_SUMMED)
6
C Return the sum of the split orders which are required in orders.inc (BORN_ORDERS)
7
C Also the values needed for the counterterms are stored in the C_BORN_CNT common block
16
include 'nexternal.inc'
17
INTEGER NAMPSO, NSQAMPSO
18
PARAMETER (NAMPSO=%(nAmpSplitOrders)d, NSQAMPSO=%(nSqAmpSplitOrders)d)
20
PARAMETER (NGRAPHS= %(ngraphs)d)
24
REAL*8 P(0:3,NEXTERNAL-1)
30
double precision ans_summed
31
COMPLEX*16 ANS(2,0:NSQAMPSO), ANS_CNT(2, NSPLITORDERS)
32
LOGICAL KEEP_ORDER(NSQAMPSO), KEEP_ORDER_CNT(NSPLITORDERS, NSQAMPSO), FIRSTTIME
33
data keep_order / NSQAMPSO * .TRUE. /
34
common /c_keep_order_cnt/ keep_order_cnt
35
common /c_born_cnt/ ans_cnt
37
data firsttime / .TRUE. /
38
integer amp_orders(nsplitorders)
40
parameter (tiny = 1d-12)
41
double precision max_val
42
double precision wgt_ME_born,wgt_ME_real
43
common /c_wgt_ME_tree/ wgt_ME_born,wgt_ME_real
45
double precision amp2b(%(ngraphs)d), jamp2b(0:%(ncolor)d,0:nampso)
46
common/to_amps_born/ amp2b, jamp2b
47
Double Precision amp2(%(ngraphs)d), jamp2(0:%(ncolor)d)
48
common/to_amps/ amp2, jamp2
49
logical split_type_used(nsplitorders)
50
common/to_split_type_used/split_type_used
54
integer GETORDPOWFROMINDEX_B
55
integer orders_to_amp_split_pos
59
C look for orders which match the born order constraint
63
C this is for the orders of the born to integrate
64
do j = 1, nsplitorders
65
if(GETORDPOWFROMINDEX_B(j, i) .gt. born_orders(j)) then
66
keep_order(i) = .false.
71
C this is for the orders of the counterterms
72
do j = 1, nsplitorders
73
keep_order_cnt(j,i) = .true.
74
do k = 1, nsplitorders
80
if(GETORDPOWFROMINDEX_B(k, i) .gt. nlo_orders(k)-ord_subtract) then
81
keep_order_cnt(j,i) = .false.
86
if (keep_order(i)) then
87
write(*,*) 'BORN: keeping split order ', i
89
write(*,*) 'BORN: not keeping split order ', i
93
do j = 1, nsplitorders
94
write(*,*) 'counterterm S.O', j, ordernames(j)
96
if (keep_order_cnt(j,i)) then
97
write(*,*) 'BORN: keeping split order', i
99
write(*,*) 'BORN: not keeping split order', i
106
CALL SBORN_SPLITORDERS(P,ANS)
108
C the born to be integrated
112
C reset the amp_split array
113
amp_split(1:amp_split_size) = 0d0
114
amp_split_cnt(1:amp_split_size,1:2,1:nsplitorders) = dcmplx(0d0,0d0)
117
max_val = max(max_val, abs(ans(1,I)))
120
if (keep_order(i)) then
121
ANS_SUMMED = ANS_SUMMED + ANS(1,I)
122
C keep track of the separate pieces correspoinding to different coupling combinations
123
do j = 1, nsplitorders
124
amp_orders(j) = GETORDPOWFROMINDEX_B(j, i)
126
if(abs(ans(1,i)).gt.max_val*tiny) amp_split(orders_to_amp_split_pos(amp_orders)) = ans(1,i)
129
C this is to avoid fake non-zero contributions
130
if (abs(ans_summed).lt.max_val*tiny) ans_summed=0d0
132
wgt_me_born=ans_summed
134
C fill the amp2 and jamp2 arrays
135
amp2(1:ngraphs)=amp2b(1:ngraphs)! amp2 just needs to be copyed
137
do i = 0, int(jamp2b(0,0))
140
c here sum all, this may be refined later
141
jamp2(i)=jamp2(i)+jamp2b(i,j)
146
C quantities for the counterterms
147
do j = 1, nsplitorders
148
ans_cnt(1:2,j) = (0d0, 0d0)
149
if (.not.split_type_used(j)) cycle
151
if (keep_order_cnt(j,i)) then
152
ANS_CNT(1,j) = ANS_CNT(1,J) + ANS(1,I)
153
ANS_CNT(2,j) = ANS_CNT(2,J) + ANS(2,I)
154
C keep track of the separate pieces also for counterterms
155
do k = 1, nsplitorders
156
amp_orders(k) = GETORDPOWFROMINDEX_B(k, i)
157
C take into account the fact that the counterterm for a given split order
158
C will be multiplied by the corresponding squared coupling
159
if (k.eq.j) amp_orders(k) = amp_orders(k) + 2
161
C this is to avoid fake non-zero contributions
162
if (abs(ans(1,I)).gt.max_val*tiny) amp_split_cnt(orders_to_amp_split_pos(amp_orders),1,j) = ans(1,I)
163
if (abs(ans(2,I)).gt.max_val*tiny) amp_split_cnt(orders_to_amp_split_pos(amp_orders),2,j) = ans(2,I)
166
C this is to avoid fake non-zero contributions
167
if (abs(ans_cnt(1,j)).lt.max_val*tiny) ans_cnt(1,j)=(0d0,0d0)
168
if (abs(ans_cnt(2,j)).lt.max_val*tiny) ans_cnt(2,j)=(0d0,0d0)
177
SUBROUTINE SBORN_SPLITORDERS(P1,ANS)
181
C RETURNS AMPLITUDE SQUARED SUMMED/AVG OVER COLORS
183
C FOR THE POINT IN PHASE SPACE P1(0:3,NEXTERNAL-1)
191
include "nexternal.inc"
192
include "born_nhel.inc"
194
PARAMETER ( NCOMB= %(ncomb)d )
195
INTEGER NAMPSO, NSQAMPSO
196
PARAMETER (NAMPSO=%(nAmpSplitOrders)d, NSQAMPSO=%(nSqAmpSplitOrders)d)
198
PARAMETER (THEL=NCOMB*%(nconfs)d)
200
PARAMETER (NGRAPHS= %(ngraphs)d)
204
REAL*8 P1(0:3,NEXTERNAL-1)
205
COMPLEX*16 ANS(2,0:NSQAMPSO)
209
INTEGER IHEL,IDEN,i,j,jj,glu_ij
210
REAL*8 borns(2,0:NSQAMPSO)
212
INTEGER NTRY(%(nconfs)d)
213
DATA NTRY /%(nconfs)d*0/
214
COMPLEX*16 T(2,NSQAMPSO)
215
INTEGER NHEL(NEXTERNAL-1,NCOMB)
222
Double Precision amp2(ngraphs), jamp2(0:%(ncolor)d,0:NAMPSO)
223
common/to_amps_born/ amp2, jamp2
224
DATA jamp2(0,0) / %(ncolor)d/
225
LOGICAL GOODHEL(NCOMB,%(nconfs)d)
226
common /c_goodhel/goodhel
227
double complex saveamp(ngraphs,max_bhel)
228
common/to_saveamp/saveamp
229
double precision savemom(nexternal-1,2)
230
common/to_savemom/savemom
231
double precision hel_fac
232
integer get_hel,skip(%(nconfs)d)
233
common/cBorn/hel_fac,get_hel,skip
234
logical calculatedBorn
235
common/ccalculatedBorn/calculatedBorn
237
common/c_nfksprocess/nfksprocess
242
iden=iden_values(nfksprocess)
243
glu_ij = ij_values(nfksprocess)
244
NTRY(nFKSprocess)=NTRY(nFKSprocess)+1
245
if (NTRY(nFKSprocess).lt.2) then
246
if (glu_ij.eq.0) then
250
do while(nhel(glu_ij ,skip(nFKSprocess)).ne.-NHEL(GLU_IJ ,1))
251
skip(nFKSprocess)=skip(nFKSprocess)+1
253
skip(nFKSprocess)=skip(nFKSprocess)-1
260
DO JJ=1,int(jamp2(0,0))
264
if (calculatedBorn) then
266
if (savemom(j,1).ne.p1(0,j) .or. savemom(j,2).ne.p1(3,j)) then
267
calculatedBorn=.false.
268
write (*,*) "momenta not the same in Born"
273
if (.not.calculatedBorn) then
280
saveamp(jj,j)=(0d0,0d0)
290
! the following lines are to avoid segfaults when glu_ij=0
291
cond_ij=skip(nfksprocess).eq.0
292
if (.not.cond_ij) cond_ij=cond_ij.or.nhel(glu_ij,ihel).EQ.NHEL(GLU_IJ,1)
293
!if (nhel(glu_ij,ihel).EQ.NHEL(GLU_IJ,1).or.skip(nfksprocess).eq.0) then
295
IF ((GOODHEL(IHEL,nFKSprocess) .OR. GOODHEL(IHEL+SKIP(nFKSprocess),nFKSprocess) .OR. NTRY(nFKSprocess) .LT. 2) ) THEN
297
CALL BORN(P1,NHEL(1,IHEL),IHEL,T,borns)
299
ANS(1,I)=ANS(1,I)+T(1,I)
300
ANS(2,I)=ANS(2,I)+T(2,I)
302
if ( borns(1,0).ne.0d0 .AND. .NOT. GOODHEL(IHEL,nFKSprocess) ) then
303
GOODHEL(IHEL,nFKSprocess)=.TRUE.
305
if ( borns(2,0).ne.0d0 .AND. .NOT. GOODHEL(IHEL+SKIP(nFKSprocess),nFKSprocess) ) then
306
GOODHEL(IHEL+SKIP(nFKSprocess),nFKSprocess)=.TRUE.
312
ANS(1,I)=ANS(1,I)/DBLE(IDEN)
313
ANS(2,I)=ANS(2,I)/DBLE(IDEN)
314
ANS(1,0)=ANS(1,0)+ANS(1,I)
315
ANS(2,0)=ANS(2,0)+ANS(2,I)
317
calculatedBorn=.true.
321
SUBROUTINE BORN(P,NHEL,HELL,ANS,borns)
324
C RETURNS AMPLITUDE SQUARED SUMMED/AVG OVER COLORS
325
C FOR THE POINT WITH EXTERNAL LINES W(0:6,NEXTERNAL-1)
333
INTEGER NAMPSO, NSQAMPSO
334
PARAMETER (NAMPSO=%(nAmpSplitOrders)d, NSQAMPSO=%(nSqAmpSplitOrders)d)
335
INTEGER NGRAPHS, NEIGEN
336
PARAMETER (NGRAPHS= %(ngraphs)d,NEIGEN= 1)
337
INTEGER NWAVEFUNCS, NCOLOR
338
PARAMETER (NWAVEFUNCS=%(nwavefuncs)d, NCOLOR=%(ncolor)d)
342
parameter (imag1 = (0d0,1d0))
343
include "nexternal.inc"
344
include "born_nhel.inc"
349
REAL*8 P(0:3,NEXTERNAL-1),borns(2,0:NSQAMPSO)
350
INTEGER NHEL(NEXTERNAL-1), HELL
351
COMPLEX*16 ANS(2,NSQAMPSO)
355
INTEGER I,J,M,N,ihel,back_hel,glu_ij
356
INTEGER IC(NEXTERNAL-1),nmo
357
parameter (nmo=nexternal-1)
359
REAL*8 CF(NCOLOR,NCOLOR)
360
COMPLEX*16 ZTEMP, AMP(NGRAPHS), JAMP(NCOLOR,NAMPSO), W(%(wavefunctionsize)d,NWAVEFUNCS), jamph(2, ncolor,nampso)
361
COMPLEX*16 TMP_JAMP(%(nb_temp_jamp)i)
365
Double Precision amp2(%(ngraphs)d), jamp2(0:%(ncolor)d,0:nampso)
366
common/to_amps_born/ amp2, jamp2
367
double complex saveamp(ngraphs,max_bhel)
368
common/to_saveamp/saveamp
369
double precision hel_fac
370
integer get_hel,skip(%(nconfs)d)
371
common/cBorn/hel_fac,get_hel,skip
372
logical calculatedBorn
373
common/ccalculatedBorn/calculatedBorn
375
common/c_nfksprocess/nfksprocess
392
glu_ij = ij_values(nfksprocess)
401
if (glu_ij.ne.0) then
402
back_hel = nhel(glu_ij)
403
if (back_hel.ne.0) then
412
DO IHEL=back_hel,-back_hel,step_hel
413
if (glu_ij.ne.0) then
414
cond_ij=IHEL.EQ.back_hel.OR.NHEL(GLU_IJ).NE.0
416
cond_ij=IHEL.EQ.back_hel
419
if (glu_ij.ne.0) then
420
if (nhel(glu_ij).ne.0) nhel(glu_ij) = ihel
422
if (.not. calculatedBorn) then
425
if(ihel.eq.back_hel)then
426
saveamp(i,hell)=amp(i)
427
elseif(ihel.eq.-back_hel)then
428
saveamp(i,hell+skip(nFKSprocess))=amp(i)
430
write(*,*) "ERROR #1 in born.f"
434
elseif (calculatedBorn) then
436
if(ihel.eq.back_hel)then
437
amp(i)=saveamp(i,hell)
438
elseif(ihel.eq.-back_hel)then
439
amp(i)=saveamp(i,hell+skip(nFKSprocess))
441
write(*,*) "ERROR #1 in born.f"
451
ZTEMP = ZTEMP + CF(J,I)*JAMP(J,M)
454
BORNS(2-(1+back_hel*ihel)/2,SQSOINDEXB(M,N))=BORNS(2-(1+back_hel*ihel)/2,SQSOINDEXB(M,N))+ZTEMP*DCONJG(JAMP(I,N))
459
amp2(i)=amp2(i)+amp(i)*dconjg(amp(i))
463
Jamp2(i,J)=Jamp2(i,J)+Jamp(i,J)*dconjg(Jamp(i,J))
464
Jamph(2-(1+back_hel*ihel)/2,i,J)=Jamp(i,J)
470
borns(1,0)=borns(1,0)+borns(1,i)
471
borns(2,0)=borns(2,0)+borns(2,i)
472
ans(1,i) = borns(1,i) + borns(2,i)
478
ZTEMP = ZTEMP + CF(J,I)*JAMPH(2,J,M)
481
ANS(2,SQSOINDEXB(M,N))= ANS(2,SQSOINDEXB(M,N)) + ZTEMP*DCONJG(JAMPH(1,I,N))
485
if (glu_ij.ne.0) nhel(glu_ij) = back_hel
491
PARAMETER ( NCOMB= %(ncomb)d )
493
PARAMETER (THEL=NCOMB*%(nconfs)d)
494
LOGICAL GOODHEL(NCOMB,%(nconfs)d)
495
common /c_goodhel/goodhel
496
DATA GOODHEL/THEL*.FALSE./
502
C Helper functions to deal with the split orders.
505
INTEGER FUNCTION SQSOINDEXB(AMPORDERA,AMPORDERB)
507
C This functions plays the role of the interference matrix. It can be hardcoded or
508
C made more elegant using hashtables if its execution speed ever becomes a relevant
509
C factor. From two split order indices of the jamps, it return the corresponding
510
C index in the squared order canonical ordering.
515
INTEGER NAMPSO, NSQAMPSO
516
PARAMETER (NAMPSO=%(nAmpSplitOrders)d, NSQAMPSO=%(nSqAmpSplitOrders)d)
518
PARAMETER (NSPLITORDERS=%(nSplitOrders)d)
522
INTEGER AMPORDERA, AMPORDERB
526
INTEGER I, SQORDERS(NSPLITORDERS)
527
INTEGER AMPSPLITORDERS(NAMPSO,NSPLITORDERS)
532
INTEGER SQSOINDEXB_FROM_ORDERS
537
SQORDERS(I)=AMPSPLITORDERS(AMPORDERA,I)+AMPSPLITORDERS(AMPORDERB,I)
539
SQSOINDEXB=SQSOINDEXB_FROM_ORDERS(SQORDERS)
544
INTEGER FUNCTION SQSOINDEXB_FROM_ORDERS(ORDERS)
546
C From a list of values for the split orders, this function returns the
547
c corresponding index in the squared orders canonical ordering.
551
PARAMETER (NSQAMPSO=%(nSqAmpSplitOrders)d)
553
PARAMETER (NSPLITORDERS=%(nSplitOrders)d)
557
INTEGER ORDERS(NSPLITORDERS)
562
INTEGER SQSPLITORDERS(NSQAMPSO,NSPLITORDERS)
569
IF (ORDERS(J).NE.SQSPLITORDERS(I,J)) GOTO 1009
571
SQSOINDEXB_FROM_ORDERS = I
576
WRITE(*,*) 'ERROR:: Stopping function sqsoindex_from_orders'
577
WRITE(*,*) 'Could not find squared orders ',(ORDERS(I),I=1,NSPLITORDERS)
584
INTEGER FUNCTION GETORDPOWFROMINDEX_B(IORDER, INDX)
586
C Return the power of the IORDER-th order appearing at position INDX
587
C in the split-orders output
591
PARAMETER (NSQAMPSO=%(nSqAmpSplitOrders)d)
593
PARAMETER (NSPLITORDERS=%(nSplitOrders)d)
602
INTEGER SQSPLITORDERS(NSQAMPSO,NSPLITORDERS)
607
IF (IORDER.GT.NSPLITORDERS.OR.IORDER.LT.1) THEN
608
WRITE(*,*) "INVALID IORDER B", IORDER
609
WRITE(*,*) "SHOULD BE BETWEEN 1 AND ", NSPLITORDERS
613
IF (INDX.GT.NSQAMPSO.OR.INDX.LT.1) THEN
614
WRITE(*,*) "INVALID INDX B", INDX
615
WRITE(*,*) "SHOULD BE BETWEEN 1 AND ", NSQAMPSO
619
GETORDPOWFROMINDEX_B=SQSPLITORDERS(INDX, IORDER)
623
SUBROUTINE GET_NSQSO_B(NSQSO)
625
C Simple subroutine returning the number of squared split order
626
C contributions returned in ANS when calling SMATRIX_SPLITORDERS
630
PARAMETER (NSQAMPSO=%(nSqAmpSplitOrders)d)