Ejemplo n.º 1
0
int main(int argc, char **argv) {

  struct precision pr;        /* for precision parameters */
  struct background ba;       /* for cosmological background */
  struct thermo th;           /* for thermodynamics */
  struct perturbs pt;         /* for source functions */
  struct bessels bs;          /* for bessel functions */
  struct transfers tr;        /* for transfer functions */
  struct primordial pm;       /* for primordial spectra */
  struct spectra sp;          /* for output spectra */
  struct nonlinear nl;        /* for non-linear spectra */
  struct lensing le;          /* for lensed sepctra */
  struct output op;           /* for output files */
  ErrorMsg errmsg;            /* for error message */

  if (input_init_from_arguments(argc, argv,&pr,&ba,&th,&pt,&bs,&tr,&pm,&sp,&nl,&le,&op,errmsg) == _FAILURE_) {
    printf("\n\nError running input_init_from_arguments \n=>%s\n",errmsg); 
    return _FAILURE_;
  }

  if (background_init(&pr,&ba) == _FAILURE_) {
    printf("\n\nError running background_init \n=>%s\n",ba.error_message);
    return _FAILURE_;
  }

  if (thermodynamics_init(&pr,&ba,&th) == _FAILURE_) {
    printf("\n\nError in thermodynamics_init \n=>%s\n",th.error_message);
    return _FAILURE_;
  }

  /********************************************/
  /***** output thermodynamics quantities *****/
  /********************************************/
  
  int i;
  double tau;
  double z;
  int last_index;
  double pvecback[30];
  double pvecthermo[30];

  printf("#1: redshift z\n");
  printf("#2: conformal time tau\n");
  printf("#3: electron ionization fraction x_e\n");
  printf("#4: Thomson scattering rate kappa'\n");
  printf("#5: Thomson scattering rate derivative kappa''\n");
  printf("#6: Thomson scattering rate derivative kappa'''\n");
  printf("#7: exponential of optical depth e^-kappa\n");
  printf("#8: visibility function g = kappa' e^-kappa \n");
  printf("#9: derivative of visibility function g' \n");
  printf("#10: second derivative of visibility function g'' \n");
  printf("#11: squared baryon temperature\n");
  printf("#12: squared baryon sound speed c_b^2 \n");
  printf("#13: baryon drag optical depth tau_d \n");
  printf("#14: variation rate \n");

  /* first, quantities stored in table */

  for (i=0; i < th.tt_size; i++) {

    background_tau_of_z(&ba,th.z_table[i],&tau);

    printf("%.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e\n",
	   th.z_table[i],
	   tau,
	   th.thermodynamics_table[i*th.th_size+th.index_th_xe],
	   th.thermodynamics_table[i*th.th_size+th.index_th_dkappa],
	   th.thermodynamics_table[i*th.th_size+th.index_th_ddkappa],
	   th.thermodynamics_table[i*th.th_size+th.index_th_dddkappa],
	   th.thermodynamics_table[i*th.th_size+th.index_th_exp_m_kappa],
	   th.thermodynamics_table[i*th.th_size+th.index_th_g],
	   th.thermodynamics_table[i*th.th_size+th.index_th_dg],
	   th.thermodynamics_table[i*th.th_size+th.index_th_ddg],
	   th.thermodynamics_table[i*th.th_size+th.index_th_Tb],
	   th.thermodynamics_table[i*th.th_size+th.index_th_cb2],
	   th.thermodynamics_table[i*th.th_size+th.index_th_tau_d],
	   th.thermodynamics_table[i*th.th_size+th.index_th_rate]
	   );

  }

  /* the function thermodynamics_at_z knows how to extrapolate at
     redshifts above the maximum redshift in the table. Here we add to
     the previous output a few more points at higher redshift. */

  for (z = th.z_table[th.tt_size-1]; z < 1000*th.z_table[th.tt_size-1]; z *= 2.) {

    background_tau_of_z(&ba,z,&tau);
    
    background_at_tau(&ba,tau,ba.normal_info,ba.inter_normal,&last_index,pvecback);

    thermodynamics_at_z(&ba,&th,z,th.inter_normal,&last_index,pvecback,pvecthermo);
    
    printf("%.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e %.10e\n",
	   z,
	   tau,
	   pvecthermo[th.index_th_xe],
	   pvecthermo[th.index_th_dkappa],
	   pvecthermo[th.index_th_ddkappa],
	   pvecthermo[th.index_th_dddkappa],
	   pvecthermo[th.index_th_exp_m_kappa],
	   pvecthermo[th.index_th_g],
	   pvecthermo[th.index_th_dg],
	   pvecthermo[th.index_th_ddg],
	   pvecthermo[th.index_th_Tb],
	   pvecthermo[th.index_th_cb2],
	   pvecthermo[th.index_th_tau_d],
	   pvecthermo[th.index_th_rate]
	   );
    
  }

  /****** all calculations done, now free the structures ******/

  if (thermodynamics_free(&th) == _FAILURE_) {
    printf("\n\nError in thermodynamics_free \n=>%s\n",th.error_message);
    return _FAILURE_;
  }

  if (background_free(&ba) == _FAILURE_) {
    printf("\n\nError in background_free \n=>%s\n",ba.error_message);
    return _FAILURE_;
  }

  return _SUCCESS_;

}
Ejemplo n.º 2
0
int main(int argc, char **argv) {

  struct precision pr;        /* precision parameters (1st-order) */
  struct precision2 pr2;      /* precision parameters (2nd-order) */
  struct background ba;       /* cosmological background */
  struct thermo th;           /* thermodynamics */
  struct perturbs pt;         /* source functions (1st-order) */
  struct perturbs2 pt2;       /* source functions (2nd-order) */  
  struct transfers tr;        /* transfer functions (1st-order) */
  struct bessels bs;          /* bessel functions (1st-order) */
  struct bessels2 bs2;        /* bessel functions (2nd-order) */
  struct transfers2 tr2;      /* transfer functions (2nd-order) */
  struct primordial pm;       /* primordial spectra */
  struct spectra sp;          /* output spectra (1st-order) */
  struct nonlinear nl;        /* non-linear spectra */
  struct lensing le;          /* lensed spectra */
  struct bispectra bi;        /* bispectra */
  struct fisher fi;           /* fisher matrix */
  struct output op;           /* output files */
  ErrorMsg errmsg;            /* error messages */


  // ===================================================================================
  // =                                 Parse arguments                                 =
  // ===================================================================================

  /* We introduce the n_args variable to differentiate between CLASS arguments and the arguments
  for this function */
  int n_args = 1;
  int index_k;

	/* CLASS/SONG can accept either one argument... */
  if (argc == 2 + n_args) {
    struct stat st;
    stat (argv[1], &st);
    int is_dir = (S_ISDIR (st.st_mode) != 0);
    if (!is_dir) {
      printf ("ERROR: when giving two arguments, the first one ('%s') should be a run directory\n", argv[1]);
      return _FAILURE_;
    }
    index_k = atoi(argv[2]);
  }
  /* ... or two arguments */
  else if (argc == 3 + n_args) {
    index_k = atoi(argv[3]);
  }
  else {
    printf ("usage:     %s <ini file> <pre file> <index k>\n", argv[0]);
    printf ("           %s <run_directory> <index k>\n", argv[0]);
    return _FAILURE_;
  }


  // ===================================================================================
  // =                               Compute perturbations                             =
  // ===================================================================================
  
  /* Decrease the argument counter. The reason is that CLASS should be fed only its
  default arguments, that is the parameter files and, optionally, the run directory */
  argc -= n_args;

  if (input_init_from_arguments(argc,argv,&pr,&ba,&th,&pt,&tr,&pm,
    &sp,&nl,&le,&bs,&bi,&fi,&op,errmsg) == _FAILURE_) {
    printf("\n\nError running input_init_from_arguments \n=>%s\n",errmsg); 
    return _FAILURE_;
  }

  if (pt.has_perturbations2 == _TRUE_) {

    if (input2_init_from_arguments(argc,argv,&pr,&pr2,&ba,&th,&pt,&pt2,&tr,&bs,&bs2,&tr2,&pm,
      &sp,&nl,&le,&bi,&fi,&op,errmsg) == _FAILURE_) {
      printf("\n\nError running input_init_from_arguments \n=>%s\n",errmsg);
      return _FAILURE_;
    }
    
    /* Compute only the first-order early transfer functions, no matter what is specified in
    the input files */
    pt2.has_early_transfers1_only = _TRUE_;
  }

  if (background_init(&pr,&ba) == _FAILURE_) {
    printf("\n\nError running background_init \n=>%s\n",ba.error_message);
    return _FAILURE_;
  }

  if (thermodynamics_init(&pr,&ba,&th) == _FAILURE_) {
    printf("\n\nError in thermodynamics_init \n=>%s\n",th.error_message);
    return _FAILURE_;
  }
  
  if (pt.has_perturbations2 == _FALSE_) {
    if (perturb_init(&pr,&ba,&th,&pt) == _FAILURE_) {
      printf("\n\nError in perturb_init \n=>%s\n",pt.error_message);
      return _FAILURE_;
    }
  }
  else {
    if (perturb2_init(&pr,&pr2,&ba,&th,&pt,&pt2) == _FAILURE_) {
      printf("\n\nError in perturb2_init \n=>%s\n",pt2.error_message);
      return _FAILURE_;
    }
  }

  /* Run some checks */
  if (pt.has_scalars == _FALSE_) {
    printf ("ERROR: only scalar modes supported by this function\n");
    return _FAILURE_;
  }
  int index_md = pt.index_md_scalars;
    
  if (pt.has_ad == _FALSE_) {
    printf ("ERROR: only adiabatic modes supported by this function\n");
    return _FAILURE_;
  }
  int index_ic = pt.index_ic_ad;
  
  if ((index_k<0) || (index_k>=pt.k_size[index_md])) {
    printf ("ERROR: index_k should be between index_k=%d (k=%g) and index_k=%d (k=%g)\n",
    0, pt.k[index_md][0], pt.k_size[index_md]-1, pt.k[index_md][pt.k_size[index_md]-1]);
    return _FAILURE_;
  }
    

  // ===================================================================================
  // =                             First or second order?                              =
  // ===================================================================================

  /* Should we show the line-of-sight sources or the quadratic sources? */
  short tabulate_los_sources = _FALSE_;

  /* If we are in standard 1st-order mode, we can only access the line-of-sight sources */
  if (pt2.has_perturbations2 == _FALSE_)
    tabulate_los_sources = _TRUE_;
  
  /* Information about the cosmological model */
  double h = ba.h;
  double a_equality = ba.a_eq;  
  fprintf (stderr, "# Cosmological parameters:\n");
  fprintf (stderr, "# tau0 = %g, a_equality = %g, Omega_b = %g, Tcmb = %g, Omega_cdm = %g\n",
    ba.conformal_age, ba.a_eq, ba.Omega0_b, ba.T_cmb, ba.Omega0_cdm);
  fprintf (stderr, "# omega_lambda = %g, Omega_ur = %g, Omega_fld = %g, h = %g, tau0 = %g\n",
    ba.Omega0_lambda, ba.Omega0_ur, ba.Omega0_fld, ba.h, ba.conformal_age);
  fprintf (stderr, "# omega_b = %g, omega_cdm = %g, omega_lambda = %g, omega_ur = %g, omega_fld = %g\n",
    ba.Omega0_b*h*h, ba.Omega0_cdm*h*h, ba.Omega0_lambda*h*h, ba.Omega0_ur*h*h, ba.Omega0_fld*h*h);

  /* Info about the used gauge at first order */
  fprintf (stderr, "# gauge = ");
  if (pt.gauge == newtonian)
    fprintf (stderr, "Newtonian gauge\n");
  if (pt.gauge == synchronous)
    fprintf (stderr, "synchronous gauge\n");


  /* Sizes associated to the non-running indices in the ***sources table */
  int k_size = pt.k_size[index_md];
  int tp_size = pt.tp_size[index_md];

  int qs_size;
  if (pt.has_perturbations2 == _TRUE_)
    qs_size = pt.qs_size[index_md];

  /* Account for overshooting of 'k' */
  if(index_k > k_size-1) index_k = k_size-1;
  if(index_k < 0) index_k = 0;


  // ===================================================================================
  // =                                   Print sources                                 =
  // ===================================================================================

  /* Print information on 'k' */
  double k = pt.k[index_md][index_k];
  printf("# k = %g (index_k=%d)\n", pt.k[index_md][index_k], index_k);
  fprintf (stderr, "# k = %g (index_k=%d)\n", pt.k[index_md][index_k], index_k);

  /* Vector that will contain background quantities (we are only interested in 'a') */
  double * pvecback = malloc(ba.bg_size_short*sizeof(double));

  /* Number of rows that will be printed */
  int tau_size;
  double tau_ini, tau_end;
  if (tabulate_los_sources == _TRUE_) {
    tau_size = pt.tau_size;
    tau_ini = pt.tau_sampling[0];
    tau_end = pt.tau_sampling[pt.tau_size-1];
  }
  else {
    tau_size = pt.tau_size_quadsources;
    tau_ini = pt.tau_sampling_quadsources[0];
    tau_end = pt.tau_sampling_quadsources[pt.tau_size_quadsources-1];
  };

  /* Some debug info */
  if (tabulate_los_sources == _TRUE_)
    fprintf (stderr, "# Number of source types tp_size=%d\n", tp_size);
  else
    fprintf (stderr, "# Number of source types qs_size=%d\n", qs_size);
  fprintf (stderr, "# Will print %d rows from tau=%g to %g\n", tau_size, tau_ini, tau_end);
  fprintf (stderr, "# Considered mode: index_md=%d\n", index_md);
  fprintf (stderr, "# Considered initial condition: index_ic=%d\n", index_ic);

  /* Running index used to number the columns */
  int index_print=1;

  /* First row contains the labels of the different types */
  fprintf (stderr, "%11s(%03d) ", "tau", index_print++);     // Conformal time
  fprintf (stderr, "%11s(%03d) ", "a", index_print++);       // Scale factor   
  fprintf (stderr, "%11s(%03d) ", "y", index_print++);       // Scale factor normalized to equality
  fprintf (stderr, "%11s(%03d) ", "k_tau", index_print++);   // Scale times Conformal time    
  
  /* Build labels for the line-of-sight sources */
  char label[32];
  if (tabulate_los_sources == _TRUE_) {
    for (int index_tp = 0; index_tp < tp_size; ++index_tp) {
      sprintf(label, "S_%d", index_tp);
      fprintf (stderr, "%11s(%03d) ", label, index_print++);
    }
  }
  /* Labels for the second-order quadsources */
  else {
    for (int index_tp = 0; index_tp < qs_size; ++index_tp)
      fprintf (stderr, "%11s(%03d) ", pt.qs_labels[index_md][index_tp], index_print++);
  }

  fprintf (stderr, "\n");


  // ===================================================================================
  // =                                   Loop on time                                  =
  // ===================================================================================

  for (int index_tau = 0; index_tau < tau_size; ++index_tau) {

    double tau = (tabulate_los_sources==_TRUE_ ? pt.tau_sampling[index_tau] : pt.tau_sampling_quadsources[index_tau]);
    
    /* Extract value of the scale factor */
    int dump;
    background_at_tau(
        &ba,
        tau,
        ba.short_info,
        ba.inter_normal,
        &dump,
        pvecback
        );
    double a = pvecback[ba.index_bg_a];      
    
    fprintf (stderr, "%+16g ", tau);
    fprintf (stderr, "%+16e ", a);
    fprintf (stderr, "%+16e ", log10(a/a_equality));
    fprintf (stderr, "%+16e ", tau*k);

    /* Line of sight sources */
    if (tabulate_los_sources == _TRUE_) {
      for (int index_tp = 0; index_tp < tp_size; ++index_tp) {
        double var = pt.sources[index_md][index_ic*tp_size + index_tp][index_tau*k_size + index_k];
        fprintf (stderr, "%+16e ", var);
      }
    }
    /* Sources for the second-order system */
    else {
      for (int index_tp = 0; index_tp < qs_size; ++index_tp) {
        double var = pt.quadsources[index_md][index_ic*qs_size + index_tp][index_tau*k_size + index_k];
        fprintf (stderr, "%+16e ", var);
      }
    }
    
    fprintf (stderr, "\n");
    
  } // end of for(index_tau)
  

  // =====================================================================================
  // =                                    Free memory                                    =
  // =====================================================================================

  if (pt.has_perturbations2 == _TRUE_) {
    if (perturb2_free(&pr2, &pt2) == _FAILURE_) {
      printf("\n\nError in perturb2_free \n=>%s\n",pt2.error_message);
      return _FAILURE_;
    }
  }

  if (perturb_free(&pt) == _FAILURE_) {
    printf("\n\nError in perturb_free \n=>%s\n",pt.error_message);
    return _FAILURE_;
  }

  if (thermodynamics_free(&th) == _FAILURE_) {
    printf("\n\nError in thermodynamics_free \n=>%s\n",th.error_message);
    return _FAILURE_;
  }

  if (background_free(&ba) == _FAILURE_) {
    printf("\n\nError in background_free \n=>%s\n",ba.error_message);
    return _FAILURE_;
  }

  return _SUCCESS_;

}