// File: /workspace/github_c_makefile_star2_O2/ugobas[P]tnm/buildup.c
// Function: Build_up
void Build_up(struct bond *bonds, int N_atoms, double *d_phi, int N_axes)
{
  float COSMAX=0.999; // Maximum value of cos(theta) to avoid collinear bonds
  struct bond *bond, *previous; int i, j;

  for(i=1; i<N_atoms; i++){
    bond=bonds+i;
    if(bond->i_atom<0)break;
    previous=bond->previous;
    if(previous==NULL){
      printf("ERROR, build up can not be applied at bond %d\n", i);
      return;
    }
    if((previous->previous==NULL)||
     (previous->previous->previous==NULL))continue;
    if((d_phi)&&(bond->len >= 0)){
      double factor=1.+d_phi[bond->len]/bond->l; //
      if(factor <= 0.1){
	printf("WARNING, bond length too short with buildup! ");
	printf("atoms: %s%d%c  %s%d%c f= %.2g\n",
	       bond->atom->name, bond->atom->res, bond->atom->aa,
	       bond->previous->atom->name, bond->previous->atom->res,
	       bond->previous->atom->aa, factor);
	factor=0.1;
	printf("Setting shrink factor to %.2g\n", factor);
      }
      bond->l*=factor;
      bond->r_cos_theta*=factor;
      double lcosmax=bond->l*COSMAX;
      if(bond->r_cos_theta>lcosmax){bond->r_cos_theta=lcosmax;}
      else if(bond->r_cos_theta<-lcosmax){bond->r_cos_theta=-lcosmax;}
    }

    double r_sin_theta=
      sqrt(bond->l*bond->l-bond->r_cos_theta*bond->r_cos_theta);
    if((d_phi)&&(bond->angle >= 0)){
      // Cos(theta)->Cos(theta+d_phi)
      double cos_a=cos(d_phi[bond->angle]);
      double sin_a=sin(d_phi[bond->angle]);
      bond->r_cos_theta=bond->r_cos_theta*cos_a-r_sin_theta*sin_a;
      double lcosmax=bond->l*COSMAX;
      if(bond->r_cos_theta>lcosmax){bond->r_cos_theta=lcosmax;}
      else if(bond->r_cos_theta<-lcosmax){bond->r_cos_theta=-lcosmax;}
      r_sin_theta=
	sqrt(bond->l*bond->l-bond->r_cos_theta*bond->r_cos_theta);
    }

    if((d_phi)&&(bond->torsion >= 0)){
      bond->phi += d_phi[bond->torsion];
      while(bond->phi > TWOPI){bond->phi-=TWOPI;}
      while(bond->phi <-TWOPI){bond->phi+=TWOPI;}
    }
    double ax= r_sin_theta*cos(bond->phi);
    double ay= r_sin_theta*sin(bond->phi);
    double az= -bond->r_cos_theta;

    for(j=0; j<3; j++){
      double dr=
	az*previous->dz[j]+
	ax*previous->dx[j]+
	ay*previous->dy[j];
      bond->dr[j]=dr;
      bond->r[j]=previous->r[j]+dr;
    }
    if(isnan(bond->r[0])||isnan(bond->r[1])||isnan(bond->r[2])){
      printf("ERROR nan, atom %s%d ", bond->atom->name, i);
      printf("len: %d ", bond->len);
      if(bond->len>=0)printf(" %.2g", d_phi[bond->len]);
      printf("  angle: %d ", bond->angle);
      if(bond->angle>=0){
	printf(" %.3f cos=%.3f",d_phi[bond->angle], cos(d_phi[bond->angle]));
      }
      printf("  torsion: %d ", bond->torsion);
      if(bond->torsion>=0)printf(" %.3f", d_phi[bond->torsion]);
      printf("\n");
      printf("r= %.3f", bond->l);
      printf(" r*cos(theta)= %.3f", bond->r_cos_theta);
      printf(" r*sin(theta)= %.3f", r_sin_theta);
      printf(" phi= %.3f", bond->phi);
      double *v=previous->dx; printf(" x: %.3f %.3f %.3f",v[0],v[1],v[2]);
      v=previous->dy; printf(" y: %.3f %.3f %.3f",v[0],v[1],v[2]);
      v=previous->dz; printf(" z: %.3f %.3f %.3f",v[0],v[1],v[2]);
      printf("\n"); 
      //for(i=0; i<N_axes; i++)printf("%.2f ",d_phi[i]); printf("\n"); 
      //exit(8);
    }
    double dr_dr=Scalar_product_3_d(bond->dr, bond->dr);
    bond->l=sqrt(dr_dr);
    for(j=0; j<3; j++){
      bond->dz[j]=bond->dr[j]/bond->l;
    }

    // Make new orthogonal frame
    if(bond->terminal==0 && Make_frame(bond, previous, previous->dz)<0){
      printf("Could not make last frame, exiting\n");
      return;
    }
  }
  return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %rbp
movq %rdi, %r15
movslq %esi, %rax
movq %rax, 0x30(%rsp)
leaq 0x100(%rdi), %r14
pushq $0x1
popq %rbx
movsd 0x3cae2(%rip), %xmm2    # 0x50880
movq %rdx, 0x18(%rsp)
cmpq 0x30(%rsp), %rbx
jge 0x1430f
imulq $0xc0, %rbx, %r12
cmpl $0x0, 0x20(%r15,%r12)
js 0x1430f
addq %r15, %r12
movq 0x28(%r12), %r13
testq %r13, %r13
je 0x1431e
movq 0x28(%r13), %rax
testq %rax, %rax
je 0x14154
cmpq $0x0, 0x28(%rax)
je 0x14154
testq %rbp, %rbp
je 0x13ecf
movslq 0x34(%r12), %rax
testq %rax, %rax
js 0x13ecf
movsd (%rbp,%rax,8), %xmm1
movsd 0x58(%r12), %xmm0
divsd %xmm0, %xmm1
addsd 0x3722e(%rip), %xmm1    # 0x4b048
ucomisd %xmm1, %xmm2
jb 0x13e93
leaq 0x3cb6c(%rip), %rdi     # 0x50993
xorl %eax, %eax
movsd %xmm1, 0x10(%rsp)
callq 0x20f0
movq (%r12), %rax
movq 0x28(%r12), %rdi
leaq 0x18(%rax), %rsi
movl 0x64(%rax), %edx
movsbl 0x68(%rax), %ecx
movq (%rdi), %rax
leaq 0x18(%rax), %r8
movl 0x64(%rax), %r9d
movsbl 0x68(%rax), %eax
movl %eax, (%rsp)
leaq 0x3cb60(%rip), %rdi     # 0x509c1
movsd 0x10(%rsp), %xmm0
movb $0x1, %al
callq 0x20f0
leaq 0x3cb6b(%rip), %rdi     # 0x509e0
movsd 0x3ca03(%rip), %xmm0    # 0x50880
movb $0x1, %al
callq 0x20f0
movsd 0x58(%r12), %xmm0
movsd 0x3c9ed(%rip), %xmm1    # 0x50880
mulsd %xmm1, %xmm0
movsd %xmm0, 0x58(%r12)
mulsd 0x60(%r12), %xmm1
movsd %xmm1, 0x60(%r12)
mulsd 0x3c9d4(%rip), %xmm0    # 0x50888
ucomisd %xmm0, %xmm1
ja 0x13ec8
xorpd 0x371fe(%rip), %xmm0    # 0x4b0c0
ucomisd %xmm1, %xmm0
jbe 0x13ecf
movsd %xmm0, 0x60(%r12)
movsd 0x58(%r12), %xmm0
movsd 0x60(%r12), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm0
subsd %xmm1, %xmm0
ucomisd 0x3715f(%rip), %xmm0    # 0x4b050
jb 0x13ef9
sqrtsd %xmm0, %xmm0
jmp 0x13efe
callq 0x2290
movsd %xmm0, 0x10(%rsp)
testq %rbp, %rbp
je 0x14007
movslq 0x38(%r12), %rax
testq %rax, %rax
js 0x13fb3
movsd (%rbp,%rax,8), %xmm0
callq 0x2130
movsd %xmm0, 0x20(%rsp)
movslq 0x38(%r12), %rax
movsd (%rbp,%rax,8), %xmm0
callq 0x2220
movsd 0x20(%rsp), %xmm2
mulsd 0x60(%r12), %xmm2
mulsd 0x10(%rsp), %xmm0
subsd %xmm0, %xmm2
movsd %xmm2, 0x60(%r12)
movsd 0x58(%r12), %xmm0
movapd %xmm0, %xmm1
mulsd 0x3c91b(%rip), %xmm1    # 0x50888
ucomisd %xmm1, %xmm2
ja 0x13f81
xorpd 0x37145(%rip), %xmm1    # 0x4b0c0
ucomisd %xmm2, %xmm1
jbe 0x13f8c
movsd %xmm1, 0x60(%r12)
movapd %xmm1, %xmm2
mulsd %xmm2, %xmm2
mulsd %xmm0, %xmm0
subsd %xmm2, %xmm0
ucomisd 0x370b0(%rip), %xmm0    # 0x4b050
jb 0x13fa8
sqrtsd %xmm0, %xmm0
jmp 0x13fad
callq 0x2290
movsd %xmm0, 0x10(%rsp)
movslq 0x3c(%r12), %rax
testq %rax, %rax
js 0x14007
movsd (%rbp,%rax,8), %xmm0
addsd 0x68(%r12), %xmm0
movss 0x4f85e(%rip), %xmm2    # 0x63830
cvtss2sd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x13fe2
subsd %xmm1, %xmm0
jmp 0x13fd6
movsd %xmm0, 0x68(%r12)
xorps 0x3c870(%rip), %xmm2    # 0x50860
cvtss2sd %xmm2, %xmm2
ucomisd %xmm0, %xmm2
jbe 0x14007
addsd %xmm1, %xmm0
movsd %xmm0, 0x68(%r12)
jmp 0x13ff4
movsd 0x68(%r12), %xmm0
callq 0x2130
mulsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x68(%r12), %xmm0
callq 0x2220
movsd 0x20(%rsp), %xmm4
mulsd 0x10(%rsp), %xmm0
movsd 0x60(%r12), %xmm1
xorpd 0x3707a(%rip), %xmm1    # 0x4b0c0
leaq 0xa8(%r13), %rax
movq %rax, 0x28(%rsp)
leaq 0x40(%r12), %rbp
xorl %eax, %eax
cmpq $0x3, %rax
je 0x140a7
movsd 0x90(%r13,%rax,8), %xmm2
mulsd %xmm4, %xmm2
movsd 0xa8(%r13,%rax,8), %xmm3
mulsd %xmm1, %xmm3
addsd %xmm2, %xmm3
movsd 0x78(%r13,%rax,8), %xmm2
mulsd %xmm0, %xmm2
addsd %xmm3, %xmm2
movsd %xmm2, (%r14,%rax,8)
addsd 0x8(%r13,%rax,8), %xmm2
movsd %xmm2, -0x38(%r14,%rax,8)
incq %rax
jmp 0x14059
movsd 0x8(%r12), %xmm0
ucomisd %xmm0, %xmm0
jp 0x14163
movsd 0x10(%r12), %xmm0
ucomisd %xmm0, %xmm0
jp 0x14163
movsd 0x18(%r12), %xmm0
ucomisd %xmm0, %xmm0
jp 0x14163
movq %rbp, %rdi
movq %rbp, %rsi
callq 0xf96f
ucomisd 0x36f63(%rip), %xmm0    # 0x4b050
jb 0x140f5
sqrtsd %xmm0, %xmm0
jmp 0x140fa
callq 0x2290
movq 0x18(%rsp), %rbp
movsd 0x3c779(%rip), %xmm2    # 0x50880
movsd %xmm0, 0x58(%r12)
xorl %eax, %eax
cmpq $0x3, %rax
je 0x1412c
movsd (%r14,%rax,8), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x68(%r14,%rax,8)
incq %rax
jmp 0x14110
cmpl $0x0, 0x30(%r12)
jne 0x14154
movq %r12, %rdi
movq %r13, %rsi
movq 0x28(%rsp), %rdx
callq 0x14e3b
movsd 0x3c734(%rip), %xmm2    # 0x50880
testl %eax, %eax
js 0x1433c
incq %rbx
addq $0xc0, %r14
jmp 0x13da3
movq (%r12), %rsi
addq $0x18, %rsi
leaq 0x3c88d(%rip), %rdi     # 0x509ff
movl %ebx, %edx
xorl %eax, %eax
callq 0x20f0
movl 0x34(%r12), %esi
leaq 0x3c88e(%rip), %rdi     # 0x50a15
xorl %eax, %eax
callq 0x20f0
movslq 0x34(%r12), %rax
testq %rax, %rax
js 0x141b0
movq 0x18(%rsp), %rcx
movsd (%rcx,%rax,8), %xmm0
leaq 0x3bf0f(%rip), %rdi     # 0x500b8
movb $0x1, %al
callq 0x20f0
movl 0x38(%r12), %esi
leaq 0x3c862(%rip), %rdi     # 0x50a1e
xorl %eax, %eax
callq 0x20f0
movslq 0x38(%r12), %rax
testq %rax, %rax
js 0x141fa
movq 0x18(%rsp), %rcx
movsd (%rcx,%rax,8), %xmm0
movsd %xmm0, 0x20(%rsp)
callq 0x2130
movapd %xmm0, %xmm1
leaq 0x3c83e(%rip), %rdi     # 0x50a2b
movsd 0x20(%rsp), %xmm0
movb $0x2, %al
callq 0x20f0
movl 0x3c(%r12), %esi
leaq 0x3c834(%rip), %rdi     # 0x50a3a
xorl %eax, %eax
callq 0x20f0
movslq 0x3c(%r12), %rax
testq %rax, %rax
js 0x1422f
movq 0x18(%rsp), %rcx
movsd (%rcx,%rax,8), %xmm0
leaq 0x3c84b(%rip), %rdi     # 0x50a73
movb $0x1, %al
callq 0x20f0
pushq $0xa
popq %rdi
callq 0x2060
movsd 0x58(%r12), %xmm0
leaq 0x3c804(%rip), %rdi     # 0x50a49
movb $0x1, %al
callq 0x20f0
movsd 0x60(%r12), %xmm0
leaq 0x3c7f7(%rip), %rdi     # 0x50a51
movb $0x1, %al
callq 0x20f0
leaq 0x3c7fd(%rip), %rdi     # 0x50a65
movsd 0x10(%rsp), %xmm0
movb $0x1, %al
callq 0x20f0
movsd 0x68(%r12), %xmm0
leaq 0x3c7f6(%rip), %rdi     # 0x50a79
movb $0x1, %al
callq 0x20f0
movsd 0x90(%r13), %xmm0
movsd 0x98(%r13), %xmm1
movsd 0xa0(%r13), %xmm2
leaq 0x3c7d8(%rip), %rdi     # 0x50a84
movb $0x3, %al
callq 0x20f0
movsd 0x78(%r13), %xmm0
movsd 0x80(%r13), %xmm1
movsd 0x88(%r13), %xmm2
leaq 0x3c7c5(%rip), %rdi     # 0x50a97
movb $0x3, %al
callq 0x20f0
movsd 0xa8(%r13), %xmm0
movsd 0xb0(%r13), %xmm1
movsd 0xb8(%r13), %xmm2
leaq 0x3c7af(%rip), %rdi     # 0x50aaa
movb $0x3, %al
callq 0x20f0
pushq $0xa
popq %rdi
callq 0x2060
jmp 0x140da
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x3c63f(%rip), %rdi     # 0x50964
movl %ebx, %esi
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x20f0
leaq 0x3ca54(%rip), %rdi     # 0x50d97
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2090