// File: /workspace/github_c_makefile_star2_O3/PoulinV[P]AxiCLASS/build/../source/thermodynamics.c
// Function: thermodynamics_idm_quantities
int thermodynamics_idm_quantities(struct background * pba,
                                  double z,
                                  double * y,
                                  double * dy,
                                  struct thermodynamics * pth,
                                  struct thermo_workspace * ptw,
                                  double * pvecback){
  /** Summary: */

  /** Define local variables */
  struct thermo_diffeq_workspace * ptdw = ptw->ptdw;
  struct thermo_vector * ptv = ptdw->ptv;

  /* Thermo quantities */
  double T_g, Tmat, T_idr = 0.;
  double Vrms_idm_b2, m_b, T_diff_idm_b, FHe;

  T_g = ptw->Tcmb * (1.+z);
  Tmat = y[ptv->index_ti_D_Tmat] + T_g;

  /** - First deal with any required dark radiation */
  if (pba->has_idr == _TRUE_) {
    T_idr = pba->T_idr*(1.+z);
    ptdw->dmu_idr = pth->b_idr*pow((1.+z)/1.e7,pth->n_index_idm_dr)*pba->Omega0_idr*pow(pba->h,2);
  }

  /** - Now deal with any required dark matter (and its interactions) */
  if (pba->has_idm == _TRUE_) {
    /* First, set the IDM temperature in tight coupling */
    if (ptw->has_ap_idmtca == _TRUE_ && ptdw->ap_current == ptdw->index_ap_idmtca) {
      ptdw->T_idm = T_g;
      /* If we are coupling strongly to dark radiation instead */
      if ((pth->has_idm_dr == _TRUE_) && pth->n_index_idm_dr > 0)
        ptdw->T_idm = T_idr;
    }

    /* Also set idm temperature without tight coupling */
    else {
      ptdw->T_idm = y[ptv->index_ti_T_idm];
    }

    /* Compute idm temperature derivatives, starting with homogeneous expansion */
    ptdw->T_idm_prime = - 2. * ptdw->T_idm / (1.+z);

    /* Now add also coupling to photons*/
    if (pth->has_idm_g == _TRUE_) {
      /* - photon interaction rate with idm_g */
      ptdw->dmu_idm_g = 3./8./_PI_/_G_*pow(1.+z, 2+pth->n_index_idm_g)*pba->Omega0_idm*pba->H0*pba->H0*pth->u_idm_g*pow(_c_,4)*_sigma_/1.e11/_eV_/_Mpc_over_m_;
      ptdw->T_idm_prime += - 2.*4./3. * pvecback[pba->index_bg_rho_g]/pvecback[pba->index_bg_rho_idm] * ptdw->dmu_idm_g * (ptdw->T_idm  - T_g) / pvecback[pba->index_bg_H];
    }
    /* Now add also coupling to dark radiation */
    if (pth->has_idm_dr == _TRUE_) {
      /* - idr interaction rate with idm_dr */
      ptdw->dmu_idm_dr = pth->a_idm_dr*pow((1.+ z)/1.e7,pth->n_index_idm_dr)*pba->Omega0_idm*pow(pba->h,2);
      ptdw->Sinv_idm_dr  = 4./3.*pvecback[pba->index_bg_rho_idr]/pvecback[pba->index_bg_rho_idm];
      ptdw->T_idm_prime += - 2* ptdw->dmu_idm_dr * ptdw->Sinv_idm_dr * (ptdw->T_idm - T_idr) / pvecback[pba->index_bg_H];
    }
    /* Now add also coupling to baryons */
    /* Note that here we do a simplified calculation of the velocity, as described in 2010.04074. This will be adapted in future versions. */
    if (pth->has_idm_b == _TRUE_) {
      if (z > 1.e3)
        Vrms_idm_b2 = 1.e-8;
      else
        Vrms_idm_b2 = 1.e-8*pow(((1.+z)/1.e3),2);

      FHe = 1- ptw->YHe;
      m_b = _m_p_*_c_*_c_/_eV_; /* Note that for now we always assume scattering with protons. This will be adapted in future versions. */

      T_diff_idm_b = (Tmat*_k_B_/_eV_/m_b)+(ptdw->T_idm*_k_B_/_eV_/pth->m_idm)+(Vrms_idm_b2/3.0);

      ptdw->R_idm_b = (pvecback[pba->index_bg_a]*pvecback[pba->index_bg_rho_b]*pth->cross_idm_b*pth->n_coeff_idm_b/(m_b+pth->m_idm))
        *pow(T_diff_idm_b,(pth->n_index_idm_b+1.0)/2.0)*FHe
        *(3.e-4*pow(_c_,4.)/(8.*_PI_*_Mpc_over_m_*_G_*_eV_));

      ptdw->T_idm_prime += -2.*pth->m_idm/(pth->m_idm + m_b)*ptdw->R_idm_b*(ptdw->T_idm-Tmat) / pvecback[pba->index_bg_H];
    }

    /* Now conclude by computing the sound speed */
    ptdw->c2_idm = _k_B_ /(pth->m_idm*_eV_)  * (ptdw->T_idm - (1.+z)/3. * ptdw->T_idm_prime);
  }

  return _SUCCESS_;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r9, %r12
movq %rcx, %r15
movq %rsi, %r13
movq %rdi, %r14
movq 0x80(%r8), %rbp
movq 0xb8(%rbp), %rbx
movsd 0x7dc5f(%rip), %xmm5    # 0xee260
movsd %xmm0, 0x30(%rsp)
addsd %xmm0, %xmm5
movq %r8, 0x10(%rsp)
movsd 0x38(%r8), %xmm1
mulsd %xmm5, %xmm1
movslq 0xc(%rbx), %rax
movsd (%rsi,%rax,8), %xmm0
movsd %xmm1, (%rsp)
addsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
xorpd %xmm0, %xmm0
movsd %xmm0, 0x8(%rsp)
cmpw $0x1, 0x4c6(%rdi)
movsd %xmm5, 0x18(%rsp)
jne 0x706b0
movsd 0x100(%r14), %xmm0
mulsd %xmm5, %xmm0
movsd %xmm0, 0x8(%rsp)
movapd %xmm5, %xmm0
divsd 0x9d01d(%rip), %xmm0    # 0x10d688
movsd 0x1020(%r15), %xmm1
movsd %xmm1, 0x28(%rsp)
movsd 0x1028(%r15), %xmm1
callq 0x8620
movsd 0x18(%rsp), %xmm5
mulsd 0x28(%rsp), %xmm0
mulsd 0xf8(%r14), %xmm0
movsd 0x8(%r14), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, 0x60(%rbp)
cmpw $0x1, 0x4b6(%r14)
jne 0x70a5f
movq 0x10(%rsp), %rax
cmpw $0x1, 0x60(%rax)
jne 0x70708
movl 0x90(%rbp), %eax
cmpl 0x70(%rbp), %eax
jne 0x70708
movsd (%rsp), %xmm2
movsd %xmm2, 0x38(%rbp)
cmpw $0x1, 0x38(%r15)
jne 0x70718
movsd 0x1028(%r15), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movsd (%rsp), %xmm2
jbe 0x70718
movsd 0x8(%rsp), %xmm2
jmp 0x70713
movslq 0x10(%rbx), %rax
movsd (%r13,%rax,8), %xmm2
movsd %xmm2, 0x38(%rbp)
movsd 0x7f040(%rip), %xmm0    # 0xef760
mulsd %xmm2, %xmm0
divsd %xmm5, %xmm0
movsd %xmm0, 0x40(%rbp)
cmpw $0x1, 0x36(%r15)
jne 0x707fc
movl 0x1058(%r15), %eax
addl $0x2, %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
movapd %xmm5, %xmm0
callq 0x8620
movsd 0x18(%rsp), %xmm5
mulsd 0x9ceff(%rip), %xmm0    # 0x10d660
mulsd 0xf0(%r14), %xmm0
movsd (%r14), %xmm1
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd 0x1050(%r15), %xmm0
mulsd 0x9cee0(%rip), %xmm0    # 0x10d668
mulsd 0x824d8(%rip), %xmm0    # 0xf2c68
divsd 0x824d8(%rip), %xmm0    # 0xf2c70
divsd 0x824a8(%rip), %xmm0    # 0xf2c48
divsd 0x82340(%rip), %xmm0    # 0xf2ae8
movsd %xmm0, 0x48(%rbp)
movslq 0x38c(%r14), %rax
movsd (%r12,%rax,8), %xmm1
mulsd 0x9cf96(%rip), %xmm1    # 0x10d758
movslq 0x398(%r14), %rax
divsd (%r12,%rax,8), %xmm1
mulsd %xmm0, %xmm1
movsd 0x38(%rbp), %xmm2
movapd %xmm2, %xmm0
subsd (%rsp), %xmm0
mulsd %xmm1, %xmm0
movslq 0x384(%r14), %rax
divsd (%r12,%rax,8), %xmm0
addsd 0x40(%rbp), %xmm0
movsd %xmm0, 0x40(%rbp)
cmpw $0x1, 0x38(%r15)
jne 0x708b4
movapd %xmm5, %xmm0
divsd 0x9ce74(%rip), %xmm0    # 0x10d688
movsd 0x1018(%r15), %xmm1
movsd %xmm1, (%rsp)
movsd 0x1028(%r15), %xmm1
callq 0x8620
movsd 0x18(%rsp), %xmm5
mulsd (%rsp), %xmm0
mulsd 0xf0(%r14), %xmm0
movsd 0x8(%r14), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, 0x58(%rbp)
movslq 0x3b0(%r14), %rax
movsd (%r12,%rax,8), %xmm0
mulsd 0x80c54(%rip), %xmm0    # 0xf14c0
movslq 0x398(%r14), %rax
divsd (%r12,%rax,8), %xmm0
movsd %xmm0, 0x68(%rbp)
addsd %xmm1, %xmm1
mulsd %xmm0, %xmm1
movsd 0x38(%rbp), %xmm2
movsd 0x40(%rbp), %xmm0
movapd %xmm2, %xmm3
subsd 0x8(%rsp), %xmm3
mulsd %xmm1, %xmm3
movslq 0x384(%r14), %rax
divsd (%r12,%rax,8), %xmm3
subsd %xmm3, %xmm0
movsd %xmm0, 0x40(%rbp)
cmpw $0x1, 0x34(%r15)
jne 0x70a29
movsd 0x82350(%rip), %xmm4    # 0xf2c18
movapd %xmm5, %xmm3
divsd %xmm4, %xmm3
mulsd %xmm3, %xmm3
mulsd 0x7e3ec(%rip), %xmm3    # 0xeecc8
divsd 0x7ed9c(%rip), %xmm3    # 0xef680
movsd 0x7d974(%rip), %xmm0    # 0xee260
xorps %xmm1, %xmm1
cvtsi2sdl 0x1038(%r15), %xmm1
addsd %xmm0, %xmm1
movq 0x10(%rsp), %rax
subsd 0x18(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x8232c(%rip), %xmm0    # 0xf2c40
movsd 0x20(%rsp), %xmm5
mulsd %xmm0, %xmm5
movsd 0x82322(%rip), %xmm6    # 0xf2c48
divsd %xmm6, %xmm5
movsd 0x9cd3e(%rip), %xmm7    # 0x10d670
divsd %xmm7, %xmm5
mulsd %xmm0, %xmm2
divsd %xmm6, %xmm2
movsd 0x1010(%r15), %xmm6
divsd %xmm6, %xmm2
addsd %xmm5, %xmm2
cmpltsd 0x30(%rsp), %xmm4
movsd 0x9cd1a(%rip), %xmm0    # 0x10d678
andpd %xmm4, %xmm0
andnpd %xmm3, %xmm4
orpd %xmm4, %xmm0
addsd %xmm2, %xmm0
movslq 0x380(%r14), %rax
movsd (%r12,%rax,8), %xmm2
movslq 0x390(%r14), %rax
mulsd (%r12,%rax,8), %xmm2
mulsd 0x1030(%r15), %xmm2
mulsd 0x1040(%r15), %xmm2
addsd %xmm7, %xmm6
divsd %xmm6, %xmm2
movsd %xmm2, 0x10(%rsp)
mulsd 0x7e320(%rip), %xmm1    # 0xeecd0
callq 0x8620
movsd 0x18(%rsp), %xmm5
mulsd 0x10(%rsp), %xmm0
mulsd 0x8(%rsp), %xmm0
mulsd 0x9ccb1(%rip), %xmm0    # 0x10d680
movsd %xmm0, 0x30(%rbp)
movsd 0x1010(%r15), %xmm1
movapd %xmm1, %xmm3
addsd %xmm1, %xmm3
movsd 0x9cc83(%rip), %xmm2    # 0x10d670
addsd %xmm1, %xmm2
divsd %xmm2, %xmm3
mulsd %xmm0, %xmm3
movsd 0x38(%rbp), %xmm2
movsd 0x40(%rbp), %xmm0
movapd %xmm2, %xmm4
subsd 0x20(%rsp), %xmm4
mulsd %xmm3, %xmm4
movslq 0x384(%r14), %rax
divsd (%r12,%rax,8), %xmm4
subsd %xmm4, %xmm0
movsd %xmm0, 0x40(%rbp)
jmp 0x70a32
movsd 0x1010(%r15), %xmm1
mulsd 0x8220e(%rip), %xmm1    # 0xf2c48
movsd 0x821fe(%rip), %xmm3    # 0xf2c40
divsd %xmm1, %xmm3
divsd 0x80a32(%rip), %xmm5    # 0xf1480
mulsd %xmm0, %xmm5
addsd %xmm2, %xmm5
mulsd %xmm3, %xmm5
movsd %xmm5, 0x50(%rbp)
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq