HyPar  1.0
Finite-Difference Hyperbolic-Parabolic PDE Solver on Cartesian Grids
VlasovInitialize.c
Go to the documentation of this file.
1 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <basic.h>
10 #include <arrayfunctions.h>
11 #include <bandedmatrix.h>
12 #include <physicalmodels/vlasov.h>
13 #include <mpivars.h>
14 #include <hypar.h>
15 
16 #ifdef fftw
17 #ifdef serial
18 #include <fftw3.h>
19 #else
20 #include <fftw3-mpi.h>
21 #endif
22 #endif
23 
25 double VlasovComputeCFL (void*,void*,double,double);
27 int VlasovAdvection (double*,double*,int,void*,double);
29 int VlasovUpwind (double*,double*,double*,double*,
30  double*,double*,int,void*,double);
32 int VlasovWriteEFieldAndPotential(void*, void*,double);
33 
34 int VlasovPreStep(double*,void*,void*,double);
35 int VlasovPostStage(double*,void*,void*,double);
36 
37 int VlasovEField(double*, void*, double);
38 
43 int VlasovInitialize(void *s,
44  void *m
45  )
46 {
47  HyPar *solver = (HyPar*) s;
48  MPIVariables *mpi = (MPIVariables*) m;
49  Vlasov *physics = (Vlasov*) solver->physics;
50 
51  int *dim_global = solver->dim_global;
52  int *dim_local = solver->dim_local;
53  int ghosts = solver->ghosts;
54 
55  if (solver->nvars != _MODEL_NVARS_) {
56  if (!mpi->rank) {
57  fprintf(stderr,"Error in VlasovInitialize(): nvars has to be %d.\n",_MODEL_NVARS_);
58  }
59  return(1);
60  }
61  if (solver->ndims != _MODEL_NDIMS_) {
62  if (!mpi->rank) {
63  fprintf(stderr,"Error in VlasovInitialize(): ndims has to be %d.\n",_MODEL_NDIMS_);
64  }
65  return(1);
66  }
67 
68  /* default is prescribed electric field */
69  physics->self_consistent_electric_field = 0;
70  physics->ndims_x = 1;
71  physics->ndims_v = 1;
72 
73  /* reading physical model specific inputs - all processes */
74  if (!mpi->rank) {
75  FILE *in;
76  in = fopen("physics.inp","r");
77  if (in) {
78  printf("Reading physical model inputs from file \"physics.inp\".\n");
79  char word[_MAX_STRING_SIZE_];
80  int ferr = fscanf(in,"%s",word); if (ferr != 1) return(1);
81  if (!strcmp(word, "begin")){
82  while (strcmp(word, "end")){
83  int ferr = fscanf(in,"%s",word); if (ferr != 1) return(1);
84  if (!strcmp(word, "self_consistent_electric_field")) {
85  /* read whether electric field is self-consistent or prescribed */
86  int ferr = fscanf(in,"%d", &physics->self_consistent_electric_field);
87  if (ferr != 1) return(1);
88  } else if (!strcmp(word, "x_ndims")) {
89  /* read number of spatial dimensions */
90  int ferr = fscanf(in,"%d", &physics->ndims_x);
91  if (ferr != 1) return(1);
92  } else if (!strcmp(word, "v_ndims")) {
93  /* read number of velocity dimensions */
94  int ferr = fscanf(in,"%d", &physics->ndims_v);
95  if (ferr != 1) return(1);
96  } else if (strcmp(word,"end")) {
97  char useless[_MAX_STRING_SIZE_];
98  int ferr = fscanf(in,"%s",useless); if (ferr != 1) return(ferr);
99  printf("Warning: keyword %s in file \"physics.inp\" with value %s not ",
100  word, useless);
101  printf("recognized or extraneous. Ignoring.\n");
102  }
103  }
104  } else {
105  fprintf(stderr,"Error: Illegal format in file \"physics.inp\".\n");
106  return(1);
107  }
108  }
109  fclose(in);
110  }
111 
112  if ((physics->ndims_x+physics->ndims_v) != solver->ndims) {
113  if (!mpi->rank) {
114  fprintf(stderr,"Error in VlasovInitialize:\n");
115  fprintf(stderr, " space + vel dims not equal to ndims!\n");
116  }
117  return(1);
118  }
119 
120  if (!strcmp(solver->SplitHyperbolicFlux,"yes")) {
121  if (!mpi->rank) {
122  fprintf(stderr,"Error in VlasovInitialize: This physical model does not have a splitting ");
123  fprintf(stderr,"of the hyperbolic term defined.\n");
124  }
125  return(1);
126  }
127 
128 #ifndef serial
129  /* Broadcast parsed problem data */
130  MPIBroadcast_integer(&physics->ndims_x,1,0,&mpi->world);
131  MPIBroadcast_integer(&physics->ndims_v,1,0,&mpi->world);
133  1,0,&mpi->world);
134 #endif
135 
136  /* compute local number of x-space points with ghosts */
137  physics->npts_local_x_wghosts = 1;
138  physics->npts_local_x = 1;
139  physics->npts_global_x_wghosts = 1;
140  physics->npts_global_x = 1;
141  for (int d=0; d<physics->ndims_x; d++) {
142  physics->npts_local_x_wghosts *= (dim_local[d]+2*ghosts);
143  physics->npts_local_x *= dim_local[d];
144  physics->npts_global_x_wghosts *= (dim_global[d]+2*ghosts);
145  physics->npts_global_x *= dim_global[d];
146  }
147 
148  /* allocate array to hold the electric field (needs to have ghosts);
149  note that number of electric field components is the number of
150  spatial dimensions */
151  physics->e_field = (double*) calloc( physics->npts_local_x_wghosts
152  * physics->ndims_x,
153  sizeof(double) );
154  physics->potential = (double*) calloc( physics->npts_local_x_wghosts
155  * physics->ndims_x,
156  sizeof(double) );
157 
158  /* Put the mpi object in the params for access in other functions */
159  physics->m = m;
160 
161  if (physics->self_consistent_electric_field) {
162 #ifdef fftw
163  /* If using FFTW, make sure MPI is enabled
164  Currently we only support the distrubuted memory version
165  */
166 #ifdef serial
167  fprintf(stderr,"Error in VlasovInitialize(): Using FFTW requires MPI to be enabled.\n");
168  return(1);
169 #else
170 
171  if (physics->ndims_x > 1) {
172  fprintf(stderr,"Error in VlasovInitialize():\n");
173  fprintf(stderr," Self-consistent electric field is implemented for only 1 space dimension.\n");
174  return 1;
175  }
176 
177  /* Create a scratch buffer for moving between real and complex values */
178  physics->sum_buffer = (double*) calloc(dim_local[0], sizeof(double));
179 
180  /* Initialize FFTW and set up data buffers used for the transforms */
181  fftw_mpi_init();
182  physics->alloc_local = fftw_mpi_local_size_1d(dim_global[0], mpi->comm[0],
183  FFTW_FORWARD, 0,
184  &physics->local_ni,
185  &physics->local_i_start,
186  &physics->local_no,
187  &physics->local_o_start);
188  if (dim_local[0] != physics->local_ni) {
189  fprintf(stderr,"Error in VlasovInitialize(): The FFTW data distribution is incompatible with the HyPar one.\n");
190  fprintf(stderr,"Decompose the spatial dimension so that the degrees of freedom are evenly divided.\n");
191  return(1);
192  }
193 
194  physics->phys_buffer_e = fftw_alloc_complex(physics->alloc_local);
195  physics->fourier_buffer_e = fftw_alloc_complex(physics->alloc_local);
196 
197  physics->plan_forward_e = fftw_mpi_plan_dft_1d(dim_global[0],
198  physics->phys_buffer_e,
199  physics->fourier_buffer_e,
200  mpi->comm[0],
201  FFTW_FORWARD,
202  FFTW_ESTIMATE);
203 
204  physics->plan_backward_e = fftw_mpi_plan_dft_1d(dim_global[0],
205  physics->fourier_buffer_e,
206  physics->phys_buffer_e,
207  mpi->comm[0],
208  FFTW_BACKWARD,
209  FFTW_ESTIMATE);
210 
211  physics->phys_buffer_phi = fftw_alloc_complex(physics->alloc_local);
212  physics->fourier_buffer_phi = fftw_alloc_complex(physics->alloc_local);
213 
214  physics->plan_forward_phi = fftw_mpi_plan_dft_1d(dim_global[0],
215  physics->phys_buffer_phi,
216  physics->fourier_buffer_phi,
217  mpi->comm[0],
218  FFTW_FORWARD,
219  FFTW_ESTIMATE);
220 
221  physics->plan_backward_phi = fftw_mpi_plan_dft_1d(dim_global[0],
222  physics->fourier_buffer_phi,
223  physics->phys_buffer_phi,
224  mpi->comm[0],
225  FFTW_BACKWARD,
226  FFTW_ESTIMATE);
227 #endif
228 #else
229  fprintf(stderr,"Error in VlasovInitialize():\n");
230  fprintf(stderr," Self-consistent electric field requires FFTW library.\n");
231  return(1);
232 #endif
233  }
234 
235  /* initializing physical model-specific functions */
236  solver->PreStep = VlasovPreStep;
237  solver->ComputeCFL = VlasovComputeCFL;
238  solver->FFunction = VlasovAdvection;
239  solver->Upwind = VlasovUpwind;
241  solver->PostStage = VlasovPostStage;
242 
243  int ierr = VlasovEField(solver->u, solver, 0.0);
244  if (ierr) return ierr;
245 
246  return 0;
247 }
Definition: vlasov.h:57
int(* PhysicsOutput)(void *, void *, double)
Definition: hypar.h:347
int nvars
Definition: hypar.h:29
double * potential
Definition: vlasov.h:84
MPI related function definitions.
char SplitHyperbolicFlux[_MAX_STRING_SIZE_]
Definition: hypar.h:92
int self_consistent_electric_field
Definition: vlasov.h:60
Data structure and some function declarations for banded block matrices.
int MPIBroadcast_integer(int *, int, int, void *)
Definition: MPIBroadcast.c:23
double * u
Definition: hypar.h:116
Some basic definitions and macros.
int VlasovUpwind(double *, double *, double *, double *, double *, double *, int, void *, double)
Definition: VlasovUpwind.c:17
double * e_field
Definition: vlasov.h:81
int(* Upwind)(double *, double *, double *, double *, double *, double *, int, void *, double)
Definition: hypar.h:295
int ndims
Definition: hypar.h:26
int(* FFunction)(double *, double *, int, void *, double)
Definition: hypar.h:276
Vlasov Equation.
int VlasovInitialize(void *s, void *m)
int npts_local_x
Definition: vlasov.h:69
double(* ComputeCFL)(void *, void *, double, double)
Definition: hypar.h:269
long npts_global_x
Definition: vlasov.h:72
Structure containing all solver-specific variables and functions.
Definition: hypar.h:23
#define _MAX_STRING_SIZE_
Definition: basic.h:14
int VlasovWriteEFieldAndPotential(void *, void *, double)
int VlasovPreStep(double *, void *, void *, double)
long npts_global_x_wghosts
Definition: vlasov.h:78
#define _MODEL_NDIMS_
Definition: euler1d.h:56
Contains structure definition for hypar.
MPI_Comm world
int VlasovEField(double *, void *, double)
Definition: VlasovEField.c:258
MPI_Comm * comm
int(* PreStep)(double *, void *, void *, double)
Definition: hypar.h:339
int * dim_local
Definition: hypar.h:37
void * m
Definition: vlasov.h:87
int ndims_v
Definition: vlasov.h:66
int npts_local_x_wghosts
Definition: vlasov.h:75
void * physics
Definition: hypar.h:266
int(* PostStage)(double *, void *, void *, double)
Definition: hypar.h:336
int VlasovPostStage(double *, void *, void *, double)
int ghosts
Definition: hypar.h:52
int VlasovAdvection(double *, double *, int, void *, double)
Structure of MPI-related variables.
double VlasovComputeCFL(void *, void *, double, double)
#define _MODEL_NVARS_
Definition: euler1d.h:58
Contains macros and function definitions for common array operations.
int * dim_global
Definition: hypar.h:33
int ndims_x
Definition: vlasov.h:63