source: Sophya/trunk/Cosmo/SimLSS/cosmocalc.cc@ 3120

Last change on this file since 3120 was 3115, checked in by ansari, 19 years ago

Creation initiale du groupe Cosmo avec le repertoire SimLSS de
simulation de distribution de masse 3D des galaxies par CMV+Rz
18/12/2006

File size: 11.6 KB
Line 
1#include "sopnamsp.h"
2#include "machdefs.h"
3#include <iostream>
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7#include <math.h>
8#include <unistd.h>
9
10#include "pexceptions.h"
11#include "cspline.h"
12
13#include "constcosmo.h"
14#include "cosmocalc.h"
15#include "integfunc.h"
16
17
18///////////////////////////////////////////////////////////
19//*********************** CosmoCalc *********************//
20///////////////////////////////////////////////////////////
21
22//----------------------------------------------------------
23// flat = 0 : no compute Otot from other
24// = 1 : change Omatter to get Otot=1
25// = 2 : change Olambda to get Otot=1
26// = 3 : change Orelat to get Otot=1
27// usespline = "true" : compute integrale then use spline to extrapolate
28// = "false" : compute integrale everytime
29// zmax : maximum redshift(only if usespline=true)
30
31CosmoCalc::CosmoCalc(unsigned short flat,bool usespline,double zmax)
32 : _flat(flat),
33 _zold(-1.) , _integval(0.),
34 _usespline(usespline), _computespl(true), _zmax(zmax), _spline(NULL),
35 _nspl(0), _xspl(NULL), _yspl(NULL)
36{
37 if(_usespline && _zmax<=0.) {
38 cout<<"CosmoCalc::CosmoCalc: Error bad _zmax value zmax="<< _zmax<<endl;
39 throw ParmError("CosmoCalc::UseSpline: Error bad _zmax value");
40 }
41 DefaultParam();
42 SetInteg();
43}
44
45CosmoCalc::CosmoCalc(CosmoCalc& univ)
46 : _spline(NULL), _xspl(NULL), _yspl(NULL)
47{
48 Clone(univ);
49 if(_usespline && _zmax<=0.) {
50 cout<<"CosmoCalc::CosmoCalc: Error bad _zmax value zmax="<< _zmax<<endl;
51 throw ParmError("CosmoCalc::UseSpline: Error bad _zmax value");
52 }
53}
54
55CosmoCalc::~CosmoCalc(void)
56{
57 if(_spline != NULL) delete _spline; _spline = NULL;
58 if(_xspl != NULL) delete [] _xspl; _xspl = NULL;
59 if(_yspl != NULL) delete [] _yspl; _yspl = NULL;
60}
61
62void CosmoCalc::Clone(CosmoCalc& univ)
63{
64 _flat = univ._flat;
65 _h100 = univ._h100;
66 _H0 = univ._H0;
67 _Olambda0 = univ._Olambda0;
68 _W0 = univ._W0;
69 _Omatter0 = univ._Omatter0;
70 _Obaryon0 = univ._Obaryon0;
71 _Orelat0 = univ._Orelat0;
72 _Otot0 = univ._Otot0;
73 _Ocurv0 = univ._Ocurv0;
74 _Dhubble = univ._Dhubble;
75
76 _dperc = univ._dperc;
77 _dzinc = univ._dzinc;
78 _dzmax = univ._dzmax;
79 _glorder = univ._glorder;
80 if(_xgausl.size()>0) {
81 _xgausl.resize(0); _wgausl.resize(0);
82 for(int i=0;i<(int)_xgausl.size();i++) {
83 _xgausl.push_back(univ._xgausl[i]);
84 _wgausl.push_back(univ._wgausl[i]);
85 }
86 }
87
88 _zold = -1.;
89 _integval = -1.;
90
91 _usespline = univ._usespline;
92 _computespl = true;
93 _zmax = univ._zmax;
94 _nspl = 0;
95 if(_spline) delete _spline; _spline = NULL;
96 if(_xspl) delete [] _xspl; _xspl = NULL;
97 if(_yspl) delete [] _yspl; _yspl = NULL;
98}
99
100//----------------------------------------------------------
101// On va couper l'intervalle entre [0,zmax]:
102// On parcourt [0,zmax] par pas de dzinc
103// et on cree un intervalle
104// - si la fonction varie de plus de "dperc"
105// - ou si l'increment en z est superieur a "dzmax"
106void CosmoCalc::SetInteg(double dperc,double dzinc,double dzmax,unsigned short order)
107{
108 _dperc = fabs(dperc);
109
110 _dzinc = fabs(dzinc);
111 if(_dzinc>_zmax/5.) _dzinc = _zmax/5.; // Protection against big dzinc
112
113 _dzmax = fabs(dzmax);
114 if(_dzmax<_dzinc) _dzmax = _dzinc;
115
116 _glorder = order;
117 if(_glorder<=1) _glorder = 4;
118 Compute_GaussLeg(_glorder,_xgausl,_wgausl,0.,1.);
119
120 _computespl=true;
121}
122
123void CosmoCalc::SetObaryon0(double v)
124{
125 _Obaryon0 = v;
126 if(_Obaryon0<0.) {
127 cout<<"CosmoCalc::SetObaryon0: Error bad _Obaryon0 value: "<<_Obaryon0<<endl;
128 throw ParmError("CosmoCalc::SetObaryon0: Error bad _Obaryon0 value");
129 }
130}
131
132void CosmoCalc::SetDynParam(double h100,double om0,double or0,double ol0,double w0)
133{
134 _computespl=true;
135
136 _h100 = h100;
137 _H0 = 100. * _h100 ;
138 _Dhubble = SpeedOfLight_Cst / _H0;
139
140 _Omatter0 = om0;
141 _Orelat0 = or0;
142 _Olambda0 = ol0;
143 _W0 = w0;
144 _Otot0 = _Olambda0 + _Omatter0 + _Orelat0;
145 _Ocurv0 = 1. - _Otot0;
146 if( _h100<0. || _Omatter0<0. || _Orelat0<0. || _Olambda0<0. ) {
147 cout<<"CosmoCalc::SetDynParam: Error bad parameter value"<<endl;
148 throw ParmError("CosmoCalc::SetDynParam: Error bad parameter value");
149 }
150 if(_flat==0) return;
151
152 _Otot0 = 1.; _Ocurv0 = 0.;
153 if(_flat==1) {
154 _Omatter0 = _Otot0 - _Olambda0 - _Orelat0;
155 if( _Omatter0<0. ) {
156 cout<<"CosmoCalc::SetDynParam: Error bad _Omatter0 value: "<<_Omatter0<<endl;
157 throw ParmError("CosmoCalc::SetDynParam: Error bad _Omatter0 value");
158 }
159 return;
160 }
161
162 //--
163 if(_flat==2) {
164 _Olambda0 = _Otot0 - _Omatter0 - _Orelat0;
165 if( _Olambda0<0. ) {
166 cout<<"CosmoCalc::SetDynParam: Error bad _Olambda0 value: "<<_Olambda0<<endl;
167 throw ParmError("CosmoCalc::SetDynParam: Error bad _Olambda0 value");
168 }
169 return;
170 }
171
172 //--
173 if(_flat==3) {
174 _Orelat0 = _Otot0 - _Omatter0 - _Olambda0;
175 if( _Orelat0<0. ) {
176 cout<<"CosmoCalc::SetDynParam: Error bad _Orelat0 value: "<<_Orelat0<<endl;
177 throw ParmError("CosmoCalc::SetDynParam: Error bad _Orelat0 value");
178 }
179 return;
180 }
181
182 cout<<"CosmoCalc::SetDynParam: Error bad _flat value: "<<_flat<<endl;
183 throw ParmError("CosmoCalc::SetDynParam: Error bad _flat value");
184
185}
186
187void CosmoCalc::DefaultParam(void)
188{
189 _computespl=true;
190
191 double h100 = 0.71;
192 double ol0 = 0.73, w0 = -1.;
193 double om0 = 0.135/(h100*h100);
194 // Relat = photons (2.725 K) + neutrinos (1.9 K)
195 double or0 = 2.47e-5 * (1. + 21./8.*pow(T_NU_Par/T_CMB_Par,4.)) / (h100*h100);
196 SetDynParam(h100,om0,or0,ol0,w0);
197 _Obaryon0 = 0.0224/(h100*h100);
198
199 return;
200}
201
202//----------------------------------------------------------
203void CosmoCalc::Print(double z)
204{
205 if(z<0.) z = 0.;
206
207 printf("CosmoCalc::Print(spl=%d,zmax=%g,flat=%u) for z=%g\n",int(_usespline),ZMax(),Flat(),z);
208 printf("h100=%g H0=%g Dhub=%g H(z)=%g Rhoc=%g g/cm^3\n"
209 ,h100(),H0(),Dhubble(),H(z),Rhoc(z));
210 printf("Olambda=%g W0=%g\n",Olambda(z),_W0);
211 printf("Omatter=%g Obaryon=%g\n",Omatter(z),Obaryon(z));
212 printf("Orelat=%g\n",Orelat(z));
213 printf("Otot=%g Ocurv=%g\n",Otot(z),Ocurv(z));
214 if(z <= 0.) return;
215 printf("Distance comoving: los=%g Mpc, transv=%g Mpc\n",Dloscom(z),Dtrcom(z));
216 printf("Distance: angular=%g Mpc, lum=%g Mpc\n",Dang(z),Dlum(z));
217 printf("Volume comoving element: %g Mpc^3/sr/dz=1\n",dVol(z));
218 printf("Volume comoving in [0,z] for 4Pi sr: %g Mpc^3\n",Vol4Pi(z));
219
220}
221//----------------------------------------------------------
222double CosmoCalc::Olambda(double z)
223{
224 double v = _Olambda0;
225 if(_W0 != -1.) v *= pow((1.+z),3.*(1+_W0));
226 return v / E2(z);
227}
228
229double CosmoCalc::Omatter(double z)
230{
231 return _Omatter0 * (1.+z)*(1.+z)*(1.+z) /E2(z);
232}
233
234double CosmoCalc::Obaryon(double z)
235{
236 return _Obaryon0 * (1.+z)*(1.+z)*(1.+z) /E2(z);
237}
238
239double CosmoCalc::Orelat(double z)
240{
241 double z2 = (1.+z)*(1.+z);
242 return _Orelat0 * z2*z2 /E2(z);
243}
244
245double CosmoCalc::Ocurv(double z)
246{
247 return _Ocurv0 * (1.+z)*(1.+z) /E2(z);
248}
249
250double CosmoCalc::Otot(double z)
251{
252 return Olambda(z)+Omatter(z)+Orelat(z);
253}
254
255double CosmoCalc::Rhoc(double z)
256// Densite critique au redshift "z" en "g/cm^3"
257{
258 double h2 = H(z) / MpctoMeters_Cst; h2 *= h2;
259 return 3.* h2 / (8.*M_PI*G_Newton_Cst) * 1000.;
260}
261
262//----------------------------------------------------------
263double CosmoCalc::Dloscom(double z) /* Mpc */
264{
265 return _Dhubble * NInteg(z);
266}
267
268double CosmoCalc::Dtrcom(double z) /* Mpc */
269{
270 double v = NInteg(z); // Zero curvature
271
272 if(_flat) return _Dhubble * v;
273
274 if(_Ocurv0>0.) { // hyperbolique
275 double s = sqrt(_Ocurv0);
276 v = sinh(s*v)/s;
277 } else if(_Ocurv0<0.) { // spherique
278 double s = sqrt(-_Ocurv0);
279 v = sin(s*v)/s;
280 }
281
282 return _Dhubble * v;
283
284}
285
286double CosmoCalc::Dang(double z) /* Mpc */
287{
288 return Dtrcom(z) / (1.+z);
289}
290
291double CosmoCalc::Dlum(double z) /* Mpc */
292{
293 return (1.+z) * Dtrcom(z);
294}
295
296double CosmoCalc::dVol(double z) /* Mpc^3/ sr / unite z */
297{
298 double d = Dtrcom(z);
299 return _Dhubble * d*d / E(z);
300}
301
302//----------------------------------------------------------
303double CosmoCalc::Vol4Pi(double z) /* Mpc^3 pour 4Pi sr entre [0,z] */
304 // --- on pose x = dm/dh = (1+z)*da/dh, s = sqrt(|Ok|)
305 // Ok=0 : V(z)/dh^3 = (4*Pi/3) * x^3
306 // Ok>0 : V(z)/dh^3 = (4*Pi/(2*Ok)) * (x*sqrt(1+Ok*x^2) - 1/s * asinh(s*x))
307 // Ok<0 : V(z)/dh^3 = (4*Pi/(2*Ok)) * (x*sqrt(1+Ok*x^2) - 1/s * asin(s*x) )
308 // --- on pose y = s*x (y>0)
309 // Ok>0 : V(z)/dh^3 = (4*Pi/(2*Ok*s)) * (y*sqrt(1+y^2) - asinh(y))
310 // Ok<0 : V(z)/dh^3 = (4*Pi/(2*Ok*s)) * (y*sqrt(1-y^2) - asin(y) )
311 // --- a petit "z" on a pour "y -> 0+" en faisant le DL
312 // Ok>0 : V(z)/dh^3 = 4*Pi*y^3 / (3*Ok*s) * (1 - 3*y^2/10) + O(y^7)
313 // Ok<0 : V(z)/dh^3 = -4*Pi*y^3 / (3*Ok*s) * (1 + 3*y^2/10) + O(y^7)
314 // (remarque: Ok^(3/2) = s*Ok)
315{
316 double v,x = Dtrcom(z)/_Dhubble;
317
318 if(_flat) {
319 v = 4.*M_PI/3. * x*x*x;
320 } else if(_Ocurv0>0.) {
321 double s = sqrt(_Ocurv0), y = s*x, y2 = y*y;
322 if(y<1e-6) {
323 v = 1. - 3.*y2/10.;
324 v *= 4.*M_PI*y*y2 / (3.*_Ocurv0*s);
325 } else {
326 v = y*sqrt(1.+y2) - asinh(y);
327 v *= 4.*M_PI/(2.*_Ocurv0*s);
328 }
329 } else if (_Ocurv0<0.) {
330 double s = sqrt(-_Ocurv0), y = s*x, y2 = y*y;
331 if(y<1e-6) {
332 v = 1. + 3.*y2/10.;
333 v *= -4.*M_PI*y*y2 / (3.*_Ocurv0*s);
334 } else {
335 v = y*sqrt(1.-y2) - asin(y);
336 v *= 4.*M_PI/(2.*_Ocurv0*s);
337 }
338 } else {
339 v = 4.*M_PI/3. * x*x*x;
340 }
341
342 return v * _Dhubble*_Dhubble*_Dhubble;
343}
344
345double CosmoCalc::Vol4Pi(double z1,double z2) /* Mpc^3 pour 4Pi sr entre [z1,z2] */
346{
347 return Vol4Pi(z2) - Vol4Pi(z1);
348}
349
350double CosmoCalc::E2(double z) const
351{
352 z += 1.;
353 double oldum = _Olambda0;
354
355 if(oldum>0. && _W0!=-1.) oldum *= pow(z,3.*(1.+_W0));
356
357 return oldum + z*z*(_Ocurv0 + z*(_Omatter0+z*_Orelat0));
358}
359
360//----------------------------------------------------------
361double CosmoCalc::NInteg(double z)
362{
363 if(z<0.) {
364 cout<<"CosmoCalc::NInteg: Error bad z value z="<<z<<endl;
365 throw ParmError("CosmoCalc::NInteg: Error bad z value");
366 }
367
368 // On utilise le spline
369 if(_usespline) {
370 if( (!_computespl) && (z==_zold) ) return _integval;
371 if(z>_zmax) {_zmax = z; _computespl = true;}
372 if(_computespl) Init_Spline();
373 _integval = _spline->CSplineInt(z);
374 _zold = z;
375 return _integval;
376 }
377
378 // On calcule l'integrale
379 if(z != _zold) {
380 _integval = IntegrateFunc(*this,0.,z,_dperc,_dzinc,_dzmax,_glorder);
381 _zold = z;
382 }
383 return _integval;
384
385}
386
387int_4 CosmoCalc::Init_Spline(void)
388{
389 if(_spline!=NULL)
390 {delete _spline; delete [] _xspl; delete [] _yspl;}
391
392 //-- Look for intervalles and integrate
393 vector<double> x,y;
394 double zbas=0., fbas = Integrand(zbas);
395 x.push_back(zbas); y.push_back(0.);
396 for(double z=_dzinc;z<_zmax+_dzinc && zbas<_zmax;z+=_dzinc) {
397 double f = Integrand(z);
398 bool doit = false;
399 //cout<<fbas<<","<<f<<" : "<<fabs(f-fbas)<<" >? "<<_dperc*fabs(fbas)<<endl;
400 if( fabs(f-fbas)>_dperc*fabs(fbas) ) doit = true;
401 if( z-zbas>_dzmax ) doit = true;
402 if( z>_zmax ) {doit = true; z=_zmax;}
403 if( ! doit ) continue;
404 x.push_back(z);
405 double sum = 0., dz = z-zbas;
406 for(unsigned short i=0;i<_glorder;i++) sum += _wgausl[i]*Integrand(zbas+_xgausl[i]*dz);
407 y.push_back(sum*dz);
408 //cout<<"...set... "<<zbas<<","<<z<<" , "<<fbas<<","<<f<<endl;
409 zbas = z;
410 fbas = f;
411 }
412
413 //-- Fill spline
414 _nspl = x.size();
415 _xspl = new double[_nspl];
416 _yspl = new double[_nspl];
417 for(int i=0;i<_nspl;i++) {
418 _xspl[i] = x[i];
419 _yspl[i] = y[i];
420 if(i!=0) _yspl[i] += _yspl[i-1];
421 }
422 double yp1 = Integrand(_xspl[0]);
423 double ypn = Integrand(_xspl[_nspl-1]);
424 _spline = new CSpline(_nspl,_xspl,_yspl,yp1,ypn,CSpline::NoNatural,false);
425 _spline->ComputeCSpline();
426 _computespl = false;
427
428 cout<<"CosmoCalc::Init_Spline called: (zmax="<<_zmax<<") _nspl="<<_nspl<<endl;
429 for(int i=0;i<(10<_nspl?10:_nspl);i++) cout<<_xspl[i]<<" ";
430 cout<<" ... "<<_xspl[_nspl-1]<<endl;
431
432 return _nspl;
433}
Note: See TracBrowser for help on using the repository browser.