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

  /** Summary: */

  /** Define local variables */
  int index_ap;
  /* for varying fundamental constants */
  double alpha = 1., me = 1.;

  /** - number of z values */
  ptw->Nz_reco_lin = ppr->thermo_Nz_lin;
  ptw->Nz_reco_log = ppr->thermo_Nz_log;
  ptw->Nz_reco = ptw->Nz_reco_lin + ptw->Nz_reco_log;
  ptw->Nz_reio = ppr->reionization_z_start_max / ppr->reionization_sampling;
  ptw->Nz_tot = ptw->Nz_reio + ptw->Nz_reco;

  /** - relevant cosmological parameters */

  /* primordial helium mass fraction */
  ptw->YHe = pth->YHe;
  /* primordial helium-to-hydrogen nucleon ratio */
  ptw->fHe = pth->fHe;
  /* Hubble parameter today in SI units */
  ptw->SIunit_H0 = pba->H0 * _c_ / _Mpc_over_m_;
  /* H number density today in SI units*/
  ptw->SIunit_nH0 = 3.*ptw->SIunit_H0*ptw->SIunit_H0*pba->Omega0_b/(8.*_PI_*_G_*_m_H_)*(1.-ptw->YHe);
  /* CMB temperature today in Kelvin */
  ptw->Tcmb = pba->T_cmb;

  /** - relevant constants */

  /* Prefactor in non-relativistic number density for temperature -- (2*pi*m_e) and unit conversion */
  ptw->const_NR_numberdens = 2.*_PI_*(_m_e_/_h_P_)*(_k_B_/_h_P_);
  /* Ionization energy for HI -- temperature equivalent in Kelvin */
  ptw->const_Tion_H = _h_P_*_c_*_L_H_ion_/_k_B_;
  /* Ionization energy for HeI -- temperature equivalent in Kelvin */
  ptw->const_Tion_HeI = _h_P_*_c_*_L_He1_ion_/_k_B_;
  /* Ionization energy for HeII -- temperature equivalent in Kelvin */
  ptw->const_Tion_HeII = _h_P_*_c_*_L_He2_ion_/_k_B_;

  /* the field reionization_optical_depth is computed and filled later */

  /** - Allocate and initialize differential equation workspace */
  class_alloc(ptw->ptdw,
              sizeof(struct thermo_diffeq_workspace),
              pth->error_message);

  // Initialize ionisation fraction.
  ptw->ptdw->x_reio = 1.+2.*ptw->fHe;
  ptw->ptdw->x_noreio = 1.+2.*ptw->fHe;

  /** - define approximations */
  index_ap=0;
  /* Approximations have to appear in chronological order here! */
  class_define_index(ptw->ptdw->index_ap_idmtca,ptw->has_ap_idmtca,index_ap,1); //DM tight coupling (assumed always before any recombination phases)
  class_define_index(ptw->ptdw->index_ap_brec,_TRUE_,index_ap,1); // before H- and He-recombination
  class_define_index(ptw->ptdw->index_ap_He1,_TRUE_,index_ap,1);  // during 1st He-recombination (HeIII)
  class_define_index(ptw->ptdw->index_ap_He1f,_TRUE_,index_ap,1); // in between 1st and 2nd He recombination
  class_define_index(ptw->ptdw->index_ap_He2,_TRUE_,index_ap,1);  // beginning of 2nd He-recombination (HeII)
  class_define_index(ptw->ptdw->index_ap_H,_TRUE_,index_ap,1);    // beginning of H-recombination (HI)
  class_define_index(ptw->ptdw->index_ap_frec,_TRUE_,index_ap,1); // during and after full H- and HeII-recombination
  class_define_index(ptw->ptdw->index_ap_reio,_TRUE_,index_ap,1); // during reionization
  ptw->ptdw->ap_size=index_ap;

  /* Set correct initial approximation scheme */
  ptw->ptdw->ap_current = ptw->ptdw->index_ap_brec;
  if (ptw->has_ap_idmtca == _TRUE_)
    ptw->ptdw->ap_current = ptw->ptdw->index_ap_idmtca;

  /** - store all ending redshifts for each approximation */
  class_alloc(ptw->ptdw->ap_z_limits,ptw->ptdw->ap_size*sizeof(double),pth->error_message);

  if (ptw->has_ap_idmtca == _TRUE_)
    ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_idmtca] = ptw->z_ap_idmtca;
  ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_brec] =
    ppr->recfast_z_He_1+ppr->recfast_delta_z_He_1; // beginning 1st He-recombination
  ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_He1] =
    ppr->recfast_z_He_2+ppr->recfast_delta_z_He_2; // end 1st He-recombination
  ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_He1f] =
    ppr->recfast_z_He_3+ppr->recfast_delta_z_He_3; // beginning 2nd He-recombination
  ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_He2] =
    ppr->recfast_z_early_H_recombination;          // beginning early H-recombination
  ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_H] =
    ppr->recfast_z_full_H_recombination;           // beginning full recombination equations
  ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_frec] =
    ppr->reionization_z_start_max;                 // beginning reionization
  ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_reio] = 0.0; // today

  /** - Rescale these redshifts in case of varying fundamental constants */
  if (pth->has_varconst == _TRUE_) {
    for (index_ap=0;index_ap<ptw->ptdw->ap_size;++index_ap){
      class_call(background_varconst_of_z(pba,ptw->ptdw->ap_z_limits[index_ap], &alpha, &me),
                 pba->error_message,
                 pth->error_message);
      ptw->ptdw->ap_z_limits[index_ap]*=me*alpha*alpha;
    }
  }

  /** - store smoothing deltas for transitions at the beginning of each aproximation */
  class_alloc(ptw->ptdw->ap_z_limits_delta,ptw->ptdw->ap_size*sizeof(double),pth->error_message);

  if (ptw->has_ap_idmtca == _TRUE_)
    ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_idmtca] = 0.;
  ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_brec] = 0.;
  ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_He1] = ppr->recfast_delta_z_He_1;
  ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_He1f] = ppr->recfast_delta_z_He_2;
  ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_He2] = ppr->recfast_delta_z_He_3;
  ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_H] = ppr->recfast_delta_z_early_H_recombination;
  ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_frec] = ppr->recfast_delta_z_full_H_recombination;
  ptw->ptdw->ap_z_limits_delta[ptw->ptdw->index_ap_reio] = ppr->recfast_delta_z_reio;

  /* With recombination computed by HyRec or Recfast, we need to allocate and initialize the wrappers */

  switch (pth->recombination) {

  case hyrec:
    class_alloc(ptw->ptdw->phyrec,
                sizeof(struct thermohyrec),
                pth->error_message);

    ptw->ptdw->phyrec->thermohyrec_verbose = pth->hyrec_verbose;
    class_call(thermodynamics_hyrec_init(ppr,pba,pth,ptw->SIunit_nH0,pba->T_cmb,ptw->fHe, ptw->ptdw->ap_z_limits[ptw->ptdw->index_ap_brec],ptw->ptdw->phyrec),
               ptw->ptdw->phyrec->error_message,
               pth->error_message);
    break;

  case recfast:
    class_alloc(ptw->ptdw->precfast,
                sizeof(struct thermorecfast),
                pth->error_message);

    class_call(recfast_init(ppr,pba,pth,ptw->ptdw->precfast,pth->recfast_photoion_mode,ptw->fHe),
               ptw->ptdw->precfast->error_message,
               pth->error_message);

    break;
  }

  /** - Allocate reionisation parameter workspace */
  class_alloc(ptw->ptrp,
              sizeof(struct thermo_reionization_parameters),
              pth->error_message);

  return _SUCCESS_;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x858, %rsp            # imm = 0x858
movq %rcx, %r14
movq %rdx, %r15
movq %rdi, %rbx
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0x40(%rsp)
movq %rax, 0x38(%rsp)
movl 0x1a8(%rdi), %eax
movl %eax, (%rcx)
movl 0x1ac(%rdi), %ecx
movl %ecx, 0x4(%r14)
addl %eax, %ecx
movl %ecx, 0x8(%r14)
movsd 0x3e8(%rdi), %xmm0
movsd %xmm0, 0x48(%rsp)
divsd 0x3f0(%rdi), %xmm0
cvttsd2si %xmm0, %eax
movl %eax, 0xc(%r14)
addl %eax, %ecx
movl %ecx, 0x10(%r14)
movsd (%rdx), %xmm0
movsd %xmm0, 0x18(%r14)
movsd 0x1000(%rdx), %xmm1
movsd %xmm1, 0x18(%rsp)
movsd %xmm1, 0x20(%r14)
movsd (%rsi), %xmm1
mulsd 0x8a022(%rip), %xmm1    # 0xf2bf0
divsd 0x89f12(%rip), %xmm1    # 0xf2ae8
movsd %xmm1, 0x28(%r14)
movsd 0x86a9c(%rip), %xmm2    # 0xef680
mulsd %xmm1, %xmm2
mulsd %xmm1, %xmm2
mulsd 0x20(%rsi), %xmm2
divsd 0xa4a9f(%rip), %xmm2    # 0x10d698
movsd 0x8565f(%rip), %xmm1    # 0xee260
subsd %xmm0, %xmm1
mulsd %xmm2, %xmm1
movsd %xmm1, 0x30(%r14)
movq %rsi, 0x10(%rsp)
movsd 0x18(%rsi), %xmm0
movsd %xmm0, 0x38(%r14)
movaps 0xa4b3a(%rip), %xmm0    # 0x10d760
movups %xmm0, 0x40(%r14)
movapd 0xa4b3d(%rip), %xmm0    # 0x10d770
movupd %xmm0, 0x50(%r14)
movl $0xd0, %edi
callq 0x8460
movq %rax, 0x80(%r14)
testq %rax, %rax
je 0x68fdd
movq %rax, %r13
movq %rbx, 0x30(%rsp)
movq %r15, 0x8(%rsp)
movsd 0x18(%rsp), %xmm0
addsd %xmm0, %xmm0
addsd 0x855ee(%rip), %xmm0    # 0xee260
movsd %xmm0, 0x18(%rax)
movsd %xmm0, 0x10(%rax)
movzwl 0x60(%r14), %edx
xorl %eax, %eax
movl $0x0, %r12d
testw %dx, %dx
je 0x68c9c
movl $0x0, 0x70(%r13)
movl $0x1, %r12d
movl %r12d, 0x74(%r13)
leal 0x1(%r12), %ecx
movl %ecx, 0x78(%r13)
leal 0x2(%r12), %ecx
movl %ecx, 0x20(%rsp)
movl %ecx, 0x7c(%r13)
leal 0x3(%r12), %ecx
movl %ecx, 0x24(%rsp)
movl %ecx, 0x80(%r13)
leal 0x4(%r12), %ecx
movl %ecx, 0x18(%rsp)
movl %ecx, 0x84(%r13)
leal 0x5(%r12), %ecx
movl %ecx, 0x2c(%rsp)
movl %ecx, 0x88(%r13)
leal 0x6(%r12), %ecx
movl %ecx, 0x28(%rsp)
movl %ecx, 0x8c(%r13)
leal 0x7(%r12), %ebx
movl %ebx, 0x94(%r13)
cmpw $0x1, %dx
cmovnel %r12d, %eax
movl %eax, 0x90(%r13)
leal 0x38(,%r12,8), %r15d
movq %r15, %rdi
movw %dx, 0x6(%rsp)
callq 0x8460
movq %rax, 0xa0(%r13)
testq %rax, %rax
je 0x69021
movq %rax, %rbp
cmpw $0x1, 0x6(%rsp)
jne 0x68d4c
movsd 0x68(%r14), %xmm0
movsd %xmm0, (%rbp)
movl %r12d, %eax
movq 0x30(%rsp), %r12
movsd 0x258(%r12), %xmm0
movhpd 0x270(%r12), %xmm0      # xmm0 = xmm0[0],mem[0]
movupd 0x260(%r12), %xmm1
addpd %xmm1, %xmm0
movupd %xmm0, (%rbp,%rax,8)
movsd 0x278(%r12), %xmm0
addsd 0x280(%r12), %xmm0
movl 0x20(%rsp), %eax
movsd %xmm0, (%rbp,%rax,8)
movsd 0x288(%r12), %xmm0
movl 0x24(%rsp), %eax
movsd %xmm0, (%rbp,%rax,8)
movsd 0x298(%r12), %xmm0
movl 0x18(%rsp), %eax
movsd %xmm0, (%rbp,%rax,8)
movl 0x2c(%rsp), %eax
movsd 0x48(%rsp), %xmm0
movsd %xmm0, (%rbp,%rax,8)
movl 0x28(%rsp), %eax
movq $0x0, (%rbp,%rax,8)
movq 0x8(%rsp), %r15
cmpw $0x1, 0xe78(%r15)
jne 0x68e62
xorl %r12d, %r12d
leaq 0x38(%rsp), %r15
movsd (%rbp,%r12,8), %xmm0
movq 0x10(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movq %r15, %rdx
callq 0x5e941
cmpl $0x1, %eax
je 0x690ac
movsd 0x40(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
movq 0x80(%r14), %r13
movq 0xa0(%r13), %rbp
mulsd (%rbp,%r12,8), %xmm1
movsd %xmm1, (%rbp,%r12,8)
incq %r12
movslq 0x94(%r13), %rbx
cmpq %rbx, %r12
jl 0x68df7
movq 0x8(%rsp), %r15
movq 0x30(%rsp), %r12
movslq %ebx, %rdi
shlq $0x3, %rdi
callq 0x8460
movq %rax, 0xa8(%r13)
testq %rax, %rax
je 0x69065
cmpw $0x1, 0x60(%r14)
jne 0x68e92
movslq 0x70(%r13), %rcx
movq $0x0, (%rax,%rcx,8)
movslq 0x74(%r13), %rbx
movq $0x0, (%rax,%rbx,8)
movsd 0x260(%r12), %xmm0
movslq 0x78(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x270(%r12), %xmm0
movslq 0x7c(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x280(%r12), %xmm0
movslq 0x80(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x290(%r12), %xmm0
movslq 0x84(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x2a0(%r12), %xmm0
movslq 0x88(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x2a8(%r12), %xmm0
movslq 0x8c(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x10(%r15), %eax
testl %eax, %eax
je 0x690f9
cmpl $0x1, %eax
jne 0x69187
movl $0x828, %edi            # imm = 0x828
callq 0x8460
movq %rax, 0xc0(%r13)
testq %rax, %rax
je 0x691ea
movswl 0x1062(%r15), %ecx
movl %ecx, 0x820(%rax)
movsd 0x20(%r14), %xmm2
movsd 0x30(%r14), %xmm0
movq 0x10(%rsp), %rsi
movsd 0x18(%rsi), %xmm1
movsd (%rbp,%rbx,8), %xmm3
movq %r12, %rdi
movq %r15, %rdx
movq %rax, %rcx
callq 0xdc454
cmpl $0x1, %eax
jne 0x69187
movq 0x80(%r14), %rax
movq 0xc0(%rax), %rcx
addq $0x20, %rcx
leaq 0x8544b(%rip), %rsi     # 0xee3f0
leaq 0xa5750(%rip), %rdx     # 0x10e6fc
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %r15           # imm = 0x1064
leaq 0x8506b(%rip), %rsi     # 0xee034
leaq 0xa567c(%rip), %rdx     # 0x10e64c
movq %r15, %rdi
movl $0x38c, %ecx            # imm = 0x38C
jmp 0x6926a
leaq 0x85020(%rip), %rsi     # 0xee004
leaq 0xa5657(%rip), %rdx     # 0x10e642
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl $0xd0, %ecx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %r15           # imm = 0x1064
leaq 0x85027(%rip), %rsi     # 0xee034
leaq 0xa5638(%rip), %rdx     # 0x10e64c
movq %r15, %rdi
movl $0x33e, %ecx            # imm = 0x33E
jmp 0x6926a
leaq 0x84fdc(%rip), %rsi     # 0xee004
leaq 0xa563b(%rip), %rdx     # 0x10e66a
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl %r15d, %ecx
xorl %eax, %eax
callq 0x30af0
movq 0x8(%rsp), %rdi
addq $0x1064, %rdi           # imm = 0x1064
leaq 0x84fe0(%rip), %rsi     # 0xee034
leaq 0xa55f1(%rip), %rdx     # 0x10e64c
movl $0x357, %ecx            # imm = 0x357
jmp 0x6926a
shll $0x3, %ebx
leaq 0x84f95(%rip), %rsi     # 0xee004
leaq 0xa5657(%rip), %rdx     # 0x10e6cd
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movl %ebx, %ecx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %r15           # imm = 0x1064
leaq 0x84f9f(%rip), %rsi     # 0xee034
leaq 0xa55b0(%rip), %rdx     # 0x10e64c
movq %r15, %rdi
movl $0x374, %ecx            # imm = 0x374
movq %r14, %r8
jmp 0x6926d
movq 0x10(%rsp), %rcx
addq $0xd1c, %rcx            # imm = 0xD1C
leaq 0x85331(%rip), %rsi     # 0xee3f0
leaq 0xa55bb(%rip), %rdx     # 0x10e681
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x30af0
movq 0x8(%rsp), %rdi
addq $0x1064, %rdi           # imm = 0x1064
leaq 0x84f4c(%rip), %rsi     # 0xee034
leaq 0xa555d(%rip), %rdx     # 0x10e64c
movl $0x36e, %ecx            # imm = 0x36E
jmp 0x6926a
movl $0x938, %edi            # imm = 0x938
callq 0x8460
movq %rax, 0xc8(%r13)
testq %rax, %rax
je 0x6922b
movl 0x14(%r15), %r8d
movsd 0x20(%r14), %xmm0
movq %r12, %rdi
movq 0x10(%rsp), %rsi
movq %r15, %rdx
movq %rax, %rcx
callq 0xcd9a8
cmpl $0x1, %eax
jne 0x69187
movq 0x80(%r14), %rax
movl $0x134, %ecx            # imm = 0x134
addq 0xc8(%rax), %rcx
leaq 0x852a1(%rip), %rsi     # 0xee3f0
leaq 0xa5649(%rip), %rdx     # 0x10e79f
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %r15           # imm = 0x1064
leaq 0x84ec1(%rip), %rsi     # 0xee034
leaq 0xa54d2(%rip), %rdx     # 0x10e64c
movq %r15, %rdi
movl $0x396, %ecx            # imm = 0x396
jmp 0x6926a
movl $0x48, %edi
callq 0x8460
movq %rax, %rcx
movq %rax, 0x88(%r14)
xorl %eax, %eax
testq %rcx, %rcx
jne 0x69279
leaq 0x84e57(%rip), %rsi     # 0xee004
leaq 0xa563d(%rip), %rdx     # 0x10e7f1
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl $0x48, %ecx
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %r15           # imm = 0x1064
leaq 0x84e5e(%rip), %rsi     # 0xee034
leaq 0xa546f(%rip), %rdx     # 0x10e64c
movq %r15, %rdi
movl $0x39e, %ecx            # imm = 0x39E
jmp 0x6926a
leaq 0x84e13(%rip), %rsi     # 0xee004
leaq 0xa54f2(%rip), %rdx     # 0x10e6ea
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl $0x828, %ecx            # imm = 0x828
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %r15           # imm = 0x1064
leaq 0x84e1a(%rip), %rsi     # 0xee034
leaq 0xa542b(%rip), %rdx     # 0x10e64c
movq %r15, %rdi
movl $0x387, %ecx            # imm = 0x387
jmp 0x6926a
leaq 0x84dd2(%rip), %rsi     # 0xee004
leaq 0xa5552(%rip), %rdx     # 0x10e78b
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl $0x938, %ecx            # imm = 0x938
xorl %eax, %eax
callq 0x30af0
addq $0x1064, %r15           # imm = 0x1064
leaq 0x84dd9(%rip), %rsi     # 0xee034
leaq 0xa53ea(%rip), %rdx     # 0x10e64c
movq %r15, %rdi
movl $0x392, %ecx            # imm = 0x392
movq %rbx, %r8
xorl %eax, %eax
callq 0x30af0
movl $0x1, %eax
addq $0x858, %rsp            # imm = 0x858
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq