1
0
Fork 0
mirror of https://github.com/cosmo-sims/MUSIC.git synced 2024-09-19 17:03:46 +02:00

Migrated several implementations to .cc files.

Some minor bugfixes.
No longer use Akima splines, use cubic splines in tabulated transfer functions
Added more ocnstraint infrastructure.
This commit is contained in:
Oliver Hahn 2010-11-12 15:05:45 -08:00
parent 485d6f2a4e
commit 27fe21e3d4
19 changed files with 2481 additions and 1602 deletions

View file

@ -62,7 +62,7 @@ endif
##############################################################################
CFLAGS += $(OPT)
TARGET = MUSIC
OBJS = output.o transfer_function.o Numerics.o defaults.o\
OBJS = output.o transfer_function.o Numerics.o defaults.o constraints.o random.o\
convolution_kernel.o densities.o cosmology.o poisson.o log.o main.o \
$(patsubst plugins/%.cc,plugins/%.o,$(wildcard plugins/*.cc))

View file

@ -34,6 +34,8 @@
#include <cmath>
#include <gsl/gsl_integration.h>
#include <gsl/gsl_errno.h>
#include <vector>
#include <algorithm>
#include "general.hh"

View file

@ -134,9 +134,35 @@ public:
posEqual=line.find('=');
name = trim(line.substr(0,posEqual));
value = trim(line.substr(posEqual+1));
if( (size_t)posEqual==std::string::npos && (name.size()!=0||value.size()!=0) )
{
LOGWARN("Ignoring non-assignment in %s:%d",FileName.c_str(),m_iLine);
continue;
}
if(name.length()==0&&value.size()!=0)
{
LOGWARN("Ignoring assignment missing entry name in %s:%d",FileName.c_str(),m_iLine);
continue;
}
if(value.length()==0&&name.size()!=0)
{
LOGWARN("Empty entry will be ignored in %s:%d",FileName.c_str(),m_iLine);
continue;
}
if( value.length()==0&&name.size()==0)
continue;
//.. add key/value pair to hash table ..
m_Items[inSection+'/'+name] = value;
if( m_Items.find(inSection+'/'+name) != m_Items.end() )
LOGWARN("Redeclaration overwrites previous value in %s:%d",FileName.c_str(),m_iLine);
m_Items[inSection+'/'+name] = value;
}
}

365
constraints.cc Normal file
View file

@ -0,0 +1,365 @@
/*
constraints.cc - This file is part of MUSIC -
a code to generate multi-scale initial conditions
for cosmological simulations
Copyright (C) 2010 Oliver Hahn
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/>.
*/
#include "constraints.hh"
constraint_set::constraint_set( config_file& cf, transfer_function *ptf )
: pcf_( &cf ), ptf_( ptf )
{
pcosmo_ = new Cosmology( cf );
pccalc_ = new CosmoCalc( *pcosmo_, ptf_ );
dplus0_ = 1.0;//pccalc_->CalcGrowthFactor( 1.0 );
unsigned i=0;
unsigned levelmin_TF = pcf_->getValue<unsigned>("setup","levelmin_TF");
constr_level_ = pcf_->getValueSafe<unsigned>("constraints","level",levelmin_TF);
constr_level_ = std::max(constr_level_,levelmin_TF);
//double omegam = pcf_->getValue<double>("cosmology","Omega_m");
//double rhom = omegam*2.77519737e11; //... mean matter density
//... use EdS density for estimation
double rhom = 2.77519737e11;
std::map< std::string, constr_type> constr_type_map;
constr_type_map.insert( std::pair<std::string,constr_type>("halo",halo) );
constr_type_map.insert( std::pair<std::string,constr_type>("peak",peak) );
while(true)
{
char temp1[128];
std::string temp2;
sprintf(temp1,"constraint[%u].type",i);
if( cf.containsKey( "constraints", temp1 ) )
{
std::string str_type = cf.getValue<std::string>( "constraints", temp1 );
if( constr_type_map.find(str_type) == constr_type_map.end() )
throw std::runtime_error("Unknown constraint type!\n");
//... parse a new constraint
constraint new_c;
new_c.type = constr_type_map[ str_type ];
//... read position of constraint
sprintf(temp1,"constraint[%u].pos",i);
temp2 = cf.getValue<std::string>( "constraints", temp1 );
sscanf(temp2.c_str(), "%lf,%lf,%lf", &new_c.x, &new_c.y, &new_c.z);
if( new_c.type == halo)
{
//.. halo type constraints take mass and collapse redshift
sprintf(temp1,"constraint[%u].mass",i);
double mass = cf.getValue<double>( "constraints", temp1 );
sprintf(temp1,"constraint[%u].zform",i);
double zcoll = cf.getValue<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));
LOGINFO("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 )
{
//... peak type constraints take a scale and a peak height
sprintf(temp1,"constraint[%u].Rg",i);
new_c.Rg = cf.getValue<double>( "constraints", temp1 );
sprintf(temp1,"constraint[%u].nu",i);
new_c.sigma = cf.getValue<double>( "constraints", temp1 );
LOGINFO("Constraint %d : peak with Rg=%g h-1 Mpc and nu = %g",i,new_c.Rg,new_c.sigma);
}
new_c.Rg2 = new_c.Rg*new_c.Rg;
cset_.push_back( new_c );
}else
break;
++i;
}
LOGINFO("Found %d density constraint(s) to be obeyed.",cset_.size());
}
void constraint_set::wnoise_constr_corr( double dx, size_t nx, size_t ny, size_t nz, std::vector<double>& g0, matrix& cinv, fftw_complex* cw )
{
double lsub = nx*dx;
double dk = 2.0*M_PI/lsub, d3k=dk*dk*dk;
double pnorm = pcf_->getValue<double>("cosmology","pnorm");
double nspec = pcf_->getValue<double>("cosmology","nspec");
pnorm *= dplus0_*dplus0_;
size_t nconstr = cset_.size();
size_t nzp=nz/2+1;
/*for( size_t i=0; i<nconstr; ++i )
for( size_t j=0; j<nconstr; ++j )
{
std::cerr << "fact = " << (cset_[j].sigma-g0[j])*cinv(i,j) << "\n";
std::cerr << "g(j) = " << cset_[j].sigma << "\n";
std::cerr << "g0(j) = " << g0[j] << "\n";
std::cerr << "qinv = " << cinv(i,j) << "\n";
}
*/
double chisq = 0.0, chisq0 = 0.0;
for( size_t i=0; i<nconstr; ++i )
for( size_t j=0; j<nconstr; ++j )
{
chisq += cset_[i].sigma*cinv(i,j)*cset_[j].sigma;
chisq0 += g0[i]*cinv(i,j)*g0[j];
}
LOGINFO("Chi squared for the constraints:\n sampled = %f, desired = %f", chisq0, chisq );
std::vector<double> sigma(nconstr,0.0);
#pragma omp parallel
{
std::vector<double> sigma_loc(nconstr,0.0);
#pragma omp for
for( int ix=0; ix<(int)nx; ++ix )
{
double iix(ix); if( iix > nx/2 ) iix-=nx;
iix *= 2.0*M_PI/nx;
for( size_t iy=0; iy<ny; ++iy )
{
double iiy(iy); if( iiy > ny/2 ) iiy-=ny;
iiy *= 2.0*M_PI/nx;
for( size_t iz=0; iz<nzp; ++iz )
{
double iiz(iz);
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 Pk = pnorm*T*T*pow(k,nspec)*d3k;
size_t q = ((size_t)ix*ny+(size_t)iy)*nzp+(size_t)iz;
double fac = sqrt(Pk);
for( unsigned i=0; i<nconstr; ++i )
for( unsigned j=0; j<=i; ++j )
{
std::complex<double>
ci = eval_constr(i,iix,iiy,iiz),
cj = eval_constr(j,iix,iiy,iiz);
#ifdef FFTW3
cw[q][0] += (cset_[j].sigma-g0[j])*cinv(i,j) * std::real(ci)*fac;
cw[q][1] += (cset_[j].sigma-g0[j])*cinv(i,j) * std::imag(ci)*fac;
if( i!=j )
{
cw[q][0] += (cset_[i].sigma-g0[i])*cinv(j,i) * std::real(cj)*fac;
cw[q][1] += (cset_[i].sigma-g0[i])*cinv(j,i) * std::imag(cj)*fac;
}
else
{
if( iz>0&&iz<nz/2 )
sigma_loc[i] += 2.0*std::real(std::conj(ci)*std::complex<double>(cw[q][0],cw[q][1]))*fac;
else
sigma_loc[i] += std::real(std::conj(ci)*std::complex<double>(cw[q][0],cw[q][1]))*fac;
}
#else
cw[q].re += (cset_[j].sigma-g0[j])*cinv(i,j) * std::real(ci)*fac;
cw[q].im += (cset_[j].sigma-g0[j])*cinv(i,j) * std::imag(ci)*fac;
if(i!=j)
{
cw[q].re += (cset_[i].sigma-g0[i])*cinv(j,i) * std::real(cj)*fac;
cw[q].im += (cset_[i].sigma-g0[i])*cinv(j,i) * std::imag(cj)*fac;
}
else
{
if( iz>0&&iz<nz/2 )
sigma_loc[i] += 2.0*std::real(std::conj(ci)*std::complex<double>(cw[q].re,cw[q].im))*fac;
else
sigma_loc[i] += std::real(std::conj(ci)*std::complex<double>(cw[q].re,cw[q].im))*fac;
}
#endif
}
}
}
}
//.. 'critical' section for the global reduction
#pragma omp critical
{
for(int i=0; i<(int)nconstr; ++i )
sigma[i] += sigma_loc[i];
}
}
for(int i=0; i<(int)nconstr; ++i )
LOGINFO("Constraint %3d : sigma = %+6f (%+6f)",i,sigma[i],cset_[i].sigma);
}
void constraint_set::wnoise_constr_corr( double dx, fftw_complex* cw, size_t nx, size_t ny, size_t nz, std::vector<double>& g0 )
{
size_t nconstr = cset_.size();
size_t nzp=nz/2+1;
g0.assign(nconstr,0.0);
double pnorm = pcf_->getValue<double>("cosmology","pnorm");
double nspec = pcf_->getValue<double>("cosmology","nspec");
pnorm *= dplus0_*dplus0_;
double lsub = nx*dx;
double dk = 2.0*M_PI/lsub, d3k=dk*dk*dk;
for( size_t i=0; i<nconstr; ++i )
{
double gg = 0.0;
#pragma omp parallel for reduction(+:gg)
for( int ix=0; ix<(int)nx; ++ix )
{
double iix(ix); if( iix > nx/2 ) iix-=nx;
iix *= 2.0*M_PI/nx;
for( size_t iy=0; iy<ny; ++iy )
{
double iiy(iy); if( iiy > ny/2 ) iiy-=ny;
iiy *= 2.0*M_PI/nx;
for( size_t iz=0; iz<nzp; ++iz )
{
double iiz(iz);
iiz *= 2.0*M_PI/nx;
double k = sqrt(iix*iix+iiy*iiy+iiz*iiz)*(double)nx/lsub;
double T = ptf_->compute(k,total);
std::complex<double> v(std::conj(eval_constr(i,iix,iiy,iiz)));
v *= sqrt(pnorm*pow(k,nspec)*T*T*d3k);
if( iz>0&&iz<nz/2)
v*=2;
size_t q = ((size_t)ix*ny+(size_t)iy)*nzp+(size_t)iz;
#ifdef FFTW3
std::complex<double> ccw(cw[q][0],cw[q][1]);
#else
std::complex<double> ccw(cw[q].re,cw[q].im);
#endif
gg += std::real(v*ccw);
}
}
}
g0[i] = gg;
}
}
void constraint_set::icov_constr( double dx, size_t nx, size_t ny, size_t nz, matrix& cij )
{
size_t nconstr = cset_.size();
size_t nzp=nz/2+1;
double pnorm = pcf_->getValue<double>("cosmology","pnorm");
double nspec = pcf_->getValue<double>("cosmology","nspec");
pnorm *= dplus0_*dplus0_;
cij = matrix(nconstr,nconstr);
double lsub = nx*dx;
double dk = 2.0*M_PI/lsub, d3k=dk*dk*dk;
//... compute lower triangle of covariance matrix
//... and fill in upper triangle
for( unsigned i=0; i<nconstr; ++i )
for( unsigned j=0; j<=i; ++j )
{
float c1(0.0), c2(0.0);
#pragma omp parallel for reduction(+:c1,c2)
for( int ix=0; ix<(int)nx; ++ix )
{
double iix(ix); if( iix > nx/2 ) iix-=nx;
iix *= 2.0*M_PI/nx;
for( size_t iy=0; iy<ny; ++iy )
{
double iiy(iy); if( iiy > ny/2 ) iiy-=ny;
iiy *= 2.0*M_PI/nx;
for( size_t iz=0; iz<nzp; ++iz )
{
double iiz(iz);
iiz *= 2.0*M_PI/nx;
double k = sqrt(iix*iix+iiy*iiy+iiz*iiz)*(double)nx/lsub;
double T = ptf_->compute(k,total);
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;
if( iz>0&&iz<nz/2)
v*=2;
c1 += std::real(v);
c2 += std::real(std::conj(v));
}
}
}
cij(i,j) = c1;
cij(j,i) = c2;
}
//... invert convariance matrix
cij.invert();
}

View file

@ -25,56 +25,358 @@
#define __CONSTRAINTS_HH
#include <vector>
#include "config_file.hh"
#include <complex>
#include <gsl/gsl_linalg.h>
#include "general.hh"
#include "config_file.hh"
#include "transfer_function.hh"
#include "cosmology.hh"
//! matrix class serving as a gsl wrapper
class matrix
{
protected:
gsl_matrix * m_;
//double *data_;
size_t M_, N_;
public:
matrix( size_t M, size_t N )
: M_(M), N_(N)
{
m_ = gsl_matrix_alloc(M_,N_);
}
matrix( size_t N )
: M_(N), N_(N)
{
m_ = gsl_matrix_alloc(M_,N_);
}
matrix( const matrix& o )
{
M_ = o.M_;
N_ = o.N_;
m_ = gsl_matrix_alloc(M_,N_);
gsl_matrix_memcpy(m_, o.m_ );
}
~matrix()
{
gsl_matrix_free( m_ );
}
double& operator()( size_t i, size_t j )
{ return *gsl_matrix_ptr( m_, i, j ); }
const double& operator()( size_t i, size_t j ) const
{ return *gsl_matrix_const_ptr( m_, i, j ); }
matrix& operator=( const matrix& o )
{
gsl_matrix_free( m_ );
M_ = o.M_;
N_ = o.N_;
m_ = gsl_matrix_alloc(M_,N_);
gsl_matrix_memcpy(m_, o.m_ );
return *this;
}
matrix& invert()
{
if( M_!=N_ )
throw std::runtime_error("Attempt to invert a non-square matrix!");
int s;
gsl_matrix* im = gsl_matrix_alloc(M_,N_);
gsl_permutation * p = gsl_permutation_alloc (M_);
gsl_linalg_LU_decomp( m_, p, &s );
gsl_linalg_LU_invert( m_, p, im );
gsl_matrix_memcpy(m_, im);
gsl_permutation_free(p);
gsl_matrix_free(im);
return *this;
}
};
//! class to impose constraints on the white noise field (van de Weygaert & Bertschinger 1996)
class constraint_set
{
public:
enum constr_type{ halo, peak };
protected:
struct constraint{
typedef struct constraint{
constr_type type;
double x,y,z;
unsigned level;
double gx,gy,gz;
double Rg, Rg2;
double gRg, gRg2;
double sigma;
};
config_file *pcf_;
std::vector<constraint> cset_;
transfer_function *ptf_;
CosmoCalc *pccalc_;
Cosmology *pcosmo_;
double dplus0_;
unsigned constr_level_;
inline std::complex<double> eval_constr( size_t icon, double kx, double ky, double kz )
{
double re, im, kdotx, k2;
kdotx = cset_[icon].gx*kx+cset_[icon].gy*ky+cset_[icon].gz*kz;
k2 = kx*kx+ky*ky+kz*kz;
re = im = exp(-k2*cset_[icon].gRg2/2.0);
re *= cos( kdotx );
im *= sin( kdotx );
return std::complex<double>(re,im);
}
//! apply constraints to the white noise
void wnoise_constr_corr( double dx, size_t nx, size_t ny, size_t nz, std::vector<double>& g0, matrix& cinv, fftw_complex* cw );
//! measure sigma for each constraint in the unconstrained noise
void wnoise_constr_corr( double dx, fftw_complex* cw, size_t nx, size_t ny, size_t nz, std::vector<double>& g0 );
//! compute the covariance between the constraints
void icov_constr( double dx, size_t nx, size_t ny, size_t nz, matrix& cij );
public:
constraint_set( config_file& cf )
//! constructor
constraint_set( config_file& cf, transfer_function *ptf );
//! destructor
~constraint_set()
{
float tf0, tf1,tf2,tf3;
unsigned ti;
unsigned i=0;
delete pccalc_;
delete pcosmo_;
}
template< typename rng >
void apply( unsigned ilevel, int x0[], int lx[], rng* wnoise )
{
if( cset_.size() == 0 || constr_level_ != ilevel )
return;
while(true)
unsigned nlvl = 1<<ilevel;
double boxlength = pcf_->getValue<double>("setup","boxlength");
//... compute constraint coordinates for grid
for( size_t i=0; i<cset_.size(); ++i )
{
char temp1[128];
std::string temp2;
sprintf(temp1,"constraint[%u]",i);
if( cf.containsKey( "constraints", temp1 ) )
{
temp2 = cf.getValue<std::string>( "constraints", temp1 );
sscanf( temp2.c_str(), "%f,%f,%f,%u,%f", &tf0, &tf1, &tf2, &ti, &tf3 );
constraint new_c;
new_c.x = tf0;
new_c.y = tf1;
new_c.z = tf2;
new_c.level = ti;
new_c.sigma = tf3;
cset_.push_back( new_c );
}
else
break;
++i;
cset_[i].gx = cset_[i].x * (double)nlvl;
cset_[i].gy = cset_[i].y * (double)nlvl;
cset_[i].gz = cset_[i].z * (double)nlvl;
cset_[i].gRg = cset_[i].Rg/boxlength * (double)nlvl;
cset_[i].gRg2 = cset_[i].gRg*cset_[i].gRg;
if(cset_[i].gRg > 0.5*lx[0])
LOGWARN("Constraint %d appears to be too large scale",i);
}
std::cout << " - Found " << cset_.size() << " density constraint(s) to be obeyed.\n";
std::vector<double> g0;
// unsigned levelmax = pcf_->getValue<unsigned>("setup","levelmax");
unsigned levelmin = pcf_->getValue<unsigned>("setup","levelmin_TF");
bool bperiodic = ilevel==levelmin;
double dx = pcf_->getValue<double>("setup","boxlength")/(1<<ilevel);
LOGINFO("Computing constrained realization...");
if( bperiodic )
{
//... we are operating on the periodic coarse grid
size_t nx = lx[0], ny = lx[1], nz = lx[2], nzp = nz+2;
fftw_real * w = new fftw_real[nx*ny*nzp];
fftw_complex * cw = reinterpret_cast<fftw_complex*> (w);
#ifdef FFTW3
fftw_plan p = fftw_plan_dft_r2c_3d( nx, ny, nz, w, cw, FFTW_ESTIMATE),
ip = fftw_plan_dft_c2r_3d( nx, ny, nz, cw, w, FFTW_ESTIMATE);
#else
rfftwnd_plan p = rfftw3d_create_plan( nx, ny, nz, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE|FFTW_IN_PLACE),
ip = rfftw3d_create_plan( nx, ny, nz, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE|FFTW_IN_PLACE);
#endif
double fftnorm = 1.0/sqrt(nx*ny*nz);
#pragma omp parallel for
for( int i=0; i<(int)nx; i++ )
for( int j=0; j<(int)ny; j++ )
for( int k=0; k<(int)nz; k++ )
{
size_t q = ((size_t)i*ny+(size_t)j)*nzp+(size_t)k;
w[q] = (*wnoise)((x0[0]+i)%nx,(x0[1]+j)%ny,(x0[2]+k)%nz)*fftnorm;
}
#ifdef FFTW3
fftw_execute( p );
#else
#ifndef SINGLETHREAD_FFTW
rfftwnd_threads_one_real_to_complex( omp_get_max_threads(), p, w, NULL );
#else
rfftwnd_one_real_to_complex( p, w, NULL );
#endif
#endif
wnoise_constr_corr( dx, cw, nx, ny, nz, g0 );
matrix c(2,2);
icov_constr( dx, nx, ny, nz, c );
wnoise_constr_corr( dx, nx, ny, nz, g0, c, cw );
#ifdef FFTW3
fftw_execute( ip );
#else
#ifndef SINGLETHREAD_FFTW
rfftwnd_threads_one_complex_to_real( omp_get_max_threads(), ip, cw, NULL );
#else
rfftwnd_one_complex_to_real( ip, cw, NULL );
#endif
#endif
#pragma omp parallel for
for( int i=0; i<(int)nx; i++ )
for( int j=0; j<(int)ny; j++ )
for( int k=0; k<(int)nz; k++ )
{
size_t q = ((size_t)i*ny+(size_t)j)*nzp+(size_t)k;
(*wnoise)((x0[0]+i),(x0[1]+j),(x0[2]+k)) = w[q]*fftnorm;
}
LOGINFO("Applied constraints to level %d.",ilevel);
delete[] w;
#ifdef FFTW3
fftw_destroy_plan(p);
#else
fftwnd_destroy_plan(p);
#endif
}else{
//... we are operating on a refinement grid, not necessarily the finest
size_t nx = lx[0], ny = lx[1], nz = lx[2], nzp = nz+2;
fftw_real * w = new fftw_real[nx*ny*nzp];
fftw_complex * cw = reinterpret_cast<fftw_complex*> (w);
#ifdef FFTW3
fftw_plan p = fftw_plan_dft_r2c_3d( nx, ny, nz, w, cw, FFTW_ESTIMATE),
ip = fftw_plan_dft_c2r_3d( nx, ny, nz, cw, w, FFTW_ESTIMATE);
#else
rfftwnd_plan p = rfftw3d_create_plan( nx, ny, nz, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE|FFTW_IN_PLACE),
ip = rfftw3d_create_plan( nx, ny, nz, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE|FFTW_IN_PLACE);
#endif
double fftnorm = 1.0/sqrt(nx*ny*nz);
int il = nx/4, ir = 3*nx/4, jl=ny/4, jr = 3*ny/4, kl = nz/4, kr = 3*nz/4;
#pragma omp parallel for
for( int i=0; i<(int)nx; i++ )
for( int j=0; j<(int)ny; j++ )
for( int k=0; k<(int)nz; k++ )
{
size_t q = ((size_t)i*ny+(size_t)j)*nzp+(size_t)k;
if( i>=il && i<ir && j>=jl && j<jr && k>=kl && k<kr )
w[q] = (*wnoise)((x0[0]+i),(x0[1]+j),(x0[2]+k))*fftnorm;
else
w[q] = 0.0;
}
int nlvl05 = 1<<(ilevel-1);
int xs = nlvl05-x0[0], ys = nlvl05-x0[1], zs = nlvl05-x0[2];
for( size_t i=0; i<cset_.size(); ++i )
{
cset_[i].gx -= xs;
cset_[i].gy -= ys;
cset_[i].gz -= zs;
}
#ifdef FFTW3
fftw_execute( p );
#else
#ifndef SINGLETHREAD_FFTW
rfftwnd_threads_one_real_to_complex( omp_get_max_threads(), p, w, NULL );
#else
rfftwnd_one_real_to_complex( p, w, NULL );
#endif
#endif
wnoise_constr_corr( dx, cw, nx, ny, nz, g0 );
matrix c(2,2);
icov_constr( dx, nx, ny, nz, c );
wnoise_constr_corr( dx, nx, ny, nz, g0, c, cw );
#ifdef FFTW3
fftw_execute( ip );
#else
#ifndef SINGLETHREAD_FFTW
rfftwnd_threads_one_complex_to_real( omp_get_max_threads(), ip, cw, NULL );
#else
rfftwnd_one_complex_to_real( ip, cw, NULL );
#endif
#endif
#pragma omp parallel for
for( int i=0; i<(int)nx; i++ )
for( int j=0; j<(int)ny; j++ )
for( int k=0; k<(int)nz; k++ )
{
size_t q = ((size_t)i*ny+(size_t)j)*nzp+(size_t)k;
if( i>=il && i<ir && j>=jl && j<jr && k>=kl && k<kr )
(*wnoise)((x0[0]+i),(x0[1]+j),(x0[2]+k)) = w[q]*fftnorm;
}
LOGINFO("Applied constraints to level %d.",ilevel);
delete[] w;
#ifdef FFTW3
fftw_destroy_plan(p);
#else
fftwnd_destroy_plan(p);
#endif
}
}

View file

@ -24,9 +24,10 @@
#ifndef _COSMOLOGY_HH
#define _COSMOLOGY_HH
#include "transfer_function.hh"
#include "mesh.hh"
#include "general.hh"
#include "transfer_function.hh"
/*!
* @class CosmoCalc

View file

@ -21,7 +21,6 @@
*/
#include "constraints.hh"
#include "densities.hh"
#include "convolution_kernel.hh"

View file

@ -26,6 +26,7 @@
#include "log.hh"
#include <cassert>
#include <omp.h>
#ifdef WITH_MPI
@ -86,15 +87,9 @@
#include <vector>
#include "config_file.hh"
//#include "mesh.hh"
#include "mesh.hh"
typedef GridHierarchy<real_t> grid_hierarchy;
typedef MeshvarBnd<real_t> meshvar_bnd;
typedef Meshvar<real_t> meshvar;
#include "random.hh"
typedef random_numbers<real_t> rand_nums;
typedef random_number_generator< rand_nums,real_t> rand_gen;
//! compute square of argument
@ -136,6 +131,30 @@ typedef struct cosmology{
WDMmass, //!< Warm DM particle mass
WDMg_x, //!< Warm DM particle degrees of freedom
astart; //!< expansion factor a for which to generate initial conditions
cosmology( config_file cf )
{
double zstart = cf.getValue<double>( "setup", "zstart" );
astart = 1.0/(1.0+zstart);
Omega_b = cf.getValue<double>( "cosmology", "Omega_b" );
Omega_m = cf.getValue<double>( "cosmology", "Omega_m" );
Omega_L = cf.getValue<double>( "cosmology", "Omega_L" );
H0 = cf.getValue<double>( "cosmology", "H0" );
sigma8 = cf.getValue<double>( "cosmology", "sigma_8" );
nspect = cf.getValue<double>( "cosmology", "nspec" );
WDMg_x = cf.getValueSafe<double>( "cosmology", "WDMg_x", 1.5 );
WDMmass = cf.getValueSafe<double>( "cosmology", "WDMmass", 0.0 );
dplus = 0.0;
pnorm = 0.0;
vfact = 0.0;
}
cosmology( void )
{
}
}Cosmology;
//! basic box/grid/refinement structure parameters

257
main.cc
View file

@ -50,7 +50,7 @@
#include "transfer_function.hh"
#define THE_CODE_NAME "music!"
#define THE_CODE_VERSION "0.7.3a"
#define THE_CODE_VERSION "0.8a"
namespace music
@ -149,6 +149,68 @@ void modify_grid_for_TF( const refinement_hierarchy& rh_full, refinement_hierarc
}
void print_hierarchy_stats( config_file& cf, const refinement_hierarchy& rh )
{
double omegam = cf.getValue<double>("cosmology","Omega_m");
double omegab = cf.getValue<double>("cosmology","Omega_b");
bool bbaryons = cf.getValue<bool>("setup","baryons");
double boxlength = cf.getValue<double>("setup","boxlength");
unsigned levelmin = rh.levelmin();
double dx = boxlength/(double)(1<<levelmin), dx3=dx*dx*dx;
double rhom = 2.77519737e11; // h-1 M_o / (h-1 Mpc)**3
double cmass, bmass(0.0), mtotgrid;
if( bbaryons )
{
cmass = (omegam-omegab)*rhom*dx3;
bmass = omegab*rhom*dx3;
}else
cmass = omegam*rhom*dx3;
std::cout << "-------------------------------------------------------------\n";
if( rh.get_shift(0)!=0||rh.get_shift(1)!=0||rh.get_shift(2)!=0 )
std::cout << " - Domain will be shifted by (" << rh.get_shift(0) << ", " << rh.get_shift(1) << ", " << rh.get_shift(2) << ")\n" << std::endl;
std::cout << " - Grid structure:\n";
for( unsigned ilevel=rh.levelmin(); ilevel<=rh.levelmax(); ++ilevel )
{
double rfac = 1.0/(1<<(ilevel-rh.levelmin())), rfac3=rfac*rfac*rfac;
mtotgrid = omegam*rhom*dx3*rfac3*rh.size(ilevel, 0)*rh.size(ilevel, 1)*rh.size(ilevel, 2);
std::cout
<< " Level " << std::setw(3) << ilevel << " : offset = (" << std::setw(5) << rh.offset(ilevel,0) << ", " << std::setw(5) << rh.offset(ilevel,0) << ", " << std::setw(5) << rh.offset(ilevel,0) << ")\n"
<< " size = (" << std::setw(5) << rh.size(ilevel,0) << ", " << std::setw(5) << rh.size(ilevel,1) << ", " << std::setw(5) << rh.size(ilevel,2) << ")\n";
if( ilevel == rh.levelmax() )
{
std::cout << "-------------------------------------------------------------\n";
std::cout << " - Finest level :\n";
/*std::cout << " extent = " << dx*rfac*rh.size(ilevel,0) << " x "
<< dx*rfac*rh.size(ilevel,1) << " x "
<< dx*rfac*rh.size(ilevel,2) << " (h-1 Mpc)**3\n\n";*/
std::cout << " mtotgrid = " << mtotgrid << " h-1 M_o\n";
std::cout << " particle mass = " << cmass*rfac3 << " h-1 M_o\n";
if( bbaryons )
std::cout << " baryon mass/cell = " << bmass*rfac3 << " h-1 M_o\n";
if( dx*rfac > 0.1 )
std::cout << " dx = " << dx*rfac << " h-1 Mpc\n";
else if( dx*rfac > 1e-4 )
std::cout << " dx = " << dx*rfac*1000.0 << " h-1 kpc\n";
else
std::cout << " dx = " << dx*rfac*1.e6 << " h-1 pc\n";
}
}
std::cout << "-------------------------------------------------------------\n";
}
void coarsen_density( const refinement_hierarchy& rh, grid_hierarchy& u )
{
for( int i=rh.levelmax(); i>0; --i )
@ -228,13 +290,9 @@ int main (int argc, const char * argv[])
unsigned lbase, lmax, lbaseTF;
double err;
cosmology cosmo;
double boxlength, zstart;
std::vector<long> rngseeds;
std::vector<std::string> rngfnames;
double x0[3], lx[3];
unsigned npad = 8;
//------------------------------------------------------------------------------
//... parse command line options
//------------------------------------------------------------------------------
splash();
if( argc != 2 ){
@ -247,7 +305,10 @@ int main (int argc, const char * argv[])
exit(0);
}
//------------------------------------------------------------------------------
//... open log file
//------------------------------------------------------------------------------
char logfname[128];
sprintf(logfname,"%s_log.txt",argv[1]);
MUSIC::log::setOutput(logfname);
@ -270,21 +331,22 @@ int main (int argc, const char * argv[])
#endif
/******************************************************************************************************/
/* read and interpret config file *********************************************************************/
/******************************************************************************************************/
//------------------------------------------------------------------------------
//... read and interpret config file
//------------------------------------------------------------------------------
config_file cf(argv[1]);
std::string tfname,randfname,temp, outformat, outfname, poisson_solver_name;;
bool shift_back(false), align_top(false), kspace(false), force_shift(false);
float tf0,tf1,tf2;
std::string tfname,randfname,temp;
bool force_shift(false);
double boxlength;
//------------------------------------------------------------------------------
//... initialize some parameters about grid set-up
//------------------------------------------------------------------------------
boxlength = cf.getValue<double>( "setup", "boxlength" );
lbase = cf.getValue<unsigned>( "setup", "levelmin" );
lmax = cf.getValue<unsigned>( "setup", "levelmax" );
lbaseTF = cf.getValueSafe<unsigned>( "setup", "levelmin_TF", lbase );
force_shift = cf.getValueSafe<bool>("setup", "force_shift", force_shift );
if( lbase == lmax && !force_shift )
cf.insertValue("setup","no_shift","yes");
@ -300,62 +362,12 @@ int main (int argc, const char * argv[])
cf.insertValue("setup","levelmin_TF",cf.getValue<std::string>("setup","levelmin"));
}
temp = cf.getValue<std::string>( "setup", "ref_offset" );
sscanf( temp.c_str(), "%g,%g,%g", &tf0, &tf1, &tf2 ); x0[0] = tf0; x0[1] = tf1; x0[2] = tf2;
//------------------------------------------------------------------------------
//... initialize multithread FFTW
//------------------------------------------------------------------------------
temp = cf.getValue<std::string>( "setup", "ref_extent" );
sscanf( temp.c_str(), "%g,%g,%g", &tf0, &tf1, &tf2 ); lx[0] = tf0; lx[1] = tf1; lx[2] = tf2;
npad = cf.getValue<unsigned>( "setup", "padding" );
align_top = cf.getValueSafe<bool>( "setup", "align_top", false );
kspace = cf.getValueSafe<bool>( "poisson", "kspace", false );
if( kspace )
poisson_solver_name = std::string("fft_poisson");
else
poisson_solver_name = std::string("mg_poisson");
// TODO: move cosmology parameters reading to cosmo_calc
zstart = cf.getValue<double>( "setup", "zstart" );
cosmo.astart = 1.0/(1.0+zstart);
cosmo.Omega_b = cf.getValue<double>( "cosmology", "Omega_b" );
cosmo.Omega_m = cf.getValue<double>( "cosmology", "Omega_m" );
cosmo.Omega_L = cf.getValue<double>( "cosmology", "Omega_L" );
cosmo.H0 = cf.getValue<double>( "cosmology", "H0" );
cosmo.sigma8 = cf.getValue<double>( "cosmology", "sigma_8" );
cosmo.nspect = cf.getValue<double>( "cosmology", "nspec" );
cosmo.WDMg_x = cf.getValueSafe<double>( "cosmology", "WDMg_x", 1.5 );
cosmo.WDMmass = cf.getValueSafe<double>( "cosmology", "WDMmass", 0.0 );
cosmo.dplus = 0.0;
cosmo.pnorm = 0.0;
cosmo.vfact = 0.0;
//cosmo.Gamma = cf.getValueSafe<double>( "cosmology", "Gamma", -1.0 );
/******************************************************************************************************/
/******************************************************************************************************/
shift_back = cf.getValueSafe<bool>( "output", "shift_back", shift_back );
outformat = cf.getValue<std::string>( "output", "format" );
outfname = cf.getValue<std::string>( "output", "filename" );
unsigned grad_order = cf.getValueSafe<unsigned> ( "poisson" , "grad_order", 4 );
bool bdefd = cf.getValueSafe<bool> ( "poisson" , "fft_fine", true );
//... if in unigrid mode, use k-space instead
//if(bdefd&lbase==lmax)
//kspace=true;
//... switch off if using kspace anyway
bdefd &= !kspace;
/******************************************************************************************************/
/******************************************************************************************************/
/******************************************************************************************************/
#if not defined(SINGLETHREAD_FFTW)
#ifdef FFTW3
fftw_init_threads();
@ -365,9 +377,14 @@ int main (int argc, const char * argv[])
#endif
#endif
//------------------------------------------------------------------------------
//... initialize cosmology
//------------------------------------------------------------------------------
transfer_function_plugin *the_transfer_function_plugin
= select_transfer_function_plugin( cf );
cosmology cosmo( cf );
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 );
@ -383,20 +400,28 @@ int main (int argc, const char * argv[])
}
/******************************************************************************************************/
/******************************************************************************************************/
//------------------------------------------------------------------------------
//... determine run parameters
//------------------------------------------------------------------------------
bool
do_baryons = cf.getValue<bool>("setup","baryons"),
do_2LPT = cf.getValue<bool>("setup","use_2LPT"),
do_LLA = cf.getValue<bool>("setup","use_LLA"),
do_CVM = cf.getValueSafe<bool>("setup","center_velocities",false);
if( !the_transfer_function_plugin->tf_is_distinct() && do_baryons )
std::cout << " - WARNING: The selected transfer function does not support\n"
<< " distinct amplitudes for baryon and DM fields!\n"
<< " Perturbation amplitudes will be identical!" << std::endl;
//------------------------------------------------------------------------------
//... determine the refinement hierarchy
//------------------------------------------------------------------------------
refinement_hierarchy rh_Poisson( cf );
store_grid_structure(cf, rh_Poisson);
rh_Poisson.output();
//rh_Poisson.output();
print_hierarchy_stats( cf, rh_Poisson );
refinement_hierarchy rh_TF( rh_Poisson );
modify_grid_for_TF( rh_Poisson, rh_TF, cf );
@ -407,31 +432,54 @@ int main (int argc, const char * argv[])
LOGUSER("Grid structure for density convolution:");
rh_TF.output_log();
if( !the_transfer_function_plugin->tf_is_distinct() && do_baryons )
std::cout << " - WARNING: The selected transfer function does not support\n"
<< " distinct amplitudes for baryon and DM fields!\n"
<< " Perturbation amplitudes will be identical!" << std::endl;
//------------------------------------------------------------------------------
//... initialize the output plug-in
//------------------------------------------------------------------------------
std::string outformat, outfname;
outformat = cf.getValue<std::string>( "output", "format" );
outfname = cf.getValue<std::string>( "output", "filename" );
output_plugin *the_output_plugin = select_output_plugin( cf );
//------------------------------------------------------------------------------
//... initialize the random numbers
rand_gen rand( cf, rh_TF );
//------------------------------------------------------------------------------
rand_gen rand( cf, rh_TF, the_transfer_function_plugin );
//------------------------------------------------------------------------------
//... initialize the Poisson solver
//------------------------------------------------------------------------------
bool kspace = cf.getValueSafe<bool>( "poisson", "kspace", false );
std::string poisson_solver_name;
if( kspace )
poisson_solver_name = std::string("fft_poisson");
else
poisson_solver_name = std::string("mg_poisson");
unsigned grad_order = cf.getValueSafe<unsigned> ( "poisson" , "grad_order", 4 );
bool bdefd = cf.getValueSafe<bool> ( "poisson" , "fft_fine", true );
//... if in unigrid mode, use k-space instead
//if(bdefd&lbase==lmax)
//kspace=true;
//... switch off if using kspace anyway
bdefd &= !kspace;
poisson_plugin_creator *the_poisson_plugin_creator = get_poisson_plugin_map()[ poisson_solver_name ];
poisson_plugin *the_poisson_solver = the_poisson_plugin_creator->create( cf );
//---------------------------------------------------------------------------------
//... THIS IS THE MAIN DRIVER BRANCHING TREE RUNNING THE VARIOUS PARTS OF THE CODE
//---------------------------------------------------------------------------------
bool bfatal = false;
try{
if( ! do_2LPT )
{
LOGUSER("Entering 1LPT branch");
//------------------------------------------------------------------------------
//... cdm density and displacements
//------------------------------------------------------------------------------
std::cout << "=============================================================\n";
std::cout << " COMPUTING DARK MATTER DISPLACEMENTS\n";
std::cout << "-------------------------------------------------------------\n";
@ -443,7 +491,7 @@ int main (int argc, const char * argv[])
my_tf_type = total;
GenerateDensityHierarchy( cf, the_transfer_function_plugin, cdm , rh_TF, rand, f, true, false );
GenerateDensityHierarchy( cf, the_transfer_function_plugin, my_tf_type , rh_TF, rand, f, true, false );
coarsen_density(rh_Poisson, f);
normalize_density(f);
@ -460,7 +508,9 @@ int main (int argc, const char * argv[])
the_output_plugin->write_dm_potential(u);
//------------------------------------------------------------------------------
//... DM displacements
//------------------------------------------------------------------------------
{
grid_hierarchy data_forIO(u);
for( int icoord = 0; icoord < 3; ++icoord )
@ -482,7 +532,9 @@ int main (int argc, const char * argv[])
}
}
//------------------------------------------------------------------------------
//... gas density
//------------------------------------------------------------------------------
if( do_baryons )
{
std::cout << "=============================================================\n";
@ -510,7 +562,9 @@ int main (int argc, const char * argv[])
std::cout << "-------------------------------------------------------------\n";
LOGUSER("Computing velocitites...");
//------------------------------------------------------------------------------
//... velocities
//------------------------------------------------------------------------------
if( !the_transfer_function_plugin->tf_has_velocities() || !do_baryons )
{
if( do_baryons )
@ -838,41 +892,36 @@ int main (int argc, const char * argv[])
std::cout << "=============================================================\n";
//... clean up
//------------------------------------------------------------------------------
//... finish output
//------------------------------------------------------------------------------
the_output_plugin->finalize();
delete the_output_plugin;
if( !bfatal )
{
std::cout << " - Wrote output file \'" << outfname << "\'\n using plugin \'" << outformat << "\'...\n";
LOGUSER("Wrote output file \'%s\'.",outfname.c_str());
}
//------------------------------------------------------------------------------
//... clean up
//------------------------------------------------------------------------------
delete the_transfer_function_plugin;
delete the_poisson_solver;
/** we are done ! **/
std::cout << " - Done!" << std::endl << std::endl;
ltime=time(NULL);
LOGUSER("Run finished succesfully on %s",asctime( localtime(&ltime) ));
///*****************************************///
/*std::string save_fname(std::string(argv[1])+std::string("_stats"));
std::ofstream ofs(save_fname.c_str());
time_t ltime=time(NULL);
ofs << "Parameter dump for the run on " << asctime( localtime(&ltime) );
ofs << "You ran " << THE_CODE_NAME << " version " << THE_CODE_VERSION << std::endl << std::endl;
cf.dump( ofs );
*/
#ifdef FFTW3
fftw_cleanup_threads();
#endif
//------------------------------------------------------------------------------
//... we are done !
//------------------------------------------------------------------------------
std::cout << " - Done!" << std::endl << std::endl;
ltime=time(NULL);
LOGUSER("Run finished succesfully on %s",asctime( localtime(&ltime) ));
cf.log_dump();

26
mesh.hh
View file

@ -956,12 +956,25 @@ public:
std::string temp;
temp = cf_.getValue<std::string>( "setup", "ref_offset" );
sscanf( temp.c_str(), "%lf,%lf,%lf", &x0ref_[0], &x0ref_[1], &x0ref_[2] );
if( cf_.containsKey("setup","ref_offset") && cf_.containsKey("setup","ref_center") )
throw std::runtime_error("Found both ref_offset and ref_center. You can only specify one.");
temp = cf_.getValue<std::string>( "setup", "ref_extent" );
sscanf( temp.c_str(), "%lf,%lf,%lf", &lxref_[0],&lxref_[1],&lxref_[2] );
if( cf_.containsKey("setup","ref_center") )
{
temp = cf_.getValue<std::string>( "setup", "ref_center" );
sscanf( temp.c_str(), "%lf,%lf,%lf", &x0ref_[0], &x0ref_[1], &x0ref_[2] );
x0ref_[0] = fmod( x0ref_[0]-0.5*lxref_[0]+1.0,1.0);
x0ref_[1] = fmod( x0ref_[1]-0.5*lxref_[1]+1.0,1.0);
x0ref_[2] = fmod( x0ref_[2]-0.5*lxref_[2]+1.0,1.0);
}else{
temp = cf_.getValue<std::string>( "setup", "ref_offset" );
sscanf( temp.c_str(), "%lf,%lf,%lf", &x0ref_[0], &x0ref_[1], &x0ref_[2] );
}
unsigned
ncoarse = 1<<levelmin_;
@ -1253,6 +1266,9 @@ public:
unsigned levelmax( void ) const
{ return levelmax_; }
//! get the total shift of the coordinate system
int get_shift( int idim ) const
{ return xshift_[idim]; }
//! write refinement hierarchy to stdout
void output( void )
@ -1285,5 +1301,11 @@ public:
};
typedef GridHierarchy<real_t> grid_hierarchy;
typedef MeshvarBnd<real_t> meshvar_bnd;
typedef Meshvar<real_t> meshvar;
#endif

View file

@ -28,6 +28,7 @@
#include <map>
#include "general.hh"
#include "mesh.hh"
/*!

View file

@ -142,9 +142,9 @@ protected:
tmp2 = new T_store[block_buf_size_];
tmp3 = new T_store[block_buf_size_];
int fileno = 0;
//int fileno = 0;
size_t npart_left = nptot;
//size_t npart_left = nptot;
while( true )
{

View file

@ -110,8 +110,8 @@ private:
}
public:
transfer_CAMB_plugin( config_file& cf )//Cosmology aCosm, std::string filename_Tk, TFtype iwhich )
: transfer_function_plugin( cf )//, m_filename_Tk( filename_Tk ), m_psinterp( NULL )
transfer_CAMB_plugin( config_file& cf )
: transfer_function_plugin( cf )
{
m_filename_Tk = pcf_->getValue<std::string>("cosmology","transfer_file");
@ -122,13 +122,9 @@ public:
acc_baryon = gsl_interp_accel_alloc();
spline_tot = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
spline_cdm = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
spline_baryon = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
/*spline_tot = gsl_spline_alloc( gsl_interp_linear, m_tab_k.size() );
spline_cdm = gsl_spline_alloc( gsl_interp_linear, m_tab_k.size() );
spline_baryon = gsl_spline_alloc( gsl_interp_linear, m_tab_k.size() );*/
spline_tot = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
spline_cdm = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
spline_baryon = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
gsl_spline_init (spline_tot, &m_tab_k[0], &m_tab_Tk_tot[0], m_tab_k.size() );
gsl_spline_init (spline_cdm, &m_tab_k[0], &m_tab_Tk_cdm[0], m_tab_k.size() );

View file

@ -156,12 +156,12 @@ protected:
T_c = T_c_f*T_c_ln_beta/(T_c_ln_beta+T_c_C_noalpha*SQR(q)) +
(1-T_c_f)*T_c_ln_beta/(T_c_ln_beta+T_c_C_alpha*SQR(q));
s_tilde = sound_horizon*pow(1+CUBE(beta_node/xx),-1./3.);
s_tilde = sound_horizon*pow(1.+CUBE(beta_node/xx),-1./3.);
xx_tilde = k*s_tilde;
T_b_T0 = T_c_ln_nobeta/(T_c_ln_nobeta+T_c_C_noalpha*SQR(q));
T_b = sin(xx_tilde)/(xx_tilde)*(T_b_T0/(1+SQR(xx/5.2))+
alpha_b/(1+CUBE(beta_b/xx))*exp(-pow(k/k_silk,1.4)));
T_b = sin(xx_tilde)/(xx_tilde)*(T_b_T0/(1.+SQR(xx/5.2))+
alpha_b/(1.+CUBE(beta_b/xx))*exp(-pow(k/k_silk,1.4)));
f_baryon = obhh/omhh;
T_full = f_baryon*T_b + (1-f_baryon)*T_c;
@ -187,7 +187,6 @@ public:
cosmo_.Omega_b/(cosmo_.Omega_m-cosmo_.Omega_b),//-aCosm.Omega_b),
Tcmb);
std::cerr << "CHECK!!\n";
tf_distinct_ = false;
tf_withvel_ = false;
}

View file

@ -79,17 +79,55 @@ private:
m_tab_k.push_back( log10(k) );
#if 1
m_tab_Tk_tot.push_back( log10(Tktot) );
m_tab_Tk_baryon.push_back( log10(Tkb) );
m_tab_Tk_cdm.push_back( log10(Tkc) );
m_tab_Tvk_cdm.push_back( log10(Tkvc) );
m_tab_Tvk_baryon.push_back( log10(Tkvb) );
#else
/* m_tab_Tk_tot.push_back( log10(fabs(Tktot)) );
m_tab_Tk_baryon.push_back( log10(fabs(Tkb)) );
m_tab_Tk_cdm.push_back( log10(fabs(Tkc)) );
m_tab_Tvk_cdm.push_back( log10(fabs(Tkvc)) );
m_tab_Tvk_baryon.push_back( log10(fabs(Tkvb)) );*/
m_tab_Tk_tot.push_back( Tktot );
m_tab_Tk_baryon.push_back( Tkb );
m_tab_Tk_cdm.push_back( Tkc );
m_tab_Tvk_cdm.push_back( Tkvc );
m_tab_Tvk_baryon.push_back( Tkvb );
#endif
}
ifs.close();
/*******/
/*double Tmin=1e30;
for( int i=0; i<m_tab_Tvk_baryon.size(); ++i )
if( m_tab_Tvk_baryon[i] < Tmin ) Tmin = m_tab_Tvk_baryon[i];
if( Tmin > 0.0 ) Tmin = 0.0;
std::cerr << "Tmin = " << Tmin << std::endl;
for( int i=0; i<m_tab_Tvk_baryon.size(); ++i )
{ m_tab_Tvk_baryon[i] = log10(m_tab_Tvk_baryon[i]-1.1*Tmin);
std::cerr << m_tab_Tvk_baryon[i] << std::endl;
}
Tmin=1e30;
for( int i=0; i<m_tab_Tk_baryon.size(); ++i )
if( m_tab_Tk_baryon[i] < Tmin ) Tmin = m_tab_Tk_baryon[i];
if( Tmin > 0.0 ) Tmin = 0.0;
std::cerr << "Tmin = " << Tmin << std::endl;
for( int i=0; i<m_tab_Tk_baryon.size(); ++i )
{ m_tab_Tk_baryon[i] = log10(m_tab_Tk_baryon[i]-1.1*Tmin);
std::cerr << m_tab_Tk_baryon[i] << std::endl;
}*/
/*******/
#ifdef WITH_MPI
@ -130,11 +168,11 @@ public:
acc_dbaryon = gsl_interp_accel_alloc();
spline_dtot = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
spline_dcdm = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
spline_dbaryon = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
spline_vcdm = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
spline_vbaryon = gsl_spline_alloc( gsl_interp_akima, m_tab_k.size() );
spline_dtot = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
spline_dcdm = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
spline_dbaryon = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
spline_vcdm = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
spline_vbaryon = gsl_spline_alloc( gsl_interp_cspline, m_tab_k.size() );
gsl_spline_init (spline_dtot, &m_tab_k[0], &m_tab_Tk_tot[0], m_tab_k.size() );
gsl_spline_init (spline_dcdm, &m_tab_k[0], &m_tab_Tk_cdm[0], m_tab_k.size() );

View file

@ -28,6 +28,7 @@
#include <map>
#include "general.hh"
#include "mesh.hh"
//! abstract base class for Poisson solvers and gradient calculations
class poisson_plugin

1410
random.cc Normal file

File diff suppressed because it is too large Load diff

1495
random.hh

File diff suppressed because it is too large Load diff

View file

@ -34,21 +34,22 @@
#include <gsl/gsl_errno.h>
#include <gsl/gsl_spline.h>
#include <gsl/gsl_sf_gamma.h>
#include <gsl/gsl_errno.h>
#include "Numerics.hh"
#include "general.hh"
//#include "general.hh"
#include <complex>
//#define XI_SAMPLE
//#include "cosmology.hh"
#include "config_file.hh"
enum tf_type{
total, cdm, baryon, vcdm, vbaryon
};
//! Abstract base class for transfer functions
/*!
This class implements a purely virtual interface that can be
@ -230,13 +231,15 @@ protected:
void transform( real_t pnorm, real_t dplus, unsigned N, real_t q, std::vector<double>& rr, std::vector<double>& TT )
{
const double mu = 0.5;
double qmin = 1.0e-6, qmax = 1.0e+6;
double qmin = 1.0e-7, qmax = 1.0e+7;
q = 0.0;
N = 16384;
//N = 16384;
N = 1<<12;
#ifdef NZERO_Q
//q=0.4;
q=0.4;
#endif
@ -269,7 +272,7 @@ protected:
for( unsigned i=0; i<N; ++i )
{
//double lambda0=1e-4;
double lambda0=1e-4;
double k = k0*exp(((int)i - (int)N/2+1) * dlnk);
double T = ptf_->compute( k, type_ );
@ -278,7 +281,7 @@ protected:
#ifdef XI_SAMPLE
in[i][0] = dplus*dplus*sqrtpnorm*sqrtpnorm*T*T*pow(k,nspec_)*pow(k,1.5-q)*exp(-k*lambda0);//*exp(k*lambda1);
#else
in[i][0] = dplus*sqrtpnorm*T*pow(k,0.5*nspec_)*pow(k,1.5-q);//*exp(-k*lambda0);//*exp(k*lambda1);
in[i][0] = dplus*sqrtpnorm*T*pow(k,0.5*nspec_)*pow(k,1.5-q);//*exp(-k*1e-5);//*exp(k*lambda0);//*exp(k*lambda1);
#endif
in[i][1] = 0.0;
@ -422,6 +425,8 @@ protected:
if(type_==total) fname = "transfer_real_total.txt";
if(type_==cdm) fname = "transfer_real_cdm.txt";
if(type_==baryon) fname = "transfer_real_baryon.txt";
if(type_==vcdm) fname = "transfer_real_vcdm.txt";
if(type_==vbaryon) fname = "transfer_real_vbaryon.txt";
std::ofstream ofs(fname.c_str());//"transfer_real.txt");
@ -475,6 +480,9 @@ public:
/*****************************************************************/
//... compute T(r=0) by 3D k-space integration
//if( true )//type==baryon || type==vbaryon )
// Tr0_ = 0.0;
//else
{
const double REL_PRECISION=1.e-5;