MP-Gadget  5.0.1.dev1-76bc7d4726-dirty
test_omega_nu_single.c
Go to the documentation of this file.
1 #include <stdarg.h>
2 #include <stddef.h>
3 #include <setjmp.h>
4 #include <cmocka.h>
5 #include <stdio.h>
6 #include <math.h>
7 #include <gsl/gsl_integration.h>
8 #include "stub.h"
9 #include "../omega_nu_single.h"
10 #include "../physconst.h"
11 
12 #define T_CMB0 2.7255 /* present-day CMB temperature, from Fixsen 2009 */
13 
14 /* A test case that checks initialisation. */
15 static void test_rho_nu_init(void **state) {
16  (void) state; /* unused */
17  double mnu = 0.06;
18  _rho_nu_single rho_nu_tab;
19  /*Initialise*/
20  rho_nu_init(&rho_nu_tab, 0.01, mnu, BOLEVK*TNUCMB*T_CMB0);
21  /*Check everything initialised ok*/
22  assert_true(rho_nu_tab.mnu == mnu);
23  assert_true(rho_nu_tab.acc);
24  assert_true(rho_nu_tab.interp);
25  assert_true(rho_nu_tab.loga);
26  assert_true(rho_nu_tab.rhonu);
27  /*Check that loga is correctly ordered (or interpolation won't work)*/
28  int i;
29  for(i=1; i<200; i++){
30  assert_true(rho_nu_tab.loga[i] > rho_nu_tab.loga[i-1]);
31  }
32 }
33 /*Check massless neutrinos work*/
34 #define STEFAN_BOLTZMANN 5.670373e-5
35 #define OMEGAR (4*STEFAN_BOLTZMANN*8*M_PI*GRAVITY/(3*LIGHTCGS*LIGHTCGS*LIGHTCGS*HUBBLE*HUBBLE*HubbleParam*HubbleParam)*pow(T_CMB0,4))
36 #define GSL_VAL 200
37 
38 
39 /* Check that the table gives the right answer. */
40 static void test_omega_nu_single(void **state) {
41  (void) state; /* unused */
42  double mnu = 0.5;
43  double HubbleParam = 0.7;
44  _omega_nu omnu;
45  /*Initialise*/
46  double MNu[3] = {mnu, mnu, 0};
47  init_omega_nu(&omnu, MNu, 0.01, 0.7,T_CMB0);
48  assert_true(omnu.RhoNuTab[0].mnu == mnu);
49  /*This is the critical density at z=0:
50  * we allow it to change by what is (at the time of writing) the uncertainty on G.*/
51  assert_true(fabs(omnu.rhocrit - 1.8784e-29*HubbleParam*HubbleParam) < 5e-3*omnu.rhocrit);
52  /*Check everything initialised ok*/
53  double omnuz0 = omega_nu_single(&omnu, 1, 0);
54  /*Check redshift scaling*/
55  assert_true(fabs(omnuz0/pow(0.5,3) - omega_nu_single(&omnu, 0.5, 0)) < 5e-3*omnuz0);
56  /*Check not just a^-3 scaling*/
57  assert_true(omnuz0/pow(0.01,3) < omega_nu_single(&omnu, 0.01, 0));
58  /*Check that we have correctly accounted for neutrino decoupling*/
59  assert_true(fabs(omnuz0 - mnu/93.14/HubbleParam/HubbleParam) < 1e-3*omnuz0);
60  /*Check degenerate species works*/
61  assert_true(omega_nu_single(&omnu, 0.1, 1) == omega_nu_single(&omnu, 0.1, 0));
62  /*Check we get it right for massless neutrinos*/
63  double omnunomassz0 = omega_nu_single(&omnu, 1, 2);
64  assert_true(omnunomassz0 - OMEGAR*7./8.*pow(pow(4/11.,1/3.)*1.00381,4)< 1e-5*omnunomassz0);
65  assert_true(omnunomassz0/pow(0.5,4) == omega_nu_single(&omnu, 0.5, 2));
66  /*Check that we return something vaguely sensible for very early times*/
67  assert_true(omega_nu_single(&omnu,1e-4,0) > omega_nu_single(&omnu, 1,0)/pow(1e-4,3));
68 }
69 
70 
71 double get_rho_nu_conversion();
72 
73 /*Note q carries units of eV/c. kT/c has units of eV/c.
74  * M_nu has units of eV Here c=1. */
75 double rho_nu_int(double q, void * params);
76 
77 double do_exact_rho_nu_integration(double a, double mnu, double rhocrit)
78 {
79  gsl_function F;
80  gsl_integration_workspace * w = gsl_integration_workspace_alloc (GSL_VAL);
81  double abserr;
82  F.function = &rho_nu_int;
83  double kTnu = BOLEVK*TNUCMB*T_CMB0;
84  double param[2] = {mnu * a, kTnu};
85  F.params = &param;
86  double result;
87  gsl_integration_qag (&F, 0, 500*kTnu,0 , 1e-9,GSL_VAL,6,w,&result, &abserr);
88  result*=get_rho_nu_conversion()/pow(a,4)/rhocrit;
89  gsl_integration_workspace_free (w);
90  return result;
91 }
92 
93 /*Check exact integration against the interpolation table*/
94 static void test_omega_nu_single_exact(void **state)
95 {
96  double mnu = 0.05;
97  double hubble = 0.7;
98  int i;
99  _omega_nu omnu;
100  /*Initialise*/
101  double MNu[3] = {mnu, mnu, mnu};
102  init_omega_nu(&omnu, MNu, 0.01, hubble,T_CMB0);
103  double omnuz0 = omega_nu_single(&omnu, 1, 0);
104  double rhocrit = omnu.rhocrit;
105  assert_true(fabs(1 - do_exact_rho_nu_integration(1, mnu, rhocrit)/omnuz0) < 1e-6);
106  for(i=1; i< 123; i++) {
107  double a = 0.01 + i/123.;
108  omnuz0 = omega_nu_single(&omnu, a, 0);
109  double omexact = do_exact_rho_nu_integration(a, mnu, rhocrit);
110  if(fabs(omnuz0 - omexact) > 1e-6 * omnuz0)
111  printf("a=%g %g %g %g\n",a, omnuz0, omexact, omnuz0/omexact-1);
112  assert_true(fabs(1 - omexact/omnuz0) < 1e-6);
113  }
114 }
115 
116 static void test_omega_nu_init_degenerate(void **state) {
117  /*Check we correctly initialise omega_nu with degenerate neutrinos*/
118  _omega_nu omnu;
119  /*Initialise*/
120  double MNu[3] = {0.2,0.2,0.2};
121  init_omega_nu(&omnu, MNu, 0.01, 0.7,T_CMB0);
122  /*Check that we initialised the right number of arrays*/
123  assert_int_equal(omnu.nu_degeneracies[0], 3);
124  assert_int_equal(omnu.nu_degeneracies[1], 0);
125  assert_true(omnu.RhoNuTab[0].loga);
126  assert_false(omnu.RhoNuTab[1].loga);
127 }
128 
129 static void test_omega_nu_init_nondeg(void **state) {
130  /*Now check that it works with a non-degenerate set*/
131  _omega_nu omnu;
132  /*Initialise*/
133  double MNu[3] = {0.2,0.1,0.3};
134  int i;
135  init_omega_nu(&omnu, MNu, 0.01, 0.7,T_CMB0);
136  /*Check that we initialised the right number of arrays*/
137  for(i=0; i<3; i++) {
138  assert_int_equal(omnu.nu_degeneracies[i], 1);
139  assert_true(omnu.RhoNuTab[i].loga);
140  }
141 }
142 
143 static void test_get_omega_nu(void **state) {
144  /*Check that we get the right answer from get_omega_nu, in terms of rho_nu*/
145  _omega_nu omnu;
146  /*Initialise*/
147  double MNu[3] = {0.2,0.1,0.3};
148  init_omega_nu(&omnu, MNu, 0.01, 0.7,T_CMB0);
149  double total =0;
150  int i;
151  for(i=0; i<3; i++) {
152  total += omega_nu_single(&omnu, 0.5, i);
153  }
154  assert_true(fabs(get_omega_nu(&omnu, 0.5) - total) < 1e-6*total);
155 }
156 
157 static void test_get_omegag(void **state) {
158  /*Check that we get the right answer from get_omegag*/
159  _omega_nu omnu;
160  /*Initialise*/
161  double MNu[3] = {0.2,0.1,0.3};
162  const double HubbleParam = 0.7;
163  init_omega_nu(&omnu, MNu, 0.01, HubbleParam,T_CMB0);
164  const double omegag = OMEGAR/pow(0.5,4);
165  assert_true(fabs(get_omegag(&omnu, 0.5)/omegag -1)< 1e-6);
166 }
167 
168 /*Test integrate the fermi-dirac kernel between 0 and qc*/
169 static void test_nufrac_low(void **state)
170 {
171  assert_true(nufrac_low(0) == 0);
172  /*Mathematica integral: 1.*Integrate[x*x/(Exp[x] + 1), {x, 0, 0.5}]/(3*Zeta[3]/2)*/
173  assert_true(fabs(nufrac_low(1)/0.0595634-1)< 1e-5);
174  assert_true(fabs(nufrac_low(0.5)/0.00941738-1)< 1e-5);
175 }
176 
177 static void test_hybrid_neutrinos(void **state)
178 {
179  /*Check that we get the right answer from get_omegag*/
180  _omega_nu omnu;
181  /*Initialise*/
182  double MNu[3] = {0.2,0.2,0.2};
183  const double HubbleParam = 0.7;
184  init_omega_nu(&omnu, MNu, 0.01, HubbleParam,T_CMB0);
185  init_hybrid_nu(&omnu.hybnu, MNu, 700, 299792, 0.5,omnu.kBtnu);
186  /*Check that the fraction of omega change over the jump*/
187  double nufrac_part = nufrac_low(700/299792.*0.2/omnu.kBtnu);
188  assert_true(fabs(particle_nu_fraction(&omnu.hybnu, 0.50001, 0)/nufrac_part -1) < 1e-5);
189  assert_true(particle_nu_fraction(&omnu.hybnu, 0.49999, 0) == 0);
190  assert_true(fabs(get_omega_nu_nopart(&omnu, 0.499999)*(1-nufrac_part)/get_omega_nu_nopart(&omnu, 0.500001)-1) < 1e-4);
191  /*Ditto omega_nu_single*/
192  assert_true(fabs(omega_nu_single(&omnu, 0.499999, 0)*(1-nufrac_part)/omega_nu_single(&omnu, 0.500001, 0)-1) < 1e-4);
193 }
194 
195 
196 int main(void) {
197  const struct CMUnitTest tests[] = {
198  cmocka_unit_test(test_rho_nu_init),
199  cmocka_unit_test(test_omega_nu_single),
200  cmocka_unit_test(test_omega_nu_init_degenerate),
201  cmocka_unit_test(test_omega_nu_init_nondeg),
202  cmocka_unit_test(test_get_omega_nu),
203  cmocka_unit_test(test_get_omegag),
204  cmocka_unit_test(test_omega_nu_single_exact),
205  cmocka_unit_test(test_nufrac_low),
206  cmocka_unit_test(test_hybrid_neutrinos),
207  };
208  return cmocka_run_group_tests_mpi(tests, NULL, NULL);
209 }
void init_hybrid_nu(_hybrid_nu *const hybnu, const double mnu[], const double vcrit, const double light, const double nu_crit_time, const double kBtnu)
void init_omega_nu(_omega_nu *omnu, const double MNu[], const double a0, const double HubbleParam, const double tcmb0)
void rho_nu_init(_rho_nu_single *const rho_nu_tab, double a0, const double mnu, const double kBtnu)
double omega_nu_single(const _omega_nu *const omnu, const double a, int i)
double get_omegag(const _omega_nu *const omnu, const double a)
double particle_nu_fraction(const _hybrid_nu *const hybnu, const double a, const int i)
double nufrac_low(const double qc)
double get_omega_nu(const _omega_nu *const omnu, const double a)
double get_omega_nu_nopart(const _omega_nu *const omnu, const double a)
#define TNUCMB
#define BOLEVK
Definition: physconst.h:13
double rhocrit
_hybrid_nu hybnu
int nu_degeneracies[NUSPECIES]
_rho_nu_single RhoNuTab[NUSPECIES]
gsl_interp * interp
gsl_interp_accel * acc
static void test_omega_nu_single_exact(void **state)
static void test_omega_nu_init_nondeg(void **state)
static void test_omega_nu_single(void **state)
#define GSL_VAL
static void test_rho_nu_init(void **state)
static void test_get_omega_nu(void **state)
double do_exact_rho_nu_integration(double a, double mnu, double rhocrit)
static void test_nufrac_low(void **state)
static void test_omega_nu_init_degenerate(void **state)
#define T_CMB0
int main(void)
double get_rho_nu_conversion()
static void test_get_omegag(void **state)
static void test_hybrid_neutrinos(void **state)
double rho_nu_int(double q, void *params)
#define OMEGAR