// File: /workspace/github_c_makefile_star2_O0/PoulinV[P]AxiCLASS/build/../source/thermodynamics.c
// Function: thermodynamics_reionization_get_tau
int thermodynamics_reionization_get_tau(
                                        struct precision * ppr,
                                        struct background * pba,
                                        struct thermodynamics * pth,
                                        struct thermo_workspace * ptw
                                        ) {

  /** Summary: */

  /** Define local variables */
  /* running index inside thermodynamics table */
  int index_z,index_reio_start=0;
  double x_e_min;

  x_e_min = _HUGE_;

  /**
   * We are searching now for the start of reionization. This will be
   * the time at which the optical depth tau_reio will be computed.
   *
   * Note that the value reionization_parameters[index_reio_start] is
   * only the start of the reionization function added manually, but
   * not necessarily the total start of reionization. Reionization
   * could be longer/shifted by energy injection.
   *
   * The actual the definition of tau_reio is not unique and
   * unambiguous. We defined it here to be the optical depth up to the
   * time at which there is a global minimum in the free electron
   * fraction. We search for this time by iterating over the
   * thermodynamics table, in order to find the corresponding
   * index_reio_start.
   */

  for (index_z=0; index_z<pth->tt_size-1; index_z++) {
    if (pth->thermodynamics_table[index_z*pth->th_size+pth->index_th_xe] < x_e_min) {
      x_e_min = pth->thermodynamics_table[index_z*pth->th_size+pth->index_th_xe];
      index_reio_start = index_z;
    }
  }

  class_test(index_reio_start == pth->tt_size,
             pth->error_message,
             "reionization start = %e > largest redshift in thermodynamics table",pth->z_table[index_reio_start]);

  if (index_reio_start == 0) {
    /* the global minimum of xe(z) is at z=0. This is possible in
       models no reionization and no exotic energy
       injection. According to our definition of the reionization
       optical depth, tau_reio should then be zero. */
    ptw->reionization_optical_depth = 0;
    return _SUCCESS_;
  }
  if (index_reio_start < 3) {
    /* we need a minimum of three values to do a spline integration in the next step */
    index_reio_start =3;
  }

  /** - --> spline \f$ d \tau / dz \f$ with respect to z in view of
   *         integrating for optical depth between 0 and the just found
   *         starting index
   */
  class_call(array_spline_table_line_to_line(pth->tau_table,
                                             index_reio_start,
                                             pth->thermodynamics_table,
                                             pth->th_size,
                                             pth->index_th_dkappa,
                                             pth->index_th_dddkappa,
                                             _SPLINE_EST_DERIV_,
                                             pth->error_message),
             pth->error_message,
             pth->error_message);

  /** - --> integrate for optical depth */
  class_call(array_integrate_all_spline_table_line_to_line(pth->tau_table,
                                                           index_reio_start,
                                                           pth->thermodynamics_table,
                                                           pth->th_size,
                                                           pth->index_th_dkappa,
                                                           pth->index_th_dddkappa,
                                                           &(ptw->reionization_optical_depth),
                                                           pth->error_message),
             pth->error_message,
             pth->error_message);

  ptw->reionization_optical_depth *= -1; // tau and z go in reverse order, so we must flip the sign

  return _SUCCESS_;
}

// Assembly:
subq $0x2048, %rsp           # imm = 0x2048
movq %rdi, 0x2038(%rsp)
movq %rsi, 0x2030(%rsp)
movq %rdx, 0x2028(%rsp)
movq %rcx, 0x2020(%rsp)
movl $0x0, 0x2018(%rsp)
movsd 0x131ab6(%rip), %xmm0   # 0x1f14f0
movsd %xmm0, 0x2010(%rsp)
movl $0x0, 0x201c(%rsp)
movl 0x201c(%rsp), %eax
movq 0x2028(%rsp), %rcx
movl 0xf08(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0xbfb22
movq 0x2028(%rsp), %rax
movq 0xf20(%rax), %rax
movl 0x201c(%rsp), %ecx
movq 0x2028(%rsp), %rdx
imull 0xf04(%rdx), %ecx
movq 0x2028(%rsp), %rdx
addl 0xe7c(%rdx), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
movsd 0x2010(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xbfb0a
movq 0x2028(%rsp), %rax
movq 0xf20(%rax), %rax
movl 0x201c(%rsp), %ecx
movq 0x2028(%rsp), %rdx
imull 0xf04(%rdx), %ecx
movq 0x2028(%rsp), %rdx
addl 0xe7c(%rdx), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x2010(%rsp)
movl 0x201c(%rsp), %eax
movl %eax, 0x2018(%rsp)
jmp 0xbfb0c
movl 0x201c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x201c(%rsp)
jmp 0xbfa4e
movl 0x2018(%rsp), %eax
movq 0x2028(%rsp), %rcx
cmpl 0xf08(%rcx), %eax
jne 0xbfbd5
leaq 0x1810(%rsp), %rdi
movq 0x2028(%rsp), %rax
movq 0xf10(%rax), %rax
movslq 0x2018(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
leaq 0x134770(%rip), %rsi    # 0x1f42d8
movb $0x1, %al
callq 0x5b9c0
leaq 0x1010(%rsp), %rdi
leaq 0x1810(%rsp), %rcx
leaq 0x1124fc(%rip), %rsi    # 0x1d2082
leaq 0x13478e(%rip), %rdx    # 0x1f431b
movb $0x0, %al
callq 0x5b9c0
movq 0x2028(%rsp), %rdi
addq $0x1064, %rdi           # imm = 0x1064
leaq 0x1010(%rsp), %r8
leaq 0x112482(%rip), %rsi    # 0x1d2034
leaq 0x134783(%rip), %rdx    # 0x1f433c
movl $0xc0c, %ecx            # imm = 0xC0C
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x2044(%rsp)
jmp 0xbfdfd
cmpl $0x0, 0x2018(%rsp)
jne 0xbfbff
movq 0x2020(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x70(%rax)
movl $0x0, 0x2044(%rsp)
jmp 0xbfdfd
cmpl $0x3, 0x2018(%rsp)
jge 0xbfc14
movl $0x3, 0x2018(%rsp)
movq 0x2028(%rsp), %rax
movq 0xf18(%rax), %rdi
movl 0x2018(%rsp), %esi
movq 0x2028(%rsp), %rax
movq 0xf20(%rax), %rdx
movq 0x2028(%rsp), %rax
movl 0xf04(%rax), %ecx
movq 0x2028(%rsp), %rax
movl 0xe80(%rax), %r8d
movq 0x2028(%rsp), %rax
movl 0xe8c(%rax), %r9d
movq 0x2028(%rsp), %rax
addq $0x1064, %rax           # imm = 0x1064
movl $0x1, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x1c1c0
cmpl $0x1, %eax
jne 0xbfcf6
leaq 0x810(%rsp), %rdi
movq 0x2028(%rsp), %rcx
addq $0x1064, %rcx           # imm = 0x1064
leaq 0x112731(%rip), %rsi    # 0x1d23d8
leaq 0x1346b2(%rip), %rdx    # 0x1f4360
movb $0x0, %al
callq 0x5b9c0
movq 0x2028(%rsp), %rdi
addq $0x1064, %rdi           # imm = 0x1064
leaq 0x810(%rsp), %r8
leaq 0x112361(%rip), %rsi    # 0x1d2034
leaq 0x134662(%rip), %rdx    # 0x1f433c
movl $0xc28, %ecx            # imm = 0xC28
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x2044(%rsp)
jmp 0xbfdfd
movq 0x2028(%rsp), %rax
movq 0xf18(%rax), %rdi
movl 0x2018(%rsp), %esi
movq 0x2028(%rsp), %rax
movq 0xf20(%rax), %rdx
movq 0x2028(%rsp), %rax
movl 0xf04(%rax), %ecx
movq 0x2028(%rsp), %rax
movl 0xe80(%rax), %r8d
movq 0x2028(%rsp), %rax
movl 0xe8c(%rax), %r9d
movq 0x2020(%rsp), %r10
addq $0x70, %r10
movq 0x2028(%rsp), %rax
addq $0x1064, %rax           # imm = 0x1064
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x22d70
cmpl $0x1, %eax
jne 0xbfdd8
leaq 0x10(%rsp), %rdi
movq 0x2028(%rsp), %rcx
addq $0x1064, %rcx           # imm = 0x1064
leaq 0x112649(%rip), %rsi    # 0x1d23d8
leaq 0x13467a(%rip), %rdx    # 0x1f4410
movb $0x0, %al
callq 0x5b9c0
movq 0x2028(%rsp), %rdi
addq $0x1064, %rdi           # imm = 0x1064
leaq 0x10(%rsp), %r8
leaq 0x11227c(%rip), %rsi    # 0x1d2034
leaq 0x13457d(%rip), %rdx    # 0x1f433c
movl $0xc34, %ecx            # imm = 0xC34
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x2044(%rsp)
jmp 0xbfdfd
movq 0x2020(%rsp), %rax
movsd 0x1129e8(%rip), %xmm0   # 0x1d27d0
mulsd 0x70(%rax), %xmm0
movsd %xmm0, 0x70(%rax)
movl $0x0, 0x2044(%rsp)
movl 0x2044(%rsp), %eax
addq $0x2048, %rsp           # imm = 0x2048
retq
nopl (%rax)