// File: /workspace/github_c_makefile_star2_O2/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 0x792a2(%rip), %xmm5    # 0xe5260
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 0x6c06d
movsd 0x100(%r14), %xmm0
mulsd %xmm5, %xmm0
movsd %xmm0, 0x8(%rsp)
movapd %xmm5, %xmm0
divsd 0x98520(%rip), %xmm0    # 0x104548
movsd 0x1020(%r15), %xmm1
movsd %xmm1, 0x28(%rsp)
movsd 0x1028(%r15), %xmm1
callq 0x8650
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 0x6c416
movq 0x10(%rsp), %rax
cmpw $0x1, 0x60(%rax)
jne 0x6c0c5
movl 0x90(%rbp), %eax
cmpl 0x70(%rbp), %eax
jne 0x6c0c5
movsd (%rsp), %xmm2
movsd %xmm2, 0x38(%rbp)
cmpw $0x1, 0x38(%r15)
jne 0x6c0d5
movsd 0x1028(%r15), %xmm0
xorpd %xmm1, %xmm1
ucomisd %xmm1, %xmm0
movsd (%rsp), %xmm2
jbe 0x6c0d5
movsd 0x8(%rsp), %xmm2
jmp 0x6c0d0
movslq 0x10(%rbx), %rax
movsd (%r13,%rax,8), %xmm2
movsd %xmm2, 0x38(%rbp)
movsd 0x7a65b(%rip), %xmm0    # 0xe6738
mulsd %xmm2, %xmm0
divsd %xmm5, %xmm0
movsd %xmm0, 0x40(%rbp)
cmpw $0x1, 0x36(%r15)
jne 0x6c1b6
movl 0x1058(%r15), %eax
addl $0x2, %eax
cvtsi2sd %eax, %xmm1
movapd %xmm5, %xmm0
callq 0x8650
movsd 0x18(%rsp), %xmm5
mulsd 0x98405(%rip), %xmm0    # 0x104520
mulsd 0xf0(%r14), %xmm0
movsd (%r14), %xmm1
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
mulsd 0x1050(%r15), %xmm0
mulsd 0x983e6(%rip), %xmm0    # 0x104528
mulsd 0x7d9de(%rip), %xmm0    # 0xe9b28
divsd 0x7d9de(%rip), %xmm0    # 0xe9b30
divsd 0x7d9ae(%rip), %xmm0    # 0xe9b08
divsd 0x7d846(%rip), %xmm0    # 0xe99a8
movsd %xmm0, 0x48(%rbp)
movslq 0x38c(%r14), %rax
movsd (%r12,%rax,8), %xmm1
mulsd 0x9849c(%rip), %xmm1    # 0x104618
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 0x6c26e
movapd %xmm5, %xmm0
divsd 0x9837a(%rip), %xmm0    # 0x104548
movsd 0x1018(%r15), %xmm1
movsd %xmm1, (%rsp)
movsd 0x1028(%r15), %xmm1
callq 0x8650
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 0x7c25a(%rip), %xmm0    # 0xe8480
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 0x6c3e0
movsd 0x7d856(%rip), %xmm4    # 0xe9ad8
movapd %xmm5, %xmm3
divsd %xmm4, %xmm3
mulsd %xmm3, %xmm3
mulsd 0x79a12(%rip), %xmm3    # 0xe5ca8
divsd 0x7a4aa(%rip), %xmm3    # 0xe6748
movsd 0x78fba(%rip), %xmm0    # 0xe5260
cvtsi2sdl 0x1038(%r15), %xmm1
addsd %xmm0, %xmm1
movq 0x10(%rsp), %rax
subsd 0x18(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd 0x7d835(%rip), %xmm0    # 0xe9b00
movsd 0x20(%rsp), %xmm5
mulsd %xmm0, %xmm5
movsd 0x7d82b(%rip), %xmm6    # 0xe9b08
divsd %xmm6, %xmm5
movsd 0x98247(%rip), %xmm7    # 0x104530
divsd %xmm7, %xmm5
mulsd %xmm0, %xmm2
divsd %xmm6, %xmm2
movsd 0x1010(%r15), %xmm6
divsd %xmm6, %xmm2
addsd %xmm5, %xmm2
cmpltsd 0x30(%rsp), %xmm4
movsd 0x98223(%rip), %xmm0    # 0x104538
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 0x79949(%rip), %xmm1    # 0xe5cb0
callq 0x8650
movsd 0x18(%rsp), %xmm5
mulsd 0x10(%rsp), %xmm0
mulsd 0x8(%rsp), %xmm0
mulsd 0x981ba(%rip), %xmm0    # 0x104540
movsd %xmm0, 0x30(%rbp)
movsd 0x1010(%r15), %xmm1
movapd %xmm1, %xmm3
addsd %xmm1, %xmm3
movsd 0x9818c(%rip), %xmm2    # 0x104530
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 0x6c3e9
movsd 0x1010(%r15), %xmm1
mulsd 0x7d717(%rip), %xmm1    # 0xe9b08
movsd 0x7d707(%rip), %xmm3    # 0xe9b00
divsd %xmm1, %xmm3
divsd 0x7c03b(%rip), %xmm5    # 0xe8440
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