// File: /workspace/github_c_makefile_star2_O0/PoulinV[P]AxiCLASS/build/../source/background.c
// Function: background_ncdm_distribution
int background_ncdm_distribution(
                                 void * pbadist,
                                 double q,
                                 double * f0
                                 ) {
  struct background * pba;
  struct background_parameters_for_distributions * pbadist_local;
  int n_ncdm,lastidx;
  double ksi;
  double qlast,dqlast,f0last,df0last;
  double *param;
  /* Variables corresponding to entries in param: */
  //double square_s12,square_s23,square_s13;
  //double mixing_matrix[3][3];
  //int i;

  /** - extract from the input structure pbadist all the relevant information */
  pbadist_local = pbadist;          /* restore actual format of pbadist */
  pba = pbadist_local->pba;         /* extract the background structure from it */
  param = pba->ncdm_psd_parameters; /* extract the optional parameter list from it */
  n_ncdm = pbadist_local->n_ncdm;   /* extract index of ncdm species under consideration */
  ksi = pba->ksi_ncdm[n_ncdm];      /* extract chemical potential */

  /** - shall we interpolate in file, or shall we use analytical formula below? */

  /** - a) deal first with the case of interpolating in files */
  if (pba->got_files[n_ncdm]==_TRUE_) {

    lastidx = pbadist_local->tablesize-1;
    if (q<pbadist_local->q[0]) {
      //Handle q->0 case:
      *f0 = pbadist_local->f0[0];
    }
    else if (q>pbadist_local->q[lastidx]) {
      //Handle q>qmax case (ensure continuous and derivable function with Boltzmann tail):
      qlast=pbadist_local->q[lastidx];
      f0last=pbadist_local->f0[lastidx];
      dqlast=qlast - pbadist_local->q[lastidx-1];
      df0last=f0last - pbadist_local->f0[lastidx-1];

      *f0 = f0last*exp(-(qlast-q)*df0last/f0last/dqlast);
    }
    else{
      //Do interpolation:
      class_call(array_interpolate_spline(
                                          pbadist_local->q,
                                          pbadist_local->tablesize,
                                          pbadist_local->f0,
                                          pbadist_local->d2f0,
                                          1,
                                          q,
                                          &pbadist_local->last_index,
                                          f0,
                                          1,
                                          pba->error_message),
                 pba->error_message,     pba->error_message);
    }
  }

  /** - b) deal now with case of reading analytical function */
  else{
    /**
       Next enter your analytic expression(s) for the p.s.d.'s. If
       you need different p.s.d.'s for different species, put each
       p.s.d inside a condition, like for instance: if (n_ncdm==2)
       {*f0=...}.  Remember that n_ncdm = 0 refers to the first
       species.
    */

    /**************************************************/
    /*    FERMI-DIRAC INCLUDING CHEMICAL POTENTIALS   */
    /**************************************************/

    *f0 = 1.0/pow(2*_PI_,3)*(1./(exp(q-ksi)+1.) +1./(exp(q+ksi)+1.));

    /**************************************************/

    /** This form is only appropriate for approximate studies, since in
        reality the chemical potentials are associated with flavor
        eigenstates, not mass eigenstates. It is easy to take this into
        account by introducing the mixing angles. In the later part
        (not read by the code) we illustrate how to do this. */

    if (_FALSE_) {

      /* We must use the list of extra parameters read in input, stored in the
         ncdm_psd_parameter list, extracted above from the structure
         and now called param[..] */

      /* check that this list has been read */
      class_test(param == NULL,
                 pba->error_message,
                 "Analytic expression wants to use 'ncdm_psd_parameters', but they have not been entered!");

      /* extract values from the list (in this example, mixing angles) */
      double square_s12=param[0];
      double square_s23=param[1];
      double square_s13=param[2];

      /* infer mixing matrix */
      double mixing_matrix[3][3];
      int i;

      mixing_matrix[0][0]=pow(fabs(sqrt((1-square_s12)*(1-square_s13))),2);
      mixing_matrix[0][1]=pow(fabs(sqrt(square_s12*(1-square_s13))),2);
      mixing_matrix[0][2]=fabs(square_s13);
      mixing_matrix[1][0]=pow(fabs(sqrt((1-square_s12)*square_s13*square_s23)+sqrt(square_s12*(1-square_s23))),2);
      mixing_matrix[1][1]=pow(fabs(sqrt(square_s12*square_s23*square_s13)-sqrt((1-square_s12)*(1-square_s23))),2);
      mixing_matrix[1][2]=pow(fabs(sqrt(square_s23*(1-square_s13))),2);
      mixing_matrix[2][0]=pow(fabs(sqrt(square_s12*square_s23)-sqrt((1-square_s12)*square_s13*(1-square_s23))),2);
      mixing_matrix[2][1]=pow(sqrt((1-square_s12)*square_s23)+sqrt(square_s12*square_s13*(1-square_s23)),2);
      mixing_matrix[2][2]=pow(fabs(sqrt((1-square_s13)*(1-square_s23))),2);

      /* loop over flavor eigenstates and compute psd of mass eigenstates */
      *f0=0.0;
      for (i=0;i<3;i++) {

        *f0 += mixing_matrix[i][n_ncdm]*1.0/pow(2*_PI_,3)*(1./(exp(q-pba->ksi_ncdm[i])+1.) +1./(exp(q+pba->ksi_ncdm[i])+1.));

      }
    } /* end of region not used, but shown as an example */
  }

  return _SUCCESS_;
}

// Assembly:
subq $0x898, %rsp            # imm = 0x898
movq %rdi, 0x888(%rsp)
movsd %xmm0, 0x880(%rsp)
movq %rsi, 0x878(%rsp)
movq 0x888(%rsp), %rax
movq %rax, 0x868(%rsp)
movq 0x868(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x870(%rsp)
movq 0x870(%rsp), %rax
movq 0x260(%rax), %rax
movq %rax, 0x830(%rsp)
movq 0x868(%rsp), %rax
movl 0x8(%rax), %eax
movl %eax, 0x864(%rsp)
movq 0x870(%rsp), %rax
movq 0x2a0(%rax), %rax
movslq 0x864(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x858(%rsp)
movq 0x870(%rsp), %rax
movq 0x258(%rax), %rax
movslq 0x864(%rsp), %rcx
cmpl $0x1, (%rax,%rcx,4)
jne 0xa96b4
movq 0x868(%rsp), %rax
movl 0xc(%rax), %eax
subl $0x1, %eax
movl %eax, 0x860(%rsp)
movsd 0x880(%rsp), %xmm1
movq 0x868(%rsp), %rax
movq 0x10(%rax), %rax
movsd (%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xa9487
movq 0x868(%rsp), %rax
movq 0x18(%rax), %rax
movsd (%rax), %xmm0
movq 0x878(%rsp), %rax
movsd %xmm0, (%rax)
jmp 0xa96af
movsd 0x880(%rsp), %xmm0
movq 0x868(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x860(%rsp), %rcx
ucomisd (%rax,%rcx,8), %xmm0
jbe 0xa95c9
movq 0x868(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x860(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x850(%rsp)
movq 0x868(%rsp), %rax
movq 0x18(%rax), %rax
movslq 0x860(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x840(%rsp)
movsd 0x850(%rsp), %xmm0
movq 0x868(%rsp), %rax
movq 0x10(%rax), %rax
movl 0x860(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
subsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x848(%rsp)
movsd 0x840(%rsp), %xmm0
movq 0x868(%rsp), %rax
movq 0x18(%rax), %rax
movl 0x860(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
subsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x838(%rsp)
movsd 0x840(%rsp), %xmm0
movsd %xmm0, 0x28(%rsp)
movsd 0x850(%rsp), %xmm0
subsd 0x880(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
mulsd 0x838(%rsp), %xmm0
divsd 0x840(%rsp), %xmm0
divsd 0x848(%rsp), %xmm0
callq 0x8670
movaps %xmm0, %xmm1
movsd 0x28(%rsp), %xmm0
mulsd %xmm1, %xmm0
movq 0x878(%rsp), %rax
movsd %xmm0, (%rax)
jmp 0xa96ad
movq 0x868(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0x868(%rsp), %rax
movl 0xc(%rax), %esi
movq 0x868(%rsp), %rax
movq 0x18(%rax), %rdx
movq 0x868(%rsp), %rax
movq 0x20(%rax), %rcx
movsd 0x880(%rsp), %xmm0
movq 0x868(%rsp), %r9
addq $0x28, %r9
movq 0x878(%rsp), %r10
movq 0x870(%rsp), %rax
addq $0xd1c, %rax            # imm = 0xD1C
movl $0x1, %r8d
movq %r10, (%rsp)
movl $0x1, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x24220
cmpl $0x1, %eax
jne 0xa96ab
leaq 0x30(%rsp), %rdi
movq 0x870(%rsp), %rcx
addq $0xd1c, %rcx            # imm = 0xD1C
leaq 0x128d79(%rip), %rsi    # 0x1d23d8
leaq 0x145cea(%rip), %rdx    # 0x1ef350
movb $0x0, %al
callq 0x5b9c0
movq 0x870(%rsp), %rdi
addq $0xd1c, %rdi            # imm = 0xD1C
leaq 0x30(%rsp), %r8
leaq 0x1289ac(%rip), %rsi    # 0x1d2034
leaq 0x145d6c(%rip), %rdx    # 0x1ef3fb
movl $0x658, %ecx            # imm = 0x658
movb $0x0, %al
callq 0x5b9c0
movl $0x1, 0x894(%rsp)
jmp 0xa9773
jmp 0xa96ad
jmp 0xa96af
jmp 0xa9768
movsd 0x12bdcc(%rip), %xmm0   # 0x1d5488
movsd 0x129fd4(%rip), %xmm1   # 0x1d3698
callq 0x8610
movaps %xmm0, %xmm1
movsd 0x128b74(%rip), %xmm0   # 0x1d2248
divsd %xmm1, %xmm0
movsd %xmm0, 0x20(%rsp)
movsd 0x880(%rsp), %xmm0
subsd 0x858(%rsp), %xmm0
callq 0x8670
movaps %xmm0, %xmm1
movsd 0x128b48(%rip), %xmm0   # 0x1d2248
addsd %xmm0, %xmm1
movsd 0x128b3c(%rip), %xmm0   # 0x1d2248
divsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x880(%rsp), %xmm0
addsd 0x858(%rsp), %xmm0
callq 0x8670
movsd 0x18(%rsp), %xmm1
movaps %xmm0, %xmm3
movsd 0x20(%rsp), %xmm0
movsd 0x128b04(%rip), %xmm2   # 0x1d2248
addsd %xmm2, %xmm3
movsd 0x128af8(%rip), %xmm2   # 0x1d2248
divsd %xmm3, %xmm2
addsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movq 0x878(%rsp), %rax
movsd %xmm0, (%rax)
movl $0x0, 0x894(%rsp)
movl 0x894(%rsp), %eax
addq $0x898, %rsp            # imm = 0x898
retq
nopw %cs:(%rax,%rax)