// File: /workspace/github_c_makefile_star2_O1/ugobas[P]tnm/kinetic_tnm.c
// Function: Compute_kinetic
int Compute_kinetic(struct Jacobian *J,
		    struct axe *axe1, int naxe1,
		    atom *atoms1, int natoms1,
		    struct Reference Ref, int SQR)
{
  int N_kin=0;
  int test=(J->Jacobian_ar[0][0]==0);
  // Put center of mass at the origin
  Center_atoms(atoms1, natoms1, Ref);
  // Reorient the Cartesian axes along the principal axes
  //Reorient_axes(atoms1, natoms1, Ref);

  Set_rot_shift(axe1, naxe1, atoms1, natoms1);
  Eckart_main(axe1, naxe1, atoms1, natoms1, Ref);
  Internal_Jacobian(*J, Ref, atoms1, natoms1, axe1, naxe1);
  if(test){
    Eckart_test(J->Jacobian_ar, naxe1, atoms1, natoms1, Ref, axe1);
    if(0)Correlate_Jacobian(*J, Ref, axe1, naxe1);
  }
  Kinetic_energy_fast(J, axe1, naxe1, atoms1, natoms1, Ref);
  //Kinetic_energy_Jac(*J, Ref, naxe1);

  if(SQR){
    // Compute T_sqrt with Cholevsky decomposition
    // Empty matrices
    if(J->T_sqrt_inv){
      Empty_matrix_f(J->T_sqrt_inv, naxe1); J->T_sqrt_inv=NULL;
    }
    if(J->T_sqrt_inv_tr!=NULL){
      Empty_matrix_f(J->T_sqrt_inv_tr, naxe1); J->T_sqrt_inv_tr=NULL;
    }
    if(J->T_sqrt_tr!=NULL){
      Empty_matrix_f(J->T_sqrt_tr, N_kin); J->T_sqrt_tr=NULL;
    }
    if(J->Jtilde_ar!=NULL){
      Empty_matrix_f(J->Jtilde_ar, naxe1); J->Jtilde_ar=NULL;
    }

    // Compute T_sqrt with Cholevsky decomposition
    Kinetic_sqrt(J, &(N_kin), naxe1, T_COMPUTE, E_MIN);    
    // Transpose matrix to accelerate computation
    if(J->T_sqrt_inv){
      J->T_sqrt_inv_tr=Transpose_matrix(J->T_sqrt_inv, N_kin, naxe1);
    }else{
      J->T_sqrt_tr=Transpose_matrix_d2f(J->T_sqrt, N_kin, N_kin);
    }
  }
  J->N_kin=N_kin;

  // Show results
  if(DBG){
    int i, j, m=10;
    printf("Masses: ");
    for(i=0; i<3*m; i+=3)printf("%.0f ", Ref.mass_coord[i]);
    printf("\nJacobian: ");
    for(i=0; i<m; i++)printf("%.1f ", J->Jacobian_ar[i][0]);
    printf("\nKinetic energy matrix. ");
    printf("%d dofs atoms= %d cart= %d Nkin= %d\n",
	   naxe1, natoms1, Ref.N_Cart, N_kin);
    for(i=0; i<m; i++){
      for(j=0; j<m; j++)printf("%.2g\t", J->T_sqrt[i][j]);
      printf("\n");
    }
    printf("Axis properties\n");
    struct axe *axe=axe1;
    for(i=0; i<30; i++){
      printf("%c%d\t%s-%s\t%d-%d\t%d-%d\t%.2g\t%.2g\t%.2g\t%.2g\t%.2g\n",
	     axe->type, i,
	     axe->bond->previous->atom->name, axe->bond->atom->name,
	     axe->first_atom, axe->last_atom,
	     axe->first_kin, axe->last_kin,
	     axe->rot[0],
	     axe->local_shift[0], axe->local_rot[0],
	     axe->global_shift[0], axe->global_rot[0]);
      axe++;
    }
  }
  START=0;

  return(N_kin);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movl %r9d, 0x58(%rsp)
movq %rcx, %r15
movl %edx, %ebp
movq %rsi, %rbx
leaq 0x110(%rsp), %r14
movl $0x0, 0x38(%rsp)
movq %rdi, 0x60(%rsp)
movq 0x10(%rdi), %rax
movq (%rax), %rax
movss (%rax), %xmm0
movss %xmm0, 0x54(%rsp)
movaps (%r14), %xmm0
movaps 0x10(%r14), %xmm1
movaps 0x20(%r14), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rcx, %rdi
movl %r8d, 0x5c(%rsp)
movl %r8d, %esi
callq 0x214be
movq %rbx, %rdi
movl %ebp, %esi
movq %r15, %rdx
callq 0x21584
movaps (%r14), %xmm0
movaps 0x10(%r14), %xmm1
movaps 0x20(%r14), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rbx, 0x40(%rsp)
movq %rbx, %rdi
movl %ebp, %esi
movq %r15, 0x68(%rsp)
movq %r15, %rdx
callq 0x21855
movl %ebp, 0x3c(%rsp)
testl %ebp, %ebp
jle 0x211cd
movq 0x138(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x60(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x78(%rsp)
leaq 0x110(%rsp), %rax
movl (%rax), %eax
movq %rax, 0x70(%rsp)
movl 0x3c(%rsp), %eax
movq %rax, 0x80(%rsp)
movq $0x0, 0x48(%rsp)
movq 0x40(%rsp), %r14
cmpl $0x0, 0x70(%rsp)
jle 0x211ab
movq 0x48(%rsp), %rcx
imulq $0x158, %rcx, %rbp      # imm = 0x158
addq 0x40(%rsp), %rbp
movq 0x78(%rsp), %rax
movq (%rax,%rcx,8), %r12
leaq 0xd8(%rbp), %rax
movq %rax, 0x88(%rsp)
leaq 0xa8(%rbp), %rax
movq %rax, 0x90(%rsp)
xorl %ebx, %ebx
xorl %r15d, %r15d
movslq 0x18(%rbp), %rax
cmpq %rax, %rbx
jl 0x2111b
movslq 0x1c(%rbp), %rax
movl $0xc0, %r13d
movq 0x88(%rsp), %rsi
cmpq %rax, %rbx
jle 0x21129
movl $0x90, %r13d
movq 0x90(%rsp), %rsi
movq 0x98(%rsp), %rax
movslq (%rax,%rbx,4), %rax
imulq $0x70, %rax, %rax
movq 0x68(%rsp), %rdx
movq 0x10(%rdx,%rax), %rcx
movq %rcx, 0xb0(%rsp)
movups (%rdx,%rax), %xmm0
movaps %xmm0, 0xa0(%rsp)
leaq 0xc0(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x1086b
movslq %r15d, %r15
leaq (%r12,%r15,4), %rcx
addq %r14, %r13
xorl %eax, %eax
movsd 0xc0(%rsp,%rax,8), %xmm0
addsd (%r13,%rax,8), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, (%rcx,%rax,4)
incq %rax
cmpq $0x3, %rax
jne 0x21178
incq %rbx
addq %rax, %r15
cmpq 0x70(%rsp), %rbx
jne 0x210fb
movq 0x48(%rsp), %rcx
incq %rcx
addq $0x158, %r14            # imm = 0x158
movq %rcx, 0x48(%rsp)
cmpq 0x80(%rsp), %rcx
jne 0x210b3
xorps %xmm0, %xmm0
movss 0x54(%rsp), %xmm1
ucomiss %xmm0, %xmm1
movq 0x40(%rsp), %rbx
movq 0x60(%rsp), %rbp
movl 0x5c(%rsp), %r15d
movl 0x3c(%rsp), %r14d
leaq 0x110(%rsp), %r13
movq 0x68(%rsp), %r12
jne 0x21230
jp 0x21230
movq 0x10(%rbp), %rdi
movups (%r13), %xmm0
movups 0x10(%r13), %xmm1
movups 0x20(%r13), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movl %r14d, %esi
movq %r12, %rdx
movl %r15d, %ecx
movq %rbx, %r8
callq 0x221ee
movups (%r13), %xmm0
movups 0x10(%r13), %xmm1
movups 0x20(%r13), %xmm2
movups %xmm2, 0x20(%rsp)
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %rbp, %rdi
movq %rbx, %rsi
movl %r14d, %edx
movq %r12, %rcx
callq 0x2229b
cmpl $0x0, 0x58(%rsp)
je 0x21317
movq 0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x21282
movl %r14d, %esi
callq 0x4960c
movq $0x0, 0x30(%rbp)
movq 0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x2129b
movl %r14d, %esi
callq 0x4960c
movq $0x0, 0x38(%rbp)
movq 0x40(%rbp), %rdi
testq %rdi, %rdi
je 0x212b3
xorl %esi, %esi
callq 0x4960c
movq $0x0, 0x40(%rbp)
movq 0x18(%rbp), %rdi
testq %rdi, %rdi
je 0x212cc
movl %r14d, %esi
callq 0x4960c
movq $0x0, 0x18(%rbp)
leaq 0x47e21(%rip), %rax     # 0x690f4
movss (%rax), %xmm0
leaq 0x38(%rsp), %rsi
movq %rbp, %rdi
movl %r14d, %edx
xorl %ecx, %ecx
callq 0x22749
movq 0x30(%rbp), %rdi
testq %rdi, %rdi
je 0x21304
movl 0x38(%rsp), %esi
movl %r14d, %edx
callq 0x22959
movq %rax, 0x38(%rbp)
jmp 0x21317
movq 0x28(%rbp), %rdi
movl 0x38(%rsp), %edx
movl %edx, %esi
callq 0x229a5
movq %rax, 0x40(%rbp)
movl 0x38(%rsp), %r12d
movl %r12d, 0x8(%rbp)
cmpl $0x0, 0x57fe1(%rip)     # 0x79308
je 0x2149f
leaq 0x372c6(%rip), %rdi     # 0x585fa
xorl %eax, %eax
callq 0x20f0
movq 0x18(%r13), %rbx
movq $-0x3, %r14
leaq 0x372b6(%rip), %r13     # 0x58603
xorps %xmm0, %xmm0
cvtss2sd 0xc(%rbx,%r14,4), %xmm0
movq %r13, %rdi
movb $0x1, %al
callq 0x20f0
addq $0x3, %r14
cmpq $0x1b, %r14
jb 0x2134d
leaq 0x37297(%rip), %rdi     # 0x58609
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x20f0
leaq 0x316bd(%rip), %r13     # 0x52a3f
movq 0x10(%rbp), %rax
movq (%rax,%rbx,8), %rax
xorps %xmm0, %xmm0
cvtss2sd (%rax), %xmm0
movq %r13, %rdi
movb $0x1, %al
callq 0x20f0
incq %rbx
cmpq $0xa, %rbx
jne 0x21382
leaq 0x3726a(%rip), %rdi     # 0x58615
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x20f0
leaq 0x110(%rsp), %rax
movl 0x4(%rax), %ecx
leaq 0x37268(%rip), %rdi     # 0x5862e
movl 0x3c(%rsp), %esi
movl %r15d, %edx
movl %r12d, %r8d
xorl %eax, %eax
callq 0x20f0
leaq 0x37275(%rip), %r15     # 0x58653
xorl %r14d, %r14d
movq 0x28(%rbp), %rax
movq (%rax,%rbx,8), %rax
movsd (%rax,%r14,8), %xmm0
movq %r15, %rdi
movb $0x1, %al
callq 0x20f0
incq %r14
cmpq $0xa, %r14
jne 0x213e1
movl $0xa, %edi
callq 0x2060
incq %rbx
cmpq $0xa, %rbx
jne 0x213de
leaq 0x375c3(%rip), %rdi     # 0x589df
callq 0x2090
xorl %ebp, %ebp
leaq 0x3722f(%rip), %r14     # 0x58659
movq 0x40(%rsp), %rbx
movsbl (%rbx), %esi
movq 0x8(%rbx), %rax
movq (%rax), %r8
movq 0x28(%rax), %rax
movq (%rax), %rcx
addq $0x18, %rcx
addq $0x18, %r8
movl 0x10(%rbx), %r9d
movl 0x14(%rbx), %eax
movl 0x18(%rbx), %edx
movl 0x1c(%rbx), %edi
movsd 0x48(%rbx), %xmm0
movsd 0xc0(%rbx), %xmm1
movsd 0xd8(%rbx), %xmm2
movsd 0x90(%rbx), %xmm3
movsd 0xa8(%rbx), %xmm4
movl %edi, 0x10(%rsp)
movl %edx, 0x8(%rsp)
movl %eax, (%rsp)
movq %r14, %rdi
movl %ebp, %edx
movb $0x5, %al
callq 0x20f0
addq $0x158, %rbx            # imm = 0x158
incl %ebp
cmpl $0x1e, %ebp
jne 0x2142f
movl $0x0, 0x47a03(%rip)     # 0x68eac
movl %r12d, %eax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq