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

Massive code cleanup

New conservative transfer function scheme.
New random number generator that preserves coarse Fourier modes instead of applying Hoffman-Ribak
Some minor bugs fixed.
This commit is contained in:
Oliver Hahn 2010-09-24 16:14:09 -07:00
parent aa9e88310e
commit fcc53f6edf
10 changed files with 1848 additions and 707 deletions

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,10 @@
#include "densities.hh"
#include "transfer_function.hh"
#define ACC_RF(i,j,k) (((((i)+nx)%nx)*ny+(((j)+ny)%ny))*2*(nz/2+1)+(((k)+nz)%nz))
#define ACC_RC(i,j,k) (((((i)+nxc)%nxc)*nyc+(((j)+nyc)%nyc))*2*(nzc/2+1)+(((k)+nzc)%nzc))
namespace convolution{
//! encapsulates all parameters required for transfer function convolution
@ -45,7 +49,10 @@ namespace convolution{
bool is_finest;
bool smooth;
};
/////////////////////////////////////////////////////////////////
//! abstract base class for a transfer function convolution kernel
class kernel{
@ -54,16 +61,31 @@ namespace convolution{
//! all parameters (physical/numerical)
parameters cparam_;
config_file *pcf_;
transfer_function* ptf_;
refinement_hierarchy* prefh_;
tf_type type_;
//! constructor
kernel( const parameters& cp, tf_type type )
: cparam_( cp )
kernel( config_file& cf, transfer_function* ptf, refinement_hierarchy& refh, tf_type type )
: pcf_(&cf), ptf_(ptf), prefh_(&refh), type_(type)//cparam_( cp )
{ }
//! dummy constructor
/*kernel( void )
{ }*/
//! compute/load the kernel
virtual kernel* fetch_kernel( int ilevel, bool isolated=false ) = 0;
//! virtual destructor
virtual ~kernel(){ };
//! purely virtual method to obtain a pointer to the underlying data
virtual void* get_ptr() = 0;
//! free memory
virtual void deallocate() = 0;
};
@ -71,7 +93,7 @@ namespace convolution{
struct kernel_creator
{
//! creates a convolution kernel object
virtual kernel * create( const parameters& cp, tf_type type ) const = 0;
virtual kernel * create( config_file& cf, transfer_function* ptf, refinement_hierarchy& refh, tf_type type ) const = 0;
//! destructor
virtual ~kernel_creator() { }
@ -91,15 +113,18 @@ namespace convolution{
{ get_kernel_map()[ kernel_name ] = this; }
//! creates an instance of the kernel object
kernel * create( const parameters& cp, tf_type type ) const
{ return new Derived( cp, type ); }
kernel * create( config_file& cf, transfer_function* ptf, refinement_hierarchy& refh, tf_type type ) const
{ return new Derived( cf, ptf, refh, type ); }
};
//! actual implementation of the FFT convolution (independent of the actual kernel)
template< typename real_t >
void perform( kernel* pk, void *pd );
} //namespace convolution

View file

@ -45,16 +45,15 @@ bool is_number(const std::string& s)
return true;
}
// TODO: use optimized convolution routine when in unigrid mode
/*******************************************************************************************/
/*******************************************************************************************/
/*******************************************************************************************/
void GenerateDensityUnigrid( config_file& cf, transfer_function *ptf, tf_type type,
refinement_hierarchy& refh, grid_hierarchy& delta, bool kspace, bool bdeconvolve, bool smooth )
{
unsigned levelmin,levelmax,levelminPoisson;
real_t boxlength;
unsigned ran_cube_size;
std::vector<long> rngseeds;
std::vector<std::string> rngfnames;
levelminPoisson = cf.getValue<unsigned>("setup","levelmin");
@ -62,48 +61,14 @@ void GenerateDensityUnigrid( config_file& cf, transfer_function *ptf, tf_type ty
levelmax = cf.getValue<unsigned>("setup","levelmax");
boxlength = cf.getValue<real_t>( "setup", "boxlength" );
ran_cube_size = cf.getValueSafe<unsigned>("random","cubesize",DEF_RAN_CUBE_SIZE);
unsigned nbase = 1<<levelmin;
std::cerr << " - Running unigrid version\n";
//... parse random number options
for( int i=0; i<=100; ++i )
{
char seedstr[128];
std::string tempstr;
sprintf(seedstr,"seed[%d]",i);
if( cf.containsKey( "random", seedstr ) )
tempstr = cf.getValue<std::string>( "random", seedstr );
else
tempstr = std::string("-2");
if( is_number( tempstr ) )
{
long ltemp;
cf.convert( tempstr, ltemp );
rngfnames.push_back( "" );
rngseeds.push_back( ltemp );
}else{
rngfnames.push_back( tempstr );
rngseeds.push_back(-1);
std::cout << " - Random numbers for level " << std::setw(3) << i << " will be read from file.\n";
}
}
//... parse grid setup parameters
unsigned nbase = (unsigned)pow(2,levelmin);
float lxref[3];
std::string temp = cf.getValue<std::string>( "setup", "ref_extent" );
sscanf( temp.c_str(), "%g,%g,%g", &lxref[0],&lxref[1],&lxref[2] );
int shift[3];
shift[0] = cf.getValue<int>("setup","shift_x");
shift[1] = cf.getValue<int>("setup","shift_y");
shift[2] = cf.getValue<int>("setup","shift_z");
//... select the transfer function to be used
convolution::kernel_creator *the_kernel_creator;
if( kspace )
{
std::cout << " - Using k-space transfer function kernel.\n";
@ -125,49 +90,21 @@ void GenerateDensityUnigrid( config_file& cf, transfer_function *ptf, tf_type ty
#endif
}
convolution::parameters conv_param;
conv_param.ptf = ptf;
conv_param.pcf = &cf;
//.. determine for which levels random seeds/random number files are given
int lmaxread = -1, lmingiven = -1;
for( unsigned ilevel = 0; ilevel < rngseeds.size(); ++ilevel )
{
if( rngfnames[ilevel].size() > 0 )
lmaxread = ilevel;
if( rngseeds[ilevel] > 0 && lmingiven == -1 )
lmingiven = ilevel;
}
if( (unsigned)lmingiven!=levelmin || levelmin!=levelminPoisson )
{
std::cerr <<" - Internal error: GenerateDensityUnigrid was called for a non-trivial\n"
<<" problem set-up. This should not happen, GenerateDensityHierarchy\n"
<<" should be called instead\n";
throw std::runtime_error("Internal error");
}
//... initialize random number generator
random_number_generator<random_numbers<real_t>,real_t> rand_gen( cf, refh );
//... initialize convolution kernel
convolution::kernel *the_tf_kernel = the_kernel_creator->create( cf, ptf, refh, type );
//...
std::cout << " - Performing noise convolution on level " << std::setw(2) << levelmax << " ..." << std::endl;
//... create convolution mesh
DensityGrid<real_t> *top = new DensityGrid<real_t>( nbase, nbase, nbase );
double x0[3] = { refh.offset(levelmin,0), refh.offset(levelmin,1), refh.offset(levelmin,2) };
double lx[3] = { refh.size(levelmin,0), refh.size(levelmin,1), refh.size(levelmin,2) };
x0[0] /= pow(2,levelmin); x0[1] /= pow(2,levelmin); x0[2] /= pow(2,levelmin);
lx[0] /= pow(2,levelmin); lx[1] /= pow(2,levelmin); lx[2] /= pow(2,levelmin);
random_numbers<real_t> *rc = new random_numbers<real_t>( nbase, ran_cube_size, rngseeds[levelmin], true );//, x0, lx );
if( shift[0]!=0||shift[1]!=0||shift[2]!=0 )
std::cout << " - WARNING: will ignore non-zero shift in unigrid mode!\n";
top->fill_rand( rc, 1.0, 0, 0, 0, true );
//top->fill_rand( rc, x0[0], x0[1], x0[2], true );
//rc->fill_all(*top);
delete rc;
//... fill with random numbers
rand_gen.load( *top, levelmin );
#if defined(SINGLE_PEAK)
top->zero();
@ -177,14 +114,15 @@ void GenerateDensityUnigrid( config_file& cf, transfer_function *ptf, tf_type ty
top->zero();
unsigned i0=top->size(0)/2, i1=top->size(1)/2, i2=top->size(2)/2;
(*top)(i0,i1,i2) = 1.0/8.0;
(*top)(i0+1,i1,i2) = 1.0/8.0;
(*top)(i0,i1+1,i2) = 1.0/8.0;
(*top)(i0,i1,i2+1) = 1.0/8.0;
(*top)(i0+1,i1+1,i2) = 1.0/8.0;
(*top)(i0+1,i1,i2+1) = 1.0/8.0;
(*top)(i0,i1+1,i2+1) = 1.0/8.0;
(*top)(i0+1,i1+1,i2+1) = 1.0/8.0;
double weight = 1.0;
(*top)(i0,i1,i2) = weight/8.0;
(*top)(i0+1,i1,i2) = weight/8.0;
(*top)(i0,i1+1,i2) = weight/8.0;
(*top)(i0,i1,i2+1) = weight/8.0;
(*top)(i0+1,i1+1,i2) = weight/8.0;
(*top)(i0+1,i1,i2+1) = weight/8.0;
(*top)(i0,i1+1,i2+1) = weight/8.0;
(*top)(i0+1,i1+1,i2+1) = weight/8.0;
}
#endif
@ -203,33 +141,31 @@ void GenerateDensityUnigrid( config_file& cf, transfer_function *ptf, tf_type ty
(*top)(i0+1,i1+1,i2+1) = 1.0/8.0;
}
#endif
//... load convolution kernel
the_tf_kernel->fetch_kernel( levelmin, false );
conv_param.lx = boxlength;
conv_param.ly = boxlength;
conv_param.lz = boxlength;
conv_param.nx = top->nx_;
conv_param.ny = top->ny_;
conv_param.nz = top->nz_;
conv_param.coarse_fact = 0;
conv_param.deconvolve = bdeconvolve;
conv_param.is_finest = true;
conv_param.smooth = smooth;
convolution::kernel *the_tf_kernel = the_kernel_creator->create( conv_param, type );
//... perform convolution
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*>( top->get_data_ptr() ) );
//... clean up kernel
delete the_tf_kernel;
//... create multi-grid hierarchy
delta.create_base_hierarchy(levelmin);
//... copy convolved field to multi-grid hierarchy
top->copy( *delta.get_grid(levelmin) );
//... delete convolution grid
delete top;
for( int i=levelmax; i>0; --i )
mg_straight().restrict( (*delta.get_grid(i)), (*delta.get_grid(i-1)) );
}
/*******************************************************************************************/
/*******************************************************************************************/
/*******************************************************************************************/
void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type type,
refinement_hierarchy& refh, grid_hierarchy& delta, bool bdeconvolve, bool smooth )
{
@ -237,10 +173,7 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
real_t boxlength;
std::vector<long> rngseeds;
std::vector<std::string> rngfnames;
bool force_shift(false), kspaceTF;
unsigned ran_cube_size;
constraint_set contraints(cf);
bool kspaceTF;
double tstart, tend;
tstart = omp_get_wtime();
@ -250,53 +183,12 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
levelmin = cf.getValueSafe<unsigned>("setup","levelmin_TF",levelminPoisson);
levelmax = cf.getValue<unsigned>("setup","levelmax");
boxlength = cf.getValue<real_t>( "setup", "boxlength" );
force_shift = cf.getValueSafe<bool>("setup", "force_shift", force_shift );
kspaceTF = cf.getValueSafe<bool>("setup", "kspace_TF", false);
ran_cube_size = cf.getValueSafe<unsigned>("random","cubesize",DEF_RAN_CUBE_SIZE);
//... parse random number options
for( int i=0; i<=100; ++i )
{
char seedstr[128];
std::string tempstr;
sprintf(seedstr,"seed[%d]",i);
if( cf.containsKey( "random", seedstr ) )
tempstr = cf.getValue<std::string>( "random", seedstr );
else
tempstr = std::string("-2");
if( is_number( tempstr ) )
{
long ltemp;
cf.convert( tempstr, ltemp );
rngfnames.push_back( "" );
rngseeds.push_back( ltemp );
}else{
rngfnames.push_back( tempstr );
rngseeds.push_back(-1);
std::cout << " - Random numbers for level " << std::setw(3) << i << " will be read from file.\n";
}
}
random_number_generator<random_numbers<real_t>,real_t> rand_gen( cf, refh );
//... parse grid setup parameters
unsigned nbase = (unsigned)pow(2,levelmin);
float lxref[3];
std::string temp = cf.getValue<std::string>( "setup", "ref_extent" );
sscanf( temp.c_str(), "%g,%g,%g", &lxref[0],&lxref[1],&lxref[2] );
int shift[3];
shift[0] = cf.getValue<int>("setup","shift_x");
shift[1] = cf.getValue<int>("setup","shift_y");
shift[2] = cf.getValue<int>("setup","shift_z");
/*#ifdef SINGLE_PRECISION
convolution::kernel_creator *the_kernel_creator = convolution::get_kernel_map()[ "tf_kernel_real_float" ];
#else
convolution::kernel_creator *the_kernel_creator = convolution::get_kernel_map()[ "tf_kernel_real_double" ];
#endif*/
convolution::kernel_creator *the_kernel_creator;
@ -324,110 +216,13 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
#endif
}
convolution::parameters conv_param;
conv_param.ptf = ptf;
conv_param.pcf = &cf;
//... compute absolute grid offsets
std::vector<int> offtotx(levelmax+1,0),offtoty(levelmax+1,0),offtotz(levelmax+1,0);
for( unsigned ilevel = levelmin+1; ilevel<=levelmax; ++ilevel )
{
//... build a partial sum to get absolute offsets
offtotx[ilevel] = 2*(offtotx[ilevel-1]+refh.offset(ilevel,0));
offtoty[ilevel] = 2*(offtoty[ilevel-1]+refh.offset(ilevel,1));
offtotz[ilevel] = 2*(offtotz[ilevel-1]+refh.offset(ilevel,2));
}
for( unsigned ilevel = levelmin+1; ilevel<=levelmax; ++ilevel )
{
//... the arrays are doubled in size for the isolated BCs
offtotx[ilevel] -= refh.size(ilevel,0)/2;
offtoty[ilevel] -= refh.size(ilevel,1)/2;
offtotz[ilevel] -= refh.size(ilevel,2)/2;
}
//.. determine for which levels random seeds/random number files are given
int lmaxread = -1, lmingiven = -1;
for( unsigned ilevel = 0; ilevel < rngseeds.size(); ++ilevel )
{
if( rngfnames[ilevel].size() > 0 )
lmaxread = ilevel;
if( rngseeds[ilevel] > 0 && lmingiven == -1 )
lmingiven = ilevel;
}
/***** RESORT TO UNIGRID VERSION FOR SIMPLE GRID SETUPS *****/
// TODO: need to make sure unigrid gets called whenever possible
// FIXME: temporarily disabled
if( lmingiven == (int)levelmin && levelmin == levelmax && levelmin==levelminPoisson )
{
GenerateDensityUnigrid(cf,ptf,type,refh,delta,kspaceTF,bdeconvolve,smooth);
return;
}
/***** GENERATE WHITE NOISE FIELDS FOR MULTI-LEVEL GRID *****/
//... if random numbers are to be read from file, do this now
std::vector< random_numbers<real_t>* > randc;
randc.assign(std::max(lmaxread,std::max(lmingiven,(int)levelmax))+1,(random_numbers<real_t>*)NULL);
if( lmaxread >= (int)levelmin )
{
randc[lmaxread] = new random_numbers<real_t>( (unsigned)pow(2,lmaxread), rngfnames[lmaxread] );
for( int ilevel = lmaxread-1; ilevel >= (int)levelmin; --ilevel )
randc[ilevel] = new random_numbers<real_t>( *randc[ilevel+1] );
}
//... if random numbers are not given for lower levels, obtain them by averaging
//if( lmingiven >= (int)levelmin )
if( lmingiven > (int)levelmin )
{
randc[lmingiven] = new random_numbers<real_t>( (unsigned)pow(2,lmingiven), ran_cube_size, rngseeds[lmingiven], true );//, x0, lx );
for( int ilevel = lmingiven-1; ilevel >= (int)levelmin; --ilevel ){
if( rngseeds[ilevel-levelmin] > 0 )
std::cerr << " - Warning: random seed for level " << ilevel << " will be ignored.\n"
<< " consistency requires that it is obtained by restriction from level " << lmingiven << std::endl;
randc[ilevel] = new random_numbers<real_t>( *randc[ilevel+1] );
}
}
//... if random seeds are given for levels coarser than levelmin, use them as constraints
if( lmingiven < (int)levelmin && !(lmaxread>=(int)levelmin) )
{
randc[lmingiven] = new random_numbers<real_t>( (unsigned)pow(2,lmingiven), ran_cube_size, rngseeds[lmingiven], true );//, x0, lx );
for( int ilevel = lmingiven+1; ilevel <= (int)levelmin; ++ilevel )
{
long seed = rngseeds[ilevel];
if( seed <= 0 )
seed = rngseeds[lmingiven]+ilevel;
randc[ilevel] = new random_numbers<real_t>( *randc[ilevel-1], ran_cube_size, seed, true );
delete randc[ilevel-1];
randc[ilevel-1]=NULL;
}
}
//... create and initialize density grids with white noise
PaddedDensitySubGrid<real_t>* coarse(NULL), *fine(NULL);
DensityGrid<real_t>* top(NULL);
//... clean up ...//
for( unsigned i=0; i<randc.size(); ++i )
{
if( i<levelmin || i>levelmax )
if( randc[i] != NULL )
{
delete randc[i];
randc[i]=NULL;
}
}
convolution::kernel *the_tf_kernel = the_kernel_creator->create( cf, ptf, refh, type );
/***** PERFORM CONVOLUTIONS *****/
@ -436,40 +231,8 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
std::cout << " - Performing noise convolution on level " << std::setw(2) << levelmax << " ..." << std::endl;
top = new DensityGrid<real_t>( nbase, nbase, nbase );
random_numbers<real_t> *rc;
if( levelminPoisson == levelmin && !force_shift)
{
if( randc[levelmin] == NULL )
rc = new random_numbers<real_t>( nbase, ran_cube_size, rngseeds[levelmin], true );
else
rc = randc[levelmin];
if( shift[0]!=0||shift[1]!=0||shift[2]!=0 )
std::cout << " - WARNING: will ignore non-zero shift in unigrid mode!\n";
rand_gen.load( *top, levelmin );
top->fill_rand( rc, 1.0, 0, 0, 0, true );
}
else
{
int lfac = (int)pow(2,levelmin-levelminPoisson);
int x0[3] = { -shift[0]*lfac, -shift[1]*lfac, -shift[2]*lfac };
int lx[3] = { refh.size(levelmin,0), refh.size(levelmin,1), refh.size(levelmin,2) };
if( randc[levelmin] == NULL )
rc = randc[levelmin] = new random_numbers<real_t>( nbase, ran_cube_size, rngseeds[levelmin], x0, lx );
//
//if( randc[levelmin] == NULL )
// rc = new random_numbers<real_t>( nbase, ran_cube_size, rngseeds[levelmin], true );
else
rc = randc[levelmin];
top->fill_rand( rc, 1.0, x0[0], x0[1], x0[2], true );
}
delete rc;
#if defined(SINGLE_PEAK)
top->zero();
(*top)(top->size(0)/2, top->size(1)/2, top->size(2)/2) = 1.0;
@ -506,21 +269,9 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
(*top)(i0+1,i1+1,i2+1) = 1.0/8.0;
}
#endif
conv_param.lx = boxlength;
conv_param.ly = boxlength;
conv_param.lz = boxlength;
conv_param.nx = top->nx_;
conv_param.ny = top->ny_;
conv_param.nz = top->nz_;
conv_param.coarse_fact = 0;
conv_param.deconvolve = bdeconvolve;
conv_param.is_finest = true;
conv_param.smooth = smooth;
convolution::kernel *the_tf_kernel = the_kernel_creator->create( conv_param, type );
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*>( top->get_data_ptr() ) );
delete the_tf_kernel;
convolution::perform<real_t>( the_tf_kernel->fetch_kernel( levelmax ), reinterpret_cast<void*>( top->get_data_ptr() ) );
the_tf_kernel->deallocate();
delta.create_base_hierarchy(levelmin);
top->copy( *delta.get_grid(levelmin) );
@ -537,75 +288,13 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
if( i==0 )
{
int lfac = (int)pow(2,levelmin-levelminPoisson);
top = new DensityGrid<real_t>( nbase, nbase, nbase );
random_numbers<real_t> *rc;
/*int x0[3] = { refh.offset_abs(levelmin,0)-lfac*shift[0],
refh.offset_abs(levelmin,1)-lfac*shift[1],
refh.offset_abs(levelmin,2)-lfac*shift[2] };
int lx[3] = { refh.size(levelmin,0),
refh.size(levelmin,1),
refh.size(levelmin,2) };*/
if( randc[levelmin] == NULL )
{
std::cout << " - Creating new random numbers for level " << levelmin << std::endl;
rc = randc[levelmin] = new random_numbers<real_t>( nbase, ran_cube_size, rngseeds[levelmin], true );//x0, lx );
}
else
rc = randc[levelmin];
top->fill_rand( rc, 1.0, -lfac*shift[0], -lfac*shift[1], -lfac*shift[2], true );
delete rc;
randc[levelmin] = NULL;
}
fine = new PaddedDensitySubGrid<real_t>( refh.offset(levelmin+i+1,0),
refh.offset(levelmin+i+1,1),
refh.offset(levelmin+i+1,2),
refh.size(levelmin+i+1,0),
refh.size(levelmin+i+1,1),
refh.size(levelmin+i+1,2) );
{
random_numbers<real_t> *rc;
int x0[3],lx[3];
int lfac = (int)pow(2,levelmin+i+1-levelminPoisson);
lx[0] = 2*refh.size(levelmin+i+1,0);
lx[1] = 2*refh.size(levelmin+i+1,1);
lx[2] = 2*refh.size(levelmin+i+1,2);
x0[0] = refh.offset_abs(levelmin+i+1,0)-lfac*shift[0]-lx[0]/4;
x0[1] = refh.offset_abs(levelmin+i+1,1)-lfac*shift[1]-lx[1]/4;
x0[2] = refh.offset_abs(levelmin+i+1,2)-lfac*shift[2]-lx[2]/4;
if( randc[levelmin+i+1] == NULL )
{
std::cout << " - Creating new random numbers for level " << levelmin+1+i << std::endl;
rc = randc[levelmin+i+1] = new random_numbers<real_t>((unsigned)pow(2,levelmin+i+1), ran_cube_size, rngseeds[levelmin+i+1], x0, lx);
}
else
rc = randc[levelmin+i+1];
fine->fill_rand( rc, 1.0, x0[0], x0[1], x0[2], false );
if( true )//i> 0 )//i+levelmin+1 > (unsigned)lmingiven )
{
if(i==0)
fine->constrain( *top );
else
fine->constrain( *coarse );
}
delete rc;
rc = NULL;
rand_gen.load(*top,levelmin);
}
fine = new PaddedDensitySubGrid<real_t>( refh.offset(levelmin+i+1,0), refh.offset(levelmin+i+1,1), refh.offset(levelmin+i+1,2),
refh.size(levelmin+i+1,0), refh.size(levelmin+i+1,1), refh.size(levelmin+i+1,2) );
rand_gen.load(*fine,levelmin+i+1);
//.......................................................................................................//
//... PERFORM CONVOLUTIONS ..............................................................................//
@ -638,18 +327,7 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
DensityGrid<real_t> top_save( *top );
conv_param.lx = boxlength;
conv_param.ly = boxlength;
conv_param.lz = boxlength;
conv_param.nx = top->nx_;
conv_param.ny = top->ny_;
conv_param.nz = top->nz_;
conv_param.coarse_fact = levelmax-levelmin;
conv_param.deconvolve = bdeconvolve;
conv_param.is_finest = false;
conv_param.smooth = smooth;
convolution::kernel *the_tf_kernel = the_kernel_creator->create( conv_param, type );
the_tf_kernel->fetch_kernel( levelmin );
//... 1) compute standard convolution for levelmin
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*>( top->get_data_ptr() ) );
@ -663,9 +341,7 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
refh.size(levelmin+i+1,0)/2, refh.size(levelmin+i+1,1)/2, refh.size(levelmin+i+1,2)/2 );
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*>( top->get_data_ptr() ) );
delete the_tf_kernel;
the_tf_kernel->deallocate();
meshvar_bnd delta_longrange( *delta.get_grid(levelmin) );
top->copy( delta_longrange );
@ -675,25 +351,13 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
for( int j=1; j<=(int)levelmax-(int)levelmin; ++j )
{
int R = j;
delta.add_patch( refh.offset(levelmin+j,0), refh.offset(levelmin+j,1), refh.offset(levelmin+j,2),
refh.size(levelmin+j,0), refh.size(levelmin+j,1), refh.size(levelmin+j,2) );
mg_cubic_mult().prolong( delta_longrange, *delta.get_grid(levelmin+j),
refh.offset_abs(levelmin,0), refh.offset_abs(levelmin,1), refh.offset_abs(levelmin,2),
refh.offset_abs(levelmin+j,0), refh.offset_abs(levelmin+j,1), refh.offset_abs(levelmin+j,2), R);
}
//delta.add_patch( refh.offset(levelmin+1,0), refh.offset(levelmin+1,1), refh.offset(levelmin+1,2),
// refh.size(levelmin+1,0), refh.size(levelmin+1,1), refh.size(levelmin+1,2) );
//mg_cubic().prolong( delta_longrange, *delta.get_grid(levelmin+1) );
refh.offset_abs(levelmin+j,0), refh.offset_abs(levelmin+j,1), refh.offset_abs(levelmin+j,2), j);
}
}
else
{
@ -703,34 +367,8 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
std::cout << " - Performing noise convolution on level " << std::setw(2) << levelmin+i << " ..." << std::endl;
//delta.add_patch( refh.offset(levelmin+i+1,0), refh.offset(levelmin+i+1,1), refh.offset(levelmin+i+1,2),
// refh.size(levelmin+i+1,0), refh.size(levelmin+i+1,1), refh.size(levelmin+i+1,2) );
//mg_cubic().prolong( *delta.get_grid(levelmin+i), *delta.get_grid(levelmin+i+1) );
real_t dx,lx,ly,lz;
dx = boxlength/pow(2.0,levelmin+i);
lx = dx * coarse->nx_;
ly = dx * coarse->ny_;
lz = dx * coarse->nz_;
//.. set convolution parameters
//TODO: this needs to be changed, forgetting to set a parameter will not be warned!
conv_param.lx = lx;
conv_param.ly = ly;
conv_param.lz = lz;
conv_param.nx = coarse->nx_;
conv_param.ny = coarse->ny_;
conv_param.nz = coarse->nz_;
conv_param.coarse_fact = levelmax-levelmin-i;
conv_param.deconvolve = bdeconvolve;
conv_param.is_finest = false;
conv_param.smooth = smooth;
convolution::kernel *the_tf_kernel = the_kernel_creator->create( conv_param, type );
PaddedDensitySubGrid<real_t> coarse_save( *coarse );
the_tf_kernel->fetch_kernel( levelmin+i );
//... 1) the inner region
coarse->subtract_boundary_oct_mean();
@ -744,26 +382,17 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
coarse->zero_subgrid(refh.offset(levelmin+i+1,0), refh.offset(levelmin+i+1,1), refh.offset(levelmin+i+1,2),
refh.size(levelmin+i+1,0)/2, refh.size(levelmin+i+1,1)/2, refh.size(levelmin+i+1,2)/2 );
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*> (coarse->get_data_ptr()) );
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*>( coarse->get_data_ptr() ) );
//... interpolate to finer grid(s)
meshvar_bnd delta_longrange( *delta.get_grid(levelmin+i) );
coarse->copy_unpad( delta_longrange );
for( int j=1; j<=(int)levelmax-(int)levelmin-i; ++j )
{
int R = j;
//delta.add_patch( refh.offset(levelmin+i+j,0), refh.offset(levelmin+i+j,1), refh.offset(levelmin+i+j,2),
// refh.size(levelmin+i+j,0), refh.size(levelmin+i+j,1), refh.size(levelmin+i+j,2) );
mg_cubic_mult().prolong_add( delta_longrange, *delta.get_grid(levelmin+i+j),
mg_cubic_mult().prolong_add( delta_longrange, *delta.get_grid(levelmin+i+j),
refh.offset_abs(levelmin+i,0), refh.offset_abs(levelmin+i,1), refh.offset_abs(levelmin+i,2),
refh.offset_abs(levelmin+i+j,0), refh.offset_abs(levelmin+i+j,1), refh.offset_abs(levelmin+i+j,2), R);
refh.offset_abs(levelmin+i+j,0), refh.offset_abs(levelmin+i+j,1), refh.offset_abs(levelmin+i+j,2), j);
}
//mg_cubic().prolong_add( delta_longrange, *delta.get_grid(levelmin+i+1) );
//... 3) the coarse-grid correction
*coarse = coarse_save;
@ -771,7 +400,8 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*> (coarse->get_data_ptr()) );
coarse->upload_bnd_add( *delta.get_grid(levelmin+i-1) );
delete the_tf_kernel;
//... clean up
the_tf_kernel->deallocate();
delete coarse;
}
@ -786,34 +416,15 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
* multi-grid: finest sub-grid .....
\**********************************************************************************************************/
std::cout << " - Performing noise convolution on level " << std::setw(2) << levelmax << " ..." << std::endl;
real_t dx,lx,ly,lz;
dx = boxlength/pow(2.0,levelmax);
lx = dx * coarse->nx_;
ly = dx * coarse->ny_;
lz = dx * coarse->nz_;
//... set convolution parameters
conv_param.lx = lx;
conv_param.ly = ly;
conv_param.lz = lz;
conv_param.nx = coarse->nx_;
conv_param.ny = coarse->ny_;
conv_param.nz = coarse->nz_;
conv_param.coarse_fact = 0;
conv_param.deconvolve = bdeconvolve;
conv_param.is_finest = true;
conv_param.smooth = smooth;
#if defined(SINGLE_PEAK) || defined(SINGLE_OCT_PEAK)
{
coarse->zero();
int
i0 = pow(2,levelmax)/2 - refh.offset_abs(levelmax,0) + coarse->nx_/4,
i1 = pow(2,levelmax)/2 - refh.offset_abs(levelmax,1) + coarse->nx_/4,
i2 = pow(2,levelmax)/2 - refh.offset_abs(levelmax,2) + coarse->nx_/4;
i0 = (1<<(levelmax-1)) - refh.offset_abs(levelmax,0) + coarse->nx_/4,
i1 = (1<<(levelmax-1)) - refh.offset_abs(levelmax,1) + coarse->nx_/4,
i2 = (1<<(levelmax-1)) - refh.offset_abs(levelmax,2) + coarse->nx_/4;
#if defined(SINGLE_PEAK)
(*coarse)(i0,i1,i2) = 1.0;
#elif defined(SINGLE_OCT_PEAK)
@ -834,12 +445,11 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
coarse->zero();
#endif
//... 1) grid self-contributio
//... 1) grid self-contribution
PaddedDensitySubGrid<real_t> coarse_save( *coarse );
//... create convolution kernel
convolution::kernel *the_tf_kernel = the_kernel_creator->create( conv_param, type );
the_tf_kernel->fetch_kernel( levelmax );
//... subtract oct mean on boundary but not in interior
coarse->subtract_boundary_oct_mean();
@ -860,26 +470,19 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
//... perform convolution
convolution::perform<real_t>( the_tf_kernel, reinterpret_cast<void*> (coarse->get_data_ptr()) );
the_tf_kernel->deallocate();
//coarse->subtract_mean();
//... upload data to coarser grid
coarse->upload_bnd_add( *delta.get_grid(levelmax-1) );
delete the_tf_kernel;
//delete the_tf_kernel;
delete coarse;
}
//... clean up ...//
for( unsigned i=0; i<randc.size(); ++i )
{
if( i<levelmin || i>levelmax )
if( randc[i] != NULL )
{
delete randc[i];
randc[i]=NULL;
}
}
delete the_tf_kernel;
#if 0
// NEVER, NEVER ENABLE THE FOLLOWING
@ -888,11 +491,11 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
//for( int i=levelmin; i<(int)levelmax; ++i )
// enforce_mean( (*delta.get_grid(i+1)), (*delta.get_grid(i)) );
// for( unsigned i=levelmax; i>levelmin; --i )
// enforce_coarse_mean( (*delta.get_grid(i)), (*delta.get_grid(i-1)) );
for( unsigned i=levelmax; i>levelmin; --i )
enforce_coarse_mean( (*delta.get_grid(i)), (*delta.get_grid(i-1)) );
#endif
#if 1
#if 0
//... subtract the box mean.... this will otherwise add
//... a constant curvature term to the potential
double sum = 0.0;
@ -928,12 +531,7 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
}
#endif
//... fill coarser levels with data from finer ones...
for( int i=levelmax; i>0; --i )
mg_straight().restrict( (*delta.get_grid(i)), (*delta.get_grid(i-1)) );
tend = omp_get_wtime();
if( true )//verbosity > 1 )
std::cout << " - Density calculation took " << tend-tstart << "s with " << omp_get_max_threads() << " threads." << std::endl;
@ -941,8 +539,12 @@ void GenerateDensityHierarchy( config_file& cf, transfer_function *ptf, tf_type
}
/*******************************************************************************************/
/*******************************************************************************************/
/*******************************************************************************************/
void normalize_density( grid_hierarchy& delta )
{
{
double sum = 0.0;
unsigned levelmin = delta.levelmin(), levelmax = delta.levelmax();

16
main.cc
View file

@ -49,7 +49,7 @@
#include "transfer_function.hh"
#define THE_CODE_NAME "music!"
#define THE_CODE_VERSION "0.6.0a"
#define THE_CODE_VERSION "0.7.0a"
namespace music
@ -150,6 +150,9 @@ void modify_grid_for_TF( const refinement_hierarchy& rh_full, refinement_hierarc
void coarsen_density( const refinement_hierarchy& rh, grid_hierarchy& u )
{
for( int i=rh.levelmax(); i>0; --i )
mg_straight().restrict( *(u.get_grid(i)), *(u.get_grid(i-1)) );
for( unsigned i=1; i<=rh.levelmax(); ++i )
{
if( rh.offset(i,0) != u.get_grid(i)->offset(0)
@ -164,9 +167,7 @@ void coarsen_density( const refinement_hierarchy& rh, grid_hierarchy& u )
}
}
for( int i=rh.levelmax(); i>0; --i )
mg_straight().restrict( *(u.get_grid(i)), *(u.get_grid(i-1)) );
}
void store_grid_structure( config_file& cf, const refinement_hierarchy& rh )
@ -326,9 +327,8 @@ int main (int argc, const char * argv[])
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
@ -451,11 +451,11 @@ int main (int argc, const char * argv[])
u = f; u.zero();
err = the_poisson_solver->solve(f, u);
the_output_plugin->write_dm_mass(f);
the_output_plugin->write_dm_density(f);
err = the_poisson_solver->solve(f, u);
if(!bdefd)
f.deallocate();

32
mesh.hh
View file

@ -273,6 +273,9 @@ public:
return *this;
}
real_t* get_ptr( void )
{ return m_pdata; }
};
//! MeshvarBnd derived class adding boundary ghost cell functionality
@ -599,7 +602,7 @@ public:
*/
void cell_pos( unsigned ilevel, int i, int j, int k, double* ppos ) const
{
double h = 1.0/pow(2,ilevel);//, htop = h*2.0;
double h = 1.0/(1<<ilevel);//, htop = h*2.0;
ppos[0] = h*((double)offset_abs(ilevel,0)+(double)i+0.5);
ppos[1] = h*((double)offset_abs(ilevel,1)+(double)j+0.5);
ppos[2] = h*((double)offset_abs(ilevel,2)+(double)k+0.5);
@ -845,7 +848,7 @@ public:
{
for( unsigned i=0; i<=levelmax(); ++i )
{
unsigned n = (unsigned)pow(2,i);
unsigned n = 1<<i;
if( m_pgrids[i]->size(0) == n &&
m_pgrids[i]->size(1) == n &&
m_pgrids[i]->size(2) == n )
@ -959,9 +962,8 @@ public:
sscanf( temp.c_str(), "%lf,%lf,%lf", &lxref_[0],&lxref_[1],&lxref_[2] );
unsigned
ncoarse = (unsigned)pow(2,levelmin_);
//ncoarse_tf = (unsigned)pow(2,levelmin_tf_);
ncoarse = 1<<levelmin_;
//... determine shift
double xc[3];
@ -1012,19 +1014,20 @@ public:
//... determine the position of the refinement region on the finest grid
int il,jl,kl,ir,jr,kr;
int nresmax = (int)pow(2,levelmax_);
int nresmax = 1<<levelmax_;
il = (int)(x0ref_[0] * nresmax);
jl = (int)(x0ref_[1] * nresmax);
kl = (int)(x0ref_[2] * nresmax);
ir = (int)((x0ref_[0]+lxref_[0]) * nresmax + 1.0);
jr = (int)((x0ref_[0]+lxref_[0]) * nresmax + 1.0);
kr = (int)((x0ref_[0]+lxref_[0]) * nresmax + 1.0);
jr = (int)((x0ref_[1]+lxref_[1]) * nresmax + 1.0);
kr = (int)((x0ref_[2]+lxref_[2]) * nresmax + 1.0);
//... align with coarser grids ...
if( align_top_ )
{
//... require alignment with top grid
unsigned nref = (unsigned)pow(2,levelmax_-levelmin_)*2;
unsigned nref = 1<<(levelmax_-levelmin_+1);
il = (int)((double)il/nref)*nref;
jl = (int)((double)jl/nref)*nref;
@ -1065,7 +1068,7 @@ public:
if( align_top_ )
{
//... require alignment with top grid
unsigned nref = (unsigned)pow(2,ilevel-levelmin_);
unsigned nref = 1<<(ilevel-levelmin_);
il = (int)((double)il/nref)*nref;
jl = (int)((double)jl/nref)*nref;
@ -1096,7 +1099,7 @@ public:
for( unsigned ilevel=levelmin_+1; ilevel<=levelmax_; ++ilevel )
{
double h = 1.0/pow(2,ilevel);
double h = 1.0/(1<<ilevel);
x0_[ilevel] = h*(double)oax_[ilevel];
y0_[ilevel] = h*(double)oay_[ilevel];
@ -1109,7 +1112,7 @@ public:
for( unsigned ilevel=0; ilevel <=levelmin_; ++ilevel )
{
unsigned n = (unsigned)pow(2,ilevel);
unsigned n = 1<<ilevel;
xl_[ilevel] = yl_[ilevel] = zl_[ilevel] = 1.0;
nx_[ilevel] = ny_[ilevel] = nz_[ilevel] = n;
@ -1152,7 +1155,7 @@ public:
*/
void adjust_level( unsigned ilevel, int nx, int ny, int nz, int oax, int oay, int oaz )
{
double h = 1.0/pow(2,ilevel);
double h = 1.0/(1<<ilevel);
int dx,dy,dz;
@ -1198,7 +1201,8 @@ public:
for( unsigned i=0; i<=levelmax(); ++i )
{
unsigned n = (unsigned)pow(2,i);
unsigned n = 1<<i;
if( oax_[i]==0 && oay_[i]==0 && oaz_[i]==0
&& nx_[i]==n && ny_[i]==n && nz_[i]==n )
{

View file

@ -113,7 +113,7 @@ public:
template< typename m1, typename m2 >
inline void prolong( m1& V, m2& v, int oxc, int oyc, int ozc, int oxf, int oyf, int ozf, int R ) const
{
int N = (int)pow(2,R);
int N = 1<<R;
int Nl= -N/2+1;//, Nr=N/2;
double dx = 1.0/(double)N;
@ -147,7 +147,6 @@ public:
zf = (dx*(double)(ozf+k+Nl)-ozc)-0.5*dx + 0.5;
double val = interp_cubic(xf-xc,yf-yc,zf-zc,V,iic,jjc,kkc);
v(i,j,k) = val;
finemean += val; finecount++;
@ -159,9 +158,9 @@ public:
//... subtract the mean difference caused by interpolation
//double dmean = coarsemean-finemean;
/*double dmean = coarsemean-finemean;
/*#pragma omp parallel for
#pragma omp parallel for
for( int i=0; i<nx; ++i )
for( int j=0; j<ny; ++j )
for( int k=0; k<nz; ++k )
@ -171,7 +170,7 @@ public:
template< typename m1, typename m2 >
inline void prolong_add( m1& V, m2& v, int oxc, int oyc, int ozc, int oxf, int oyf, int ozf, int R ) const
{
int N = (int)pow(2,R);
int N = 1<<R;
int Nl= -N/2+1;//, Nr=N/2;
double dx = 1.0/(double)N;
@ -213,15 +212,15 @@ public:
coarsemean /= coarsecount;
finemean /= finecount;
//double dmean = coarsemean-finemean;
/*double dmean = coarsemean-finemean;
//... subtract the mean difference caused by interpolation
/*#pragma omp parallel for
#pragma omp parallel for
for( int i=0; i<nx; ++i )
for( int j=0; j<ny; ++j )
for( int k=0; k<nz; ++k )
v(i,j,k) += dmean;
*/
*/
}
};

View file

@ -258,7 +258,7 @@ void solver<S,I,O,T>::twoGrid( unsigned ilevel )
MeshvarBnd<T> *uf, *uc, *ff, *fc;
T
h = 1.0/(pow(2.0,ilevel)),
h = 1.0/(1<<ilevel),
c0 = -1.0/m_scheme.ccoeff(),
h2 = h*h;
@ -456,7 +456,7 @@ double solver<S,I,O,T>::compute_RMS_resid( const GridHierarchy<T>& uh, const Gri
ny = uh.get_grid(ilevel)->size(1),
nz = uh.get_grid(ilevel)->size(2);
double h = 1.0/pow(2,ilevel), h2=h*h, err;
double h = 1.0/(1<<ilevel), h2=h*h, err;
double sum = 0.0;
unsigned count = 0;

View file

@ -647,7 +647,7 @@ double fft_poisson_plugin::gradient( int dir, grid_hierarchy& u, grid_hierarchy&
dmax = fabs(data[idx]);
}
std::cerr << " - component max. is " << dmax*nx << std::endl;
//std::cerr << " - component max. is " << dmax*nx << std::endl;
delete[] data;
return 0.0;

929
random.hh

File diff suppressed because it is too large Load diff

View file

@ -40,7 +40,7 @@
#include <complex>
//#define XI_SAMPLE
#include "config_file.hh"
@ -271,7 +271,12 @@ protected:
double lambda0=1e-4;
//double lambda1=1e4;
double k = k0*exp(((int)i - (int)N/2+1) * dlnk);
in[i].re = dplus*sqrtpnorm*ptf_->compute( k, type_ )*pow(k,0.5*nspec_)*pow(k,1.5-q)*exp(-k*lambda0);//*exp(k*lambda1);
double T = ptf_->compute( k, type_ );
#ifdef XI_SAMPLE
in[i].re = dplus*dplus*sqrtpnorm*sqrtpnorm*T*T*pow(k,nspec_)*pow(k,1.5-q)*exp(-k*lambda0);//*exp(k*lambda1);
#else
in[i].re = dplus*sqrtpnorm*T*pow(k,0.5*nspec_)*pow(k,1.5-q)*exp(-k*lambda0);//*exp(k*lambda1);
#endif
in[i].im = 0.0;
sum_in += in[i].re;
@ -431,12 +436,10 @@ public:
//.. need a factor sqrt( 2*kny^2_x + 2*kny^2_y + 2*kny^2_z )/2 = sqrt(3/2)kny (in equilateral case)
//#warning Need to integrate from Boxsize (see below)?
gsl_integration_qag (&F, 0.0, sqrt(1.5)*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, 1.24070098*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, 1.280788*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, 1.116*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, sqrt(3)*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, 0.5*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, 1.280788*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
//gsl_integration_qag (&F, 0.0, sqrt(2.0)*knymax, 0, 1e-8, 20000, GSL_INTEG_GAUSS21, wp, &Tr0_, &error);
gsl_integration_workspace_free(wp);
@ -521,7 +524,12 @@ public:
static double call_wrapper( double k, void *arg )
{
double *a = (double*)arg;
return 4.0*M_PI*a[0]*ptf_->compute( k, type_ )*pow(k,0.5*nspec_)*k*k;
double T = ptf_->compute( k, type_ );
#ifdef XI_SAMPLE
return 4.0*M_PI*a[0]*a[0]*T*T*pow(k,nspec_)*k*k;
#else
return 4.0*M_PI*a[0]*T*pow(k,0.5*nspec_)*k*k;
#endif
}
~TransferFunction_real()