Skeleton 2-1/2D Darwin OpenMP Particle-in-Cell (PIC) codes field
diagnostics
by Viktor K. Decyk
copyright 2007-2015, regents of the university of california

This directory contains procedures that are useful for performing wave
diagnostics, such as measuring the wavenumber and frequency of plasma
waves, for the 2-1/2D Darwin OpenMP Particle-in-Cell (PIC) codes in the
mdpic2 directory.  The procedures, written in Fortran, are in the file
mdfield2.f.  The file mdfield2_f.c contains wrapper functions to allow
the Fortran procedures to be called from C.

The electric and magnetic fields used to advance particles are smoothed
by suppressing large wavenumbers in order to avoid numerical errors due
to aliasing.  The field diagnostics, however, are normally unsmoothed.
The main diagnostics are the electrostatic potential and the vector
potential in fourier space, in the Coulomb gauge.  These are calculated
by the procedures MPOTP2 and MAPOTP23, respectively.  Other diagnostics,
such as the unsmoothed longitudinal electric field and magnetic field
can be calculated from the potentials with the procedures MGRADF2 and
MCURLF2, respectively.  The procedure MEPOIS23 can be called with
isign=1 to obtain the unsmoothed transverse electric field.  The fourier
modes are normally stored to disk for later post-processing, such as by
performing a fourier transform in time to obtain the frequencies for
different wavenumbers.  It is usually not necessary to store all the
modes to disk, since the high wavenumber modes are usually unimportant.
Furthermore, the fourier modes are stored in a packed format which is
difficult to work with.  Thus procedures RDMODES2 and RDVMODES2 are also
provided to extract a subset of the fourier modes for the potential and
vector fields respectively, and copy them in an unpacked format for
easier post-processing. (The procedures WRMODES2 and WRVMODES2 are
provided to repack the scalar or vector fourier modes, if needed.)

No warranty for proper operation of this software is given or implied.
Software or information may be copied, distributed, and used at own
risk; it may not be distributed without this notice included verbatim
with each file.  If use of these codes results in a publication, an
acknowledgement is requested.

To use these procedures, one first needs to add some declarations in the
main programs mdpic2.90 and mdpic2.c in the parent directory mdpic2,
similar to the following.

For Fortran:
   integer :: modesx, modesy, modesxd, modesyd
   complex, dimension(:,:), pointer :: potc, pott
   complex, dimension(:,:,:), pointer :: vpotc, vpott

For C:
   int modesx, modesy, modesxd, modesyd;
   float complex *potc = NULL, *pott = NULL;
   float complex *vpotc = NULL, *vpott = NULL;
   
Then before the main iteration loop, one needs to allocate the arrays.

For Fortran:
   modesx = nx/4; modesy = ny/4
   modesxd = modesx; modesyd = min(2*modesy-1,ny)
   allocate(potc(nxeh,nye),vpotc(ndim,nxeh,nye))
   allocate(pott(modesxd,modesyd))
   allocate(vpott(ndim,modesxd,modesyd))

For C:
   modesx = nx/4; modesy = ny/4;
   modesxd = modesx; modesyd = 2*modesy - 1;
   modesyd = modesyd < ny ? modesyd : ny;
   potc = (float complex *) malloc(nxeh*nye*sizeof(float complex));
   vpotc = (float complex *) malloc(ndim*nxeh*nye*sizeof(float complex));
   pott = (float complex *) malloc(modesxd*modesyd*sizeof(float complex));
   vpott = (float complex *) malloc(ndim*modesxd*modesyd*sizeof(float complex));

Finally, in the main iteration loops just before the push procedures,
one can add some diagnostics, such as:

For Fortran:
! perform potential diagnostic and unpack into array pott
! updates potc, pott, wt
   call MPOTP2(qe,potc,ffc,wt,nx,ny,nxeh,nye,nxh,nyh)
   call RDMODES2(potc,pott,nx,ny,modesx,modesy,nxeh,nye,modesxd,modesyd)
! perform vector potential diagnostic and unpack into array vpott
! updates vpotc, vpott, wt
   call MAPOTP23(cue,vpotc,ffc,ci,wt,nx,ny,nxeh,nye,nxh,nyh)
   call RDVMODES2(vpotc,vpott,nx,ny,modesx,modesy,ndim,nxeh,nye,modesxd,modesyd)

For C:
/* perform potential diagnostic and unpack into array pott */
/* updates potc, pott, wt                                  */
   cmpotp2((float complex *)qe,potc,ffc,&wt,nx,ny,nxeh,nye,nxh,nyh);
   crdmodes2(potc,pott,nx,ny,modesx,modesy,nxeh,nye,modesxd,modesyd);
/* perform vector potential diagnostic and unpack into array vpott */
/* updates vpotc, vpott, wt                                        */
   cmapotp23((float complex *)cue,vpotc,ffc,ci,&wt,nx,ny,nxeh,nye,nxh,nyh);
   crdvmodes2(vpotc,vpott,nx,ny,modesx,modesy,ndim,nxeh,nye,modesxd,modesyd);

One would have to modify the Makefile as well to include the files
mdfield2.f and mdfield2_f.c, as needed.
