// File: /workspace/github_c_makefile_star2_O2/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 %r12
pushq %rbx
subq $0x1000, %rsp           # imm = 0x1000
movq %rcx, %r15
movq %rdx, %r14
movslq 0xf08(%rdx), %rax
cmpl $0x2, %eax
pushq $0x1
popq %rbx
movl %ebx, %edx
cmovgel %eax, %edx
decl %edx
movsd 0x9b186(%rip), %xmm0    # 0x104570
xorl %esi, %esi
xorl %ecx, %ecx
cmpl %esi, %edx
je 0x6942a
movq 0xf20(%r14), %rdi
movslq 0xf04(%r14), %r8
movslq %esi, %r9
imulq %r8, %r9
movslq 0xe7c(%r14), %r8
addq %r9, %r8
movsd (%rdi,%r8,8), %xmm1
ucomisd %xmm1, %xmm0
cmoval %esi, %ecx
minsd %xmm0, %xmm1
incl %esi
movapd %xmm1, %xmm0
jmp 0x693ee
cmpl %eax, %ecx
jne 0x69496
movq 0xf10(%r14), %rcx
movsd (%rcx,%rax,8), %xmm0
leaq 0x9de3e(%rip), %rsi     # 0x10727f
movq %rsp, %r15
movq %r15, %rdi
movb $0x1, %al
callq 0x2e014
leaq 0x7bc2d(%rip), %rsi     # 0xe5082
leaq 0x9de66(%rip), %rdx     # 0x1072c2
leaq 0x800(%rsp), %r12
movq %r12, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r14           # imm = 0x1064
leaq 0x7bbb5(%rip), %rsi     # 0xe5034
leaq 0x9de5d(%rip), %rdx     # 0x1072e3
movq %r14, %rdi
movl $0xc0c, %ecx            # imm = 0xC0C
movq %r12, %r8
jmp 0x6958f
testl %ecx, %ecx
je 0x69515
cmpl $0x4, %ecx
pushq $0x3
popq %rbp
cmovgel %ecx, %ebp
movq 0xf18(%r14), %rdi
movq 0xf20(%r14), %rdx
movl 0xf04(%r14), %ecx
movl 0xe80(%r14), %r8d
movl 0xe8c(%r14), %r9d
leaq 0x1064(%r14), %r12
movl %ebp, %esi
pushq %r12
pushq $0x1
callq 0x12065
popq %rcx
popq %rdx
cmpl $0x1, %eax
jne 0x6951f
leaq 0x7bf0a(%rip), %rsi     # 0xe53f0
leaq 0x9de1a(%rip), %rdx     # 0x107307
movq %rsp, %r14
movq %r14, %rdi
movq %r12, %rcx
xorl %eax, %eax
callq 0x2e014
leaq 0x7bb30(%rip), %rsi     # 0xe5034
leaq 0x9ddd8(%rip), %rdx     # 0x1072e3
movq %r12, %rdi
movl $0xc28, %ecx            # imm = 0xC28
jmp 0x6958c
andq $0x0, 0x70(%r15)
jmp 0x695aa
movq 0xf18(%r14), %rdi
movq 0xf20(%r14), %rdx
movl 0xf04(%r14), %ecx
movl 0xe80(%r14), %r8d
movl 0xe8c(%r14), %r9d
addq $0x70, %r15
movl %ebp, %esi
pushq %r12
pushq %r15
callq 0x1567a
popq %rcx
popq %rdx
cmpl $0x1, %eax
jne 0x69598
leaq 0x7be91(%rip), %rsi     # 0xe53f0
leaq 0x9de51(%rip), %rdx     # 0x1073b7
movq %rsp, %r14
movq %r14, %rdi
movq %r12, %rcx
xorl %eax, %eax
callq 0x2e014
leaq 0x7bab7(%rip), %rsi     # 0xe5034
leaq 0x9dd5f(%rip), %rdx     # 0x1072e3
movq %r12, %rdi
movl $0xc34, %ecx            # imm = 0xC34
movq %r14, %r8
xorl %eax, %eax
callq 0x2e014
jmp 0x695ac
movsd (%r15), %xmm0
xorpd 0x7bc8b(%rip), %xmm0    # 0xe5230
movlpd %xmm0, (%r15)
xorl %ebx, %ebx
movl %ebx, %eax
addq $0x1000, %rsp           # imm = 0x1000
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq