15 #include "gadgetconfig.h"
17 #include <gsl/gsl_integration.h>
19 #if defined(PMGRID) || defined(NGENIC)
21 #include <gsl/gsl_integration.h>
22 #include <gsl/gsl_rng.h>
25 #include "../data/allvars.h"
26 #include "../data/dtypes.h"
27 #include "../data/intposconvert.h"
28 #include "../data/mymalloc.h"
29 #include "../data/simparticles.h"
30 #include "../domain/domain.h"
31 #include "../logs/timer.h"
32 #include "../mpi_utils/mpi_utils.h"
33 #include "../pm/pm_mpi_fft.h"
34 #include "../system/system.h"
35 #include "../time_integration/timestep.h"
42 #if defined(PMGRID) && defined(PERIODIC)
46 #if PMGRID != ((PMGRID / LONG_X) * LONG_X)
47 #error "PMGRID must be a multiple of the stretch factor in the x-direction"
52 #if PMGRID != ((PMGRID / LONG_Y) * LONG_Y)
53 #error "PMGRID must be a multiple of the stretch factor in the y-direction"
58 #if PMGRID != ((PMGRID / LONG_Z) * LONG_Z)
59 #error "PMGRID must be a multiple of the stretch factor in the x-direction"
63 #define GRIDX ((PMGRID / LONG_X) * DBX + DBX_EXTRA)
64 #define GRIDY ((PMGRID / LONG_Y) * DBY + DBY_EXTRA)
65 #define GRIDZ ((PMGRID / LONG_Z) * DBZ + DBZ_EXTRA)
67 #define INTCELL ((~((MyIntPosType)0)) / PMGRID + 1)
69 #if(GRIDX > 1024) || (GRIDY > 1024) || (GRIDZ > 1024)
70 typedef long long large_array_offset;
73 typedef int large_array_offset;
76 #ifdef NUMPART_PER_TASK_LARGE
77 typedef long long large_numpart_type;
80 typedef int large_numpart_type;
87 #ifndef POWERSPEC_FOLDFAC
88 #define POWERSPEC_FOLDFAC 16
95 void pmforce_measure_powerspec(
int flag,
int *typeflag);
96 void pmforce_do_powerspec(
int *typeflag);
97 #if defined(GRAVITY_TALLBOX)
98 void pmforce_setup_tallbox_kernel(
void);
99 double pmperiodic_tallbox_long_range_potential(
double x,
double y,
double z);
107 long long maxfftsize;
119 fft_real *rhogrid, *forcegrid, *workspace;
126 fft_complex *fft_of_rhogrid;
128 #if defined(GRAVITY_TALLBOX)
131 fft_complex *fft_of_kernel;
134 #ifdef PM_ZOOM_OPTIMIZED
144 struct part_slab_data
146 large_array_offset globalindex;
147 large_numpart_type partindex;
149 large_array_offset localindex;
152 part_slab_data *part;
156 struct pm_periodic_sortindex_comparator
159 const part_slab_data *data;
162 pm_periodic_sortindex_comparator(
const part_slab_data *data_) : data(data_) {}
164 bool operator()(
const large_numpart_type &a,
const large_numpart_type &b)
const
166 return data[a].globalindex < data[b].globalindex;
171 size_t *localfield_sendcount, *localfield_first, *localfield_offset, *localfield_recvcount;
172 large_array_offset *localfield_globalindex, *import_globalindex;
173 fft_real *localfield_data, *import_data;
175 void pmforce_zoom_optimized_prepare_density(
int mode,
int *typelist);
176 void pmforce_zoom_optimized_readout_forces_or_potential(fft_real *grid,
int dim);
187 partbuf *partin, *partout;
189 size_t nimport, nexport;
191 size_t *Sndpm_count, *Sndpm_offset;
192 size_t *Rcvpm_count, *Rcvpm_offset;
194 void pmforce_uniform_optimized_prepare_density(
int mode,
int *typelist);
196 void pmforce_uniform_optimized_readout_forces_or_potential_xy(fft_real *grid,
int dim);
198 void pmforce_uniform_optimized_readout_forces_or_potential_xz(fft_real *grid,
int dim);
199 void pmforce_uniform_optimized_readout_forces_or_potential_zy(fft_real *grid,
int dim);
206 void pmforce_periodic(
int mode,
int *typelist);
208 void calculate_power_spectra(
int num);
210 static double growthfactor_integrand(
double a,
void *param)
215 double linear_growth_factor(
double astart,
double aend) {
return linear_growth(aend) / linear_growth(astart); }
217 double linear_growth(
double a)
221 const int worksize = 100000;
223 double result, abserr;
226 gsl_integration_workspace *workspace = gsl_integration_workspace_alloc(worksize);
227 F.function = &growthfactor_integrand;
229 gsl_integration_qag(&F, 0, a, 0, 1.0e-8, worksize, GSL_INTEG_GAUSS41, workspace, &result, &abserr);
231 gsl_integration_workspace_free(workspace);
233 return hubble_a * result;
global_data_all_processes All
#define MAXLEN_PATH_EXTRA
expr pow(half base, half exp)