// File: /workspace/github_c_makefile_star2_O2/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, 0x10(%rsp)
movsd %xmm1, 0x20(%r14)
movsd (%rsi), %xmm1
mulsd 0x85227(%rip), %xmm1    # 0xe9ab0
divsd 0x85117(%rip), %xmm1    # 0xe99a8
movsd %xmm1, 0x28(%r14)
movsd 0x81ea9(%rip), %xmm2    # 0xe6748
mulsd %xmm1, %xmm2
mulsd %xmm1, %xmm2
mulsd 0x20(%rsi), %xmm2
divsd 0x9fca4(%rip), %xmm2    # 0x104558
movsd 0x809a4(%rip), %xmm1    # 0xe5260
subsd %xmm0, %xmm1
mulsd %xmm2, %xmm1
movsd %xmm1, 0x30(%r14)
movq %rsi, 0x8(%rsp)
movsd 0x18(%rsi), %xmm0
movsd %xmm0, 0x38(%r14)
movaps 0x9fd3f(%rip), %xmm0    # 0x104620
movups %xmm0, 0x40(%r14)
movapd 0x9fd42(%rip), %xmm0    # 0x104630
movupd %xmm0, 0x50(%r14)
movl $0xd0, %edi
callq 0x8490
movq %rax, 0x80(%r14)
testq %rax, %rax
je 0x64af3
movq %rax, %r13
movq %rbx, 0x28(%rsp)
movq %r15, 0x30(%rsp)
movsd 0x10(%rsp), %xmm0
addsd %xmm0, %xmm0
addsd 0x80933(%rip), %xmm0    # 0xe5260
movsd %xmm0, 0x18(%rax)
movsd %xmm0, 0x10(%rax)
movzwl 0x60(%r14), %r12d
xorl %eax, %eax
movl $0x0, %r15d
testw %r12w, %r12w
je 0x64953
pushq $0x1
popq %r15
andl $0x0, 0x70(%r13)
movl %r15d, 0x74(%r13)
leal 0x1(%r15), %ecx
movl %ecx, 0x78(%r13)
leal 0x2(%r15), %ecx
movl %ecx, 0x18(%rsp)
movl %ecx, 0x7c(%r13)
leal 0x3(%r15), %ecx
movl %ecx, 0x1c(%rsp)
movl %ecx, 0x80(%r13)
leal 0x4(%r15), %ecx
movl %ecx, 0x10(%rsp)
movl %ecx, 0x84(%r13)
leal 0x5(%r15), %ecx
movl %ecx, 0x24(%rsp)
movl %ecx, 0x88(%r13)
leal 0x6(%r15), %ecx
movl %ecx, 0x20(%rsp)
movl %ecx, 0x8c(%r13)
leal 0x7(%r15), %ebp
movl %ebp, 0x94(%r13)
cmpw $0x1, %r12w
cmovnel %r15d, %eax
movl %eax, 0x90(%r13)
leal 0x38(,%r15,8), %ebx
movq %rbx, %rdi
callq 0x8490
movq %rax, 0xa0(%r13)
testq %rax, %rax
je 0x64b37
cmpw $0x1, %r12w
jne 0x649f3
movsd 0x68(%r14), %xmm0
movsd %xmm0, (%rax)
movl %r15d, %ecx
movq 0x28(%rsp), %rdx
movsd 0x258(%rdx), %xmm0
movhpd 0x270(%rdx), %xmm0      # xmm0 = xmm0[0],mem[0]
movupd 0x260(%rdx), %xmm1
addpd %xmm1, %xmm0
movupd %xmm0, (%rax,%rcx,8)
movsd 0x278(%rdx), %xmm0
addsd 0x280(%rdx), %xmm0
movl 0x18(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x288(%rdx), %xmm0
movl 0x1c(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x298(%rdx), %xmm0
movl 0x10(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movl 0x24(%rsp), %ecx
movsd 0x48(%rsp), %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0x20(%rsp), %ecx
andq $0x0, (%rax,%rcx,8)
movq 0x30(%rsp), %r12
cmpw $0x1, 0xe78(%r12)
jne 0x64b7d
xorl %r15d, %r15d
leaq 0x38(%rsp), %rbx
movslq %ebp, %rdi
cmpq %rdi, %r15
jge 0x64b7f
movsd (%rax,%r15,8), %xmm0
movq 0x8(%rsp), %rdi
leaq 0x40(%rsp), %rsi
movq %rbx, %rdx
callq 0x5a991
cmpl $0x1, %eax
je 0x64d3c
movsd 0x40(%rsp), %xmm0
movsd 0x38(%rsp), %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
movq 0x80(%r14), %r13
movq 0xa0(%r13), %rax
mulsd (%rax,%r15,8), %xmm1
movsd %xmm1, (%rax,%r15,8)
incq %r15
movl 0x94(%r13), %ebp
jmp 0x64a8c
leaq 0x8050a(%rip), %rsi     # 0xe5004
leaq 0xa09e1(%rip), %rdx     # 0x1054e2
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl $0xd0, %ecx
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r15           # imm = 0x1064
leaq 0x80511(%rip), %rsi     # 0xe5034
leaq 0xa09c2(%rip), %rdx     # 0x1054ec
movq %r15, %rdi
movl $0x33e, %ecx            # imm = 0x33E
jmp 0x64ef5
leaq 0x804c6(%rip), %rsi     # 0xe5004
leaq 0xa09c5(%rip), %rdx     # 0x10550a
leaq 0x50(%rsp), %r14
movq %r14, %rdi
movl %ebx, %ecx
xorl %eax, %eax
callq 0x2e014
movq 0x30(%rsp), %rdi
addq $0x1064, %rdi           # imm = 0x1064
leaq 0x804cb(%rip), %rsi     # 0xe5034
leaq 0xa097c(%rip), %rdx     # 0x1054ec
movl $0x357, %ecx            # imm = 0x357
movq %r14, %r8
jmp 0x64ef8
movl %ebp, %edi
shlq $0x3, %rdi
callq 0x8490
movq %rax, 0xa8(%r13)
testq %rax, %rax
je 0x64cf8
cmpw $0x1, 0x60(%r14)
jne 0x64ba9
movslq 0x70(%r13), %rcx
andq $0x0, (%rax,%rcx,8)
movslq 0x74(%r13), %rbx
andq $0x0, (%rax,%rbx,8)
movq 0x28(%rsp), %r15
movsd 0x260(%r15), %xmm0
movslq 0x78(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x270(%r15), %xmm0
movslq 0x7c(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x280(%r15), %xmm0
movslq 0x80(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x290(%r15), %xmm0
movslq 0x84(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x2a0(%r15), %xmm0
movslq 0x88(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movsd 0x2a8(%r15), %xmm0
movslq 0x8c(%r13), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x10(%r12), %eax
testl %eax, %eax
je 0x64d87
cmpl $0x1, %eax
jne 0x64e16
movl $0x828, %edi            # imm = 0x828
callq 0x8490
movq %rax, 0xc0(%r13)
testq %rax, %rax
je 0x64e75
movswl 0x1062(%r12), %ecx
movl %ecx, 0x820(%rax)
movsd 0x20(%r14), %xmm2
movsd 0x30(%r14), %xmm0
movq 0x8(%rsp), %rsi
movsd 0x18(%rsi), %xmm1
movq 0xa0(%r13), %rcx
movsd (%rcx,%rbx,8), %xmm3
movq %r15, %rdi
movq %r12, %rdx
movq %rax, %rcx
callq 0xd440c
cmpl $0x1, %eax
jne 0x64e16
movq 0x80(%r14), %rax
movq 0xc0(%rax), %rcx
addq $0x20, %rcx
leaq 0x80730(%rip), %rsi     # 0xe53f0
leaq 0xa08d5(%rip), %rdx     # 0x10559c
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r12           # imm = 0x1064
leaq 0x80350(%rip), %rsi     # 0xe5034
leaq 0xa0801(%rip), %rdx     # 0x1054ec
movq %r12, %rdi
movl $0x38c, %ecx            # imm = 0x38C
jmp 0x64ef5
shll $0x3, %ebp
leaq 0x80302(%rip), %rsi     # 0xe5004
leaq 0xa0864(%rip), %rdx     # 0x10556d
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl %ebp, %ecx
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r12           # imm = 0x1064
leaq 0x8030c(%rip), %rsi     # 0xe5034
leaq 0xa07bd(%rip), %rdx     # 0x1054ec
movq %r12, %rdi
movl $0x374, %ecx            # imm = 0x374
jmp 0x64ef5
movq 0x8(%rsp), %rcx
addq $0xd1c, %rcx            # imm = 0xD1C
leaq 0x806a1(%rip), %rsi     # 0xe53f0
leaq 0xa07cb(%rip), %rdx     # 0x105521
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r12           # imm = 0x1064
leaq 0x802c1(%rip), %rsi     # 0xe5034
leaq 0xa0772(%rip), %rdx     # 0x1054ec
movq %r12, %rdi
movl $0x36e, %ecx            # imm = 0x36E
jmp 0x64ef5
movl $0x938, %edi            # imm = 0x938
callq 0x8490
movq %rax, 0xc8(%r13)
testq %rax, %rax
je 0x64eb6
movl 0x14(%r12), %r8d
movsd 0x20(%r14), %xmm0
movq %r15, %rdi
movq 0x8(%rsp), %rsi
movq %r12, %rdx
movq %rax, %rcx
callq 0xc62b0
cmpl $0x1, %eax
jne 0x64e16
movq 0x80(%r14), %rax
movl $0x134, %ecx            # imm = 0x134
addq 0xc8(%rax), %rcx
leaq 0x80612(%rip), %rsi     # 0xe53f0
leaq 0xa085a(%rip), %rdx     # 0x10563f
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r12           # imm = 0x1064
leaq 0x80232(%rip), %rsi     # 0xe5034
leaq 0xa06e3(%rip), %rdx     # 0x1054ec
movq %r12, %rdi
movl $0x396, %ecx            # imm = 0x396
jmp 0x64ef5
pushq $0x48
popq %rdi
callq 0x8490
movq %rax, %rcx
movq %rax, 0x88(%r14)
xorl %eax, %eax
testq %rcx, %rcx
jne 0x64f02
leaq 0x801ca(%rip), %rsi     # 0xe5004
leaq 0xa0850(%rip), %rdx     # 0x105691
leaq 0x50(%rsp), %rbx
pushq $0x48
popq %rcx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r12           # imm = 0x1064
leaq 0x801d3(%rip), %rsi     # 0xe5034
leaq 0xa0684(%rip), %rdx     # 0x1054ec
movq %r12, %rdi
movl $0x39e, %ecx            # imm = 0x39E
jmp 0x64ef5
leaq 0x80188(%rip), %rsi     # 0xe5004
leaq 0xa0707(%rip), %rdx     # 0x10558a
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl $0x828, %ecx            # imm = 0x828
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r12           # imm = 0x1064
leaq 0x8018f(%rip), %rsi     # 0xe5034
leaq 0xa0640(%rip), %rdx     # 0x1054ec
movq %r12, %rdi
movl $0x387, %ecx            # imm = 0x387
jmp 0x64ef5
leaq 0x80147(%rip), %rsi     # 0xe5004
leaq 0xa0767(%rip), %rdx     # 0x10562b
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movl $0x938, %ecx            # imm = 0x938
xorl %eax, %eax
callq 0x2e014
addq $0x1064, %r12           # imm = 0x1064
leaq 0x8014e(%rip), %rsi     # 0xe5034
leaq 0xa05ff(%rip), %rdx     # 0x1054ec
movq %r12, %rdi
movl $0x392, %ecx            # imm = 0x392
movq %rbx, %r8
xorl %eax, %eax
callq 0x2e014
pushq $0x1
popq %rax
addq $0x858, %rsp            # imm = 0x858
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq