mirror of
https://github.com/cosmo-sims/MUSIC.git
synced 2024-09-16 13:33:46 +02:00
WIP transition to monofonic infrastructure
This commit is contained in:
parent
30feb0ed4a
commit
0bf5a6cfe7
30 changed files with 1700 additions and 2371 deletions
|
@ -1,410 +0,0 @@
|
|||
/*
|
||||
This file is part of MUSIC -
|
||||
a tool to generate initial conditions for cosmological simulations
|
||||
|
||||
Copyright (C) 2008-12 Oliver Hahn, ojha@gmx.de
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __TRANSFERFUNCTION_HH
|
||||
#define __TRANSFERFUNCTION_HH
|
||||
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <gsl/gsl_errno.h>
|
||||
#include <gsl/gsl_spline.h>
|
||||
#include <gsl/gsl_sf_gamma.h>
|
||||
|
||||
#include "Numerics.hh"
|
||||
#include "general.hh"
|
||||
|
||||
#include <complex>
|
||||
|
||||
#define NZERO_Q
|
||||
|
||||
typedef std::complex<double> complex;
|
||||
|
||||
//! Abstract base class for transfer functions
|
||||
/*!
|
||||
This class implements a purely virtual interface that can be
|
||||
used to derive instances implementing various transfer functions.
|
||||
*/
|
||||
class TransferFunction{
|
||||
public:
|
||||
Cosmology m_Cosmology;
|
||||
|
||||
public:
|
||||
|
||||
TransferFunction( Cosmology acosm ) : m_Cosmology( acosm ) { };
|
||||
virtual double compute( double k ) = 0;
|
||||
virtual ~TransferFunction(){ };
|
||||
virtual double get_kmax( void ) = 0;
|
||||
virtual double get_kmin( void ) = 0;
|
||||
};
|
||||
|
||||
class TransferFunction_real
|
||||
{
|
||||
|
||||
public:
|
||||
gsl_interp_accel *accp, *accn;
|
||||
gsl_spline *splinep, *splinen;
|
||||
double Tr0_, Tmin_, Tmax_, Tscale_;
|
||||
double rneg_, rneg2_;
|
||||
static TransferFunction *ptf_;
|
||||
static double nspec_;
|
||||
|
||||
protected:
|
||||
|
||||
double krgood( double mu, double q, double dlnr, double kr )
|
||||
{
|
||||
double krnew = kr;
|
||||
complex cdgamma, zm, zp;
|
||||
double arg, iarg, xm, xp, y;
|
||||
gsl_sf_result g_a, g_p;
|
||||
|
||||
xp = 0.5*(mu+1.0+q);
|
||||
xm = 0.5*(mu+1.0-q);
|
||||
y = M_PI/(2.0*dlnr);
|
||||
zp=complex(xp,y);
|
||||
zm=complex(xm,y);
|
||||
|
||||
gsl_sf_lngamma_complex_e (zp.real(), zp.imag(), &g_a, &g_p);
|
||||
zp=std::polar(exp(g_a.val),g_p.val);
|
||||
double zpa = g_p.val;
|
||||
|
||||
gsl_sf_lngamma_complex_e (zm.real(), zm.imag(), &g_a, &g_p);
|
||||
zm=std::polar(exp(g_a.val),g_p.val);
|
||||
double zma = g_p.val;
|
||||
|
||||
arg=log(2.0/kr)/dlnr+(zpa+zma)/M_PI;
|
||||
iarg=(double)((int)(arg + 0.5));
|
||||
|
||||
if( arg!=iarg )
|
||||
krnew=kr*exp((arg-iarg)*dlnr);
|
||||
|
||||
return krnew;
|
||||
}
|
||||
|
||||
void transform( double pnorm, double dplus, unsigned N, double q, std::vector<double>& rr, std::vector<double>& TT )
|
||||
{
|
||||
const double mu = 0.5;
|
||||
double qmin = 1.0e-6, qmax = 1.0e+6;
|
||||
|
||||
q = 0.0;
|
||||
|
||||
N = 16384;
|
||||
|
||||
#ifdef NZERO_Q
|
||||
//q = 0.4;
|
||||
q = 0.2;
|
||||
#endif
|
||||
|
||||
double kmin = qmin, kmax=qmax;
|
||||
double rmin = qmin, rmax = qmax;
|
||||
double k0 = exp(0.5*(log(kmax)+log(kmin)));
|
||||
double r0 = exp(0.5*(log(rmax)+log(rmin)));
|
||||
double L = log(rmax)-log(rmin);
|
||||
double k0r0 = k0*r0;
|
||||
double dlnk = L/N, dlnr = L/N;
|
||||
|
||||
double sqrtpnorm = sqrt(pnorm);
|
||||
|
||||
double dir = 1.0;
|
||||
|
||||
double fftnorm = 1.0/N;
|
||||
|
||||
complex_t in[N], out[N];
|
||||
fftw_plan p,ip;
|
||||
|
||||
//... perform anti-ringing correction from Hamilton (2000)
|
||||
k0r0 = krgood( mu, q, dlnr, k0r0 );
|
||||
|
||||
std::ofstream ofsk("transfer_k.txt");
|
||||
double sum_in = 0.0;
|
||||
for( unsigned i=0; i<N; ++i )
|
||||
{
|
||||
|
||||
double k = k0*exp(((int)i - (int)N/2+1) * dlnk);
|
||||
//double k = k0*exp(((int)i - (int)N/2) * dlnk);
|
||||
//double k = k0*exp(ii * dlnk);
|
||||
|
||||
//... some constants missing ...//
|
||||
in[i].re = dplus*sqrtpnorm*ptf_->compute( k )*pow(k,0.5*nspec_)*pow(k,1.5-q);
|
||||
in[i].im = 0.0;
|
||||
|
||||
sum_in += in[i].re;
|
||||
ofsk << std::setw(16) << k <<std::setw(16) << in[i].re << std::endl;
|
||||
}
|
||||
ofsk.close();
|
||||
|
||||
|
||||
p = fftw_create_plan(N, FFTW_FORWARD, FFTW_ESTIMATE);
|
||||
ip = fftw_create_plan(N, FFTW_BACKWARD, FFTW_ESTIMATE);
|
||||
|
||||
//fftw_one(p, in, out);
|
||||
fftw_one(p, in, out);
|
||||
|
||||
//... compute the Hankel transform by convolution with the Bessel function
|
||||
for( unsigned i=0; i<N; ++i )
|
||||
{
|
||||
int ii=i;
|
||||
if( ii > (int)N/2 )
|
||||
ii -= N;
|
||||
|
||||
#ifndef NZERO_Q
|
||||
double y=ii*M_PI/L;
|
||||
complex zp((mu+1.0)*0.5,y);
|
||||
gsl_sf_result g_a, g_p;
|
||||
gsl_sf_lngamma_complex_e(zp.real(), zp.imag(), &g_a, &g_p);
|
||||
|
||||
double arg = 2.0*(log(2.0/k0r0)*y+g_p.val);
|
||||
complex cu = complex(out[i].re,out[i].im)*std::polar(1.0,arg);
|
||||
out[i].re = cu.real()*fftnorm;
|
||||
out[i].im = cu.imag()*fftnorm;
|
||||
|
||||
#else
|
||||
//complex x(dir*q, (double)ii*2.0*M_PI/L);
|
||||
complex x(dir*q, (double)ii*2.0*M_PI/L);
|
||||
gsl_sf_result g_a, g_p;
|
||||
|
||||
complex g1, g2, garg, U, phase;
|
||||
complex twotox = pow(complex(2.0,0.0),x);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//.. evaluate complex Gamma functions
|
||||
|
||||
garg = 0.5*(mu+1.0+x);
|
||||
gsl_sf_lngamma_complex_e (garg.real(), garg.imag(), &g_a, &g_p);
|
||||
g1 = std::polar(exp(g_a.val),g_p.val);
|
||||
|
||||
|
||||
garg = 0.5*(mu+1.0-x);
|
||||
gsl_sf_lngamma_complex_e (garg.real(), garg.imag(), &g_a, &g_p);
|
||||
g2 = std::polar(exp(g_a.val),g_p.val);
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
//.. compute U
|
||||
|
||||
if( (fabs(g2.real()) < 1e-19 && fabs(g2.imag()) < 1e-19) )
|
||||
{
|
||||
//std::cerr << "Warning : encountered possible singularity in TransferFunction_real::transform!\n";
|
||||
g1 = 1.0; g2 = 1.0;
|
||||
}
|
||||
|
||||
|
||||
U = twotox * g1 / g2;
|
||||
phase = pow(complex(k0r0,0.0),complex(0.0,2.0*M_PI*(double)ii/L));
|
||||
|
||||
complex cu = complex(out[i].re,out[i].im)*U*phase*fftnorm;
|
||||
|
||||
out[i].re = cu.real();
|
||||
out[i].im = cu.imag();
|
||||
|
||||
if( (out[i].re != out[i].re)||(out[i].im != out[i].im) )
|
||||
{ std::cerr << "NaN @ i=" << i << ", U= " << U << ", phase = " << phase << ", g1 = " << g1 << ", g2 = " << g2 << std::endl;
|
||||
std::cerr << "mu+1+q = " << mu+1.0+q << std::endl;
|
||||
//break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*out[N/2].im = 0.0;
|
||||
out[N/2+1].im = 0.0;
|
||||
out[N/2+1].re = out[N/2].re;
|
||||
out[N/2].im = 0.0;*/
|
||||
|
||||
fftw_one(ip, out, in);
|
||||
|
||||
rr.assign(N,0.0);
|
||||
TT.assign(N,0.0);
|
||||
|
||||
r0 = k0r0/k0;
|
||||
|
||||
for( unsigned i=0; i<N; ++i )
|
||||
{
|
||||
int ii = i;
|
||||
ii -= N/2-1;
|
||||
//ii -= N/2;
|
||||
//if( ii>N/2)
|
||||
// ii-=N;
|
||||
|
||||
|
||||
|
||||
double r = r0*exp(-ii*dlnr);
|
||||
rr[N-i-1] = r;
|
||||
TT[N-i-1] = 4.0*M_PI* sqrt(M_PI/2.0) * in[i].re*pow(r,-(1.5+q));
|
||||
|
||||
//TT[N-i-1] = 4.0*M_PI* sqrt(M_PI/2.0) * in[i].re*exp( -dir*(q+1.5)*ii*dlnr +q*log(k0r0))/r0;
|
||||
|
||||
//rr[i] = r;
|
||||
//TT[i] = 4.0*M_PI* sqrt(M_PI/2.0) * in[i].re*pow(r,-(1.5+q));
|
||||
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
std::ofstream ofs("transfer_real_new.txt");
|
||||
for( unsigned i=0; i<N; ++i )
|
||||
{
|
||||
int ii = i;
|
||||
ii -= N/2-1;
|
||||
|
||||
double r = r0*exp(-ii*dlnr);//r0*exp(ii*dlnr);
|
||||
double T = 4.0*M_PI* sqrt(M_PI/2.0) * in[i].re*pow(r,-(1.5+q));
|
||||
ofs << r << "\t\t" << T << "\t\t" << in[i].im << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fftw_destroy_plan(p);
|
||||
fftw_destroy_plan(ip);
|
||||
}
|
||||
|
||||
public:
|
||||
TransferFunction_real( TransferFunction *tf, double nspec, double pnorm, double dplus, double rmin, double rmax, double knymax, unsigned nr )
|
||||
{
|
||||
|
||||
ptf_ = tf;
|
||||
nspec_ = nspec;
|
||||
|
||||
double q = 0.8;
|
||||
|
||||
std::vector<double> r,T,xp,yp,xn,yn;
|
||||
|
||||
transform( pnorm, dplus, nr, q, r, T );
|
||||
|
||||
//... determine r=0 zero component by integrating up to the Nyquist frequency
|
||||
gsl_integration_workspace * wp;
|
||||
gsl_function F;
|
||||
wp = gsl_integration_workspace_alloc(20000);
|
||||
F.function = &call_wrapper;
|
||||
double par[2]; par[0] = dplus*sqrt(pnorm); //par[1] = M_PI/kny;
|
||||
F.params = (void*)par;
|
||||
double error;
|
||||
|
||||
//#warning factor of sqrt(1.5) needs to be adjusted for non-equilateral boxes
|
||||
//.. need a factor sqrt( 2*kny^2_x + 2*kny^2_y + 2*kny^2_z )/2 = sqrt(3/2)kny (in equilateral case)
|
||||
gsl_integration_qag (&F, 0.0, sqrt(1.5)*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
|
||||
//Tr0_ = 0.0;
|
||||
gsl_integration_workspace_free(wp);
|
||||
|
||||
|
||||
for( unsigned i=0; i<r.size(); ++i )
|
||||
{
|
||||
// spline positive and negative part separately
|
||||
/*if( T[i] > 0.0 )
|
||||
{
|
||||
xp.push_back( 2.0*log10(r[i]) );
|
||||
yp.push_back( log10(T[i]) );
|
||||
rneg_ = r[i];
|
||||
rneg2_ = rneg_*rneg_;
|
||||
}else {
|
||||
xn.push_back( 2.0*log10(r[i]) );
|
||||
yn.push_back( log10(-T[i]) );
|
||||
}*/
|
||||
|
||||
|
||||
if( r[i] > rmin && r[i] < rmax )
|
||||
{
|
||||
xp.push_back( 2.0*log10(r[i]) );
|
||||
yp.push_back( log10(fabs(T[i])) );
|
||||
xn.push_back( 2.0*log10(r[i]) );
|
||||
if( T[i] >= 0.0 )
|
||||
yn.push_back( 1.0 );
|
||||
else
|
||||
yn.push_back( -1.0 );
|
||||
|
||||
|
||||
//ofs << std::setw(16) << xp.back() << std::setw(16) << yp.back() << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
accp = gsl_interp_accel_alloc ();
|
||||
accn = gsl_interp_accel_alloc ();
|
||||
|
||||
//... spline interpolation is only marginally slower here
|
||||
splinep = gsl_spline_alloc (gsl_interp_cspline, xp.size() );
|
||||
splinen = gsl_spline_alloc (gsl_interp_cspline, xn.size() );
|
||||
|
||||
//... set up everything for spline interpolation
|
||||
gsl_spline_init (splinep, &xp[0], &yp[0], xp.size() );
|
||||
gsl_spline_init (splinen, &xn[0], &yn[0], xn.size() );
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
double dlogr = (log10(rmax)-log10(rmin))/100;
|
||||
std::ofstream ofs("transfer_splinep.txt");
|
||||
|
||||
for( int i=0; i< 100; ++i )
|
||||
{
|
||||
double r = rmin*pow(10.0,i*dlogr);
|
||||
ofs << std::setw(16) << r << std::setw(16) << compute_real(r*r) << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static double call_wrapper( double k, void *arg )
|
||||
{
|
||||
double *a = (double*)arg;
|
||||
return 4.0*M_PI*a[0]*ptf_->compute( k )*pow(k,0.5*nspec_)*k*k;
|
||||
}
|
||||
|
||||
~TransferFunction_real()
|
||||
{
|
||||
gsl_spline_free (splinen);
|
||||
gsl_interp_accel_free (accn);
|
||||
gsl_spline_free (splinep);
|
||||
gsl_interp_accel_free (accp);
|
||||
|
||||
}
|
||||
|
||||
inline double compute_real( double r2 ) const
|
||||
{
|
||||
const double EPS = 1e-8;
|
||||
const double Reps2 = EPS*EPS;
|
||||
|
||||
if( r2 <Reps2 )
|
||||
return Tr0_;
|
||||
double q;
|
||||
/*if( r2 < rneg2_ )
|
||||
q = pow(10.0,gsl_spline_eval (splinep, log10(r2), accp));
|
||||
else
|
||||
q = -pow(10.0,gsl_spline_eval(splinen, log10(r2), accn));*/
|
||||
|
||||
double logr2 = log10(r2);
|
||||
q = pow(10.0,gsl_spline_eval(splinep, logr2, accp));
|
||||
double sign = 1.0;
|
||||
if( gsl_spline_eval(splinen, logr2, accn) < 0.0 )
|
||||
sign = -1.0;
|
||||
return q*sign;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -31,7 +31,7 @@ double dsigma2_tophat( double k, void *pparams )
|
|||
|
||||
double w = 3.0*(sin(x)-x*cos(x))/(x*x*x);
|
||||
|
||||
double tfk = ptf->compute(k,total);
|
||||
double tfk = ptf->compute(k,delta_matter);
|
||||
return k*k * w*w * pow(k,nspect) * tfk*tfk;
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ double dsigma2_gauss( double k, void *pparams )
|
|||
|
||||
double w = exp(-x*x*0.5);
|
||||
|
||||
double tfk = ptf->compute(k,total);
|
||||
double tfk = ptf->compute(k,delta_matter);
|
||||
return k*k * w*w * pow(k,nspect) * tfk*tfk;
|
||||
}
|
||||
|
||||
|
@ -76,15 +76,15 @@ void compute_sigma_tophat( config_file& cf, transfer_function *ptf, double R, st
|
|||
z.clear();
|
||||
sigma.clear();
|
||||
|
||||
cosmology cosm( cf );
|
||||
CosmoCalc ccalc( cosm, ptf );
|
||||
cosmology::parameters cosm( cf );
|
||||
cosmology::calculator ccalc( cf );
|
||||
|
||||
double zmin = 0.0, zmax = 200.0;
|
||||
int nz = 100;
|
||||
for( int i=0; i <nz; ++i )
|
||||
z.push_back( zmax - i*(zmax-zmin)/(nz-1.0) );
|
||||
|
||||
double D0 = ccalc.CalcGrowthFactor(1.0);
|
||||
double D0 = ccalc.get_growth_factor(1.0);
|
||||
|
||||
double sigma8 = cf.get_value<double>("cosmology","sigma_8");
|
||||
double nspec = cf.get_value<double>("cosmology","nspec");
|
||||
|
@ -109,7 +109,7 @@ void compute_sigma_tophat( config_file& cf, transfer_function *ptf, double R, st
|
|||
params[2] = reinterpret_cast<char*> (&nspec);
|
||||
|
||||
double sig = sqrt(4.0*M_PI*integrate( &dsigma2_tophat, 1e-4, 1e4, reinterpret_cast<void*>(params) ));
|
||||
double Dz = ccalc.CalcGrowthFactor(1./(1.+z[i]));
|
||||
double Dz = ccalc.get_growth_factor(1./(1.+z[i]));
|
||||
sigma.push_back( sig*sigma8/sigma0*Dz/D0 );
|
||||
}
|
||||
}
|
||||
|
@ -119,15 +119,15 @@ void compute_sigma_gauss( config_file& cf, transfer_function *ptf, double R, std
|
|||
z.clear();
|
||||
sigma.clear();
|
||||
|
||||
cosmology cosm( cf );
|
||||
CosmoCalc ccalc( cosm, ptf );
|
||||
cosmology::parameters cosm( cf );
|
||||
cosmology::calculator ccalc( cf );
|
||||
|
||||
double zmin = 0.0, zmax = 200.0;
|
||||
int nz = 100;
|
||||
for( int i=0; i <nz; ++i )
|
||||
z.push_back( zmax - i*(zmax-zmin)/(nz-1.0) );
|
||||
|
||||
double D0 = ccalc.CalcGrowthFactor(1.0);
|
||||
double D0 = ccalc.get_growth_factor(1.0);
|
||||
|
||||
double sigma8 = cf.get_value<double>("cosmology","sigma_8");
|
||||
double nspec = cf.get_value<double>("cosmology","nspec");
|
||||
|
@ -152,7 +152,7 @@ void compute_sigma_gauss( config_file& cf, transfer_function *ptf, double R, std
|
|||
params[2] = reinterpret_cast<char*> (&nspec);
|
||||
|
||||
double sig = sqrt(4.0*M_PI*integrate( &dsigma2_gauss, 1e-4, 1e4, reinterpret_cast<void*>(params) ));
|
||||
double Dz = ccalc.CalcGrowthFactor(1./(1.+z[i]));
|
||||
double Dz = ccalc.get_growth_factor(1./(1.+z[i]));
|
||||
|
||||
//std::cerr << z[i] << " " << sig << std::endl;
|
||||
sigma.push_back( sig*sigma8/sigma0*Dz/D0 );
|
||||
|
@ -163,8 +163,8 @@ void compute_sigma_gauss( config_file& cf, transfer_function *ptf, double R, std
|
|||
constraint_set::constraint_set( config_file& cf, transfer_function *ptf )
|
||||
: pcf_( &cf ), ptf_( ptf )
|
||||
{
|
||||
pcosmo_ = new Cosmology( cf );
|
||||
pccalc_ = new CosmoCalc( *pcosmo_, ptf_ );
|
||||
pcosmo_ = new cosmology::parameters( cf );
|
||||
pccalc_ = new cosmology::calculator( cf );
|
||||
dplus0_ = 1.0;//pccalc_->CalcGrowthFactor( 1.0 );
|
||||
|
||||
|
||||
|
@ -218,9 +218,9 @@ constraint_set::constraint_set( config_file& cf, transfer_function *ptf )
|
|||
double zcoll = cf.get_value<double>( "constraints", temp1 );
|
||||
new_c.Rg = pow((mass/pow(2.*M_PI,1.5)/rhom),1./3.);
|
||||
|
||||
new_c.sigma = 1.686/(pccalc_->CalcGrowthFactor(1./(1.+zcoll))/pccalc_->CalcGrowthFactor(1.0));
|
||||
new_c.sigma = 1.686/(pccalc_->get_growth_factor(1./(1.+zcoll))/pccalc_->get_growth_factor(1.0));
|
||||
music::ilog.Print("sigma of constraint : %g", new_c.sigma );
|
||||
new_c.sigma *=pccalc_->CalcGrowthFactor(astart)/pccalc_->CalcGrowthFactor(1.0);
|
||||
new_c.sigma *=pccalc_->get_growth_factor(astart)/pccalc_->get_growth_factor(1.0);
|
||||
music::ilog.Print("Constraint %d : halo with %g h-1 M_o",i,pow(2.*M_PI,1.5)*rhom*pow(new_c.Rg,3));
|
||||
}
|
||||
else if( new_c.type == peak )
|
||||
|
@ -324,7 +324,7 @@ void constraint_set::wnoise_constr_corr( double dx, size_t nx, size_t ny, size_t
|
|||
|
||||
double k = sqrt(iix*iix+iiy*iiy+iiz*iiz)*(double)nx/lsub;
|
||||
|
||||
double T = ptf_->compute(k,total);
|
||||
double T = ptf_->compute(k,delta_matter);
|
||||
double Pk = pnorm*T*T*pow(k,nspec)*d3k;
|
||||
|
||||
size_t q = ((size_t)ix*ny+(size_t)iy)*nzp+(size_t)iz;
|
||||
|
@ -407,7 +407,7 @@ void constraint_set::wnoise_constr_corr( double dx, complex_t* cw, size_t nx, si
|
|||
iiz *= 2.0*M_PI/nx;
|
||||
|
||||
double k = sqrt(iix*iix+iiy*iiy+iiz*iiz)*(double)nx/lsub;
|
||||
double T = ptf_->compute(k,total);
|
||||
double T = ptf_->compute(k,delta_matter);
|
||||
|
||||
std::complex<double> v(std::conj(eval_constr(i,iix,iiy,iiz)));
|
||||
|
||||
|
@ -472,7 +472,7 @@ void constraint_set::icov_constr( double dx, size_t nx, size_t ny, size_t nz, ma
|
|||
iiz *= 2.0*M_PI/nx;
|
||||
|
||||
double k = sqrt(iix*iix+iiy*iiy+iiz*iiz)*(double)nx/lsub;
|
||||
double T = ptf_->compute(k,total);
|
||||
double T = ptf_->compute(k,delta_matter);
|
||||
std::complex<double> v(std::conj(eval_constr(i,iix,iiy,iiz)));
|
||||
v *= eval_constr(j,iix,iiy,iiz);
|
||||
v *= pnorm * pow(k,nspec) * T * T * d3k;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#include <general.hh>
|
||||
#include <config_file.hh>
|
||||
#include <transfer_function.hh>
|
||||
#include <cosmology.hh>
|
||||
#include <cosmology_calculator.hh>
|
||||
|
||||
//! matrix class serving as a gsl wrapper
|
||||
class matrix
|
||||
|
@ -119,8 +119,8 @@ protected:
|
|||
config_file *pcf_;
|
||||
std::vector<constraint> cset_;
|
||||
transfer_function *ptf_;
|
||||
CosmoCalc *pccalc_;
|
||||
Cosmology *pcosmo_;
|
||||
const cosmology::calculator *pccalc_;
|
||||
const cosmology::parameters *pcosmo_;
|
||||
double dplus0_;
|
||||
unsigned constr_level_;
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ class kernel_k : public kernel
|
|||
{
|
||||
protected:
|
||||
/**/
|
||||
double boxlength_, patchlength_, nspec_, pnorm_, volfac_, kfac_, kmax_;
|
||||
double boxlength_, patchlength_, nspec_, pnorm_, kfac_, kmax_;
|
||||
TransferFunction_k *tfk_;
|
||||
|
||||
public:
|
||||
|
@ -165,9 +165,8 @@ public:
|
|||
: kernel(cf, ptf, refh, type)
|
||||
{
|
||||
boxlength_ = pcf_->get_value<double>("setup", "boxlength");
|
||||
nspec_ = pcf_->get_value<double>("cosmology", "nspec");
|
||||
pnorm_ = pcf_->get_value<double>("cosmology", "pnorm");
|
||||
volfac_ = 1.0; //pow(boxlength,3)/pow(2.0*M_PI,3);
|
||||
nspec_ = ptf->cosmo_params_["n_s"];
|
||||
pnorm_ = ptf->cosmo_params_["pnorm"];
|
||||
kfac_ = 2.0 * M_PI / boxlength_;
|
||||
kmax_ = kfac_ / 2;
|
||||
tfk_ = new TransferFunction_k(type_, ptf_, nspec_, pnorm_);
|
||||
|
@ -231,7 +230,7 @@ public:
|
|||
for (size_t i = 0; i < len; ++i)
|
||||
{
|
||||
double kk = kfac_ * in_k[i];
|
||||
out_Tk[i] = volfac_ * tfk_->compute(kk);
|
||||
out_Tk[i] = tfk_->compute(kk);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
224
src/cosmology.hh
224
src/cosmology.hh
|
@ -1,224 +0,0 @@
|
|||
/*
|
||||
|
||||
cosmology.hh - This file is part of MUSIC -
|
||||
a code to generate multi-scale initial conditions
|
||||
for cosmological simulations
|
||||
|
||||
Copyright (C) 2010 Oliver Hahn
|
||||
|
||||
*/
|
||||
|
||||
#ifndef _COSMOLOGY_HH
|
||||
#define _COSMOLOGY_HH
|
||||
|
||||
|
||||
#include "transfer_function.hh"
|
||||
#include "mesh.hh"
|
||||
#include "general.hh"
|
||||
|
||||
/*!
|
||||
* @class CosmoCalc
|
||||
* @brief provides functions to compute cosmological quantities
|
||||
*
|
||||
* This class provides member functions to compute cosmological quantities
|
||||
* related to the Friedmann equations and linear perturbation theory
|
||||
*/
|
||||
class CosmoCalc
|
||||
{
|
||||
public:
|
||||
//! data structure to store cosmological parameters
|
||||
Cosmology m_Cosmology;
|
||||
|
||||
//! pointer to an instance of a transfer function plugin
|
||||
transfer_function_plugin *m_pTransferFunction;
|
||||
|
||||
|
||||
//! constructor for a cosmology calculator object
|
||||
/*!
|
||||
* @param acosmo a cosmological parameters structure
|
||||
* @param pTransferFunction pointer to an instance of a transfer function object
|
||||
*/
|
||||
|
||||
CosmoCalc( const Cosmology acosmo, transfer_function_plugin *pTransferFunction )
|
||||
{
|
||||
m_Cosmology = acosmo;
|
||||
m_pTransferFunction = pTransferFunction;
|
||||
}
|
||||
|
||||
//! returns the amplitude of amplitude of the power spectrum
|
||||
/*!
|
||||
* @param k the wave number in h/Mpc
|
||||
* @param a the expansion factor of the universe
|
||||
* @returns power spectrum amplitude for wave number k at time a
|
||||
*/
|
||||
inline real_t Power( real_t k, real_t a ){
|
||||
real_t m_Dplus = CalcGrowthFactor( a );
|
||||
real_t m_DplusOne = CalcGrowthFactor( 1.0 );
|
||||
real_t m_pNorm = ComputePNorm( 1e4 );
|
||||
m_Dplus /= m_DplusOne;
|
||||
m_DplusOne = 1.0;
|
||||
real_t scale = m_Dplus/m_DplusOne;
|
||||
return m_pNorm*scale*scale*TransferSq(k)*pow((double)k,(double)m_Cosmology.nspect);
|
||||
}
|
||||
|
||||
inline static double H_of_a( double a, void *Params )
|
||||
{
|
||||
Cosmology *cosm = (Cosmology*)Params;
|
||||
double a2 = a*a;
|
||||
double Ha = sqrt(cosm->Omega_m/(a2*a) + cosm->Omega_k/a2
|
||||
+ cosm->Omega_DE * pow(a,-3.*(1.+cosm->w_0+cosm->w_a)) * exp(-3.*(1.0-a)*cosm->w_a) );
|
||||
return Ha;
|
||||
}
|
||||
|
||||
inline static double Hprime_of_a( double a, void *Params )
|
||||
{
|
||||
Cosmology *cosm = (Cosmology*)Params;
|
||||
double a2 = a*a;
|
||||
double H = H_of_a( a, Params );
|
||||
double Hprime = 1/(a*H) * ( -1.5 * cosm->Omega_m / (a2*a) - cosm->Omega_k / a2
|
||||
- 1.5 * cosm->Omega_DE * pow( a, -3.*(1.+cosm->w_0+cosm->w_a) ) * exp( -3.*(1.0-a)*cosm->w_a )
|
||||
* ( 1. + cosm->w_0 + (1.-a) * cosm->w_a ) );
|
||||
return Hprime;
|
||||
}
|
||||
|
||||
|
||||
//! Integrand used by function CalcGrowthFactor to determine the linear growth factor D+
|
||||
inline static double GrowthIntegrand( double a, void *Params )
|
||||
{
|
||||
double Ha = a * H_of_a( a, Params );
|
||||
return 2.5/( Ha * Ha * Ha );
|
||||
}
|
||||
|
||||
//! Computes the linear theory growth factor D+
|
||||
/*! Function integrates over member function GrowthIntegrand and computes
|
||||
* /a
|
||||
* D+(a) = 5/2 H(a) * | [a'^3 * H(a')^3]^(-1) da'
|
||||
* /0
|
||||
*/
|
||||
real_t CalcGrowthFactor( real_t a )
|
||||
{
|
||||
real_t integral = integrate( &GrowthIntegrand, 0.0, a, (void*)&m_Cosmology );
|
||||
return H_of_a( a, (void*)&m_Cosmology ) * integral;
|
||||
}
|
||||
|
||||
//! Compute the factor relating particle displacement and velocity
|
||||
/*! Function computes
|
||||
*
|
||||
* vfac = a^2 * H(a) * dlogD+ / d log a = a^2 * H'(a) + 5/2 * [ a * D+(a) * H(a) ]^(-1)
|
||||
*
|
||||
*/
|
||||
real_t CalcVFact( real_t a )
|
||||
{
|
||||
real_t Dp = CalcGrowthFactor( a );
|
||||
real_t H = H_of_a( a, (void*)&m_Cosmology );
|
||||
real_t Hp = Hprime_of_a( a, (void*)&m_Cosmology );
|
||||
real_t a2 = a*a;
|
||||
|
||||
return ( a2 * Hp + 2.5 / ( a * Dp * H ) ) * 100.0;
|
||||
}
|
||||
|
||||
|
||||
//! Integrand for the sigma_8 normalization of the power spectrum
|
||||
/*! Returns the value of the primordial power spectrum multiplied with
|
||||
the transfer function and the window function of 8 Mpc/h at wave number k */
|
||||
static double dSigma8( double k, void *Params )
|
||||
{
|
||||
if( k<=0.0 )
|
||||
return 0.0f;
|
||||
|
||||
transfer_function *ptf = (transfer_function *)Params;
|
||||
|
||||
double x = k*8.0;
|
||||
double w = 3.0*(sin(x)-x*cos(x))/(x*x*x);
|
||||
static double nspect = (double)ptf->cosmo_.nspect;
|
||||
|
||||
double tf = ptf->compute(k, total);
|
||||
|
||||
//... no growth factor since we compute at z=0 and normalize so that D+(z=0)=1
|
||||
return k*k * w*w * pow((double)k,(double)nspect) * tf*tf;
|
||||
|
||||
}
|
||||
|
||||
//! Integrand for the sigma_8 normalization of the power spectrum
|
||||
/*! Returns the value of the primordial power spectrum multiplied with
|
||||
the transfer function and the window function of 8 Mpc/h at wave number k */
|
||||
static double dSigma8_0( double k, void *Params )
|
||||
{
|
||||
if( k<=0.0 )
|
||||
return 0.0f;
|
||||
|
||||
transfer_function *ptf = (transfer_function *)Params;
|
||||
|
||||
double x = k*8.0;
|
||||
double w = 3.0*(sin(x)-x*cos(x))/(x*x*x);
|
||||
static double nspect = (double)ptf->cosmo_.nspect;
|
||||
|
||||
double tf = ptf->compute(k, total0);
|
||||
|
||||
//... no growth factor since we compute at z=0 and normalize so that D+(z=0)=1
|
||||
return k*k * w*w * pow((double)k,(double)nspect) * tf*tf;
|
||||
|
||||
}
|
||||
|
||||
|
||||
//! Computes the square of the transfer function
|
||||
/*! Function evaluates the supplied transfer function m_pTransferFunction
|
||||
* and returns the square of its value at wave number k
|
||||
* @param k wave number at which to evaluate the transfer function
|
||||
*/
|
||||
inline real_t TransferSq( real_t k ){
|
||||
//.. parameter supplied transfer function
|
||||
real_t tf1 = m_pTransferFunction->compute(k, total);
|
||||
return tf1*tf1;
|
||||
}
|
||||
|
||||
|
||||
//! Computes the normalization for the power spectrum
|
||||
/*!
|
||||
* integrates the power spectrum to fix the normalization to that given
|
||||
* by the sigma_8 parameter
|
||||
*/
|
||||
real_t ComputePNorm( real_t kmax )
|
||||
{
|
||||
real_t sigma0, kmin;
|
||||
kmax = m_pTransferFunction->get_kmax();//m_Cosmology.H0/8.0;
|
||||
kmin = m_pTransferFunction->get_kmin();//0.0;
|
||||
|
||||
if( !m_pTransferFunction->tf_has_total0() )
|
||||
sigma0 = 4.0 * M_PI * integrate( &dSigma8, (double)kmin, (double)kmax, (void*)m_pTransferFunction );
|
||||
else
|
||||
sigma0 = 4.0 * M_PI * integrate( &dSigma8_0, (double)kmin, (double)kmax, (void*)m_pTransferFunction );
|
||||
|
||||
return m_Cosmology.sigma8*m_Cosmology.sigma8/sigma0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//! compute the jeans sound speed
|
||||
/*! given a density in g/cm^-3 and a mass in g it gives back the sound
|
||||
* speed in cm/s for which the input mass is equal to the jeans mass
|
||||
* @param rho density
|
||||
* @param mass mass scale
|
||||
* @returns jeans sound speed
|
||||
*/
|
||||
inline double jeans_sound_speed( double rho, double mass )
|
||||
{
|
||||
const double G = 6.67e-8;
|
||||
return pow( 6.0*mass/M_PI*sqrt(rho)*pow(G,1.5), 1.0/3.0 );
|
||||
}
|
||||
|
||||
//! computes the density from the potential using the Laplacian
|
||||
void compute_Lu_density( const grid_hierarchy& u, grid_hierarchy& fnew, unsigned order=4 );
|
||||
|
||||
//! computes the 2nd order density perturbations using also off-diagonal terms in the potential Hessian
|
||||
void compute_LLA_density( const grid_hierarchy& u, grid_hierarchy& fnew, unsigned order=4 );
|
||||
|
||||
//! computes the source term for the 2nd order perturbations in the displacements
|
||||
void compute_2LPT_source( const grid_hierarchy& u, grid_hierarchy& fnew, unsigned order=4 );
|
||||
|
||||
void compute_2LPT_source_FFT( config_file& cf_, const grid_hierarchy& u, grid_hierarchy& fnew );
|
||||
|
||||
|
||||
#endif // _COSMOLOGY_HH
|
||||
|
|
@ -17,11 +17,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <vec.hh>
|
||||
#include "math/vec.hh"
|
||||
|
||||
#include <cosmology_parameters.hh>
|
||||
#include <physical_constants.hh>
|
||||
#include <transfer_function_plugin.hh>
|
||||
#include <transfer_function.hh>
|
||||
#include <math/ode_integrate.hh>
|
||||
#include <logger.hh>
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
|||
#include <gsl/gsl_integration.h>
|
||||
#include <gsl/gsl_errno.h>
|
||||
|
||||
namespace cosmology_new
|
||||
namespace cosmology
|
||||
{
|
||||
|
||||
/*!
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
cosmology::parameters cosmo_param_;
|
||||
|
||||
//! pointer to an instance of a transfer function plugin
|
||||
std::unique_ptr<TransferFunction_plugin> transfer_function_;
|
||||
std::unique_ptr<transfer_function_plugin> transfer_function_;
|
||||
|
||||
private:
|
||||
static constexpr double REL_PRECISION = 1e-10;
|
||||
|
@ -90,7 +90,7 @@ private:
|
|||
*/
|
||||
void compute_growth( std::vector<double>& tab_a, std::vector<double>& tab_D, std::vector<double>& tab_f )
|
||||
{
|
||||
using v_t = vec_t<3, double>;
|
||||
using v_t = vec_t<3,double>;
|
||||
|
||||
// set ICs, very deep in radiation domination
|
||||
const double a0 = 1e-10;
|
||||
|
@ -177,9 +177,10 @@ public:
|
|||
Dplus_target_ = D_of_a_( atarget_ ) / Dnow_;
|
||||
|
||||
music::ilog << "Linear growth factors: D+_target = " << Dplus_target_ << ", D+_start = " << Dplus_start_ << std::endl;
|
||||
music::ilog << "-------------------------------------------------------------------------------" << std::endl;
|
||||
|
||||
// set up transfer functions and compute normalisation
|
||||
transfer_function_ = select_TransferFunction_plugin(cf, cosmo_param_);
|
||||
transfer_function_ = select_transfer_function_plugin(cf, cosmo_param_);
|
||||
transfer_function_->intialise();
|
||||
if( !transfer_function_->tf_isnormalised_ ){
|
||||
cosmo_param_.set("pnorm", this->compute_pnorm_from_sigma8() );
|
||||
|
@ -190,9 +191,14 @@ public:
|
|||
}
|
||||
cosmo_param_.set("sqrtpnorm", std::sqrt(cosmo_param_["pnorm"]));
|
||||
|
||||
music::ilog << std::setw(32) << std::left << "TF supports distinct CDM+baryons"
|
||||
// if (!transfer_function_->tf_is_distinct())
|
||||
// music::wlog << " - WARNING: The selected transfer function does not support" << std::endl
|
||||
// << " distinct amplitudes for baryon and DM fields!" << std::endl
|
||||
// << " Perturbation amplitudes will be identical!" << std::endl;
|
||||
|
||||
music::ilog << std::setw(32) << std::left << " . TF supports distinct CDM+baryons"
|
||||
<< " : " << (transfer_function_->tf_is_distinct() ? "yes" : "no") << std::endl;
|
||||
music::ilog << std::setw(32) << std::left << "TF maximum wave number"
|
||||
music::ilog << std::setw(32) << std::left << " . TF maximum wave number"
|
||||
<< " : " << transfer_function_->get_kmax() << " h/Mpc" << std::endl;
|
||||
|
||||
m_n_s_ = cosmo_param_["n_s"];
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
* @brief namespace encapsulating all things cosmology
|
||||
*
|
||||
*/
|
||||
namespace cosmology_new{
|
||||
namespace cosmology{
|
||||
|
||||
//! we store here the preset cosmological paramters
|
||||
parameters::defaultmmap_t parameters::default_pmaps_
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <config_file.hh>
|
||||
#include <general.hh>
|
||||
|
||||
namespace cosmology_new
|
||||
namespace cosmology
|
||||
{
|
||||
//! structure for cosmological parameters
|
||||
class parameters
|
||||
|
@ -50,6 +50,19 @@ namespace cosmology_new
|
|||
return it->second;
|
||||
}
|
||||
|
||||
//! get routine for cosmological parameter key-value pairs
|
||||
double& get(const std::string &key)
|
||||
{
|
||||
auto it = pmap_.find(key);
|
||||
if (it == pmap_.end())
|
||||
{
|
||||
auto errmsg = std::string("Cosmological parameter \'") + key + std::string("\' does not exist in internal list.");
|
||||
music::elog << errmsg << std::endl;
|
||||
throw std::runtime_error(errmsg.c_str());
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
//! set routine for cosmological parameter key-value pairs
|
||||
void set(const std::string &key, const double value)
|
||||
{
|
||||
|
@ -69,6 +82,9 @@ namespace cosmology_new
|
|||
//! shortcut get routine for cosmological parameter key-value pairs through bracket operator
|
||||
inline double operator[](const std::string &key) const { return this->get(key); }
|
||||
|
||||
//! shortcut get routine for cosmological parameter key-value pairs through bracket operator
|
||||
inline double& operator[](const std::string &key) { return this->get(key); }
|
||||
|
||||
//! default constructor does nothing
|
||||
parameters() {}
|
||||
|
||||
|
|
|
@ -253,9 +253,10 @@ void fft_interpolate(m1 &V, m2 &v, bool from_basegrid = false)
|
|||
/*******************************************************************************************/
|
||||
/*******************************************************************************************/
|
||||
|
||||
void GenerateDensityUnigrid(config_file &cf, transfer_function *ptf, tf_type type,
|
||||
void GenerateDensityUnigrid(config_file &cf, const cosmology::calculator* cc, tf_type type,
|
||||
refinement_hierarchy &refh, noise_generator &rand, grid_hierarchy &delta, bool smooth, bool shift)
|
||||
{
|
||||
auto ptf = cc->transfer_function_.get();
|
||||
unsigned levelmin, levelmax, levelminPoisson;
|
||||
|
||||
levelminPoisson = cf.get_value<unsigned>("setup", "levelmin");
|
||||
|
@ -308,10 +309,11 @@ void GenerateDensityUnigrid(config_file &cf, transfer_function *ptf, tf_type typ
|
|||
/*******************************************************************************************/
|
||||
/*******************************************************************************************/
|
||||
|
||||
void GenerateDensityHierarchy(config_file &cf, transfer_function *ptf, tf_type type,
|
||||
void GenerateDensityHierarchy(config_file &cf, const cosmology::calculator* cc, tf_type type,
|
||||
refinement_hierarchy &refh, noise_generator &rand,
|
||||
grid_hierarchy &delta, bool smooth, bool shift)
|
||||
{
|
||||
auto ptf = cc->transfer_function_.get();
|
||||
unsigned levelmin, levelmax, levelminPoisson;
|
||||
std::vector<long> rngseeds;
|
||||
std::vector<std::string> rngfnames;
|
||||
|
|
|
@ -15,16 +15,14 @@
|
|||
|
||||
#include "general.hh"
|
||||
#include "config_file.hh"
|
||||
// #include "density_grid.hh"
|
||||
#include "random.hh"
|
||||
#include "cosmology.hh"
|
||||
#include "transfer_function.hh"
|
||||
#include "general.hh"
|
||||
|
||||
void GenerateDensityHierarchy(config_file &cf, transfer_function *ptf, tf_type type,
|
||||
void GenerateDensityHierarchy(config_file &cf, const cosmology::calculator* cc, tf_type type,
|
||||
refinement_hierarchy &refh, noise_generator &rand, grid_hierarchy &delta, bool smooth, bool shift);
|
||||
|
||||
void GenerateDensityUnigrid(config_file &cf, transfer_function *ptf, tf_type type,
|
||||
void GenerateDensityUnigrid(config_file &cf, const cosmology::calculator*, tf_type type,
|
||||
refinement_hierarchy &refh, noise_generator &rand, grid_hierarchy &delta, bool smooth, bool shift);
|
||||
|
||||
void normalize_density(grid_hierarchy &delta);
|
||||
|
|
|
@ -12,9 +12,10 @@
|
|||
|
||||
#include <logger.hh>
|
||||
#include <config_file.hh>
|
||||
|
||||
#include <memory>
|
||||
#include <cassert>
|
||||
#include <omp.h>
|
||||
#include <complex>
|
||||
|
||||
#include <fftw3.h>
|
||||
|
||||
|
@ -35,6 +36,8 @@
|
|||
#define FFTW_PREFIX fftwl
|
||||
#endif
|
||||
|
||||
using ccomplex_t = std::complex<real_t>;
|
||||
|
||||
#define FFTW_GEN_NAME_PRIM(a, b) a##_##b
|
||||
#define FFTW_GEN_NAME(a, b) FFTW_GEN_NAME_PRIM(a, b)
|
||||
#define FFTW_API(x) FFTW_GEN_NAME(FFTW_PREFIX, x)
|
||||
|
@ -46,14 +49,13 @@ using fftw_plan_t = FFTW_GEN_NAME(FFTW_PREFIX, plan);
|
|||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
using vec3_t = std::array<real_t,3>;
|
||||
|
||||
namespace CONFIG
|
||||
{
|
||||
// extern int MPI_thread_support;
|
||||
// extern int MPI_task_rank;
|
||||
// extern int MPI_task_size;
|
||||
// extern bool MPI_ok;
|
||||
extern int MPI_task_rank;
|
||||
extern int MPI_task_size;
|
||||
extern bool MPI_ok;
|
||||
// extern bool MPI_threads_ok;
|
||||
extern bool FFTW_threads_ok;
|
||||
extern int num_threads;
|
||||
|
@ -80,7 +82,8 @@ inline T POW4( T a ){
|
|||
|
||||
|
||||
//! structure for cosmological parameters
|
||||
typedef struct cosmology{
|
||||
/*
|
||||
typedef struct cosmology_old{
|
||||
double
|
||||
Omega_m, //!< baryon+dark matter density
|
||||
Omega_b, //!< baryon matter density
|
||||
|
@ -133,7 +136,7 @@ typedef struct cosmology{
|
|||
{
|
||||
|
||||
}
|
||||
}Cosmology;
|
||||
}Cosmology;*/
|
||||
|
||||
//! basic box/grid/refinement structure parameters
|
||||
typedef struct {
|
||||
|
|
171
src/main.cc
171
src/main.cc
|
@ -44,7 +44,9 @@ extern "C"
|
|||
#include <densities.hh>
|
||||
|
||||
#include <convolution_kernel.hh>
|
||||
#include <cosmology.hh>
|
||||
#include <perturbation_theory.hh>
|
||||
#include <cosmology_parameters.hh>
|
||||
#include <cosmology_calculator.hh>
|
||||
#include <transfer_function.hh>
|
||||
|
||||
#define THE_CODE_NAME "music!"
|
||||
|
@ -53,9 +55,9 @@ extern "C"
|
|||
// initialise with "default" values
|
||||
namespace CONFIG{
|
||||
// int MPI_thread_support = -1;
|
||||
// int MPI_task_rank = 0;
|
||||
// int MPI_task_size = 1;
|
||||
// bool MPI_ok = false;
|
||||
int MPI_task_rank = 0;
|
||||
int MPI_task_size = 1;
|
||||
bool MPI_ok = false;
|
||||
// bool MPI_threads_ok = false;
|
||||
bool FFTW_threads_ok = false;
|
||||
int num_threads = 1;
|
||||
|
@ -67,7 +69,7 @@ namespace music
|
|||
|
||||
struct framework
|
||||
{
|
||||
transfer_function *the_transfer_function;
|
||||
// transfer_function *the_transfer_function;
|
||||
// poisson_solver *the_poisson_solver;
|
||||
config_file *the_config_file;
|
||||
refinement_hierarchy *the_refinement_hierarchy;
|
||||
|
@ -76,13 +78,15 @@ namespace music
|
|||
}
|
||||
|
||||
//... declare static class members here
|
||||
transfer_function *TransferFunction_real::ptf_ = NULL;
|
||||
// transfer_function *TransferFunction_real::ptf_ = NULL;
|
||||
transfer_function *TransferFunction_k::ptf_ = NULL;
|
||||
tf_type TransferFunction_k::type_;
|
||||
tf_type TransferFunction_real::type_;
|
||||
real_t TransferFunction_real::nspec_ = -1.0;
|
||||
// tf_type TransferFunction_real::type_;
|
||||
// real_t TransferFunction_real::nspec_ = -1.0;
|
||||
real_t TransferFunction_k::nspec_ = -1.0;
|
||||
|
||||
std::unique_ptr<cosmology::calculator> the_cosmo_calc;
|
||||
|
||||
//... prototypes for routines used in main driver routine
|
||||
void splash(void);
|
||||
void modify_grid_for_TF(const refinement_hierarchy &rh_full, refinement_hierarchy &rh_TF, config_file &cf);
|
||||
|
@ -95,17 +99,24 @@ void splash(void)
|
|||
{
|
||||
|
||||
music::ilog << std::endl
|
||||
<< " __ __ __ __ ______ __ ______ " << std::endl
|
||||
<< " /\\ \"-./ \\ /\\ \\/\\ \\ /\\ ___\\ /\\ \\ /\\ ___\\ " << std::endl
|
||||
<< " \\ \\ \\-./\\ \\ \\ \\ \\_\\ \\ \\ \\___ \\ \\ \\ \\ \\ \\ \\____ " << std::endl
|
||||
<< " \\ \\_\\ \\ \\_\\ \\ \\_____\\ \\/\\_____\\ \\ \\_\\ \\ \\_____\\ " << std::endl
|
||||
<< " \\/_/ \\/_/ \\/_____/ \\/_____/ \\/_/ \\/_____/ " << std::endl << std::endl
|
||||
<< " this is " << THE_CODE_NAME << " version " << THE_CODE_VERSION << std::endl << std::endl;
|
||||
<< " __ __ __ __ ______ __ ______ " << std::endl
|
||||
<< " /\\ \"-./ \\ /\\ \\/\\ \\ /\\ ___\\ /\\ \\ /\\ ___\\ " << std::endl
|
||||
<< " \\ \\ \\-./\\ \\ \\ \\ \\_\\ \\ \\ \\___ \\ \\ \\ \\ \\ \\ \\____ " << std::endl
|
||||
<< " \\ \\_\\ \\ \\_\\ \\ \\_____\\ \\/\\_____\\ \\ \\_\\ \\ \\_____\\ " << std::endl
|
||||
<< " \\/_/ \\/_/ \\/_____/ \\/_____/ \\/_/ \\/_____/ " << std::endl << std::endl
|
||||
<< " this is " << THE_CODE_NAME << " version " << THE_CODE_VERSION << std::endl << std::endl;
|
||||
|
||||
#if defined(CMAKE_BUILD)
|
||||
music::ilog.Print("Version built from git rev.: %s, tag: %s, branch: %s", GIT_REV, GIT_TAG, GIT_BRANCH);
|
||||
// git and versioning info:
|
||||
music::ilog << "Version: git rev.: " << GIT_REV << ", tag: " << GIT_TAG << ", branch: " << GIT_BRANCH << std::endl;
|
||||
|
||||
// Compilation CMake configuration, time etc info:
|
||||
music::ilog << "This " << CMAKE_BUILDTYPE_STR << " build was compiled at " << __TIME__ << " on " << __DATE__ << std::endl;
|
||||
|
||||
#ifdef __GNUC__
|
||||
music::ilog << "Compiled with GNU C++ version " << __VERSION__ <<std::endl;
|
||||
#else
|
||||
music::ilog << "Compiled with " << __VERSION__ << std::endl;
|
||||
#endif
|
||||
music::ilog << std::endl << std::endl;
|
||||
}
|
||||
|
||||
void modify_grid_for_TF(const refinement_hierarchy &rh_full, refinement_hierarchy &rh_TF, config_file &cf)
|
||||
|
@ -378,6 +389,7 @@ int main(int argc, const char *argv[])
|
|||
splash();
|
||||
std::cout << " This version is compiled with the following plug-ins:\n";
|
||||
|
||||
cosmology::print_ParameterSets();
|
||||
print_region_generator_plugins();
|
||||
print_transfer_function_plugins();
|
||||
print_RNG_plugins();
|
||||
|
@ -407,8 +419,6 @@ int main(int argc, const char *argv[])
|
|||
config_file cf(argv[1]);
|
||||
std::string tfname, randfname, temp;
|
||||
bool force_shift(false);
|
||||
double boxlength;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//... init multi-threading
|
||||
|
@ -424,7 +434,6 @@ int main(int argc, const char *argv[])
|
|||
//... initialize some parameters about grid set-up
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
boxlength = cf.get_value<double>("setup", "boxlength");
|
||||
lbase = cf.get_value<unsigned>("setup", "levelmin");
|
||||
lmax = cf.get_value<unsigned>("setup", "levelmax");
|
||||
lbaseTF = cf.get_value_safe<unsigned>("setup", "levelmin_TF", lbase);
|
||||
|
@ -463,39 +472,42 @@ int main(int argc, const char *argv[])
|
|||
do_LLA = cf.get_value_safe<bool>("setup", "use_LLA", false),
|
||||
do_counter_mode = cf.get_value_safe<bool>("setup", "zero_zoom_velocity", false);
|
||||
|
||||
transfer_function_plugin *the_transfer_function_plugin = select_transfer_function_plugin(cf);
|
||||
the_cosmo_calc = std::make_unique<cosmology::calculator>(cf);
|
||||
|
||||
cosmology cosmo(cf);
|
||||
bool tf_has_velocities = the_cosmo_calc.get()->transfer_function_.get()->tf_has_velocities();
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
//! starting redshift
|
||||
const real_t zstart = cf.get_value<double>("setup", "zstart");
|
||||
const real_t astart = 1.0/(1.0+zstart);
|
||||
|
||||
music::ilog << "- starting at a=" << 1.0/(1.0+zstart) << std::endl;
|
||||
|
||||
music::ilog << "- starting at a=" << cosmo.astart << std::endl;
|
||||
|
||||
CosmoCalc ccalc(cosmo, the_transfer_function_plugin);
|
||||
cosmo.pnorm = ccalc.ComputePNorm(2.0 * M_PI / boxlength);
|
||||
cosmo.dplus = ccalc.CalcGrowthFactor(cosmo.astart) / ccalc.CalcGrowthFactor(1.0);
|
||||
cosmo.vfact = ccalc.CalcVFact(cosmo.astart);
|
||||
|
||||
if (!the_transfer_function_plugin->tf_has_total0())
|
||||
cosmo.pnorm *= cosmo.dplus * cosmo.dplus;
|
||||
double cosmo_dplus = the_cosmo_calc->get_growth_factor(astart) / the_cosmo_calc->get_growth_factor(1.0);
|
||||
double cosmo_vfact = the_cosmo_calc->get_vfact(astart);
|
||||
|
||||
if (!the_cosmo_calc.get()->transfer_function_.get()->tf_has_total0()){
|
||||
the_cosmo_calc->cosmo_param_["pnorm"] *= cosmo_dplus * cosmo_dplus;
|
||||
}
|
||||
double cosmo_pnorm = the_cosmo_calc->cosmo_param_["pnorm"];
|
||||
//... directly use the normalisation via a parameter rather than the calculated one
|
||||
cosmo.pnorm = cf.get_value_safe<double>("setup", "force_pnorm", cosmo.pnorm);
|
||||
cosmo_pnorm = cf.get_value_safe<double>("setup", "force_pnorm", cosmo_pnorm);
|
||||
|
||||
double vfac2lpt = 1.0;
|
||||
|
||||
if (the_transfer_function_plugin->tf_velocity_units() && do_baryons)
|
||||
if (the_cosmo_calc->transfer_function_->tf_velocity_units() && do_baryons)
|
||||
{
|
||||
vfac2lpt = cosmo.vfact; // if the velocities are in velocity units, we need to divide by vfact for the 2lPT term
|
||||
cosmo.vfact = 1.0;
|
||||
vfac2lpt = cosmo_vfact; // if the velocities are in velocity units, we need to divide by vfact for the 2lPT term
|
||||
cosmo_vfact = 1.0;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
{
|
||||
char tmpstr[128];
|
||||
snprintf(tmpstr, 128, "%.12g", cosmo.pnorm);
|
||||
snprintf(tmpstr, 128, "%.12g", cosmo_pnorm);
|
||||
cf.insert_value("cosmology", "pnorm", tmpstr);
|
||||
snprintf(tmpstr, 128, "%.12g", cosmo.dplus);
|
||||
snprintf(tmpstr, 128, "%.12g", cosmo_dplus);
|
||||
cf.insert_value("cosmology", "dplus", tmpstr);
|
||||
snprintf(tmpstr, 128, "%.12g", cosmo.vfact);
|
||||
snprintf(tmpstr, 128, "%.12g", cosmo_vfact);
|
||||
cf.insert_value("cosmology", "vfact", tmpstr);
|
||||
}
|
||||
|
||||
|
@ -505,16 +517,13 @@ int main(int argc, const char *argv[])
|
|||
//... determine run parameters
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
if (!the_transfer_function_plugin->tf_is_distinct() && do_baryons)
|
||||
music::wlog << " - WARNING: The selected transfer function does not support" << std::endl
|
||||
<< " distinct amplitudes for baryon and DM fields!" << std::endl
|
||||
<< " Perturbation amplitudes will be identical!" << std::endl;
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//... start up the random number generator plugin
|
||||
//... see if we need to set some grid building constraints
|
||||
noise_generator rand( cf, the_transfer_function_plugin );
|
||||
noise_generator rand( cf );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//... determine the refinement hierarchy
|
||||
|
@ -549,13 +558,11 @@ int main(int argc, const char *argv[])
|
|||
music::ilog << " GENERATING WHITE NOISE\n";
|
||||
music::ilog << "-------------------------------------------------------------------------------" << std::endl;
|
||||
music::ilog << "Computing white noise..." << std::endl;
|
||||
// rand_gen rand(cf, rh_TF, the_transfer_function_plugin);
|
||||
rand.initialize_for_grid_structure( rh_TF );
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//... initialize the Poisson solver
|
||||
//------------------------------------------------------------------------------
|
||||
// bool bdefd = cf.get_value_safe<bool> ( "poisson" , "fft_fine", true );
|
||||
bool bdefd = true; // we set this by default and don't allow it to be changed outside any more
|
||||
bool bglass = cf.get_value_safe<bool>("output", "glass", false);
|
||||
bool bsph = cf.get_value_safe<bool>("setup", "do_SPH", false) && do_baryons;
|
||||
|
@ -610,11 +617,11 @@ int main(int argc, const char *argv[])
|
|||
music::ulog.Print("Computing dark matter displacements...");
|
||||
|
||||
grid_hierarchy f(nbnd); //, u(nbnd);
|
||||
tf_type my_tf_type = cdm;
|
||||
if (!do_baryons || !the_transfer_function_plugin->tf_is_distinct())
|
||||
my_tf_type = total;
|
||||
tf_type my_tf_type = delta_cdm;
|
||||
if (!do_baryons)
|
||||
my_tf_type = delta_matter;
|
||||
|
||||
GenerateDensityHierarchy(cf, the_transfer_function_plugin, my_tf_type, rh_TF, rand, f, false, false);
|
||||
GenerateDensityHierarchy(cf, the_cosmo_calc.get(), my_tf_type, rh_TF, rand, f, false, false);
|
||||
coarsen_density(rh_Poisson, f, bspectral_sampling);
|
||||
f.add_refinement_mask(rh_Poisson.get_coord_shift());
|
||||
|
||||
|
@ -678,7 +685,7 @@ int main(int argc, const char *argv[])
|
|||
music::ilog << " COMPUTING BARYON DENSITY\n";
|
||||
music::ilog << "-------------------------------------------------------------------------------" << std::endl;
|
||||
music::ulog.Print("Computing baryon density...");
|
||||