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

  /* These wil affect when and how the temperature integration starts*/
  double z_initial;
  int Nz_log;
  /* This describes until when (if at all) any idm might be coupled to either photon or IDR temp*/
  double z_idm_dec, z_idm_dec_min=_HUGE_;

  double R_dm;
  double f1nu = 7./8.*pow((4./11.),(4./3.));

  z_initial = ppr->thermo_z_initial;
  Nz_log = ppr->thermo_Nz_log;

  /* Set this initially to False and check if it's needed */
  ptw->has_ap_idmtca = _FALSE_;

  /* If there is idm, we want the thermodynamics table to
   * start at a much larger z, in order to capture the possible
   * non-trivial behavior of the dark matter interaction rate at early times */

  /* First, calculate the approximate decoupling time iff there is coupling, based on formulae from 2010.04074 */
  if (pba->has_idm == _TRUE_) {
    if ((pth->has_idm_g == _TRUE_) && (pth->n_index_idm_g > -2)) {
      z_idm_dec = pow(3.01e9, 1./(2+pth->n_index_idm_g)) * pow((1.+pba->Neff*f1nu)/(1.+3.044*f1nu), 1./(4.+2.*pth->n_index_idm_g)) * pow(pth->u_idm_g*1e4, -1./(2.+pth->n_index_idm_g));
      if (pth->thermodynamics_verbose > 3)
        printf("The decoupling redshift for idm_g is z_idm_dec = %.5e\n", z_idm_dec);
      z_idm_dec_min = MIN(z_idm_dec, z_idm_dec_min);
    }
    if ((pth->has_idm_b == _TRUE_) && (pth->n_index_idm_b > -3)) {
      R_dm = pth->m_idm / (_m_p_*_c_*_c_/_eV_);
      z_idm_dec = 4e4 * pow(  9.15/pth->n_coeff_idm_b
                              *pow((1.+pba->Neff*f1nu)/(1.+3.044*f1nu), 1./2.) * (0.0224/pba->Omega0_b/pba->h/pba->h)
                              *pow(R_dm, (pth->n_index_idm_b+1.)/2.)/pow(1.+R_dm, (pth->n_index_idm_b-1.)/2.)
                              *pow(10.,4*pth->n_index_idm_b - 25)/pth->cross_idm_b        ,  2./(pth->n_index_idm_b+3));

      if (pth->n_index_idm_b == -2)
        z_idm_dec *= 10;
      if (pth->thermodynamics_verbose > 3)
        printf("The decoupling redshift for idm_b is z_idm_dec = %.5e\n", z_idm_dec);
      z_idm_dec_min = MIN(z_idm_dec, z_idm_dec_min);
    }
    if ((pth->has_idm_dr == _TRUE_) && (pth->n_index_idm_dr > 0)) {
      z_idm_dec = pow(10., 7.-6./ pth->n_index_idm_dr)
        * pow( 1.6 * (1e-6/pba->Omega0_idr/pba->h/pba->h)
               * pow((1.+pba->Neff*f1nu)/(1.+3.044*f1nu), 1./2.)
               * (1e6 / pth->a_idm_dr)  ,  1./pth->n_index_idm_dr);
      if (pth->thermodynamics_verbose > 3)
        printf("The decoupling redshift for idm_dr is z_idm_dec = %.5e\n", z_idm_dec);
      /* we need to be careful if idm is coupled to photons and idr at the same time */
      class_test(z_idm_dec_min != _HUGE_ && fabs(pba->T_idr - pba->T_cmb) > 1e-2,
                 pth->error_message,
                 "It seems that at early times idm is thermally coupled to both idr and photons (possibly through baryons).\nPlease set the initial temperatures equal or disable this error.");

      z_idm_dec_min = MIN(z_idm_dec, z_idm_dec_min);
    }

    /* if there is initial coupling then we need the approximation scheme ap_idmtca */
    if (z_idm_dec_min != _HUGE_) {
      ptw->has_ap_idmtca = _TRUE_;
      /* assert that ap_idmtca ends before ap_brec ends */
      ptw->z_ap_idmtca = MAX( 1e2 * z_idm_dec_min, (ppr->recfast_z_He_1+ppr->recfast_delta_z_He_1)*1.5);
      if (pth->thermodynamics_verbose > 3)
        printf("Starting the idm TCA at z_ap_idmtca = %.5e\n", ptw->z_ap_idmtca);
    }

    /* From this, decide the initial time of integration */
    /* start the integration before the decoupling */
    if (ptw->has_ap_idmtca == _TRUE_) {
      class_test(ptw->z_ap_idmtca * ppr->a_ini_over_a_today_default > 1,
                 pth->error_message,
                 "The decoupling time of the idm species is set earlier than the background integration. Start the background integration earlier.");

      z_initial = MAX(z_initial, MIN(100 * ptw->z_ap_idmtca, 1/ppr->a_ini_over_a_today_default-2.));
    }

    /* if there is no coupling at early time, we need to set an another starting point */
    else {
      z_initial = MAX(ppr->thermo_z_initial_if_idm, z_initial);
    }

    if (pth->thermodynamics_verbose > 2)
      printf(" -> Increasing the initial redshift of thermodynamics from %e to %e \n",ppr->thermo_z_initial,z_initial);

    /* Rescale Nz_log (if necessary) in order to cover with equal spacing the enlarged range */
    Nz_log = MAX((int)(Nz_log/log(ppr->thermo_z_initial)*log(z_initial)),Nz_log);
  }

  ppr->thermo_z_initial = z_initial;
  ppr->thermo_Nz_log = Nz_log;
  class_test(z_initial * ppr->a_ini_over_a_today_default > 1.,
             pth->error_message,
             "The initial starting time for the temperature integration is set earlier than the background integration. Adjust obtain_z_ini to mitigate this");
  class_test(z_initial <  ppr->recfast_z_He_3,
             pth->error_message,
             "The initial starting time for the temperature integration is set after HeliumIII recombination starts. Adjust obtain_z_ini to mitigate this");

  return _SUCCESS_;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x1020, %rsp           # imm = 0x1020
movq %rdx, %rbx
movq %rdi, %r14
movsd 0x190(%rdi), %xmm1
movl 0x1ac(%rdi), %ebp
movw $0x0, 0x60(%rcx)
cmpw $0x1, 0x4b6(%rsi)
jne 0x68a06
movq %rcx, %r15
movq %rsi, %r12
movsd 0xa52a1(%rip), %xmm3    # 0x10d6b0
cmpw $0x1, 0x36(%rbx)
movsd %xmm1, 0x10(%rsp)
jne 0x68519
movl 0x1058(%rbx), %eax
cmpl $-0x1, %eax
jl 0x68519
addl $0x2, %eax
cvtsi2sd %eax, %xmm0
movsd 0x85e22(%rip), %xmm1    # 0xee260
divsd %xmm0, %xmm1
movsd 0xa526e(%rip), %xmm0    # 0x10d6b8
callq 0x8620
movsd %xmm0, (%rsp)
movsd 0x328(%r12), %xmm0
mulsd 0xa2652(%rip), %xmm0    # 0x10aab8
movsd 0x85df2(%rip), %xmm2    # 0xee260
addsd %xmm2, %xmm0
divsd 0xa5246(%rip), %xmm0    # 0x10d6c0
xorps %xmm1, %xmm1
cvtsi2sdl 0x1058(%rbx), %xmm1
addsd %xmm1, %xmm1
addsd 0x88fa7(%rip), %xmm1    # 0xf1438
divsd %xmm1, %xmm2
movapd %xmm2, %xmm1
callq 0x8620
mulsd (%rsp), %xmm0
movsd %xmm0, (%rsp)
movsd 0x1050(%rbx), %xmm0
mulsd 0xa5210(%rip), %xmm0    # 0x10d6c8
xorps %xmm2, %xmm2
cvtsi2sdl 0x1058(%rbx), %xmm2
addsd 0x86835(%rip), %xmm2    # 0xeed00
movsd 0x86315(%rip), %xmm1    # 0xee7e8
divsd %xmm2, %xmm1
callq 0x8620
movapd %xmm0, %xmm3
mulsd (%rsp), %xmm3
cmpw $0x4, 0x1060(%rbx)
jl 0x6850b
leaq 0xa9986(%rip), %rdi     # 0x111e7c
movapd %xmm3, %xmm0
movb $0x1, %al
movsd %xmm3, (%rsp)
callq 0x8030
movsd (%rsp), %xmm3
minsd 0xa519d(%rip), %xmm3    # 0x10d6b0
movsd 0x10(%rsp), %xmm1
cmpw $0x1, 0x34(%rbx)
jne 0x686d8
cmpl $-0x2, 0x1038(%rbx)
jl 0x686d8
movsd %xmm3, (%rsp)
movsd 0x1010(%rbx), %xmm0
divsd 0xa512a(%rip), %xmm0    # 0x10d670
movsd %xmm0, 0x18(%rsp)
movsd 0xa517c(%rip), %xmm0    # 0x10d6d0
divsd 0x1040(%rbx), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x328(%r12), %xmm0
mulsd 0xa2544(%rip), %xmm0    # 0x10aab8
addsd 0x85ce4(%rip), %xmm0    # 0xee260
divsd 0xa513c(%rip), %xmm0    # 0x10d6c0
movsd 0x86744(%rip), %xmm1    # 0xeecd0
callq 0x8620
mulsd 0x8(%rsp), %xmm0
movsd 0xa5139(%rip), %xmm2    # 0x10d6d8
divsd 0x20(%r12), %xmm2
movsd 0x8(%r12), %xmm1
divsd %xmm1, %xmm2
divsd %xmm1, %xmm2
mulsd %xmm2, %xmm0
movsd %xmm0, 0x8(%rsp)
xorps %xmm1, %xmm1
cvtsi2sdl 0x1038(%rbx), %xmm1
addsd 0x85c8e(%rip), %xmm1    # 0xee260
mulsd 0x866f6(%rip), %xmm1    # 0xeecd0
movsd 0x18(%rsp), %xmm0
callq 0x8620
mulsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rsp)
xorps %xmm1, %xmm1
cvtsi2sdl 0x1038(%rbx), %xmm1
movsd 0x18(%rsp), %xmm0
addsd 0x85c56(%rip), %xmm0    # 0xee260
addsd 0x861d6(%rip), %xmm1    # 0xee7e8
mulsd 0x866b6(%rip), %xmm1    # 0xeecd0
callq 0x8620
movsd 0x8(%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movl 0x1038(%rbx), %eax
leal -0x19(,%rax,4), %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
movsd 0x861a5(%rip), %xmm0    # 0xee7f0
callq 0x8620
mulsd 0x8(%rsp), %xmm0
divsd 0x1030(%rbx), %xmm0
movl 0x1038(%rbx), %eax
addl $0x3, %eax
xorps %xmm2, %xmm2
cvtsi2sd %eax, %xmm2
movsd 0x8668a(%rip), %xmm1    # 0xeed00
divsd %xmm2, %xmm1
callq 0x8620
movapd %xmm0, %xmm3
mulsd 0xa5055(%rip), %xmm3    # 0x10d6e0
cmpl $-0x2, 0x1038(%rbx)
jne 0x6869c
mulsd 0x86154(%rip), %xmm3    # 0xee7f0
movsd (%rsp), %xmm0
cmpw $0x4, 0x1060(%rbx)
jl 0x686ce
leaq 0xa9801(%rip), %rdi     # 0x111eb3
movapd %xmm3, %xmm0
movb $0x1, %al
movsd %xmm3, 0x8(%rsp)
callq 0x8030
movsd 0x8(%rsp), %xmm3
movsd (%rsp), %xmm0
minsd %xmm0, %xmm3
movsd 0x10(%rsp), %xmm1
cmpw $0x1, 0x38(%rbx)
jne 0x6887d
movsd 0x1028(%rbx), %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
jbe 0x6887d
movsd %xmm3, (%rsp)
movsd 0x86f62(%rip), %xmm1    # 0xef668
divsd %xmm0, %xmm1
addsd 0x87056(%rip), %xmm1    # 0xef768
movsd 0x860d6(%rip), %xmm0    # 0xee7f0
callq 0x8620
movsd 0x865c9(%rip), %xmm2    # 0xeecf0
divsd 0xf8(%r12), %xmm2
movsd 0x8(%r12), %xmm1
divsd %xmm1, %xmm2
divsd %xmm1, %xmm2
mulsd 0x8a440(%rip), %xmm2    # 0xf2b88
movsd %xmm2, 0x18(%rsp)
movsd %xmm0, 0x8(%rsp)
movsd 0x328(%r12), %xmm0
mulsd 0xa2352(%rip), %xmm0    # 0x10aab8
addsd 0x85af2(%rip), %xmm0    # 0xee260
divsd 0xa4f4a(%rip), %xmm0    # 0x10d6c0
movsd 0x86552(%rip), %xmm1    # 0xeecd0
callq 0x8620
movsd 0x8a3c5(%rip), %xmm1    # 0xf2b50
divsd 0x1018(%rbx), %xmm1
mulsd 0x18(%rsp), %xmm0
mulsd %xmm1, %xmm0
movsd 0x85abb(%rip), %xmm1    # 0xee260
divsd 0x1028(%rbx), %xmm1
callq 0x8620
movapd %xmm0, %xmm3
mulsd 0x8(%rsp), %xmm3
cmpw $0x4, 0x1060(%rbx)
jl 0x687e4
leaq 0xa971d(%rip), %rdi     # 0x111eea
movapd %xmm3, %xmm0
movb $0x1, %al
movsd %xmm3, 0x8(%rsp)
callq 0x8030
movsd 0x8(%rsp), %xmm3
movsd (%rsp), %xmm2
ucomisd 0xa4ebf(%rip), %xmm2    # 0x10d6b0
movsd 0x10(%rsp), %xmm1
jne 0x687fb
jnp 0x68879
movsd 0x100(%r12), %xmm0
subsd 0x18(%r12), %xmm0
andpd 0x85a2c(%rip), %xmm0    # 0xee240
ucomisd 0x887a4(%rip), %xmm0    # 0xf0fc0
jbe 0x68879
leaq 0xa96fd(%rip), %rsi     # 0x111f22
leaq 0x820(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x30af0
leaq 0x85844(%rip), %rsi     # 0xee082
leaq 0xa9788(%rip), %rdx     # 0x111fcd
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %rbx           # imm = 0x1064
leaq 0x857cf(%rip), %rsi     # 0xee034
leaq 0xa97a1(%rip), %rdx     # 0x11200d
movq %rbx, %rdi
movl $0x1232, %ecx           # imm = 0x1232
jmp 0x68ae8
minsd %xmm2, %xmm3
ucomisd 0xa4e2b(%rip), %xmm3    # 0x10d6b0
jne 0x68889
jnp 0x688da
movw $0x1, 0x60(%r15)
mulsd 0x86488(%rip), %xmm3    # 0xeed20
movsd 0x258(%r14), %xmm0
addsd 0x260(%r14), %xmm0
mulsd 0x88716(%rip), %xmm0    # 0xf0fc8
maxsd %xmm3, %xmm0
movsd %xmm0, 0x68(%r15)
cmpw $0x4, 0x1060(%rbx)
jl 0x688da
leaq 0xa975c(%rip), %rdi     # 0x112029
movb $0x1, %al
callq 0x8030
movsd 0x10(%rsp), %xmm1
cmpw $0x1, 0x60(%r15)
jne 0x6895e
movsd 0x68(%r15), %xmm0
movsd (%r14), %xmm3
movapd %xmm0, %xmm2
mulsd %xmm3, %xmm2
ucomisd 0x85963(%rip), %xmm2    # 0xee260
jbe 0x68b07
leaq 0xa974b(%rip), %rsi     # 0x112055
leaq 0x820(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x30af0
leaq 0x8575f(%rip), %rsi     # 0xee082
leaq 0xa97ac(%rip), %rdx     # 0x1120d6
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %rbx           # imm = 0x1064
leaq 0x856ea(%rip), %rsi     # 0xee034
leaq 0xa96bc(%rip), %rdx     # 0x11200d
movq %rbx, %rdi
movl $0x1245, %ecx           # imm = 0x1245
jmp 0x68ae8
maxsd 0x198(%r14), %xmm1
cmpw $0x3, 0x1060(%rbx)
movsd 0x190(%r14), %xmm0
movsd %xmm1, 0x10(%rsp)
jl 0x68997
leaq 0xa9786(%rip), %rdi     # 0x11210d
movb $0x2, %al
callq 0x8030
movsd 0x190(%r14), %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %ebp, %xmm1
movsd %xmm1, (%rsp)
callq 0x82c0
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x8(%rsp)
movsd 0x10(%rsp), %xmm0
callq 0x82c0
mulsd 0x8(%rsp), %xmm0
cvttsd2si %xmm0, %eax
cmpl %eax, %ebp
jg 0x68a00
movsd 0x190(%r14), %xmm0
callq 0x82c0
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, (%rsp)
movsd 0x10(%rsp), %xmm0
callq 0x82c0
mulsd (%rsp), %xmm0
cvttsd2si %xmm0, %ebp
movsd 0x10(%rsp), %xmm1
movsd %xmm1, 0x190(%r14)
movl %ebp, 0x1ac(%r14)
movsd (%r14), %xmm0
mulsd %xmm1, %xmm0
ucomisd 0x85839(%rip), %xmm0    # 0xee260
jbe 0x68a81
leaq 0xa9723(%rip), %rsi     # 0x112153
leaq 0x820(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x30af0
leaq 0x85639(%rip), %rsi     # 0xee082
leaq 0xa9792(%rip), %rdx     # 0x1121e2
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %rbx           # imm = 0x1064
leaq 0x855c4(%rip), %rsi     # 0xee034
leaq 0xa9596(%rip), %rdx     # 0x11200d
movq %rbx, %rdi
movl $0x125a, %ecx           # imm = 0x125A
jmp 0x68ae8
movsd 0x278(%r14), %xmm0
xorl %eax, %eax
ucomisd %xmm1, %xmm0
jbe 0x68af7
leaq 0xa977a(%rip), %rsi     # 0x112213
leaq 0x820(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x30af0
leaq 0x855d0(%rip), %rsi     # 0xee082
leaq 0xa5b69(%rip), %rdx     # 0x10e622
leaq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %rbx           # imm = 0x1064
leaq 0x8555b(%rip), %rsi     # 0xee034
leaq 0xa952d(%rip), %rdx     # 0x11200d
movq %rbx, %rdi
movl $0x125d, %ecx           # imm = 0x125D
movq %r15, %r8
xorl %eax, %eax
callq 0x30af0
movl $0x1, %eax
addq $0x1020, %rsp           # imm = 0x1020
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
mulsd 0x86211(%rip), %xmm0    # 0xeed20
movsd 0x85749(%rip), %xmm2    # 0xee260
divsd %xmm3, %xmm2
addsd 0x86c3d(%rip), %xmm2    # 0xef760
minsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jbe 0x68967
movapd %xmm0, %xmm1
jmp 0x68967