// File: /workspace/github_c_makefile_star2_O1/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 $0x848, %rsp            # imm = 0x848
movq %rcx, %r14
movq %rdx, %rbx
movq %rdi, %r12
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, 0x30(%rsp)
movq %rax, 0x28(%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, 0x38(%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, 0x8(%rsp)
movsd %xmm1, 0x20(%r14)
movsd (%rsi), %xmm1
mulsd 0x8a6a9(%rip), %xmm1    # 0xf5bc0
divsd 0x8a599(%rip), %xmm1    # 0xf5ab8
movsd %xmm1, 0x28(%r14)
movsd 0x87153(%rip), %xmm2    # 0xf2680
mulsd %xmm1, %xmm2
mulsd %xmm1, %xmm2
mulsd 0x20(%rsi), %xmm2
divsd 0xa5136(%rip), %xmm2    # 0x110678
movsd 0x85d16(%rip), %xmm1    # 0xf1260
subsd %xmm0, %xmm1
mulsd %xmm2, %xmm1
movsd %xmm1, 0x30(%r14)
movq %rsi, (%rsp)
movsd 0x18(%rsi), %xmm0
movsd %xmm0, 0x38(%r14)
movaps 0xa51d2(%rip), %xmm0    # 0x110740
movups %xmm0, 0x40(%r14)
movapd 0xa51d5(%rip), %xmm0    # 0x110750
movupd %xmm0, 0x50(%r14)
movl $0xd0, %edi
callq 0x8460
movq %rax, 0x80(%r14)
testq %rax, %rax
je 0x6b5d5
movq %rax, %r13
movq %rbx, 0x20(%rsp)
movsd 0x8(%rsp), %xmm0
addsd %xmm0, %xmm0
addsd 0x85caf(%rip), %xmm0    # 0xf1260
movsd %xmm0, 0x18(%rax)
movsd %xmm0, 0x10(%rax)
movzwl 0x60(%r14), %r15d
testw %r15w, %r15w
je 0x6b619
movl $0x0, 0x70(%r13)
movl $0x1, %ebx
jmp 0x6b61b
leaq 0x85a28(%rip), %rsi     # 0xf1004
leaq 0xa600f(%rip), %rdx     # 0x1115f2
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl $0xd0, %ecx
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %rbx           # imm = 0x1064
leaq 0x85a2f(%rip), %rsi     # 0xf1034
leaq 0xa5ff0(%rip), %rdx     # 0x1115fc
movq %rbx, %rdi
movl $0x33e, %ecx            # imm = 0x33E
jmp 0x6bbac
xorl %ebx, %ebx
movl %ebx, 0x74(%r13)
leal 0x1(%rbx), %eax
movl %eax, 0x78(%r13)
leal 0x2(%rbx), %eax
movl %eax, 0x10(%rsp)
movl %eax, 0x7c(%r13)
leal 0x3(%rbx), %eax
movl %eax, 0x14(%rsp)
movl %eax, 0x80(%r13)
leal 0x4(%rbx), %eax
movl %eax, 0x8(%rsp)
movl %eax, 0x84(%r13)
leal 0x5(%rbx), %eax
movl %eax, 0x1c(%rsp)
movl %eax, 0x88(%r13)
leal 0x6(%rbx), %eax
movl %eax, 0x18(%rsp)
movl %eax, 0x8c(%r13)
leal 0x7(%rbx), %ebp
movl %ebp, 0x94(%r13)
movl %ebx, 0x90(%r13)
cmpw $0x1, %r15w
jne 0x6b68c
movl 0x70(%r13), %eax
movl %eax, 0x90(%r13)
shll $0x3, %ebp
movq %rbp, %rdi
callq 0x8460
movq %rax, 0xa0(%r13)
testq %rax, %rax
je 0x6b969
cmpw $0x1, %r15w
jne 0x6b6bd
movsd 0x68(%r14), %xmm0
movslq 0x70(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl %ebx, %ecx
movsd 0x258(%r12), %xmm0
movhpd 0x270(%r12), %xmm0      # xmm0 = xmm0[0],mem[0]
movupd 0x260(%r12), %xmm1
addpd %xmm1, %xmm0
movupd %xmm0, (%rax,%rcx,8)
movsd 0x278(%r12), %xmm0
addsd 0x280(%r12), %xmm0
movl 0x10(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x288(%r12), %xmm0
movl 0x14(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x298(%r12), %xmm0
movl 0x8(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movl 0x1c(%rsp), %ecx
movsd 0x38(%rsp), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0x18(%rsp), %ecx
movq $0x0, (%rax,%rcx,8)
movq 0x20(%rsp), %r15
cmpw $0x1, 0xe78(%r15)
jne 0x6b7da
movq 0x80(%r14), %rax
cmpl $0x0, 0x94(%rax)
jle 0x6b7da
xorl %ebx, %ebx
leaq 0x30(%rsp), %r13
leaq 0x28(%rsp), %rbp
movq 0xa0(%rax), %rax
movsd (%rax,%rbx,8), %xmm0
movq (%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x60fe9
cmpl $0x1, %eax
je 0x6bae2
movsd 0x30(%rsp), %xmm0
movsd 0x28(%rsp), %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
movq 0x80(%r14), %rax
movq 0xa0(%rax), %rax
mulsd (%rax,%rbx,8), %xmm1
movsd %xmm1, (%rax,%rbx,8)
incq %rbx
movq 0x80(%r14), %rax
movslq 0x94(%rax), %rcx
cmpq %rcx, %rbx
jl 0x6b774
movq 0x80(%r14), %rbp
movslq 0x94(%rbp), %r13
leaq (,%r13,8), %rdi
callq 0x8460
movq %rax, 0xa8(%rbp)
testq %rax, %rax
je 0x6b9ac
cmpw $0x1, 0x60(%r14)
jne 0x6b819
movslq 0x70(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movslq 0x74(%rbp), %rbx
movq $0x0, (%rax,%rbx,8)
movsd 0x260(%r12), %xmm0
movslq 0x78(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x270(%r12), %xmm0
movslq 0x7c(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x280(%r12), %xmm0
movslq 0x80(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x290(%r12), %xmm0
movslq 0x84(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x2a0(%r12), %xmm0
movslq 0x88(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x2a8(%r12), %xmm0
movslq 0x8c(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x10(%r15), %eax
testl %eax, %eax
je 0x6b9f2
cmpl $0x1, %eax
jne 0x6ba7f
movl $0x828, %edi            # imm = 0x828
callq 0x8460
movq %rax, 0xc0(%rbp)
testq %rax, %rax
je 0x6bb2c
movswl 0x1062(%r15), %ecx
movl %ecx, 0x820(%rax)
movsd 0x20(%r14), %xmm2
movsd 0x30(%r14), %xmm0
movq (%rsp), %rsi
movsd 0x18(%rsi), %xmm1
movq 0xa0(%rbp), %rcx
movsd (%rcx,%rbx,8), %xmm3
movq %r12, %rdi
movq %r15, %rdx
movq %rax, %rcx
callq 0xdf9a0
cmpl $0x1, %eax
jne 0x6ba7f
movq 0x80(%r14), %rax
movq 0xc0(%rax), %rcx
addq $0x20, %rcx
leaq 0x85abf(%rip), %rsi     # 0xf13f0
leaq 0xa5d74(%rip), %rdx     # 0x1116ac
leaq 0x40(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %r15           # imm = 0x1064
leaq 0x856df(%rip), %rsi     # 0xf1034
leaq 0xa5ca0(%rip), %rdx     # 0x1115fc
movq %r15, %rdi
movl $0x38c, %ecx            # imm = 0x38C
jmp 0x6bbac
leaq 0x85694(%rip), %rsi     # 0xf1004
leaq 0xa5ca3(%rip), %rdx     # 0x11161a
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl %ebp, %ecx
xorl %eax, %eax
callq 0x30c2c
movq 0x20(%rsp), %rdi
addq $0x1064, %rdi           # imm = 0x1064
leaq 0x85699(%rip), %rsi     # 0xf1034
leaq 0xa5c5a(%rip), %rdx     # 0x1115fc
movl $0x357, %ecx            # imm = 0x357
jmp 0x6bbac
shll $0x3, %r13d
leaq 0x8564d(%rip), %rsi     # 0xf1004
leaq 0xa5cbf(%rip), %rdx     # 0x11167d
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl %r13d, %ecx
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %r15           # imm = 0x1064
leaq 0x85656(%rip), %rsi     # 0xf1034
leaq 0xa5c17(%rip), %rdx     # 0x1115fc
movq %r15, %rdi
movl $0x374, %ecx            # imm = 0x374
jmp 0x6bbac
movl $0x938, %edi            # imm = 0x938
callq 0x8460
movq %rax, 0xc8(%rbp)
testq %rax, %rax
je 0x6bb6d
movl 0x14(%r15), %r8d
movsd 0x20(%r14), %xmm0
movq %r12, %rdi
movq (%rsp), %rsi
movq %r15, %rdx
movq %rax, %rcx
callq 0xd1244
cmpl $0x1, %eax
jne 0x6ba7f
movq 0x80(%r14), %rax
movl $0x134, %ecx            # imm = 0x134
addq 0xc8(%rax), %rcx
leaq 0x859a9(%rip), %rsi     # 0xf13f0
leaq 0xa5d01(%rip), %rdx     # 0x11174f
leaq 0x40(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %r15           # imm = 0x1064
leaq 0x855c9(%rip), %rsi     # 0xf1034
leaq 0xa5b8a(%rip), %rdx     # 0x1115fc
movq %r15, %rdi
movl $0x396, %ecx            # imm = 0x396
jmp 0x6bbac
movl $0x48, %edi
callq 0x8460
movq %rax, %rcx
movq %rax, 0x88(%r14)
xorl %eax, %eax
testq %rcx, %rcx
jne 0x6bbbb
leaq 0x8555f(%rip), %rsi     # 0xf1004
leaq 0xa5cf5(%rip), %rdx     # 0x1117a1
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl $0x48, %ecx
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %r15           # imm = 0x1064
leaq 0x85566(%rip), %rsi     # 0xf1034
leaq 0xa5b27(%rip), %rdx     # 0x1115fc
movq %r15, %rdi
movl $0x39e, %ecx            # imm = 0x39E
jmp 0x6bbac
movq (%rsp), %rcx
addq $0xd1c, %rcx            # imm = 0xD1C
leaq 0x858fc(%rip), %rsi     # 0xf13f0
leaq 0xa5b36(%rip), %rdx     # 0x111631
leaq 0x40(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %r15           # imm = 0x1064
leaq 0x8551c(%rip), %rsi     # 0xf1034
leaq 0xa5add(%rip), %rdx     # 0x1115fc
movq %r15, %rdi
movl $0x36e, %ecx            # imm = 0x36E
jmp 0x6bbac
leaq 0x854d1(%rip), %rsi     # 0xf1004
leaq 0xa5b60(%rip), %rdx     # 0x11169a
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl $0x828, %ecx            # imm = 0x828
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %r15           # imm = 0x1064
leaq 0x854d8(%rip), %rsi     # 0xf1034
leaq 0xa5a99(%rip), %rdx     # 0x1115fc
movq %r15, %rdi
movl $0x387, %ecx            # imm = 0x387
jmp 0x6bbac
leaq 0x85490(%rip), %rsi     # 0xf1004
leaq 0xa5bc0(%rip), %rdx     # 0x11173b
leaq 0x40(%rsp), %r14
movq %r14, %rdi
movl $0x938, %ecx            # imm = 0x938
xorl %eax, %eax
callq 0x30c2c
addq $0x1064, %r15           # imm = 0x1064
leaq 0x85497(%rip), %rsi     # 0xf1034
leaq 0xa5a58(%rip), %rdx     # 0x1115fc
movq %r15, %rdi
movl $0x392, %ecx            # imm = 0x392
movq %r14, %r8
xorl %eax, %eax
callq 0x30c2c
movl $0x1, %eax
addq $0x848, %rsp            # imm = 0x848
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq