Compute the self-consistent electric field over the local domain: The field is solved from the solution values using a Poisson solve in Fourier space.
102 fprintf(stderr,
"Error in SetEFieldSelfConsistent():\n");
103 fprintf(stderr,
" Implemented for 1 spatial dimension only.\n");
109 fprintf(stderr,
"Error in SetEFieldSelfConsistent():\n");
110 fprintf(stderr,
" Using a self-consistent electric field requires FFTW.\n");
117 int ghosts = solver->
ghosts;
118 int ndims = solver->
ndims;
120 double *sum_buffer = param->sum_buffer;
121 double *field = param->
e_field;
122 fftw_complex *phys_buffer_e = param->phys_buffer_e;
123 fftw_complex *fourier_buffer_e = param->fourier_buffer_e;
124 fftw_plan plan_forward_e = param->plan_forward_e;
125 fftw_plan plan_backward_e = param->plan_backward_e;
126 ptrdiff_t local_ni = param->local_ni;
127 ptrdiff_t local_i_start = param->local_i_start;
128 ptrdiff_t local_no = param->local_no;
129 ptrdiff_t local_o_start = param->local_o_start;
131 fftw_complex *phys_buffer_phi = param->phys_buffer_phi;
132 fftw_complex *fourier_buffer_phi = param->fourier_buffer_phi;
133 fftw_plan plan_forward_phi = param->plan_forward_phi;
134 fftw_plan plan_backward_phi = param->plan_backward_phi;
136 int index[ndims], bounds[ndims], bounds_noghost[ndims], offset[ndims];
140 for (
int i = 0; i < ndims; i++) bounds[i] += 2*ghosts;
162 sum_buffer[index[0]] += u[p] / dvinv;
168 for (
int i = 0; i < dim[0]; i++) {
169 MPISum_double(&sum_buffer[i], &sum_buffer[i], 1, &mpi->comm[1]);
173 double average_velocity = 0.0;
174 for (
int i = 0; i < dim[0]; i++) {
175 average_velocity += sum_buffer[i];
177 MPISum_double(&average_velocity, &average_velocity, 1, &mpi->comm[0]);
178 average_velocity /= (double) N;
181 for (
int i = 0; i < dim[0]; i++) {
182 phys_buffer_e[i][0] = sum_buffer[i] - average_velocity;
183 phys_buffer_e[i][1] = 0.0;
187 MPI_Barrier(mpi->comm[0]);
188 fftw_execute(plan_forward_e);
189 MPI_Barrier(mpi->comm[0]);
193 if (local_o_start == 0) {
195 fourier_buffer_e[0][0] = 0.0;
196 fourier_buffer_e[0][1] = 0.0;
200 int freq_start_phi = 0;
201 if (local_o_start == 0) {
203 fourier_buffer_phi[0][0] = 0.0;
204 fourier_buffer_phi[0][1] = 0.0;
207 for (
int i = freq_start_phi; i < local_no; i++) {
208 double freq_num =
FFTFreqNum(i + local_o_start, N);
209 double thek = freq_num;
211 fourier_buffer_phi[i][0] = fourier_buffer_e[i][0] / (thek*thek);
212 fourier_buffer_phi[i][1] = fourier_buffer_e[i][1]/ (thek*thek);
216 for (
int i = freq_start; i < local_no; i++) {
217 double freq_num =
FFTFreqNum(i + local_o_start, N);
218 double thek = freq_num;
219 double temp = fourier_buffer_e[i][0];
221 fourier_buffer_e[i][0] = - fourier_buffer_e[i][1] / thek;
222 fourier_buffer_e[i][1] = temp / thek;
226 MPI_Barrier(mpi->comm[0]);
227 fftw_execute(plan_backward_e);
228 MPI_Barrier(mpi->comm[0]);
231 MPI_Barrier(mpi->comm[0]);
232 fftw_execute(plan_backward_phi);
233 MPI_Barrier(mpi->comm[0]);
236 for (
int i = 0; i < dim[0]; i++) {
237 param->
e_field[i + ghosts] = - phys_buffer_e[i][0] / (double) N;
241 for (
int i = 0; i < dim[0]; i++) {
242 param->
potential[i + ghosts] = phys_buffer_phi[i][0] / (double) N;
static int FFTFreqNum(int bin, int N)
int MPISum_double(double *, double *, int, void *)
int MPIExchangeBoundaries1D(void *, double *, int, int, int, int)
Structure containing all solver-specific variables and functions.
#define _ArrayIndex1D_(N, imax, i, ghost, index)
#define _ArraySetValue_(x, size, value)
#define _ArrayIncrementIndex_(N, imax, i, done)
#define _GetCoordinate_(dir, i, dim, ghosts, x, coord)
Structure of MPI-related variables.
#define _ArrayCopy1D_(x, y, size)