// File: /workspace/github_c_makefile_star2_O1/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, %rbx
movq %rsi, %r13
movq %rdi, %r15
movq 0x80(%r8), %rbp
movq 0xb8(%rbp), %r14
movsd 0x7e166(%rip), %xmm2    # 0xf1260
movsd %xmm0, 0x30(%rsp)
addsd %xmm0, %xmm2
movq %r8, 0x18(%rsp)
movsd 0x38(%r8), %xmm1
mulsd %xmm2, %xmm1
movslq 0xc(%r14), %rax
movsd (%rsi,%rax,8), %xmm0
movsd %xmm1, 0x10(%rsp)
addsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
xorpd %xmm0, %xmm0
movsd %xmm0, (%rsp)
cmpw $0x1, 0x4c6(%rdi)
movsd %xmm2, 0x8(%rsp)
jne 0x731a6
movsd 0x100(%r15), %xmm0
mulsd %xmm2, %xmm0
movsd %xmm0, (%rsp)
movapd %xmm2, %xmm0
divsd 0x9d505(%rip), %xmm0    # 0x110668
movsd 0x1020(%rbx), %xmm1
movsd %xmm1, 0x28(%rsp)
movsd 0x1028(%rbx), %xmm1
callq 0x8620
movsd 0x8(%rsp), %xmm2
mulsd 0x28(%rsp), %xmm0
mulsd 0xf8(%r15), %xmm0
movsd 0x8(%r15), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, 0x60(%rbp)
cmpw $0x1, 0x4b6(%r15)
jne 0x73535
movq 0x18(%rsp), %rax
cmpw $0x1, 0x60(%rax)
jne 0x731f7
movl 0x90(%rbp), %eax
cmpl 0x70(%rbp), %eax
jne 0x731f7
movsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x38(%rbp)
cmpw $0x1, 0x38(%rbx)
jne 0x73207
movsd 0x1028(%rbx), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x73207
movsd (%rsp), %xmm0
jmp 0x73202
movslq 0x10(%r14), %rax
movsd (%r13,%rax,8), %xmm0
movsd %xmm0, 0x38(%rbp)
movsd 0x38(%rbp), %xmm0
mulsd 0x7f544(%rip), %xmm0    # 0xf2758
divsd %xmm2, %xmm0
movsd %xmm0, 0x40(%rbp)
cmpw $0x1, 0x36(%rbx)
jne 0x732e6
movl 0x1058(%rbx), %eax
addl $0x2, %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
movapd %xmm2, %xmm0
callq 0x8620
movsd 0x8(%rsp), %xmm2
mulsd 0x9d3f1(%rip), %xmm0    # 0x110640
mulsd 0xf0(%r15), %xmm0
movsd (%r15), %xmm1
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd 0x1050(%rbx), %xmm0
mulsd 0x9d3d3(%rip), %xmm0    # 0x110648
mulsd 0x829bb(%rip), %xmm0    # 0xf5c38
divsd 0x829bb(%rip), %xmm0    # 0xf5c40
divsd 0x8298b(%rip), %xmm0    # 0xf5c18
divsd 0x82823(%rip), %xmm0    # 0xf5ab8
movsd %xmm0, 0x48(%rbp)
movslq 0x38c(%r15), %rax
movsd (%r12,%rax,8), %xmm1
mulsd 0x9d489(%rip), %xmm1    # 0x110738
movslq 0x398(%r15), %rax
divsd (%r12,%rax,8), %xmm1
mulsd %xmm0, %xmm1
movsd 0x38(%rbp), %xmm0
subsd 0x10(%rsp), %xmm0
mulsd %xmm1, %xmm0
movslq 0x384(%r15), %rax
divsd (%r12,%rax,8), %xmm0
addsd 0x40(%rbp), %xmm0
movsd %xmm0, 0x40(%rbp)
cmpw $0x1, 0x38(%rbx)
jne 0x73398
movapd %xmm2, %xmm0
divsd 0x9d36b(%rip), %xmm0    # 0x110668
movsd 0x1018(%rbx), %xmm1
movsd %xmm1, 0x10(%rsp)
movsd 0x1028(%rbx), %xmm1
callq 0x8620
mulsd 0x10(%rsp), %xmm0
mulsd 0xf0(%r15), %xmm0
movsd 0x8(%r15), %xmm1
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm1
movsd %xmm1, 0x58(%rbp)
movslq 0x3b0(%r15), %rax
movsd (%r12,%rax,8), %xmm0
mulsd 0x81161(%rip), %xmm0    # 0xf44b0
movslq 0x398(%r15), %rax
divsd (%r12,%rax,8), %xmm0
movsd %xmm0, 0x68(%rbp)
addsd %xmm1, %xmm1
mulsd %xmm0, %xmm1
movsd 0x38(%rbp), %xmm0
movsd 0x40(%rbp), %xmm2
subsd (%rsp), %xmm0
mulsd %xmm1, %xmm0
movslq 0x384(%r15), %rax
divsd (%r12,%rax,8), %xmm0
subsd %xmm0, %xmm2
movsd %xmm2, 0x40(%rbp)
movsd 0x8(%rsp), %xmm2
cmpw $0x1, 0x34(%rbx)
jne 0x734fe
movsd 0x8283d(%rip), %xmm3    # 0xf5be8
movsd 0x8(%rsp), %xmm2
divsd %xmm3, %xmm2
mulsd %xmm2, %xmm2
mulsd 0x7e907(%rip), %xmm2    # 0xf1cc8
divsd 0x7f2b7(%rip), %xmm2    # 0xf2680
movsd 0x7de8f(%rip), %xmm0    # 0xf1260
xorps %xmm1, %xmm1
cvtsi2sdl 0x1038(%rbx), %xmm1
addsd %xmm0, %xmm1
movq 0x18(%rsp), %rax
subsd 0x18(%rax), %xmm0
movsd %xmm0, (%rsp)
movsd 0x82819(%rip), %xmm4    # 0xf5c10
movsd 0x20(%rsp), %xmm0
mulsd %xmm4, %xmm0
movsd 0x8280f(%rip), %xmm5    # 0xf5c18
divsd %xmm5, %xmm0
movsd 0x9d23b(%rip), %xmm6    # 0x110650
divsd %xmm6, %xmm0
mulsd 0x38(%rbp), %xmm4
divsd %xmm5, %xmm4
movsd 0x1010(%rbx), %xmm5
divsd %xmm5, %xmm4
addsd %xmm0, %xmm4
cmpltsd 0x30(%rsp), %xmm3
movsd 0x9d217(%rip), %xmm0    # 0x110658
andpd %xmm3, %xmm0
andnpd %xmm2, %xmm3
orpd %xmm3, %xmm0
addsd %xmm4, %xmm0
movslq 0x380(%r15), %rax
movsd (%r12,%rax,8), %xmm2
movslq 0x390(%r15), %rax
mulsd (%r12,%rax,8), %xmm2
mulsd 0x1030(%rbx), %xmm2
mulsd 0x1040(%rbx), %xmm2
addsd %xmm6, %xmm5
divsd %xmm5, %xmm2
movsd %xmm2, 0x18(%rsp)
mulsd 0x7e83f(%rip), %xmm1    # 0xf1cd0
callq 0x8620
mulsd 0x18(%rsp), %xmm0
mulsd (%rsp), %xmm0
mulsd 0x9d1b7(%rip), %xmm0    # 0x110660
movsd %xmm0, 0x30(%rbp)
movsd 0x1010(%rbx), %xmm1
movapd %xmm1, %xmm2
addsd %xmm1, %xmm2
addsd 0x9d18a(%rip), %xmm1    # 0x110650
divsd %xmm1, %xmm2
mulsd %xmm0, %xmm2
movsd 0x38(%rbp), %xmm0
movsd 0x40(%rbp), %xmm1
subsd 0x20(%rsp), %xmm0
mulsd %xmm2, %xmm0
movsd 0x8(%rsp), %xmm2
movslq 0x384(%r15), %rax
divsd (%r12,%rax,8), %xmm0
subsd %xmm0, %xmm1
movsd %xmm1, 0x40(%rbp)
movsd 0x1010(%rbx), %xmm0
mulsd 0x8270a(%rip), %xmm0    # 0xf5c18
movsd 0x826fa(%rip), %xmm1    # 0xf5c10
divsd %xmm0, %xmm1
divsd 0x80f4e(%rip), %xmm2    # 0xf4470
mulsd 0x40(%rbp), %xmm2
addsd 0x38(%rbp), %xmm2
mulsd %xmm1, %xmm2
movsd %xmm2, 0x50(%rbp)
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq