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)