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

Updated code with new panphasia_ho versions the allow the Fourier grid

to be a multiple of the grid of Panphasia cells. Fixed a few format
statements.
This commit is contained in:
Adrian Jenkins 2021-05-07 14:30:28 +01:00
parent f7c9d606f7
commit 2d5cc0ac50
4 changed files with 370 additions and 171 deletions

View file

@ -621,10 +621,11 @@ int demo_descriptor_()
char desc_name[100];
char desc_iden[8];
int error_code;
int pan_mode;
descriptor_read_in = 0;
if (error_code = parse_and_validate_descriptor_(str))
if (error_code = parse_and_validate_descriptor_(str,&pan_mode))
{
printf("Invalid descriptor %s\n", str);
@ -756,11 +757,13 @@ int PANPHASIA_init_descriptor_(char *descriptor, int *verbose)
set_panphasia_key_(verb);
check_panphasia_key_(verb);
if (error = parse_and_validate_descriptor_(descriptor))
int pan_mode;
if (error = parse_and_validate_descriptor_(descriptor,&pan_mode))
{
printf("-----------------------------------------\n");
printf("Error initating start-up Panphasia routines \n");
printf("Error code %d\n", error);
printf("pan_mode %d\n", pan_mode);
printf("-----------------------------------------\n");
abort();
};
@ -907,12 +910,9 @@ int PANPHASIA_compute_coefficients_(size_t *xstart, size_t *ystart, size_t *zsta
if (*zstart >= rel_coord_max)
return (203);
if ((*xextent > rel_coord_max) || (*xextent == 0))
return (204);
if ((*yextent > rel_coord_max) || (*yextent == 0))
return (205);
if ((*zextent > rel_coord_max) || (*zextent == 0))
return (206);
if (*xextent > rel_coord_max) return (204);
if (*yextent > rel_coord_max) return (205);
if (*zextent > rel_coord_max) return (206);
if ((*ncopy < 0) || (*ncopy > Nbasis))
return (207);
@ -920,6 +920,8 @@ int PANPHASIA_compute_coefficients_(size_t *xstart, size_t *ystart, size_t *zsta
if ((copy_list[0] < 0) || (copy_list[*ncopy - 1] >= Nbasis))
return (208);
if ((*xextent==0)||(*yextent==0)||(*zextent==0)) return(0);
for (int i = 1; i < *ncopy; i++)
if (copy_list[i] <= copy_list[i - 1])
return (209);
@ -1160,8 +1162,8 @@ int PANPHASIA_compute_coefficients_(size_t *xstart, size_t *ystart, size_t *zsta
//========================================================================================
{
FFTW_REAL *ptr_real = output_values;
FFTW_COMPLEX *ptr_cmplx = output_values;
PAN_REAL *ptr_real = output_values;
PAN_COMPLEX *ptr_cmplx = output_values;
size_t zdimension = (*flag_output_mode == 2) ? *zextent + 2 : *zextent; // For R2C pad by two in z-dimension
//printf("zdimension = %ld\n",zdimension);
@ -1183,7 +1185,7 @@ int PANPHASIA_compute_coefficients_(size_t *xstart, size_t *ystart, size_t *zsta
{
for (size_t i = 0; i < *ncopy; i++)
ptr_cmplx[out_v_index + i] = (FFTW_COMPLEX)working_space[index + copy_list[i]];
ptr_cmplx[out_v_index + i] = (PAN_COMPLEX)working_space[index + copy_list[i]];
}
else
{
@ -1233,7 +1235,7 @@ int PANPHASIA_compute_coefficients_(size_t *xstart, size_t *ystart, size_t *zsta
//======================================================================================
//======================================================================================
int parse_and_validate_descriptor_(char *descriptor)
int parse_and_validate_descriptor_(char *descriptor, int *pan_mode)
{
char *token;
@ -1302,12 +1304,12 @@ int parse_and_validate_descriptor_(char *descriptor)
if (kk_limit_set == 0)
{
sprintf(descriptor_as_read, "[Panph%d,L%llu,(%llu,%llu,%llu),S%llu,CH%lld,%s]",
sprintf(descriptor_as_read, "[Panph%llu,L%llu,(%llu,%llu,%llu),S%llu,CH%lld,%s]",
desc_order, desc_level, desc_x, desc_y, desc_z, desc_size, desc_ch, desc_name);
}
else
{
sprintf(descriptor_as_read, "[Panph%d,L%llu,(%llu,%llu,%llu),S%llu,KK%lld,CH%lld,%s]",
sprintf(descriptor_as_read, "[Panph%llu,L%llu,(%llu,%llu,%llu),S%llu,KK%lld,CH%lld,%s]",
desc_order, desc_level, desc_x, desc_y, desc_z, desc_size, desc_kk_limit, desc_ch, desc_name);
}
@ -1332,6 +1334,8 @@ int parse_and_validate_descriptor_(char *descriptor)
strcpy(full_descriptor, descriptor);
descriptor_read_in = 1;
*pan_mode = (desc_order==1)? 0:1; // 0 - Old descriptor: 1 HO descriptor
comp_ch = compute_check_digit_(); // check the check digit
if ((desc_ch != -999) && (desc_ch != comp_ch))
@ -1643,16 +1647,15 @@ void test_cell_moments(char root_descriptor[200], size_t rel_lev, size_t rel_ori
void integrate_cell(int ix, int iy, int iz, size_t xextent, size_t yextent, size_t zextent, FFTW_REAL *output_values, double *results)
{
/*/////////////////////////////////////////////////////////////////////////////
This function computes the integral over a cell of the product of the
Panphasia field with an 'analysing' Legendre polynomial. As the
integrand is a polynomial, Gaussian quadrature can be used for
integration as it is exact up to rounding error provide p_order
is less than 10.
/*/
///////////////////////////////////////////////////////////////////////////*/
/////////////////////////////////////////////////////////////////////////////
//
// This function computes the integral over a cell of the product of the
// Panphasia field with an 'analysing' Legendre polynomial. As the
// integrand is a polynomial, Gaussian quadrature can be used for
// integration as it is exact up to rounding error provide p_order
// is less than 10.
//
/////////////////////////////////////////////////////////////////////////////
const double GQ_weights[5] = {0.2955242247147529, 0.2692667193099963,
0.2190863625159820, 0.1494513491505806,
@ -1830,14 +1833,14 @@ void compute_sph_bessel_coeffs(int nfft, int pmax, int n4dimen, int fdim, double
const double pi = 4.0 * atan(1.0);
for (int l = 0; l <= pmax; l++)
{
double norm = sqrt((double)(2 * l + 1) * fdim);
double norm = sqrt((double)(2 * l + 1));
double complex phase_shift = cpow(-I, l);
for (int i = 0; i < nfft; i++)
{
int j = (i <= nfft / 2) ? i : i - nfft;
int k = abs(j);
double sign = (j < 0) ? pow(-1.0, l) : 1.0;
double x = pi * (double)k / (double)(nfft * fdim);
double x = pi*(double)fdim*(double)k/(double)nfft;
double result;
spherical_bessel_(&l, &x, &result);

View file

@ -24,6 +24,8 @@ int PANPHASIA_HO_main(void)
int error;
size_t x0 = 0, y0 = 0, z0 = 0;
size_t rel_level;
int fdim=1; //Option to scale Fourier grid dimension relative to Panphasia coefficient grid
char descriptor[300] = "[Panph6,L20,(424060,82570,148256),S1,KK0,CH-999,Auriga_100_vol2]";
PANPHASIA_init_descriptor_(descriptor, &verbose);
@ -40,9 +42,9 @@ int PANPHASIA_HO_main(void)
ptrdiff_t alloc_local, local_n0, local_0_start;
ptrdiff_t N0 = descriptor_base_size << rel_level;
ptrdiff_t N0 = fdim*(descriptor_base_size << rel_level);
alloc_local = FFTW_MPI_LOCAL_SIZE_3D(N0, N0, N0, MPI_COMM_WORLD, &local_n0, &local_0_start);
alloc_local = FFTW_MPI_LOCAL_SIZE_3D(N0, N0, N0 +2 , MPI_COMM_WORLD, &local_n0, &local_0_start);
FFTW_COMPLEX *Panphasia_White_Noise_Field;
@ -54,6 +56,8 @@ int PANPHASIA_HO_main(void)
};
fftw_free(Panphasia_White_Noise_Field);
return(0);
}
#ifdef STANDALONE_PANPHASIA_HO
@ -108,7 +112,7 @@ int main(int argc, char **argv)
ptrdiff_t N0 = descriptor_base_size << rel_level;
alloc_local = FFTW_MPI_LOCAL_SIZE_3D(N0, N0, N0, MPI_COMM_WORLD, &local_n0, &local_0_start);
alloc_local = FFTW_MPI_LOCAL_SIZE_3D(N0, N0, N0+2, MPI_COMM_WORLD, &local_n0, &local_0_start);
FFTW_COMPLEX *Panphasia_White_Noise_Field;
@ -125,6 +129,9 @@ int main(int argc, char **argv)
//==================== End FFTW ===========================
MPI_Finalize();
return(0);
}
#endif // STANDALONE_PANPHASIA_HO

View file

@ -19,75 +19,259 @@ extern const int irank_p[3][84];
extern size_t descriptor_order;
extern size_t descriptor_kk_limit;
extern size_t descriptor_base_size;
int PANPHASIA_compute_kspace_field_(size_t relative_level, ptrdiff_t N0_grid,
ptrdiff_t local_n0_return, ptrdiff_t local_0_start_return,
int PANPHASIA_compute_kspace_field_(size_t relative_level, ptrdiff_t N0_fourier_grid,
ptrdiff_t local_n0_fourier_return, ptrdiff_t local_0_start_fourier_return,
FFTW_COMPLEX *return_field)
{
size_t copy_list[Nbasis];
int fdim=1;
int pmax = 6;
int nsubdivide = (pmax%2==0)?pmax+1:pmax+2;
size_t ncopy = (pmax+1)*(pmax+2)*(pmax+3)/6;
size_t xorigin=local_0_start_return, yorigin=0, zorigin=0;
size_t xextent =local_n0_return, yextent = N0_grid, zextent = N0_grid;
if (ncopy%nsubdivide!=0) return(100010);
int nchunk = ncopy/nsubdivide;
int verbose = 1;
int flag_output_mode=2;
int error;
ptrdiff_t size_to_alloc;
ptrdiff_t size_to_alloc_fourier;
ptrdiff_t size_to_alloc_pan;
ptrdiff_t local_n0_fourier_xoffset;
FFTW_PLAN output_coeff_forward_plan;
ptrdiff_t N0_pan_grid = descriptor_base_size<<relative_level;
if (pmax>descriptor_order) return(100000);
if (N0_fourier_grid%N0_pan_grid!=0) return (100015);
int fdim = N0_fourier_grid/N0_pan_grid;
size_t nfft_dim = N0_fourier_grid;
size_t npan_dim = N0_pan_grid;
int SHARED_FOUR_PAN_SPACE = (nsubdivide==1)&&(fdim==1)&&(sizeof(PAN_REAL)==sizeof(FFTW_REAL));
////////////////////////////////////////////////////////////////////////////////////
if (pmax>descriptor_order) return(100020);
for (size_t i=0; i<Nbasis; i++) copy_list[i]=i;
printf("Dimensions of FT (%td,%td,%td)\n",N0_grid,N0_grid,N0_grid);
printf("local_no %td local_0_start %td\n",local_n0_return, local_0_start_return);
printf("Dimensions of FT (%td,%td,%td)\n",N0_fourier_grid,N0_fourier_grid,N0_fourier_grid);
printf("Dimensions of PG (%td,%td,%td)\n",N0_pan_grid,N0_pan_grid,N0_pan_grid);
printf("local_no %td local_0_start_fourier %td\n",local_n0_fourier_return, local_0_start_fourier_return);
// Compute 1-D Spherical Bessel coefficients for each order //////////////////
// These are needed for the convolutions below //////////////////
size_t n4dimen;
// Distribution for ncopy 3-D arrays //
{
n4dimen=(nfft_dim%4==0) ? 4*(nfft_dim/4)+4 : 4*(nfft_dim/4)+5;
double complex *sph_bessel_coeff = FFTW_MALLOC(sizeof(double complex)*n4dimen*(pmax+1));
if (sph_bessel_coeff==NULL) return(100030);
compute_sph_bessel_coeffs(nfft_dim, pmax, n4dimen, fdim, sph_bessel_coeff);
printf("Reached here! ndimen4 %ld\n",n4dimen);
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Determine sizes of Fourier and Panphasia coefficient 3-D arrays //
ptrdiff_t local_n0_pan;
ptrdiff_t local_0_start_pan;
{
int rank =3;
const ptrdiff_t ndimens_alloc[] = {N0_grid, N0_grid, N0_grid+2}; // Allocated for r2c
ptrdiff_t howmany = ncopy;
ptrdiff_t local_n0;
ptrdiff_t local_0_start;
size_to_alloc = FFTW_MPI_LOCAL_SIZE_MANY(rank, ndimens_alloc, howmany,
ptrdiff_t local_n0_fourier;
ptrdiff_t local_0_start_fourier;
const ptrdiff_t ndimens_alloc_fourier[] = {N0_fourier_grid, N0_fourier_grid, N0_fourier_grid+2}; // Allocated for r2c
ptrdiff_t howmany = nchunk;
size_to_alloc_fourier = FFTW_MPI_LOCAL_SIZE_MANY(rank, ndimens_alloc_fourier, howmany,
FFTW_MPI_DEFAULT_BLOCK,MPI_COMM_WORLD,
&local_n0,&local_0_start);
printf("size_to_alloc = %td\n",size_to_alloc);
printf("cf value %ld\n",ncopy*xextent*yextent*zextent);
printf("local_n0 %td local_0_start %td\n",local_n0,local_0_start);
&local_n0_fourier,&local_0_start_fourier);
if (local_0_start_fourier!=local_0_start_fourier_return){
printf("Error local_0_start_fourier!=local_0_start_fourier_return\n");
return(100032);
};
if (local_n0_fourier!=local_n0_fourier_return){
printf("Error local_n0_fourier!=local_n0_fourier_return\n");
return(100033);
};
local_0_start_pan = local_0_start_fourier/fdim;
local_n0_pan = (local_0_start_fourier + local_n0_fourier)/fdim - local_0_start_pan;
const ptrdiff_t ndimens_alloc_pan[] = {N0_pan_grid, N0_pan_grid, N0_pan_grid+2}; // Allocated for r2c
howmany = ncopy;
ptrdiff_t local_n0_pan_check;
ptrdiff_t local_0_start_pan_check;
size_to_alloc_pan = howmany * local_n0_pan * N0_pan_grid * ( N0_pan_grid+2);
ptrdiff_t size_to_alloc_pan_check = FFTW_MPI_LOCAL_SIZE_MANY(rank, ndimens_alloc_pan, howmany,
FFTW_MPI_DEFAULT_BLOCK,MPI_COMM_WORLD,
&local_n0_pan_check,&local_0_start_pan_check);
if (size_to_alloc_pan!=size_to_alloc_pan_check){
printf("size_to_alloc_pan!=size_to_alloc_pan_check\n");
return(100034);
};
void *output_coefficients= FFTW_MALLOC(sizeof(FFTW_REAL)*size_to_alloc);
local_n0_fourier_xoffset = local_0_start_fourier_return%fdim;
if (output_coefficients==NULL) return(100001);
printf("size_to_alloc_fourier = %td\n",size_to_alloc_fourier);
printf("size_to_alloc_pan = %td\n",size_to_alloc_pan);
printf("local_n0_fourier %td local_0_start_fourier %td\n",local_n0_fourier,local_0_start_fourier);
printf("local_n0_pan %td local_0_start_pan %td\n",local_n0_pan,local_0_start_pan);
printf("local_n0_fourier_xoffset %td\n",local_n0_fourier_xoffset);
FFTW_REAL *ptr_real_output_coefficients = output_coefficients;
FFTW_COMPLEX *ptr_cmplx_output_coefficients = output_coefficients;
};
/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
// Allocate arrays to store Panphasia coefficients and Fourier information
// If nsubdivide==1 then use the same structure to store both.
void *panphasia_coefficients= FFTW_MALLOC(sizeof(PAN_REAL)*size_to_alloc_pan);
void *fourier_grids;
if (panphasia_coefficients==NULL) return(100040);
void *mode_weightings = FFTW_MALLOC(sizeof(FFTW_REAL)*size_to_alloc_fourier/nchunk);
FFTW_REAL *ptr_mode_weightings;
ptr_mode_weightings = mode_weightings;
memset(ptr_mode_weightings, 0, sizeof(FFTW_REAL)*size_to_alloc_fourier/nchunk);
FFTW_REAL *ptr_real_fourier_grid;
FFTW_REAL *ptr_panphasia_coefficients = panphasia_coefficients;
FFTW_COMPLEX *ptr_cmplx_fourier_grid;
if (SHARED_FOUR_PAN_SPACE){
ptr_real_fourier_grid = panphasia_coefficients;
ptr_cmplx_fourier_grid = panphasia_coefficients;
}else{
fourier_grids= FFTW_MALLOC(sizeof(FFTW_REAL)*size_to_alloc_fourier);
if (fourier_grids==NULL) return(100041);
ptr_real_fourier_grid = fourier_grids;
ptr_cmplx_fourier_grid = fourier_grids;
};
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//////////// Compute the Panphasia coefficients ////////////////////////////////
{
size_t xorigin= local_0_start_pan, yorigin=0, zorigin=0;
size_t xextent =local_n0_pan, yextent = N0_pan_grid, zextent = N0_pan_grid;
if (error = PANPHASIA_compute_coefficients_(&xorigin,&yorigin,&zorigin,&xextent,&yextent,
&zextent, copy_list, &ncopy, panphasia_coefficients,
&flag_output_mode,&verbose)) return(100100+error);
};
///////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
////////// Output diagnostics for small grids only
{
if (N0_pan_grid<128){
int rank;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
char filename[100];
sprintf(filename,"output_real_space_field.%d",rank);
FILE *fp;
printf("local_n0_pan %ld npan_dim %ld N0_pan_grid %ld\n",local_n0_pan,
npan_dim,N0_pan_grid);
fp = fopen(filename,"w");
for (int ix=0; ix<local_n0_pan; ix++)
for (int iy=0; iy < npan_dim; iy++)
for (int iz=0; iz < npan_dim; iz++){
int index = ix*N0_pan_grid*(N0_pan_grid+2) + iy*(N0_pan_grid+2) + iz;
fprintf(fp,"%6ld%6d%6d %14.8lf %d\n",ix+local_0_start_pan,iy,iz,
ptr_panphasia_coefficients[index],index);
};
fclose(fp);
};
};
//----------------------------------------------------------------------------------
////////////// Set up FTTW plan //////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
printf("Making the plan ... \n");
//////////////////// Make plan for ncopy interleaved FTs ///////////////////////////
//////////////////////////////////////////////////////////////////////////
{
int rank = 3;
const ptrdiff_t ndimens[3] = {N0_grid, N0_grid, N0_grid};
ptrdiff_t howmany = ncopy;
const ptrdiff_t ndimens[3] = {N0_fourier_grid, N0_fourier_grid, N0_fourier_grid};
ptrdiff_t howmany = nchunk;
ptrdiff_t block = FFTW_MPI_DEFAULT_BLOCK;
ptrdiff_t tblock = FFTW_MPI_DEFAULT_BLOCK;
unsigned flags = FFTW_ESTIMATE;
output_coeff_forward_plan = FFTW_MPI_PLAN_MANY_DTF_R2C(rank, ndimens,
howmany, block, tblock,
ptr_real_output_coefficients, ptr_cmplx_output_coefficients,
ptr_real_fourier_grid, ptr_cmplx_fourier_grid,
MPI_COMM_WORLD, flags);
if (output_coeff_forward_plan==NULL) {
printf("Null plan\n");
@ -95,107 +279,93 @@ printf("local_n0 %td local_0_start %td\n",local_n0,local_0_start);
};
};
//////////////////////////////////////////////////////////////////////////
printf("Plan completed ... \n");
printf("xorigin,yorigin,zorigin (%ld,%ld,%ld)\n ",xorigin,yorigin,zorigin);
printf("xextent,yextent,zextent (%ld,%ld,%ld)\n ",xextent,yextent,zextent);
if (error = PANPHASIA_compute_coefficients_(&xorigin,&yorigin,&zorigin,&xextent,&yextent,
&zextent, copy_list, &ncopy,
ptr_real_output_coefficients,&flag_output_mode,&verbose)){
return(100100+error);
};
for (int j=0; j<4; j++){
for (int i=0; i<4; i++) printf("(%lf ) ",ptr_real_output_coefficients[j+ i*ncopy]);
printf("\n");
};
{
size_t nfft_dim;
nfft_dim = N0_grid;
int rank;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
char filename[100];
sprintf(filename,"output_real_space_field.%d",rank);
FILE *fp;
fp = fopen(filename,"w");
for (int ix=0; ix<local_n0_return; ix++)
for (int iy=0; iy < nfft_dim; iy++)
for (int iz=0; iz < nfft_dim; iz++){
int index = ix*N0_grid*(N0_grid+2) + iy*(N0_grid+2) + iz;
fprintf(fp,"%6d%6d%6d %14.8lf %d\n",ix+local_0_start_return,iy,iz,
ptr_real_output_coefficients[index],index);
};
fclose(fp);
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------
memset(return_field, 0, local_n0_fourier_return*N0_fourier_grid *(N0_fourier_grid +2) * sizeof(FFTW_COMPLEX));
FFTW_MPI_EXECUTE_DFT_R2C(output_coeff_forward_plan,ptr_real_output_coefficients,ptr_cmplx_output_coefficients);
for (int iter = 0; iter < nsubdivide; iter++){
int moffset = iter*nchunk;
for (int j=0; j<4; j++){
for (int i=0; i<4; i++) printf("(%lf %lf) ",creal(ptr_cmplx_output_coefficients[j+ i*ncopy]),
cimag(ptr_cmplx_output_coefficients[j + i*ncopy])); printf("\n");
if (!SHARED_FOUR_PAN_SPACE){
memset(ptr_real_fourier_grid, 0, sizeof(FFTW_REAL)*size_to_alloc_fourier);
// Copy Panphasia coefficients to Fourier grid with appropriate stride - fdim
size_t index_p,index_f;
int m;
for(int ix_p=0, ix_f = local_n0_fourier_xoffset; ix_p<local_n0_pan; ix_p++,ix_f+=fdim)
#ifdef USE_OPENMP
#pragma omp parallel for collapse(2) private (index_p,index_f,m)
#endif
for(int iy_p=0, iy_f=0 ; iy_p<npan_dim;iy_p++,iy_f+=fdim)
for(int iz_p=0, iz_f=0; iz_p<npan_dim;iz_p++,iz_f+=fdim){
index_p = ix_p*N0_pan_grid*(N0_pan_grid + 2) + iy_p*(N0_pan_grid + 2) + iz_p;
index_f = ix_f*N0_fourier_grid*(N0_fourier_grid + 2) + iy_f*(N0_fourier_grid + 2) + iz_f;
for (m=0; m<nchunk; m++){
ptr_real_fourier_grid[nchunk*index_f + m] =
ptr_panphasia_coefficients[ncopy*index_p + moffset + m];
};
};
};
// Compute 1-D Spherical Bessel coefficients for each order.
size_t nfft_dim;
nfft_dim = N0_grid;
if (nfft_dim<N0_grid) nfft_dim=N0_grid; if (nfft_dim<N0_grid) nfft_dim=N0_grid;
size_t n4dimen;
n4dimen=(nfft_dim%4==0) ? 4*(nfft_dim/4)+4 : 4*(nfft_dim/4)+5;
double complex *sph_bessel_coeff = FFTW_MALLOC(sizeof(double complex)*n4dimen*(pmax+1));
compute_sph_bessel_coeffs(nfft_dim, pmax, n4dimen, fdim, sph_bessel_coeff);
FFTW_MPI_EXECUTE_DFT_R2C(output_coeff_forward_plan,
ptr_real_fourier_grid,ptr_cmplx_fourier_grid);
printf("Reached here! ndimen4 %ld\n",n4dimen);
{
// Convolve and combine the FT of the Panphasia coefficient field
{
size_t index1,index2;
complex weight;
size_t p_total = (pmax+1)*(pmax+2)*(pmax+3)/6;
int m;
memset(return_field,0, local_n0_return*N0_grid*N0_grid * sizeof(FFTW_COMPLEX));
#ifdef USE_OPENMP
#pragma omp parallel for collapse(3) \
private (index1,index2,weight,m)
#endif
for(int ix=0;ix<local_n0_return;ix++)
for(int ix=0;ix<local_n0_fourier_return;ix++)
for(int iy=0;iy<nfft_dim;iy++)
for(int iz=0;iz<=nfft_dim/2;iz++){
index1 = ix*N0_grid*(N0_grid/2+1) + iy*(N0_grid/2+1) + iz;
for (int m=0; m<p_total; m++){
index2 = p_total*index1 + m;
weight = sph_bessel_coeff[n4dimen*irank_p[0][m]+ix+local_0_start_return]*
sph_bessel_coeff[n4dimen*irank_p[1][m]+iy]*
sph_bessel_coeff[n4dimen*irank_p[2][m]+iz];
return_field[index1] += weight * ptr_cmplx_output_coefficients[index2];
index1 = ix*N0_fourier_grid*(N0_fourier_grid/2+1) + iy*(N0_fourier_grid/2+1) + iz;
for (int m=0; m<nchunk; m++){
index2 = nchunk*index1 + m;
weight = sph_bessel_coeff[n4dimen*irank_p[0][m+moffset]+ix+local_0_start_fourier_return]*
sph_bessel_coeff[n4dimen*irank_p[1][m+moffset]+iy]*
sph_bessel_coeff[n4dimen*irank_p[2][m+moffset]+iz];
return_field[index1] += weight * ptr_cmplx_fourier_grid[index2];
ptr_mode_weightings[index1]+=cabs(weight)*cabs(weight);
};
};
};
}; // End loop over iter
printf("Reached here 10!\n");
@ -207,16 +377,18 @@ int m;
const double pi = 4.0 * atan(1.0);
size_t index1;
double min_weight = 100.0;
#ifdef USE_OPENMP
#pragma omp parallel for collapse(3) \
private (index1,kx,ky,kz,phase_shift_and_scale)
#endif
for(int ix=0;ix<local_n0_return;ix++)
for(int ix=0;ix<local_n0_fourier_return;ix++)
for(int iy=0;iy<nfft_dim;iy++)
for(int iz=0;iz<=nfft_dim/2;iz++){
index1 = ix*N0_grid*(N0_grid/2+1) + iy*(N0_grid/2+1) + iz;
kx = (ix+local_0_start_return>nfft_dim/2) ?
ix + local_0_start_return - nfft_dim : ix + local_0_start_return;
index1 = ix*N0_fourier_grid*(N0_fourier_grid/2+1) + iy*(N0_fourier_grid/2+1) + iz;
kx = (ix+local_0_start_fourier_return>nfft_dim/2) ?
ix + local_0_start_fourier_return - nfft_dim : ix + local_0_start_fourier_return;
ky = (iy > nfft_dim/2) ? iy-nfft_dim : iy;
kz = (iz > nfft_dim/2) ? iz-nfft_dim : iz;
@ -224,14 +396,19 @@ int m;
// Set Nyquist modes to zero - not used by IC_Gen anyway.
phase_shift_and_scale = 0.0; //1.0/pow((double)nfft_dim,1.5); // No phase shift
}else{
phase_shift_and_scale =
cexp( (-I)*pi*(double)(kx + ky + kz)/(double)nfft_dim)/pow((double)nfft_dim,1.5);
phase_shift_and_scale = sqrt( (double)(fdim*fdim*fdim))*
cexp( (double)fdim * (-I)*pi*(double)(kx + ky + kz)/
(double)nfft_dim)/pow((double)nfft_dim,1.5);
};
return_field[index1] *= phase_shift_and_scale;
if (ptr_mode_weightings[index1]<min_weight)
min_weight=ptr_mode_weightings[index1];
};
printf("Minimum weight %lf\n",sqrt(min_weight));
};
@ -251,16 +428,16 @@ int m;
#pragma omp parallel for collapse(3) \
private (index1,kx,ky,kz,ksquared,weight)
#endif
for(int ix=0;ix<local_n0_return;ix++)
for(int ix=0;ix<local_n0_fourier_return;ix++)
for(int iy=0;iy<nfft_dim;iy++)
for(int iz=0;iz<=nfft_dim/2;iz++){
kx = (ix+local_0_start_return>nfft_dim/2) ?
ix + local_0_start_return - nfft_dim : ix + local_0_start_return;
kx = (ix+local_0_start_fourier_return>nfft_dim/2) ?
ix + local_0_start_fourier_return - nfft_dim : ix + local_0_start_fourier_return;
ky = (iy > nfft_dim/2) ? iy-nfft_dim : iy;
kz = (iz > nfft_dim/2) ? iz-nfft_dim : iz;
ksquared = kx*kx + ky*ky + kz*kz;
if (ksquared<=descriptor_kk_limit){
index1 = ix*N0_grid*(N0_grid/2+1) + iy*(N0_grid/2+1) + iz;
index1 = ix*N0_fourier_grid*(N0_fourier_grid/2+1) + iy*(N0_fourier_grid/2+1) + iz;
weight = cabs(return_field[index1]);
return_field[index1] /= weight;
};
@ -271,65 +448,77 @@ int m;
printf("Reached here 12!\n");
if (nfft_dim <128){
int rank;
int rank;
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
char filename[100];
sprintf(filename,"output_k_space_field.%d",rank);
int xuse,yuse,zuse;
FFTW_REAL sign;
sprintf(filename,"output_k_space_alt.%d",rank);
FILE *fp;
if (nfft_dim <128){
FILE *fp;
fp = fopen(filename,"w");
for (int ix=0; ix<local_n0_return; ix++)
for (int ix=0; ix<local_n0_fourier_return; ix++)
for (int iy=0; iy < nfft_dim; iy++)
for (int iz=0; iz < nfft_dim; iz++){
for (int iz=0; iz <= nfft_dim/2; iz++){
if (iz>nfft_dim/2){
xuse = (nfft_dim-ix)%nfft_dim;
yuse = (nfft_dim-iy)%nfft_dim;
zuse = (nfft_dim-iz)%nfft_dim;
sign = -1.0;
}else{
xuse = ix;
yuse = iy;
zuse = iz;
sign = 1.0;
};
int index = xuse*N0_grid*(N0_grid/2+1) + yuse*(N0_grid/2+1) + zuse;
fprintf(fp,"%6d%6d%6d %14.8lf %14.8lf\n",ix+local_0_start_return,iy,iz,
creal(return_field[index]),cimag(sign*return_field[index]));
int index = ix*N0_fourier_grid*(N0_fourier_grid/2+1) + iy*(N0_fourier_grid/2+1) + iz;
fprintf(fp,"%6ld%6d%6d %14.8lf %14.8lf %14.8lf \n",ix+local_0_start_fourier_return,iy,iz,
creal(return_field[index]),cimag(return_field[index]),sqrt(ptr_mode_weightings[index]));
// ptr_mode_weightings[index]);
};
fclose(fp);
};
}else{
fp = fopen(filename,"w");
for (int ix=0; ix<local_n0_fourier_return; ix++)
for (int iy=0; iy < nfft_dim; iy++)
for (int iz=0; iz <= nfft_dim/2; iz++){
if (ix+iy+iz+local_0_start_fourier_return<100){
int index = ix*N0_fourier_grid*(N0_fourier_grid/2+1) + iy*(N0_fourier_grid/2+1) + iz;
fprintf(fp,"%6ld%6d%6d %14.8lf %14.8lf %14.8lf \n",ix+local_0_start_fourier_return,iy,iz,
creal(return_field[index]),cimag(return_field[index]),sqrt(ptr_mode_weightings[index]));
// ptr_mode_weightings[index]);
};
};
fclose(fp);
printf("Reached here 14!\n");
for (int j=0; j<4; j++){
for (int i=0; i<4; i++) printf("(%lf %lf) ",creal(return_field[j+ i*ncopy]),
cimag(return_field[j + i*ncopy])); printf("\n");
};
FFTW_FREE(output_coefficients);
// Free all memory assigned by FFTW_MALLOC
FFTW_FREE(mode_weightings);
FFTW_FREE(sph_bessel_coeff);
FFTW_FREE(panphasia_coefficients);
if (!SHARED_FOUR_PAN_SPACE) FFTW_FREE(fourier_grids);
FFTW_DESTROY_PLAN(output_coeff_forward_plan);
FFTW_DESTROY_PLAN(output_coeff_forward_plan);
printf("Reached here! 3 \n");
return(0);
printf("Reached end of PANPHASIA_compute_kspace_field_\n");
return(0);
};

View file

@ -3,7 +3,7 @@
// By default Panphasia is computed at single
// precision. To override this define PAN_DOUBLE
#define PAN_DOUBLE_PRECISION 8
//#define PAN_DOUBLE_PRECISION 8
#ifndef PAN_DOUBLE_PRECISION
@ -49,7 +49,7 @@ void compute_all_properties_of_a_panphasia_cell_(size_t *level, size_t *j1, size
void return_root_legendre_coefficients_(PAN_REAL *root);
int parse_and_validate_descriptor_(char *);
int parse_and_validate_descriptor_(char *, int *);
int demo_descriptor_();
long long int compute_check_digit_();
int PANPHASIA_init_descriptor_(char *descriptor, int *verbose);