// File: /workspace/github_c_makefile_star2_O3/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
movslq 0xf08(%rdx), %rax
cmpq $0x2, %rax
jl 0x6d9e1
leal -0x1(%rax), %ecx
movslq 0xf04(%rbx), %rdx
movslq 0xe7c(%rbx), %rsi
shlq $0x3, %rsi
addq 0xf20(%rbx), %rsi
shlq $0x3, %rdx
xorl %r8d, %r8d
movsd 0x9fd85(%rip), %xmm0    # 0x10d6b0
xorl %edi, %edi
movsd (%rsi), %xmm1
ucomisd %xmm1, %xmm0
cmoval %r8d, %edi
minsd %xmm0, %xmm1
incq %r8
addq %rdx, %rsi
movapd %xmm1, %xmm0
cmpq %r8, %rcx
jne 0x6d92d
cmpl %eax, %edi
je 0x6d9f4
testl %edi, %edi
je 0x6d9e5
cmpl $0x4, %edi
movl $0x3, %ebp
cmovgel %edi, %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 0x13d65
addq $0x10, %rsp
cmpl $0x1, %eax
jne 0x6da59
leaq 0x80a41(%rip), %rsi     # 0xee3f0
leaq 0xa2ab1(%rip), %rdx     # 0x110467
movq %rsp, %rbx
movq %rbx, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x80667(%rip), %rsi     # 0xee034
leaq 0xa2a6f(%rip), %rdx     # 0x110443
movq %r15, %rdi
movl $0xc28, %ecx            # imm = 0xC28
jmp 0x6dac7
testl %eax, %eax
je 0x6d9f4
movq $0x0, 0x70(%r14)
xorl %eax, %eax
jmp 0x6dad6
movq 0xf10(%rbx), %rcx
movsd (%rcx,%rax,8), %xmm0
leaq 0xa29d8(%rip), %rsi     # 0x1103df
movq %rsp, %r14
movq %r14, %rdi
movb $0x1, %al
callq 0x30af0
leaq 0x80667(%rip), %rsi     # 0xee082
leaq 0xa2a00(%rip), %rdx     # 0x110422
leaq 0x800(%rsp), %r15
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %rbx           # imm = 0x1064
leaq 0x805ef(%rip), %rsi     # 0xee034
leaq 0xa29f7(%rip), %rdx     # 0x110443
movq %rbx, %rdi
movl $0xc0c, %ecx            # imm = 0xC0C
movq %r15, %r8
jmp 0x6daca
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 0x17628
addq $0x10, %rsp
cmpl $0x1, %eax
jne 0x6dae4
leaq 0x80956(%rip), %rsi     # 0xee3f0
leaq 0xa2a76(%rip), %rdx     # 0x110517
movq %rsp, %rbx
movq %rbx, %rdi
movq %r15, %rcx
xorl %eax, %eax
callq 0x30af0
leaq 0x8057c(%rip), %rsi     # 0xee034
leaq 0xa2984(%rip), %rdx     # 0x110443
movq %r15, %rdi
movl $0xc34, %ecx            # imm = 0xC34
movq %rbx, %r8
xorl %eax, %eax
callq 0x30af0
movl $0x1, %eax
addq $0x1008, %rsp           # imm = 0x1008
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movsd (%r14), %xmm0
xorpd 0x8073f(%rip), %xmm0    # 0xee230
movlpd %xmm0, (%r14)
jmp 0x6d9ed