// File: /workspace/github_c_makefile_star2_O0/ugobas[P]tnm/screened_interactions.c
// Function: Screened_Interactions
int Screened_Interactions(struct interaction *Int_list,
			  float THR, atom *atoms, int N_atoms, int nres,
			  int TYPE, float S_THR)
{
  // For each pair of atoms ij, determine e_ij such that
  // e_ij=min_k(max(d_ik,d_jk) (minimum of the maximum distance).
  // C_ij=exp(e_ij-d_ij)/(1+exp(e_ij-d_ij))-> 0 if e_ij << d_ij
  // Fast algorithm: for each i store the first RMAX neighbors d<thr
  // For each i and j in list of neighbors, find e_ij

  int i1, i2, i;
  atom *atom1=atoms, *atom2;
  float Thr=THR, thr2=Thr*Thr, d, d2;

  // Allocate and rank RMAX neighbors, including bonded
  struct ranked *rank=malloc(N_atoms*sizeof(struct ranked));
  for(i=0; i<N_atoms; i++){
    rank[i].num=0;
    rank[i].store=malloc(RMAX*sizeof(struct store));
  }
  for(i1=0; i1<N_atoms; i1++){
    atom2=atom1+1;
    struct ranked *rank1=rank+i1;
    for(i2=i1+1; i2<N_atoms; i2++){
      // Interatomic distance
      d=atom2->r[0]-atom1->r[0]; d2 =d*d; if(d2>thr2)goto next;
      d=atom2->r[1]-atom1->r[1]; d2+=d*d; if(d2>thr2)goto next;
      d=atom2->r[2]-atom1->r[2]; d2+=d*d; if(d2>thr2)goto next;
      Rank(rank1,  i2, d2, RMAX);
      Rank(rank+i2,i1, d2, RMAX);
    next:
      atom2++;
    }
    atom1++;
  }

  // Thresholds
  float S_BOND=S_THR;
  if(RELAX_COV){
    if(TYPE==0){S_BOND=S_THR+(1.-S_THR)/2;} // cosine
    else if(TYPE==1){S_BOND=0.5*S_THR;} // distance from axis
    else if(TYPE==2){S_BOND=0.5*S_THR;} // Shadow
    else if(TYPE==3){S_BOND=2*S_THR;}   // SCR
  }
  float S2_NB=S_THR*S_THR, S2_BO=S_BOND*S_BOND; 
  //float delta_nb=DTHR*S_THR;
  //float delta_bo=DTHR*S_BOND;
  printf("Screened interactions type %d D=%.3f (nobond) %.3f (bond)\n",
	 TYPE, S_THR, S_BOND);
  if((TYPE<0)||(TYPE>3)){
    printf("ERROR, undefined type of screened interaction %d\n", TYPE);
    exit(8);
  }

  // Protect from screening interactions that satisfy the MIN criterion
  int **protect=NULL;
  if(PROTECT)protect=Protect_interactions(rank, atoms, N_atoms, nres);
  // WARNING! store is a linked list !!!!!

  int N_int=0, tested=0, Nprotect=0;
  float e2=1;
  for(i1=0; i1<N_atoms; i1++){
    atom1=atoms+i1;
    int res1=atom1->res, n=-1;
    struct store *store=rank[i1].first;
    while(store != NULL){
      if(protect)n++;
      i2=store->i;
      if(i2<=i1)goto No_int;
      atom2=atoms+i2;
      int res2=atom2->res;
      if(res2==res1)goto No_int;
      if(NOCOV && Covalent(res1, res2, atom1, atom2))goto No_int;
      if((protect)&&(protect[i1][n])){Nprotect++; goto store;}
      tested++;

      float d2_ij= store->x; 
      float d2_bo=100, d2_nb=d2_bo;  // Bonded and non-bonded, squared

      if(TYPE==3){
	// SCR interactions
	float d_ij=sqrt(d2_ij);
	float D2_NB=d_ij-S_THR;  D2_NB*=D2_NB;
	float D2_BO=d_ij-S_BOND; D2_BO*=D2_BO;
	//Screening_distance(&e2_nb,&e2_bo,res2,rank[i2].first, atom1, atoms);
	// Change 27/3/2015: weight SCR=0,1
	if(Screening_distance(&d2_nb, &d2_bo, D2_NB, D2_BO,
			      rank[i1].first, d2_ij, atom1, atom2, atoms))
	  goto No_int;

	/* 
	e2_nb=sqrt(d2_ij)-sqrt(e2_nb);
	if(e2_nb > delta_nb)goto No_int;
	e2_bo=sqrt(d2_ij)-sqrt(e2_bo);
	if(e2_bo > delta_bo)goto No_int;
	if(S_THR > 0){
	  e2_nb=exp(-e2_nb/S_THR);
	  e2_bo=exp(-e2_bo/S_BOND);
	  if(e2_nb<e2_bo){e2=e2_nb/(1.+e2_nb);}
	  else{e2=e2_bo/(1.+e2_bo);}
	} */

      }else if(TYPE==0){
	// Screening based on cosine
	float cos2_bo=0, cos2_nb=0;
	if(Shadow_cosine(&cos2_nb, &cos2_bo, S2_NB, S2_BO,
			 rank[i1].first, d2_ij, atom1, atom2, atoms))
	  goto No_int;

      }else if(TYPE==1){
	// Screening based on distance from axis
	if(Axis_distance(&d2_nb, &d2_bo, S2_NB, S2_BO,
			 rank[i1].first, d2_ij, atom1, atom2, atoms))
	  goto No_int;
	//w=exp(-d_min/S_THR); w=(1-w)/(1+w); if(w<0.005)goto No_int;

      }else if(TYPE==2){
	// Screening based on Onuchic radius
	if(Axis_distance_S(&d2_nb, &d2_bo, S_THR, S_BOND,
			   rank[i1].first, d2_ij, atom1, atom2, atoms))
	  goto No_int;
      }

    store:
      Int_list[N_int].i1=i1; Int_list[N_int].i2=store->i;
      Int_list[N_int].r0=sqrt(store->x); Int_list[N_int].sec_der=e2;
      N_int++;
      if(N_int >= INT_MAX){
	printf("ERROR, too many interactions %d\n", N_int); exit(8);
      }

    No_int:
      store=store->next;
    }
  }

  // INform
  printf("%d pairs tested, %d screened interactions type %d found,",
	 tested, N_int, TYPE);
  printf(" screening par=%.4f cut-off distance=%.1f", S_THR, THR);
  //if(TYPE==3)printf("cut-off for screening=%.2g", 2*exp(-DTHR));
  printf("\n");
  printf("%d pairs protected from screening because of MIN\n", Nprotect);

  for(i=0; i<N_atoms; i++)free(rank[i].store);
  free(rank);

  return(N_int);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movss %xmm0, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movss %xmm1, -0x28(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x40(%rbp)
movss -0xc(%rbp), %xmm0
movss %xmm0, -0x4c(%rbp)
movss -0x4c(%rbp), %xmm0
mulss -0x4c(%rbp), %xmm0
movss %xmm0, -0x50(%rbp)
movslq -0x1c(%rbp), %rdi
shlq $0x5, %rdi
callq 0x1180
movq %rax, -0x60(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x2c3be
movq -0x60(%rbp), %rax
movslq -0x34(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl $0x0, (%rax)
movslq 0x5fad8(%rip), %rdi     # 0x8be6c
shlq $0x4, %rdi
callq 0x1180
movq %rax, %rcx
movq -0x60(%rbp), %rax
movslq -0x34(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x2c370
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x2c532
movq -0x40(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x48(%rbp)
movq -0x60(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x2c518
movq -0x48(%rbp), %rax
movsd (%rax), %xmm0
movq -0x40(%rbp), %rax
subsd (%rax), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x54(%rbp)
movss -0x54(%rbp), %xmm0
mulss -0x54(%rbp), %xmm0
movss %xmm0, -0x58(%rbp)
movss -0x58(%rbp), %xmm0
ucomiss -0x50(%rbp), %xmm0
jbe 0x2c43d
jmp 0x2c4fe
movq -0x48(%rbp), %rax
movsd 0x8(%rax), %xmm0
movq -0x40(%rbp), %rax
subsd 0x8(%rax), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x54(%rbp)
movss -0x54(%rbp), %xmm0
movss -0x54(%rbp), %xmm2
movss -0x58(%rbp), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x58(%rbp)
movss -0x58(%rbp), %xmm0
ucomiss -0x50(%rbp), %xmm0
jbe 0x2c481
jmp 0x2c4fe
movq -0x48(%rbp), %rax
movsd 0x10(%rax), %xmm0
movq -0x40(%rbp), %rax
subsd 0x10(%rax), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x54(%rbp)
movss -0x54(%rbp), %xmm0
movss -0x54(%rbp), %xmm2
movss -0x58(%rbp), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, -0x58(%rbp)
movss -0x58(%rbp), %xmm0
ucomiss -0x50(%rbp), %xmm0
jbe 0x2c4c5
jmp 0x2c4fe
movq -0x68(%rbp), %rdi
movl -0x30(%rbp), %esi
movss -0x58(%rbp), %xmm0
movl 0x5f995(%rip), %edx     # 0x8be6c
callq 0x2cb10
movq -0x60(%rbp), %rdi
movslq -0x30(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
movl -0x2c(%rbp), %esi
movss -0x58(%rbp), %xmm0
movl 0x5f973(%rip), %edx     # 0x8be6c
callq 0x2cb10
movq -0x48(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x48(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x2c3f9
movq -0x40(%rbp), %rax
addq $0x70, %rax
movq %rax, -0x40(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2c3c5
movss -0x28(%rbp), %xmm0
movss %xmm0, -0x6c(%rbp)
movss -0x28(%rbp), %xmm0
mulss -0x28(%rbp), %xmm0
movss %xmm0, -0x70(%rbp)
movss -0x6c(%rbp), %xmm0
mulss -0x6c(%rbp), %xmm0
movss %xmm0, -0x74(%rbp)
movl -0x24(%rbp), %esi
movss -0x28(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0x6c(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
leaq 0x51107(%rip), %rdi     # 0x7d67d
movb $0x2, %al
callq 0x10d0
cmpl $0x0, -0x24(%rbp)
jl 0x2c589
cmpl $0x3, -0x24(%rbp)
jle 0x2c5a4
movl -0x24(%rbp), %esi
leaq 0x51125(%rip), %rdi     # 0x7d6b8
movb $0x0, %al
callq 0x10d0
movl $0x8, %edi
callq 0x1210
movq $0x0, -0x80(%rbp)
cmpl $0x0, 0x6fd15(%rip)     # 0x9c2c8
je 0x2c5cc
movq -0x60(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %edx
movl -0x20(%rbp), %ecx
callq 0x2cd40
movq %rax, -0x80(%rbp)
movl $0x0, -0x84(%rbp)
movl $0x0, -0x88(%rbp)
movl $0x0, -0x8c(%rbp)
movss 0x49a9e(%rip), %xmm0    # 0x76090
movss %xmm0, -0x90(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x2ca5b
movq -0x18(%rbp), %rax
movslq -0x2c(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl 0x64(%rax), %eax
movl %eax, -0x94(%rbp)
movl $0xffffffff, -0x98(%rbp) # imm = 0xFFFFFFFF
movq -0x60(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, -0xa0(%rbp)
je 0x2ca4b
cmpq $0x0, -0x80(%rbp)
je 0x2c675
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
movq -0xa0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jg 0x2c68e
jmp 0x2ca34
movq -0x18(%rbp), %rax
movslq -0x30(%rbp), %rcx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movl 0x64(%rax), %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
cmpl -0x94(%rbp), %eax
jne 0x2c6c1
jmp 0x2ca34
leaq 0x5eef8(%rip), %rax     # 0x8b5c0
cmpl $0x0, (%rax)
je 0x2c6f0
movl -0x94(%rbp), %edi
movl -0xa4(%rbp), %esi
movq -0x40(%rbp), %rdx
movq -0x48(%rbp), %rcx
callq 0x215f0
cmpl $0x0, %eax
je 0x2c6f0
jmp 0x2ca34
cmpq $0x0, -0x80(%rbp)
je 0x2c724
movq -0x80(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x98(%rbp), %rcx
cmpl $0x0, (%rax,%rcx,4)
je 0x2c724
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x2c964
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
movq -0xa0(%rbp), %rax
movss 0x4(%rax), %xmm0
movss %xmm0, -0xa8(%rbp)
movss 0x49961(%rip), %xmm0    # 0x760b0
movss %xmm0, -0xac(%rbp)
movss -0xac(%rbp), %xmm0
movss %xmm0, -0xb0(%rbp)
cmpl $0x3, -0x24(%rbp)
jne 0x2c841
movss -0xa8(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x1220
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0xb4(%rbp)
movss -0xb4(%rbp), %xmm0
subss -0x28(%rbp), %xmm0
movss %xmm0, -0xb8(%rbp)
movss -0xb8(%rbp), %xmm0
mulss -0xb8(%rbp), %xmm0
movss %xmm0, -0xb8(%rbp)
movss -0xb4(%rbp), %xmm0
subss -0x6c(%rbp), %xmm0
movss %xmm0, -0xbc(%rbp)
movss -0xbc(%rbp), %xmm0
mulss -0xbc(%rbp), %xmm0
movss %xmm0, -0xbc(%rbp)
movss -0xb8(%rbp), %xmm0
movss -0xbc(%rbp), %xmm1
movq -0x60(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rdx
movss -0xa8(%rbp), %xmm2
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x18(%rbp), %r9
leaq -0xb0(%rbp), %rdi
leaq -0xac(%rbp), %rsi
callq 0x2d0c0
cmpl $0x0, %eax
je 0x2c83c
jmp 0x2ca34
jmp 0x2c962
cmpl $0x0, -0x24(%rbp)
jne 0x2c8b0
xorps %xmm0, %xmm0
movss %xmm0, -0xc0(%rbp)
xorps %xmm0, %xmm0
movss %xmm0, -0xc4(%rbp)
movss -0x70(%rbp), %xmm0
movss -0x74(%rbp), %xmm1
movq -0x60(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rdx
movss -0xa8(%rbp), %xmm2
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x18(%rbp), %r9
leaq -0xc4(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x2d240
cmpl $0x0, %eax
je 0x2c8ab
jmp 0x2ca34
jmp 0x2c960
cmpl $0x1, -0x24(%rbp)
jne 0x2c906
movss -0x70(%rbp), %xmm0
movss -0x74(%rbp), %xmm1
movq -0x60(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rdx
movss -0xa8(%rbp), %xmm2
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x18(%rbp), %r9
leaq -0xb0(%rbp), %rdi
leaq -0xac(%rbp), %rsi
callq 0x2d410
cmpl $0x0, %eax
je 0x2c904
jmp 0x2ca34
jmp 0x2c95e
cmpl $0x2, -0x24(%rbp)
jne 0x2c95c
movss -0x28(%rbp), %xmm0
movss -0x6c(%rbp), %xmm1
movq -0x60(%rbp), %rax
movslq -0x2c(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rdx
movss -0xa8(%rbp), %xmm2
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x18(%rbp), %r9
leaq -0xb0(%rbp), %rdi
leaq -0xac(%rbp), %rsi
callq 0x2d5e0
cmpl $0x0, %eax
je 0x2c95a
jmp 0x2ca34
jmp 0x2c95c
jmp 0x2c95e
jmp 0x2c960
jmp 0x2c962
jmp 0x2c964
movl -0x2c(%rbp), %ecx
movq -0x8(%rbp), %rax
movslq -0x84(%rbp), %rdx
imulq $0xc8, %rdx, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
movq -0xa0(%rbp), %rax
movl (%rax), %ecx
movq -0x8(%rbp), %rax
movslq -0x84(%rbp), %rdx
imulq $0xc8, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x4(%rax)
movq -0xa0(%rbp), %rax
movss 0x4(%rax), %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x1220
movq -0x8(%rbp), %rax
movslq -0x84(%rbp), %rcx
imulq $0xc8, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x20(%rax)
movss -0x90(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movq -0x8(%rbp), %rax
movslq -0x84(%rbp), %rcx
imulq $0xc8, %rcx, %rcx
addq %rcx, %rax
movsd %xmm0, 0x28(%rax)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
movl -0x84(%rbp), %eax
leaq 0x6f888(%rip), %rcx     # 0x9c298
cmpl (%rcx), %eax
jl 0x2ca32
movl -0x84(%rbp), %esi
leaq 0x4f6ba(%rip), %rdi     # 0x7c0db
movb $0x0, %al
callq 0x10d0
movl $0x8, %edi
callq 0x1210
jmp 0x2ca34
movq -0xa0(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xa0(%rbp)
jmp 0x2c651
jmp 0x2ca4d
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2c601
movl -0x88(%rbp), %esi
movl -0x84(%rbp), %edx
movl -0x24(%rbp), %ecx
leaq 0x50c79(%rip), %rdi     # 0x7d6ea
movb $0x0, %al
callq 0x10d0
movss -0x28(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movss -0xc(%rbp), %xmm1
cvtss2sd %xmm1, %xmm1
leaq 0x50c92(%rip), %rdi     # 0x7d723
movb $0x2, %al
callq 0x10d0
leaq 0x515d9(%rip), %rdi     # 0x7e078
movb $0x0, %al
callq 0x10d0
movl -0x8c(%rbp), %esi
leaq 0x50c9a(%rip), %rdi     # 0x7d74d
movb $0x0, %al
callq 0x10d0
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x2caec
movq -0x60(%rbp), %rax
movslq -0x34(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
callq 0x1040
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x2cac1
movq -0x60(%rbp), %rdi
callq 0x1040
movl -0x84(%rbp), %eax
addq $0xd0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)