// File: /workspace/github_c_makefile_star2_O1/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:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x1008, %rsp           # imm = 0x1008
movq %rcx, %r14
movq %rdx, %rbx
movl 0xf08(%rdx), %eax
xorl %ecx, %ecx
cmpl $0x2, %eax
jl 0x703e7
leal -0x1(%rax), %edx
movslq 0xf04(%rbx), %rsi
movslq 0xe7c(%rbx), %rdi
shlq $0x3, %rdi
addq 0xf20(%rbx), %rdi
shlq $0x3, %rsi
xorl %r8d, %r8d
movsd 0xa02ca(%rip), %xmm0    # 0x110690
xorl %ecx, %ecx
movsd (%rdi), %xmm1
ucomisd %xmm1, %xmm0
cmoval %r8d, %ecx
minsd %xmm0, %xmm1
incq %r8
addq %rsi, %rdi
movapd %xmm1, %xmm0
cmpq %r8, %rdx
jne 0x703c8
cmpl %eax, %ecx
jne 0x70456
movq 0xf10(%rbx), %rax
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
leaq 0xa2f8e(%rip), %rsi     # 0x11338f
movq %rsp, %r14
movq %r14, %rdi
movb $0x1, %al
callq 0x30c2c
leaq 0x80c6d(%rip), %rsi     # 0xf1082
leaq 0xa2fb6(%rip), %rdx     # 0x1133d2
leaq 0x800(%rsp), %r15
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %rbx           # imm = 0x1064
leaq 0x80bf5(%rip), %rsi     # 0xf1034
leaq 0xa2fad(%rip), %rdx     # 0x1133f3
movq %rbx, %rdi
movl $0xc0c, %ecx            # imm = 0xC0C
movq %r15, %r8
jmp 0x70556
testl %ecx, %ecx
je 0x704d8
cmpl $0x4, %ecx
movl $0x3, %ebp
cmovgel %ecx, %ebp
movq 0xf18(%rbx), %rdi
movq 0xf20(%rbx), %rdx
movl 0xf04(%rbx), %ecx
movl 0xe80(%rbx), %r8d
movl 0xe8c(%rbx), %r9d
leaq 0x1064(%rbx), %r15
movl %ebp, %esi
pushq %r15
pushq $0x1
callq 0x13c30
addq $0x10, %rsp
cmpl $0x1, %eax
jne 0x704e5
leaq 0x80f47(%rip), %rsi     # 0xf13f0
leaq 0xa2f67(%rip), %rdx     # 0x113417
movq %rsp, %rbx
movq %rbx, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x30c2c
leaq 0x80b6d(%rip), %rsi     # 0xf1034
leaq 0xa2f25(%rip), %rdx     # 0x1133f3
movq %r15, %rdi
movl $0xc28, %ecx            # imm = 0xC28
jmp 0x70553
movq $0x0, 0x70(%r14)
jmp 0x70576
movq 0xf18(%rbx), %rdi
movq 0xf20(%rbx), %rdx
movl 0xf04(%rbx), %ecx
movl 0xe80(%rbx), %r8d
movl 0xe8c(%rbx), %r9d
addq $0x70, %r14
movl %ebp, %esi
pushq %r15
pushq %r14
callq 0x17499
addq $0x10, %rsp
cmpl $0x1, %eax
jne 0x70564
leaq 0x80eca(%rip), %rsi     # 0xf13f0
leaq 0xa2f9a(%rip), %rdx     # 0x1134c7
movq %rsp, %rbx
movq %rbx, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x30c2c
leaq 0x80af0(%rip), %rsi     # 0xf1034
leaq 0xa2ea8(%rip), %rdx     # 0x1133f3
movq %r15, %rdi
movl $0xc34, %ecx            # imm = 0xC34
movq %rbx, %r8
xorl %eax, %eax
callq 0x30c2c
movl $0x1, %eax
jmp 0x70578
movsd (%r14), %xmm0
xorpd 0x80cbf(%rip), %xmm0    # 0xf1230
movlpd %xmm0, (%r14)
xorl %eax, %eax
addq $0x1008, %rsp           # imm = 0x1008
popq %rbx
popq %r14
popq %r15
popq %rbp
retq