// File: /workspace/github_c_makefile_star2_O1/PoulinV[P]AxiCLASS/build/../source/background.c
// Function: background_derivs
int background_derivs(
                      double loga,
                      double* y, /* vector with argument y[index_bi] (must be already allocated with size pba->bi_size) */
                      double* dy, /* vector with argument dy[index_bi]
                                     (must be already allocated with
                                     size pba->bi_size) */
                      void * parameters_and_workspace,
                      ErrorMsg error_message
                      ) {

  /** Summary: */

  /** - define local variables */

  struct background_parameters_and_workspace * pbpaw;
  struct background * pba;
  double * pvecback, a, H, rho_M;
  double w_fld;
  pbpaw = parameters_and_workspace;
  pba =  pbpaw->pba;
  pvecback = pbpaw->pvecback;
  double cos_initial,sin_initial,n,Gac;
  /** - scale factor a (in fact, given our normalisation conventions, this stands for a/a_0) */
  a = exp(loga);

  /** - calculate functions of \f$ a \f$ with background_functions() */
  class_call(background_functions(pba, a, y, normal_info, pvecback),
             pba->error_message,
             error_message);

  /** - Short hand notation for Hubble */
  H = pvecback[pba->index_bg_H];

  /** - calculate derivative of cosmological time \f$ dt/dloga = 1/H \f$ */
  dy[pba->index_bi_time] = 1./H;

  /** - calculate derivative of conformal time \f$ d\tau/dloga = 1/aH \f$ */
  dy[pba->index_bi_tau] = 1./a/H;

  class_test(pvecback[pba->index_bg_rho_g] <= 0.,
             error_message,
             "rho_g = %e instead of strictly positive",pvecback[pba->index_bg_rho_g]);



   /* VP; in AxiCLASS we can switch from KG equation to fluid variables for the scalar field*/
   if(pba->has_scf == _TRUE_ && pba->scf_evolve_as_fluid == _TRUE_ ){
     if(pba->m_scf*pba->H0/H >= pba->threshold_scf_fluid_m_over_H){ //We switch for fluid equations at m > 3H by default.
       pba->scf_kg_eq = _FALSE_;
       // if(pba->scf_potential==axionquad &&  pba->a_c==1.0 ){
       if(pba->a_c==1.0 ){
         pba->a_c = a; //we defined a_c as the time at which the transition occurs. this is necessary for the perts.
         //for other potentials, a_c was already defined.
       }

       // printf("pba->a_c %e\n", pba->a_c);

     }
     else{
       pba->scf_kg_eq = _TRUE_;
     }
   }



  /** - calculate detivative of sound horizon \f$ drs/dloga = drs/dtau * dtau/dloga = c_s/aH \f$*/
  dy[pba->index_bi_rs] = 1./a/H/sqrt(3.*(1.+3.*pvecback[pba->index_bg_rho_b]/4./pvecback[pba->index_bg_rho_g]))*sqrt(1.-pba->K*y[pba->index_bi_rs]*y[pba->index_bi_rs]); // TBC: curvature correction

  /** - solve second order growth equation \f$ [D''(\tau)=-aHD'(\tau)+3/2 a^2 \rho_M D(\tau) \f$
      written as \f$ dD/dloga = D' / (aH) \f$ and \f$ dD'/dloga = -D' + (3/2) (a/H) \rho_M D \f$ */
  rho_M = pvecback[pba->index_bg_rho_b];
  if (pba->has_cdm == _TRUE_) {
    rho_M += pvecback[pba->index_bg_rho_cdm];
  }
  if (pba->has_idm == _TRUE_){
    rho_M += pvecback[pba->index_bg_rho_idm];
  }
  if (pba->has_scf == _TRUE_ && pba->include_scf_in_growth_factor == _TRUE_) {
    /*VP: add the scf contribution if the user wants to, e.g., for axion-like dark matter */
    if(pba->scf_potential==axionquad)
    rho_M += pvecback[pba->index_bg_rho_scf];
    else if(pba->scf_potential==axion && pba->n_axion ==1){
      rho_M += pvecback[pba->index_bg_rho_scf];
    }
    else{
      /*ignore contribution*/
    }
  }
  dy[pba->index_bi_D] = y[pba->index_bi_D_prime]/a/H;
  dy[pba->index_bi_D_prime] = -y[pba->index_bi_D_prime] + 1.5*a*rho_M*y[pba->index_bi_D]/H;

  if (pba->has_dcdm == _TRUE_) {
    /** - compute dcdm density \f$ d\rho/dloga = -3 \rho - \Gamma/H \rho \f$*/
    dy[pba->index_bi_rho_dcdm] = -3.*y[pba->index_bi_rho_dcdm] - pba->Gamma_dcdm/H*y[pba->index_bi_rho_dcdm];
  }

  if ((pba->has_dcdm == _TRUE_) && (pba->has_dr == _TRUE_)) {
    /** - Compute dr density \f$ d\rho/dloga = -4\rho - \Gamma/H \rho \f$ */
    dy[pba->index_bi_rho_dr] = -4.*y[pba->index_bi_rho_dr]+pba->Gamma_dcdm/H*y[pba->index_bi_rho_dcdm];
  }

  if (pba->has_fld == _TRUE_) {
    /** - Compute fld density \f$ d\rho/dloga = -3 (1+w_{fld}(a)) \rho \f$ */
    dy[pba->index_bi_rho_fld] = -3.*(1.+pvecback[pba->index_bg_w_fld])*y[pba->index_bi_rho_fld];
  }

  if (pba->has_scf == _TRUE_){
    /*<VP: Main modifications to SCF in AxiCLASS: we can seither solve using KG equations or fluid variables.*/
    /** - Scalar field equation: \f$ \phi'' + 2 a H \phi' + a^2 dV = 0 \f$  (note H is wrt cosmic time) */
    /*COComment - add if statement, dependent on flag, to either use KG equation or fluid equation  */
    // printf("inside SF evolution call\n");
    if (pba->scf_kg_eq == _TRUE_) {
    /* VP: OLD AXICLASS: derivative with respect to conformal time */
    // dy[pba->index_bi_phi_scf] = y[pba->index_bi_phi_prime_scf];
    // dy[pba->index_bi_phi_prime_scf] = - y[pba->index_bi_a]*
    //   (2*pvecback[pba->index_bg_H]*y[pba->index_bi_phi_prime_scf]
    //    + y[pba->index_bi_a]*dV_scf(pba,y[pba->index_bi_phi_scf])) ;

    /* VP: NEW AXICLASS: derivative with respect to log(a) */
    /** - Scalar field equation: \f$ \phi'' + 2 a H \phi' + a^2 dV = 0 \f$  (note H is wrt cosmological time)
        written as \f$ d\phi/dlna = phi' / (aH) \f$ and \f$ d\phi'/dlna = -2*phi' - (a/H) dV \f$ */
    dy[pba->index_bi_phi_scf] = y[pba->index_bi_phi_prime_scf]/a/H;
    dy[pba->index_bi_phi_prime_scf] = - 2*y[pba->index_bi_phi_prime_scf] - a*dV_scf(pba,y[pba->index_bi_phi_scf])/H ;

    dy[pba->index_bi_rho_scf] = 0; //Update the scf density until the fluid equation starts.
    // printf("aEvolving scalar field using KG equation. phi %e phi prime %e \n", y[pba->index_bi_phi_scf],y[pba->index_bi_phi_prime_scf]);
    // printf("dV %e \n", dV_scf(pba,y[pba->index_bi_phi_scf])  );
    // if(pba->background_verbose > 11) printf("Evolving scalar field using KG equation. phi %e phi prime %e \n", y[pba->index_bi_phi_scf],dy[pba->index_bi_phi_scf]  );
    }
    else if(pba->scf_kg_eq == _FALSE_) {
    dy[pba->index_bi_rho_scf] = -3.*y[pba->index_bi_rho_scf]*(1+pba->w_scf);
    dy[pba->index_bi_phi_scf] = 0;
    dy[pba->index_bi_phi_prime_scf] = 0;
    if(pba->background_verbose > 11) printf("Evolving scalar field using fluid equation, rho %e rho prime %e.\n",y[pba->index_bi_rho_scf],dy[pba->index_bi_rho_scf]);

    //
    }
    else if (pba->scf_evolve_as_fluid == _FALSE_ && pba->scf_kg_eq == _FALSE_) {
      /*COComment Throw an error code if neither KG nor fluid equations apply - this should never happen */
      class_stop(pba->error_message,"We are not evolving scalar field as KG nor fluid eq, something has gone wrong!\n");
    }
}



  return _SUCCESS_;

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1028, %rsp           # imm = 0x1028
movq %rcx, %rbp
movq %rsi, %r14
movq %rdi, %r15
movq (%rdx), %rbx
movq 0x8(%rdx), %r12
callq 0x8670
movl $0x1, %r13d
movq %rbx, %rdi
movsd %xmm0, 0x10(%rsp)
movq %r15, %rsi
movl $0x1, %edx
movq %r12, %rcx
callq 0x5f134
testl %eax, %eax
je 0x6704b
addq $0xd1c, %rbx            # imm = 0xD1C
leaq 0x8a3d9(%rip), %rsi     # 0xf13f0
leaq 0xa9020(%rip), %rdx     # 0x11003e
leaq 0x20(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30c2c
leaq 0x89ffd(%rip), %rsi     # 0xf1034
leaq 0xa9037(%rip), %rdx     # 0x110075
movq %rbp, %rdi
movl $0xc69, %ecx            # imm = 0xC69
jmp 0x6714b
movslq 0x384(%rbx), %rax
movsd (%r12,%rax,8), %xmm3
movsd 0x8a200(%rip), %xmm5    # 0xf1260
movapd %xmm5, %xmm0
divsd %xmm3, %xmm0
movslq 0x498(%rbx), %rax
movsd %xmm0, (%r14,%rax,8)
movapd %xmm5, %xmm4
movsd 0x10(%rsp), %xmm2
divsd %xmm2, %xmm4
divsd %xmm3, %xmm4
movslq 0x4a0(%rbx), %rax
movsd %xmm4, (%r14,%rax,8)
movslq 0x38c(%rbx), %rax
xorpd %xmm0, %xmm0
ucomisd (%r12,%rax,8), %xmm0
jae 0x670ef
cmpw $0x1, 0x4bc(%rbx)
jne 0x6718f
cmpw $0x1, 0x130(%rbx)
jne 0x6718f
movsd 0x188(%rbx), %xmm0
mulsd (%rbx), %xmm0
divsd %xmm3, %xmm0
ucomisd 0x138(%rbx), %xmm0
jae 0x6716a
movw $0x1, 0x230(%rbx)
jmp 0x6718f
movslq 0x38c(%rbx), %rax
movsd (%r12,%rax,8), %xmm0
leaq 0xa8f84(%rip), %rsi     # 0x110087
leaq 0x20(%rsp), %rbx
movq %rbx, %rdi
movb $0x1, %al
callq 0x30c2c
leaq 0x89f69(%rip), %rsi     # 0xf1082
leaq 0xa8f8f(%rip), %rdx     # 0x1100af
leaq 0x820(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rcx
xorl %eax, %eax
callq 0x30c2c
leaq 0x89ef8(%rip), %rsi     # 0xf1034
leaq 0xa8f32(%rip), %rdx     # 0x110075
movq %rbp, %rdi
movl $0xc76, %ecx            # imm = 0xC76
movq %r14, %r8
xorl %eax, %eax
callq 0x30c2c
movl %r13d, %eax
addq $0x1028, %rsp           # imm = 0x1028
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movw $0x0, 0x230(%rbx)
movsd 0x1c8(%rbx), %xmm0
ucomisd 0x8a0dd(%rip), %xmm0    # 0xf1260
jne 0x6718f
jp 0x6718f
movsd %xmm2, 0x1c8(%rbx)
movslq 0x390(%rbx), %rcx
movsd 0x8b4e2(%rip), %xmm1    # 0xf2680
movsd (%r12,%rcx,8), %xmm0
mulsd %xmm1, %xmm0
mulsd 0x8d3c0(%rip), %xmm0    # 0xf4570
divsd (%r12,%rax,8), %xmm0
addsd 0x8a0a2(%rip), %xmm0    # 0xf1260
mulsd %xmm1, %xmm0
xorpd %xmm2, %xmm2
ucomisd %xmm2, %xmm0
movsd %xmm3, 0x18(%rsp)
jb 0x671d8
sqrtsd %xmm0, %xmm0
jmp 0x671f5
movsd %xmm4, 0x8(%rsp)
callq 0x82b0
xorpd %xmm2, %xmm2
movsd 0x8a071(%rip), %xmm5    # 0xf1260
movsd 0x8(%rsp), %xmm4
divsd %xmm0, %xmm4
movslq 0x49c(%rbx), %rax
movsd (%r15,%rax,8), %xmm0
movsd 0x318(%rbx), %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm0, %xmm1
subsd %xmm1, %xmm5
ucomisd %xmm2, %xmm5
jb 0x67229
xorps %xmm0, %xmm0
sqrtsd %xmm5, %xmm0
jmp 0x6723e
movapd %xmm5, %xmm0
movsd %xmm4, 0x8(%rsp)
callq 0x82b0
movsd 0x8(%rsp), %xmm4
movsd 0x10(%rsp), %xmm2
movsd 0x18(%rsp), %xmm3
mulsd %xmm0, %xmm4
movslq 0x49c(%rbx), %rax
movsd %xmm4, (%r14,%rax,8)
movslq 0x390(%rbx), %rax
movsd (%r12,%rax,8), %xmm0
cmpw $0x1, 0x4b4(%rbx)
jne 0x6727f
movslq 0x394(%rbx), %rax
addsd (%r12,%rax,8), %xmm0
cmpw $0x1, 0x4b6(%rbx)
jne 0x67296
movslq 0x398(%rbx), %rax
addsd (%r12,%rax,8), %xmm0
movzwl 0x4bc(%rbx), %eax
cmpw $0x1, %ax
jne 0x672de
cmpw $0x1, 0x23c(%rbx)
jne 0x672de
movl 0x160(%rbx), %ecx
cmpl $0x4, %ecx
je 0x672d1
cmpl $0x2, %ecx
jne 0x672de
movsd 0x210(%rbx), %xmm1
ucomisd 0x89f93(%rip), %xmm1    # 0xf1260
jne 0x672de
jp 0x672de
movslq 0x3d0(%rbx), %rcx
addsd (%r12,%rcx,8), %xmm0
movslq 0x4a8(%rbx), %rcx
movsd (%r15,%rcx,8), %xmm1
divsd %xmm2, %xmm1
divsd %xmm3, %xmm1
movslq 0x4a4(%rbx), %rdx
movsd %xmm1, (%r14,%rdx,8)
movsd 0x8ccb0(%rip), %xmm1    # 0xf3fb8
mulsd %xmm2, %xmm1
mulsd %xmm0, %xmm1
mulsd (%r15,%rdx,8), %xmm1
divsd %xmm3, %xmm1
subsd (%r15,%rcx,8), %xmm1
movsd %xmm1, (%r14,%rcx,8)
cmpw $0x1, 0x4b8(%rbx)
jne 0x673a1
movslq 0x480(%rbx), %rcx
movsd (%r15,%rcx,8), %xmm0
movsd 0x110(%rbx), %xmm1
divsd %xmm3, %xmm1
mulsd %xmm0, %xmm1
mulsd 0x8d11b(%rip), %xmm0    # 0xf4470
subsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rcx,8)
cmpw $0x1, 0x4ba(%rbx)
jne 0x673a1
movslq 0x484(%rbx), %rcx
movsd (%r15,%rcx,8), %xmm0
movsd 0x110(%rbx), %xmm1
divsd %xmm3, %xmm1
movslq 0x480(%rbx), %rdx
mulsd (%r15,%rdx,8), %xmm1
mulsd 0x8d0c1(%rip), %xmm0    # 0xf4458
addsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rcx,8)
cmpw $0x1, 0x4c2(%rbx)
jne 0x673db
movslq 0x3a4(%rbx), %rcx
movsd (%r12,%rcx,8), %xmm0
addsd 0x89ea0(%rip), %xmm0    # 0xf1260
mulsd 0x8d0a8(%rip), %xmm0    # 0xf4470
movslq 0x488(%rbx), %rcx
mulsd (%r15,%rcx,8), %xmm0
movsd %xmm0, (%r14,%rcx,8)
xorl %r13d, %r13d
cmpw $0x1, %ax
jne 0x67155
movzwl 0x230(%rbx), %eax
testl %eax, %eax
je 0x6747b
cmpl $0x1, %eax
jne 0x67155
movslq 0x494(%rbx), %rax
movsd (%r15,%rax,8), %xmm0
divsd %xmm2, %xmm0
divsd %xmm3, %xmm0
movslq 0x490(%rbx), %rcx
movsd %xmm0, (%r14,%rcx,8)
movsd (%r15,%rax,8), %xmm0
movsd %xmm0, 0x8(%rsp)
movsd (%r15,%rcx,8), %xmm0
movq %rbx, %rdi
callq 0x60166
mulsd 0x10(%rsp), %xmm0
divsd 0x18(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
mulsd 0x8b302(%rip), %xmm1    # 0xf2758
subsd %xmm0, %xmm1
movslq 0x494(%rbx), %rax
movsd %xmm1, (%r14,%rax,8)
movslq 0x48c(%rbx), %rax
movq $0x0, (%r14,%rax,8)
jmp 0x67155
movslq 0x48c(%rbx), %rax
movsd (%r15,%rax,8), %xmm0
mulsd 0x8cfe0(%rip), %xmm0    # 0xf4470
movsd 0x218(%rbx), %xmm1
addsd 0x89dc0(%rip), %xmm1    # 0xf1260
mulsd %xmm0, %xmm1
movsd %xmm1, (%r14,%rax,8)
movslq 0x490(%rbx), %rcx
xorl %r13d, %r13d
movq %r13, (%r14,%rcx,8)
movslq 0x494(%rbx), %rcx
movq %r13, (%r14,%rcx,8)
cmpw $0xc, 0xd1a(%rbx)
jl 0x67155
movsd (%r15,%rax,8), %xmm0
movsd (%r14,%rax,8), %xmm1
leaq 0xa8bef(%rip), %rdi     # 0x1100d3
movb $0x2, %al
callq 0x8030
jmp 0x67155