Relativistic MHD Simulations of Relativistic Jets with RAISHIN

Ken Nishikawa
National Space Science & Technology Center/UAH
October 20, 2011
1/39
Context
 Electromagnetic code
new_bbeps1.f, a magnetized electromagnetic code
1. understanding the code
2. calculates 3d phase space distribution, velocity
moments, and entropy (PSDIST13)
add section to use this subroutine in
newbbeps1.f
3. how to add contour plots
4. call subroutine to plot phase space contour
5. understanding push1d
Kernel code: new_bbeps1.f
use
use
use
use
use
use
use
1.
2.
3.
4.
5.
6.
7.
8.
9.
init1d
bpush1d
dpush1d
push1d
fft1d
field1d
diag1d
init1d.mod
bpush1d.mod
dpush1d.mod
push1d.mod
fft1d.mod
field1d.mod
diag1d.mod







init1mod.f
bpush1mod.f
dpush1mod.f
push1mod.f
fft1mod.f
field1mod.f
diag1mod.f
 init1lib.f (fort77)
 bpush1lib.f
 dpush1lib.f
 push1lib.f
 fft1lib.f
 field1lib.f
 diag1lib.f
understand the structure of the code
understand the essential subroutines
understand init1lib.f and init1mod.f
understand diag1lib.f and diag1mod.f to implement new diagnostics
calculates 3d phase space distribution
add diagnostics of phase velocity plot (contour in color like k-ω plot)
how to add phase plot using dots
how to push particles (collect charge)
recap what we learned and plan what we will study for the rest of class
based on readme.txt
c----------------------------------------------------------------------UCLA Particle-in-Cell Framework (UPIC) codes in new_beps1.source
Written by Viktor K. Decyk, UCLA
Copyright 1994-2011, Regents of the University of California.
All rights reserved.
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.
update: July 11, 2011
I. Introduction.
This directory contains three 1d Particle-in-Cell (PIC) codes. PIC
codes model plasmas as particles which interact self-consistently via
the electromagnetic fields they themselves produce. Further details
about PIC codes can be found in the text by C. K. Birdsall and A. B.
Langdon, Plasma Physics via Computer Simulation, 1985.
These models work at the most fundamental, microscopic level of
classical physics. PIC codes are used in almost all areas of plasma
physics, such as fusion energy research, plasma accelerators, space
physics, ion propulsion, and plasma processing, and many other areas.
Particles in PIC codes interact via fields which are calculated on a
grid. PIC codes are possible whenever there is some differential
equation which describes the fields in terms of particle sources.
There are a variety of PIC codes in common use, which are
differentiated by the kinds of forces retained in the model. The
simplest is the electrostatic force, described by a Poisson equation.
More complex is fully electromagnetic models, described by Maxwell’s
equation. The most complex is the Darwin (near-field or non-radiative
electromagnetics) model, described by the Darwin subset of Maxwell’s
equation. Other models are also possible, such as the gyrokinetic, which
are not included here.
PIC codes generally have three important procedures in the main
iteration loop. The first is the deposit, where some particle quantity,
such as a charge, is accumulated on a grid via interpolation to produce
a source density. Various other quantities can also be deposited, such
as current densities, depending on the model. The second important
procedure is the field solver, which solves Maxwell’s equation or a
subset to obtain the electric and/or magnetic fields from the source
densities. Finally, once the fields are obtained, the particle forces
are found by interpolation from the grid, and the particle co-ordinates
are updated, using Newton’s second law and the Lorentz force. The
particle processing parts dominate over the field solving parts in a
typical PIC application. The codes included here are not relativistic.
The three codes are simple and intended for teaching. They are
written in Fortran77 and Fortran90. The models are periodic and only
electrons are included. The initial density profile is uniform, and the
initial velocity distribution is a drifting maxwellian. However, two
populations of electrons are possible, for example, two beams, or a
background plasma and a beam. The main diagnostic is storing the
potential and vector potential for selected fourier modes for studying
plasma waves. Both linear interpolation and the more accurate quadratic
interpolation are supported.
Details about the mathematical equations and units used in these
codes is given in a companion article, "Description of Spectral Codes
from the UPIC Framework" by Viktor K. Decyk, UCLA.
II. Installation
These programs are intended to run interactively. The preferred mode
of operation is to use X11. In addition to the X11 libraries, this
requires the free library Ygl, which is available from the web site:
http://www.thp.uni-duisburg.de/Ygl/. The default compiler is gfortran,
which is freely available from http://gcc.gnu.org/wiki/GFortranBinaries
and gives very good performance. Once Ygl has been installed, one can
execute the following command to install:
make
It will make 3 executables, new_beps1, new_bbeps1, and new_dbeps1 for
the electrostatic, electromagnetic, and darwin models, respectively.
The makefile contains definitions for many other compilers, which have
been commented out. They can be used if gfortran is not available.
The codes normally are compiled to use double precision reals, by
promoting reals to doubles in the makefile. The codes can be compiled
to use single precision reals by removing this promotion in the makefile.
If X11 is not available or not desired, a number of other graphics
libraries are possible, most notably a post-script generator. The
file generated by this library pgraph.ps can be viewed with post-script
viewers or converters. The output file can be large, but it is useful
for having a record of the graphical output. On the Macintosh, the free
program Preview will convert and compress the large post-script files to
pdf and allow one to easily move through this file. To make use of this
library, one needs to edit the makefile to comment out the X11 library
and uncomment the postscript library libpsp.f. Additional graphics
libraries, which are largely obsolete, are in the extras directory.
In the Examples directory, there are sample input files and sample
output files, and a description of their use in the file Examples.pdf.
III. Input variables
The input variables for these codes are part of the namelist input1
declared in the file input1mod.f
The following 30 variables are used by all the codes:
idrun = run identifier for current run. This is an integer which will
be appended to the name of various output files.
idcode = code identifier. This is an integer identifying the code:
1=electrostatic, 2=electromagnetic, 3=darwin
This is usually set autmomatically by the code.
indx = exponent which determines length in x direction, nx=2**indx.
This ensures the system length is a power of 2.
npx = number of background particles distributed in x direction.
npxb = number of beam particles in x direction.
inorder = interpolation order: 1=LINEAR, 2=QUADRATIC.
popt = particle optimization scheme: 1=STANDARD, 2=LOOKAHEAD.
The LOOKAHEAD scheme performs some optimizations which
occasionally can make things worse.
dopt = charge deposit optimization scheme: 1=STANDARD, 2=LOOKAHEAD.
tend = time at end of simulation, in units of plasma frequency.
dt = time interval between successive calculations. The number of time
steps the code runs is given by tend/dt. dt should be less than .2
for the electrostatic or darwin code, and less than .5*ci for the
electromagnetic code.
qme = charge on electron, in units of e, usually -1.0.
vtx/vty/vtz = thermal velocity of background electrons in x/y/z direction
typically 1.0.
vx0/vy0/vz0 = drift velocity of background electrons in x/y/z direction.
vtdx/vtdy/vtdz = thermal velocity of beam electrons in x/y/z direction.
typically 1.0.
vdx/vdy/vdz = drift velocity of beam electrons in x/y/z direction.
ax = half-width of particle in x direction, recommended values:
for linear interpolation ax = .912871, for quadratic ax = .866025.
sortime = number of time steps between electron sorting. This is used
to improve cache performance. rarely needed in 1d.
sortime=0 to suppress
nplot = maximum number of plots per page, nplot=0 to suppress plots.
ntw = number of time steps between energy diagnostic, ntw=0 to suppress
ntp = number of time steps between potential diagnostic. Extracts
potential and writes modesxp fourier modes to a file, and displays
potential in real space. ntp=0 to suppress.
modesxp = number of modes in x to keep for potential diagnostic.
ntv = number of time steps between velocity-space diagnostic. Finds
and displays velocity distributions.
The following 7 variables are used by the electromagnetic and darwin codes:
djopt = current deposit optimization scheme: 1=STANDARD, 2=LOOKAHEAD
The LOOKAHEAD scheme performs some optimizations which
occasionally can make things worse.
omx/omy/omz = magnetic field electron cyclotron frequency in x/y/z
ci = reciprical of velocity of light, ci = 0.0 gives electrostatic limit.
nta = number of time steps between vector potential diagnostic. Extracts
vector potential and writes modesxa fourier modes to a file, and
displays vector potential in real space. nta=0 to suppress.
modesxa = number of modes in x to keep for vector potential diagnostic
The following 2 variables are used only by the electromagnetic code:
nte = number of time steps between electromagnetic diagnostic,
nte=0 to suppress.
modesxe = number of modes in x to keep for electromagnetic diagnostic
(radiative part of vector potential).
The following variable is used only by the darwin code:
ndc = number of corrections in darwin iteration, typically 2 or larger.
The Darwin code can be run as an electrostatic code with external
magnetic field by setting ci = 0, and ndc = 0.
IV. Electrostatic code
In the inner loop of the code:
Deposit section:
sguard: Initialize charge density to constant background.
dpost: deposit charge density.
aguard: add charge density guard cells.
Field solve section:
fft: fourier transform charge density to k-space
pois: calculate smoothed electric field in k-space.
fft: fourier transform smoothed electric field to real space.
Particle Push section:
cguard: fill in guard cells for smoothed electric field.
push: update particle co-ordinates with smoothed electric field:
x(t)->x(t+dt); v(t-dt/2)->v(t+dt/2)
Diagnostic section:
Velocity diagnostic (if ntv > 0)
vdist: calculate velocity distribution and moments.
displayfv: display velocity distribution
Potential diagnostic (if ntp > 0)
pois: calculate potential in k-space.
gtmodes: extract fourier mode subset.
writebf: write out fourier modes to file
fft: transform potential to real space.
cguard: fill in guard cells for potential.
displays: display potential
Energy diagnostic (if ntw > 0)
store energies in file output1.idrun
In the initialization section of the code:
Input namelist data are read.
Constants are defined and arrays allocated.
fft_init: tables for the FFT are initialized.
pois_init: tables for field solvers are initialized.
distr: particle co-ordinates are initialized, from a uniform,
bi-maxwellian distribution: x(t), v(t-dt/2)
bfopen: potential output file is created.
In the declaration section of the code:
Important constants are declared:
nx = grid length
nloop = number of time steps to run
ntime = current time step
Important main arrays are declared:
part = particle co-ordinate array
qe = charge density array
fxe = smoothed electric field array
ffc = field solver table
mixup, sct = FFT tables
Important diagnostic arrays are declared:
pott = potential fourier modes
fv, fvm = velocity distribution and moments
wt = energies
V. Electromagnetic code
In the inner loop of the code:
Deposit section:
sguard: Initialize current density to zero.
djpost: deposit current density, and updates position:
x(t+dt/2)->x(t+dt)
sguard: Initialize charge density to constant background.
dpost: deposit charge density.
aguard: add current density guard cells.
aguard: add charge density guard cells.
Field solve section:
fft: fourier transform charge density to k-space
fft: fourier transform current density to k-space
maxwell: update transverse electromagnetic fields in k-space.
pois: calculate smoothed longitudinal electric field in k-space.
emfield: add smoothed longitudinal and transverse electric fields
emfield: copy smoothed magnetic field
fft: fourier transform smoothed electric field to real space.
fft: fourier transform smoothed magnetic field to real space.
Particle Push section:
cguard: fill in guard cells for smoothed electric field
baddext: add external magnetic field
cguard: fill in guard cells for smoothed magnetic field
push3: update particle co-ordinates with smoothed electric and
magnetic fields: x(t)->x(t+dt/2); v(t-dt/2)->v(t+dt/2)
Diagnostic section:
Velocity diagnostic (if ntv > 0)
vdist: calculate velocity distribution and moments.
displayfv: display velocity distribution
Potential diagnostic (if ntp > 0)
pois: calculate potential in k-space.
gtmodes: extract fourier mode subset.
writebf: write out fourier modes to file
fft: transform potential to real space.
cguard: fill in guard cells for potential.
displays: display potential
Vector Potential diagnostic (if nta > 0)
avpot: calculate vector potential in k-space.
gtmodes: extract fourier mode subset.
writebf: write out fourier modes to file
fft: transform vector potential to real space.
cguard: fill in guard cells for vector potential.
displayv: display vector potential
Electromagnetic diagnostic (if nte > 0)
avrpot: calculate radiative vector potential in k-space.
gtmodes: extract fourier mode subset.
writebf: write out fourier modes to file
fft: transform radiative vector potential to real space.
cguard: fill in guard cells for radiative vector potential.
displayv: display radiative vector potential
Energy diagnostic (if ntw > 0)
store energies in file output1.idrun
In the initialization section of the code:
Input namelist data are read.
Constants are defined and arrays allocated.
fft_init: tables for the FFT are initialized.
pois_init: tables for field solvers are initialized.
distr: particle co-ordinates are initialized, from a uniform,
bi-maxwellian distribution: x(t), v(t-dt/2)
distr: guiding centers are assigned if external magnetic field is
present
bfopen: potential output file is created.
bfopen: vector potential output file is created.
the transverse electric and magnetic fields are initialized to the
darwin fields the first time through the main loop.
In the declaration section of the code:
Important constants are declared:
nx = grid length
nloop = number of time steps to run
ntime = current time step
Important main arrays are declared:
part = particle co-ordinate array
qe = charge density array
cu = current density array
fxe = smoothed longitudinal electric field array
fxyze = smoothed total electric field array
byze = smoothed magnetic field array
eyz = transverse electric field array
byz = transverse magnetic field array
ffc = field solver table
mixup, sct = FFT tables
Important diagnostic arrays are declared:
pott = potential fourier modes
vpott = vector potential fourier modes
vpotr = radiative vector potential fourier modes
fv, fvm = velocity distribution and moments
wt = energies
VI. Darwin code
In the inner loop of the code:
Initial deposit section:
sguard: Initialize current density to zero.
sguard: Initialize momentum flux density to zero.
djpost: deposit current density.
dmjpost: deposit momentum flux density.
sguard: Initialize charge density to constant background.
dpost: deposit charge density.
aguard: add current density guard cells.
aguard: add momentum flux density guard cells.
aguard: add charge density guard cells.
wpmxn: find maximum and minimum plasma frequency
Initial field solve section:
fft: fourier transform charge density to k-space
pois: calculate smoothed longitudinal electric field in k-space.
fft: fourier transform smoothed longitudinal electric field to real
space.
cguard: fill in guard cells for smoothed longitudinal electric field
fft: fourier transform current density to k-space
bpois: calculate smoothed magnetic field in k-space.
fft: fourier transform smoothed magnetic field to real space.
baddext: add external magnetic field
cguard: fill in guard cells for smoothed magnetic field
fft: fourier transform momentum flux density to k-space
dcuperp: calculate time derivative of current
epois: calculate smoothed transverse electric field in k-space.
fft: fourier transform smoothed transverse electric field to real
space.
cguard: fill in guard cells for smoothed transverse electric field
add smoothed longitudinal and transverse electric fields
Iteration section:
sguard: Initialize acceleration density with shift.
sguard: Initialize current density to zero.
sguard: Initialize momentum flux density to zero.
dcjpost: deposit current, acceleration density, and momentum flux.
aguard: add current density guard cells.
aguard: add acceleration density guard cells.
aguard: add momentum flux density guard cells.
fft: fourier transform current density to k-space
bpois: calculate smoothed magnetic field in k-space.
fft: fourier transform smoothed magnetic field to real space.
baddext: add external magnetic field
cguard: fill in guard cells for smoothed magnetic field
fft: fourier transform acceleration density to k-space
fft: fourier transform momentum flux density to k-space
adcuperp: calculate time derivative of current
epois: calculate smoothed transverse electric field in k-space.
fft: fourier transform smoothed transverse electric field to real
space.
cguard: fill in guard cells for smoothed transverse electric field
copy smoothed transverse electric field
Particle Push section:
push3: update particle co-ordinates with smoothed electric and
magnetic fields: x(t)->x(t+dt); v(t-dt/2)->v(t+dt/2)
Diagnostic section:
Velocity diagnostic (if ntv > 0)
vdist: calculate velocity distribution and moments.
displayfv: display velocity distribution
Potential diagnostic (if ntp > 0)
pois: calculate potential in k-space.
gtmodes: extract fourier mode subset.
writebf: write out fourier modes to file
fft: transform potential to real space.
cguard: fill in guard cells for potential.
displays: display potential
Vector Potential diagnostic (if nta > 0)
apois: calculate vector potential in k-space.
gtmodes: extract fourier mode subset.
writebf: write out fourier modes to file
fft: transform vector potential to real space.
cguard: fill in guard cells for vector potential.
displayv: display vector potential
Energy diagnostic (if ntw > 0)
store energies in file output1.idrun
In the initialization section of the code:
Input namelist data are read.
Constants are defined and arrays allocated.
fft_init: tables for the FFT are initialized.
pois_init: tables for field solvers are initialized.
epois_init: tables for darwin field solver are initialized.
distr: particle co-ordinates are initialized, from a uniform,
bi-maxwellian distribution: x(t), v(t-dt/2)
distr: guiding centers are assigned if external magnetic field is
present
bfopen: potential output file is created.
bfopen: vector potential output file is created.
In the declaration section of the code:
Important constants are declared:
nx = grid length
nloop = number of time steps to run
ntime = current time step
Important main arrays are declared:
part = particle co-ordinate array
qe = charge density array
cu = current density array
cus = acceleration density array
amu = momentum flux array
fxe = smoothed longitudinal electric field array
fxyze = smoothed total electric field array
byze = smoothed magnetic field array
eyze = smoothed transverse electric field array
ffc = field solver table
ffe = darwin field solver table
mixup, sct = FFT tables
Important diagnostic arrays are declared:
pott = potential fourier modes
vpott = vector potential fourier modes
fv, fvm = velocity distribution and moments
wt = energies
VII. Code Structure
The 1d PIC simulation codes are written in layers. The top layer
consists of the 3 main programs new_beps1.f, new_bbeps1.f,
and new_dbeps1.f, which contain electrostatic, electromagnetic, and
darwin 1d codes, respectively. The middle layer consists of
52 subroutines in 8 files which define Fortran90 modules that contain
interface functions and data for the main codes. These middle layer
module files generally have names that end with ‚ ----1mod.f.‚ ----. The bottom
layer consists of 87 subroutine in 7 library files which define low level
kernel functions written in Fortran 77 for the middle layers. These
bottom layer library files have names that end with ‚ ----1lib.f.‚ ----. This
organization is used because Fortran77 code tends to run very fast,
while Fortran90 is a safer and less error prone language.
The 9 Fortran90 modules are the following:
globals.f defines module globals
contains global constants.
input1mod.f defines module input1d
defines namelist input1 containing input variables.
init1mod.f defines module init1d
contains interface procedures to initialize particle
co-ordinates:
distr => idistr1 initializes x and vx co-ordinates for 1d code.
calls DISTR1
distr => idistrh1 initializes x and vx,vy,z co-ordinates for
magnetized 1-2/2d codes.
calls DISTR1H
distr => ibdistr1 calculates guiding centers for magnetized
1-2/2d codes.
calls GBDISTR1L
push1mod.f defines module push1d
contains interface procedures to process particles:
dpost => igpost1 deposits charge density, with various interpolations
and optimizations.
calls GPOST1, GSPOST1, GSPOST1X, GPOST1L, GSPOST1L, or
GSPOST1XL
push => igpush1 push particles, with various interpolations and
optimizations.
calls GPUSH1, GSPUSH1, GPUSH1L, or GSPUSH1L
sortp => isortp1x sort particles by grid with various interpolations.
calls SORTP1X, or SORTP1XL
fft1mod.f defines module fft1d
contains interface procedures to perform ffts:
fft_init => ifft1rxinit initializes real to complex fft tables.
calls FFT1RX
fft => ifft1rx performs 1d real to complex fft and its inverse.
calls FFT1RX
fft => ifft1r2 performs multiple 1d real to complex fft and its
inverse for scalar or 2 and 3 component vector arrays.
calls FFT1RX, FFT1R2, or FFT1R3
field1mod.f defines module field1d
contains procedures to manage guard cells and solve
fields in fourier space:
cguard => icguard1 copy guard cells for scalar or 2 and 3 component
vector arrays with various interpolations.
calls CGUARD1, BGUARD1, DGUARD1, CGUARD1L, BGUARD1L,
or DGUARD1L
cguard => idguard1 copy guard cells for scalar arrays with various
interpolations.
calls DGUARD1, or DGUARD1L
sguard => isguard1 initialize field for scalar array with various
interpolations.
calls SGUARD1 or SGUARD1L
sguard => iscguard1 initialize field for 2 component vector array with
various interpolations.
calls SCGUARD1 or SCGUARD1L
sguard => isfguard1 initialize 2 component field with scaled vector
array with various interpolations.
calls SCFGUARD1 or SCFGUARD1L
aguard => iaguard1 add guard cells for scalar array with various
interpolations.
calls AGUARD1 or AGUARD1L
aguard => iacguard1 add guard cells for 2 component vector array with
various interpolations.
calls ACGUARD1 or ACGUARD1L
pois_init => ipois1init initializes tables for field solvers.
calls POISP1
pois => ipois1 solves poisson equation for electric force, potential,
or smoothing.
calls POISP1
bpois => jbpois13 solves vector poisson equation for magnetic force.
calls BPOIS13
apois => iapois13 solves vector poisson equation for vector potential.
calls BPOIS13
ibpois => iibpois13 solves vector poisson equation for magnetic field.
calls IBPOIS13
maxwel => imaxwel1 solves maxwell equation for electric and magnetic
fields.
calls MAXWEL1
emfield => iemfield1 calculates electric force from electric fields
given by maxwell and poisson equations.
calls EMFIELD1
emfield => ibmfield1 calculates magnetic force from magnetic field
given by maxwell equation.
calls BMFIELD1
avpot => iavpot13 calculates vector potential from magnetic field.
calls AVPOT13
avrpot => iavrpot13 calculates radiative vector potential from magnetic
field and current
calls AVRPOT13
gtmodes => igtmodes1 extracts selected fourier components from
potential array.
calls GTMODES1
gtmodes => igtvmodes1 extracts selected fourier components from vector
potential array.
calls GTVMODES1
ptmodes => iptmodes1 places selected fourier components into potential
array.
calls PTMODES1
ptmodes => iptvmodes1 places selected fourier components into vector
potential array.
calls PTVMODES1
dcuperp => idcuperp13 calculate transverse derivative of current
density from momentum flux.
calls DCUPERP13
adcuperp => iadcuperp13 calculate transverse derivative of current
density from momentum flux and acceleration density.
calls ADCUPERP13
epois_init => iepois13init initializes tables for darwin field solver.
calls EPOIS13
epois => iepois13 solves vector poisson equation for transverse
electric force.
calls EPOIS13
iepois => iiepois13 solves vector poisson equation for transverse
electric field.
calls EPOIS13
wpmxn => iwpmxn1 calculates maximum and minimum plasma frequency
calls WPMXN1
baddext => ibaddext1adds constant to magnetic field in real space for
1-2/2d code.
calls BADDEXT1
diag1mod.f defines module diag1d
contains diagnostic procedures:
wtimer performs wall clock timing.
get_funit returns an unconnected fortran unit number.
bfopen => bfcopen1 opens binary file for complex 1d scalar data.
bfopen => bfvcopen1 opens binary file for complex 1d vector data
writebf => ifcwrite1 writes complex 1d scalar data to a binary
file.
calls FCWRITE1
writebf => ifvcwrite1 writes complex 1d vector data to a binary file.
call FCWRITE1
readbf => ifcread1 reads complex 1d scalar data from a binary file.
calls FCREAD1
readbf => ifvcread1 reads complex 1d vector data from a binary file.
calls FCREAD1
vdist => ivdist1 calculates 1 or 3 component velocity distribution and
velocity moments.
vdist => ivdist1 calculates 1 or 3 component velocity distribution,
velocity moments, and entropy.
calls VDIST13 or VDIST1
psdist => ipsdist1 calculates 1 or 3 component phase space
distribution, velocity moments, and entropy
calls PSDIST13 or PSDIST1
bpush1mod.f defines module bpush1d
contains interface procedures to process particles
with magnetic fields:
djpost => igjpost1 deposits current density, with various
interpolations and optimizations.
calls GJPOST1, GSJPOST1, GSJPOST1X, GJPOST1L, GSJPOST1L, or
GSJPOST1XL
push3 => igbpush13 push particles with magnetic field, with various
interpolations and optimizations.
calls GBPUSH13, GSBPUSH131, GBPUSH13L, or GSBPUSH13L
retard => iretard1 retard particle position a half time-step.
calls RETARD1
dpush1mod.f defines module dpush1d
contains interface procedures to process particles
with darwin electric and magnetic fields:
dmjpost => igmjpost2 deposits momentum flux, with various
interpolations and optimizations.
calls GMJPOST1, GSMJPOST1, GMJPOST1L, or GSMJPOST1L
dcjpost => igdcjpost1 deposits momentum flux, with various
interpolations and optimizations.
calls GDCJPOST1, GSDCJPOST1, GDCJPOST1L, or GSDCJPOST1L
The 7 Fortran77 libraries are the following:
init1lib.f contains procedures to initialize particle
co-ordinates:
DISTR1 initializes x and vx co-ordinates for 1d code.
DISTR1H initializes x and vx,vy,z co-ordinates for magnetized
1-2/2d codes.
GBDISTR1L calculates guiding centers for magnetized 1-2/2d codes.
ranorm = generates gaussian random numbers.
randum = generates uniform random numbers.
push1lib.f contains procedures to process particles:
GPOST1 deposits charge density, quadratic interpolation, STANDARD
optimization.
GSPOST1 deposits charge density, quadratic interpolation, LOOKAHEAD
optimization
GSPOST1X deposits charge density, quadratic interpolation, VECTOR
optimization.
GPOST1L deposits charge density, linear interpolation, STANDARD
optimization.
GSPOST1L deposits charge density, linear interpolation, LOOKAHEAD
optimization.
GSPOST1XL deposits charge density, linear interpolation, VECTOR
optimization.
GPUSH1 push particles, quadratic interpolation, STANDARD optimization.
GSPUSH1 push particles, quadratic interpolation, LOOKAHEAD
optimization.
GPUSH1L push particles, linear interpolation, STANDARD optimization.
GSPUSH1L push particles, linear interpolation, LOOKAHEAD optimization.
SORTP1X sort particles by grid, quadratic interpolation, memory
conserving algorithm.
SORTP1XL sort particles by grid, linear interpolation, memory
conserving algorithm.
DSORTP1X sort particles by grid, quadratic interpolation, high
performance algorithm.
DSORTP1XL sort particles by grid, linear interpolation, high
performance algorithm.
RMOVE1 remove particles instead of reflecting at boundary.
fft1lib.f contains procedures to perform ffts:
FFT1RX performs real to complex fft and its inverse for scalar array.
FFT1R2 performs real to complex fft and its inverse for 2 component
vector array.
FFT1R3 performs real to complex fft and its inverse for 3 component
vector array.
FFT1C performs complex to complex fft and its inverse.
FST1RX performs fast sine transform and its inverse.
FCT1RX performs fast cosine transform and its inverse.
FDST1RX performs fast sine DST-III transform and its inverse.
FDCT1RX performs fast cosine DCT-III transform and its inverse.
field1lib.f contains procedures to manage guard cells and solve
fields equations in fourier space:
CGUARD1 copy guard cells for 2 component vector array, quadratic
interpolation.
BGUARD1 copy guard cells for 3 component vector array, quadratic
interpolation.
DGUARD1 copy guard cells for scalar array, quadratic interpolation.
SCGUARD1 initialize field for 2 component vector array, quadratic
interpolation.
SGUARD1 initialize field for scalar array, quadratic interpolation.
ACGUARD1 add guard cells for 2 component vector array, quadratic
interpolation.
CGUARD1L copy guard cells for 2 component vector array, linear
interpolation.
BGUARD1L copy guard cells for 3 component vector array, linear
interpolation.
DGUARD1L copy guard cells for scalar array, linear interpolation.
SCGUARD1L initialize field for 2 component vector array, linear
interpolation.
SGUARD1L initialize field for scalar array, linear interpolation.
ACGUARD1L add guard cells for 2 component vector array, linear
interpolation.
AGUARD1L add guard cells for scalar array, linear interpolation.
POISP1 solve poisson equation for electric force, potential, or
smoothing.
BPOIS13 solve vector poisson equation for magnetic force, vector
potential, or smoothing.
IBPOIS13 solve vector poisson equation for magnetic field.
MAXWEL1 solve maxwell equation for electric and magnetic fields.
EMFIELD1 calculate electric force from electric fields given by
maxwell and poisson equations.
BMFIELD1 calculate magnetic force from magnetic field given by maxwell
equation.
AVPOT13 calculate vector potential from magnetic field.
AVRPOT13 calculate radiative part of the vector potential
GTMODES1 extracts selected fourier components from potential array.
PTMODES1 places selected fourier components into potential array.
GTVMODES1 extracts selected fourier components from vector potential
array.
PTVMODES1 places selected fourier components into vector potential
array.
SCFGUARD1 initialize 2 component field with scaled vector array,
quadratic interpolation.
SCFGUARD1L initialize 2 component field with scaled vector array,
linear interpolation.
DCUPERP13 calculate transverse derivative of current density from
momentum flux.
ADCUPERP13 calculate transverse derivative of current density from
momentum flux and acceleration density.
EPOIS13 solve vector poisson equation for transverse electric field
or force.
WPMXN1 calculates maximum and minimum plasma frequency.
BADDEXT1 adds constant to magnetic field in real space for 1-2/2d code
diag1lib.f contains diagnostic procedures:
VDIST1 calculates 1 component velocity distribution, velocity moments,
and entropy.
VDIST13 calculates 3 component velocity distribution, velocity
moments, and entropy.
PSDIST1 calculates 1d phase space distribution, velocity moments, and
entropy.
PSDIST13 calculates 3d phase space distribution, velocity moments, and
entropy.
FCWRITE1 writes complex binary data to file
FCREAD1 writes complex binary data to file
bpush1lib.f contains procedures to process particles with
magnetic fields:
GJPOST1 deposits current density, quadratic interpolation, STANDARD
optimization.
GSJPOST1 deposits current density, quadratic interpolation, LOOKAHEAD
optimization.
GSJPOST1X deposits current density, quadratic interpolation, VECTOR
optimization.
GJPOST1L deposits current density, linear interpolation, STANDARD
optimization.
GSJPOST1L deposits current density, linear interpolation, LOOKAHEAD
optimization.
GSJPOST1XL deposits current density, linear interpolation, VECTOR
optimization.
GBPUSH13 push particles with magnetic field, quadratic interpolation,
STANDARD optimization.
GSBPUSH13 push particles with magnetic field, quadratic interpolation,
LOOKAHEAD optimization.
GPUSH1L push particles with magnetic field, linear interpolation,
STANDARD optimization.
GSBPUSH13L push particles with magnetic field, linear interpolation,
LOOKAHEAD optimization.
RETARD1 retard particle position a half time-step.
dpush1lib.f contains procedures to process particles with
darwin electric and magnetic fields:
GMJPOST1 deposits momentum flux, quadratic interpolation, STANDARD
optimization.
GSMJPOST1 deposits momentum flux, quadratic interpolation, LOOKAHEAD
optimization.
GDCJPOST1 deposits momentum flux, acceleration density and current
density, quadratic interpolation, STANDARD optimization.
GSDCJPOST1 deposits momentum flux, acceleration density and current
density, quadratic interpolation, LOOKAHEAD optimization.
GMJPOST1L deposits momentum flux, linear interpolation, STANDARD
optimization.
GSMJPOST1L deposits momentum flux, linear interpolation, LOOKAHEAD
optimization.
GDCJPOST1L deposits momentum flux, acceleration density and current
density, linear interpolation, STANDARD optimization.
GSDCJPOST1L deposits momentum flux, acceleration density and current
density, linear interpolation, LOOKAHEAD optimization.
!----------------------------------------------------------------------! * * * periodic 1d electromagnetic particle simulation kernel code * *
! this is a simple 1d skeleton particle-in-cell code designed for
! exploring new computer architectures. it contains the critical pieces
! needed for depositing charge and current, advancing particles, and
! solving the fields. the code moves only electrons, with periodic
! electromagnetic forces obtained by solving maxwell's equation with
! fast fourier transforms.
! written by viktor k. decyk, ucla
! Fortran 90 for Macintosh G3
! copyright 1999, regents of the university of california
! update: july 14, 2011
! modules below are included (ken)
! we need to add nxb, nmvf
program bbeps1
use init1d
initialize particle position and velocity
use bpush1d
use dpush1d
use push1d
 attention
use fft1d
use field1d
use diag1d produce plots
implicit none
! idimp = dimension of phase space = 4
! nmv = number of segments in v for velocity distribution
integer :: idimp = 4, nmv = 40, ipbc = 1
! default unit numbers
integer :: iuin = 8, iuot = 18, iudm = 19, iup = 11, iua = 15
integer :: iue = 26
integer :: np, npx1, nx, nxh, nxe, nxeh, nx1
integer :: nloop, itime, itime0, ntime, ltime, isign, irc
integer :: it, itw
real :: zero = 0.0, time = 0.0, tloop = 0.0
real :: tpush = 0.0, tdpost = 0.0, tdjpost = 0.0, tsort = 0.0
real :: tfft = 0.0, totpush = 0.0, ts = 0.0
real :: qbme, affp, dth, qi0, omt, q2m0, wp0
real :: we, wf, wm, wef, wke, ws
real, dimension(:,:), pointer :: part
real, dimension(:), pointer :: qe, fxe
real, dimension(:,:), pointer :: cu, amu, fxyze, byze
complex, dimension(:,:), pointer :: eyz, byz
complex, dimension(:), pointer :: ffc, ffe
integer, dimension(:), pointer :: mixup
complex, dimension(:), pointer :: sct
real, dimension(:), pointer :: pt
integer, dimension(:), pointer :: ip, npic
real, dimension(:), pointer :: sfield
complex, dimension(:), pointer :: pott
real, dimension(:,:), pointer :: vfield
complex, dimension(:,:), pointer :: vpott, vpotr
real, dimension(:,:), pointer :: fv, fvm
real, dimension(:,:), pointer :: wt
character(len=10) :: cdrun
character(len=32) :: fname
991 format (' T = ',i7)
992 format (' field, kinetic, total energies = ',3e14.7)
993 format (' electric(l,t), magnetic energies = ',3e14.7)
! read namelist
iuin = get_funit(iuin)
open(unit=iuin,file='input1',form='formatted',status='old')
read (iuin,input1) read parameters in input1
! override input data
idcode = 2
psolve = 1
ndim = 2
! create string from idrun
write (cdrun,'(i10)') idrun
cdrun = adjustl(cdrun)
! text output file
iuot = get_funit(iuot)
fname = 'output1.'//cdrun
open(unit=iuot,file=trim(fname),form='formatted',status='replace')
! np = total number of electrons in simulation
np = npx + npxb; npx1 = npx + 1
npx: ambient, npxb: beam
nx = 2**indx; nxh = nx/2
nxe = nx + 4
!
ax = .866025
if (inorder==LINEAR) then
!
ax = .912871
nxe = nx + 2
endif
nxeh = nxe/2
! dimension for index and sorting arrays
nx1 = nx + 1
! nloop = number of time steps in simulation
nloop = tend/dt + .0001
! part(1,n) = position x of particle n
! part(2,n) = velocity vx of particle n initialized by subroutine DISTR1H
! part(3,n) = velocity vy of particle n
! part(4,n) = velocity vz of particle n
allocate(part(idimp,np))
set the dimension
! in real space, qe(j) = charge density at grid point j
! in real space, fxe(j) = longitudinal force/charge at grid point j,
! that is, fxe is the convolution of the longitudinal electric field
! over the particle shape
allocate(qe(nxe),fxe(nxe))
! in real space, fxyze(i,j) = i component of force/charge at grid (j)
! that is, fxyze are the convolutions of the electric field
! over the particle shape
allocate(fxyze(3,nxe))
! cu(i,j) = i component of current at grid (j).
! byze(i,j) = i component of magnetic field at grid (j).
! byze is the convolution of the magnetic field over the particle shape
allocate(cu(2,nxe),byze(2,nxe))
! in fourier space, exyz = transverse electric field
! in fourier space, bxyz = magnetic field
allocate(eyz(2,nxeh),byz(2,nxeh))
! ffc = form factor array for poisson solver
allocate(ffc(nxh))
! mixup = array of bit reversed addresses for fft
! sct = sine/cosine table for fft
allocate(mixup(nxh),sct(nxh))
!
! open graphics device
irc = open_graphs(nplot)
enable to use GKS graphic package
! initialize timer
call wtimer(time,ltime,-1)
! initialize constants
itime0 = 0
itime = itime0
ntime = itime + itime0
qbme = qme
affp = real(nx)/real(np)
omt = sqrt(omy*omy + omz*omz)
q2m0 = qbme*qme*real(np)/real(nx)
dth = 0.0
! debug
! dth = .5*dt
! end debug
wp0 = q2m0*affp plasma frequency
! set initial time
t0 = dt*real(itime0)
! set default diagnostic file names
if (ntp > 0) fpname = 'potk1.'//cdrun
if (nta > 0) faname = 'vpotk1.'//cdrun
if (nte > 0) fename = 'vpotrk1.'//cdrun
! energy diagnostics
if (ntw > 0) then
allocate(wt((nloop-1)/ntw-(itime0/ntw)+1,7))
itw = 0
endif
! initialize electromagnetic fields
byze = 0.0
if (omt > 0.0) then
call baddext(byze,omy,omz,nx,inorder)
call cguard(byze,nx,inorder)
endif
byz = cmplx(0.0,0.0)
eyz = cmplx(0.0,0.0)
cu = 0.0
! prepare fft tables
call fft_init(mixup,sct,indx)
! calculate form factors
call pois_init(ffc,ax,affp,nx)
! initialize density profile and velocity distribution
! background electrons
if (npx > 0) call distr(part,1,npx,vtx,vty,vtz,vx0,vy0,vz0,npx,nx,
&ipbc)
! beam electrons
if (npxb > 0) call distr(part,npx1,npxb,vtdx,vtdy,vtdz,vdx,vdy,vdz&
&,npxb,nx,ipbc)
Remark! in init1mod.f distr is assined by `distr1h’
! distr => idistrh1 initializes x and vx,vy,vz co-ordinates for
! magnetized 1-2/2d codes.
! calls DISTR1H (see the next page)
! initialize charge density to background
qi0 = -qme/affp
! fix guiding centers for electrons
if (omt > 0.0) call distr(part,byze,np,qbme,nx,ipbc,inorder)
! retard electron positions to deposit current
! call retard(part,np,dth,nx)
! sorting arrays
if (sortime > 0) allocate(pt(np),ip(np),npic(nx1))
! initialize diagnostics
! diagnostic metafile
iudm = get_funit(iudm)
! velocity diagnostic
if (ntv > 0) then
allocate(fv(2*nmv+2,3),fvm(3,3))
fv(1,:) = 8.*max(vtx,vty,vtz)
endif
! potential diagnostic
if (ntp > 0) then
allocate(sfield(nxe))
if (modesxp > nxh) modesxp = nxh
allocate(pott(modesxp))
! open output file
if (nprec==0) then
nprec = -1; iup = get_funit(iup)
call bfopen(pott,modesxp,iup,nprec,trim(fpname))
endif
endif
! vector potential or electromagnetic diagnostic
if ((nta > 0) .or. (nte > 0)) then
allocate(vfield(2,nxe))
vfield = 0.0
endif
! vector potential diagnostic
if (nta > 0) then
if (modesxa > nxh) modesxa = nxh
allocate(vpott(2,modesxa))
! open output file
if (narec==0) then
narec = -1; iua = get_funit(iua)
call bfopen(vpott,modesxa,iua,narec,trim(faname))
endif
endif
! electromagnetic diagnostic
if (nte > 0) then
if (modesxe > nxh) modesxe = nxh
allocate(vpotr(2,modesxe))
! open output file
if (nerec==0) then
nerec = -1; iue = get_funit(iue)
call bfopen(vpotr,modesxe,iue,nerec,trim(fename))
endif
endif
! record time
call wtimer(time,ltime)
write (iuot,*) 'initialization wall clock time = ', time, 'sec'
!
! * * * start main iteration loop * * *  attention
!
500 if (nloop <= ntime) go to 2000
write (iuot,991) ntime
!
! prepare electromagnetic diagnostic
if (nte > 0) then
it = ntime/nte
if (ntime==nte*it) vfield = cu
endif
! initialize current density to background
call sguard(cu,zero,zero,nx,inorder)
! deposit electron current
call djpost(part,cu,np,qme,dth,tdjpost,nx,ipbc,inorder,djopt)
! initialize charge density to background
call sguard(qe,qi0,nx,inorder)
! deposit electron charge
call dpost(part,qe,np,qme,tdpost,inorder,dopt)
! add guard cells for current
call aguard(cu,nx,inorder)
! add guard cells
call aguard(qe,nx,inorder)
! velocity diagnostic
if (ntv > 0) then for example ntv=5 in input1.whistler
it = ntime/ntv
if (ntime==ntv*it) then
! calculate paticle distribution function and moments
call vdist(part,fv,fvm,np,nmv)
! display velocity distributions
call displayfv(fv,fvm,' ELECTRON',ntime,nmv,2,irc)
if (irc==1) go to 2000
endif
endif
! phase velocity diagnostic by Victor
! nmv = number of segments in v for velocity distribution
! integer :: idimp = 4, nmv = 40, ipbc = 1
! phase space diagnostic
if (nts > 0) then
for example ntv=5 in input1.whistler
it = ntime/nts
if (ntime==nts*it) then
! calculate phase space distribution function and moments
call psdist(part,fps,fpsm,nx,np,nmv)
! display phase space distributions
call displayfps(fps,fpsm,' ELECTRON',ntime,nmv,999,2,irc)
if (irc==1) go to 2000
endif
endif
!--------- for comparison ------!for comparison
!
call vdist(part,fv,fvm,np,nmv)
! display velocity distributions
call displayfv(fv,fvm,' ELECTRON',ntime,nmv,2,irc)
! transform charge to fourier space
isign = -1
call fft(qe,isign,mixup,sct,tfft,indx,inorder)
! potential diagnostic
if (ntp > 0) then
it = ntime/ntp
if (ntime==ntp*it) then
! calculate potential in fourier space
isign = 1
call pois(qe,sfield,isign,ffc,ws,nx,inorder)
! store selected fourier modes
call gtmodes(sfield,pott,nx,modesxp,inorder)
! write diagnostic output
call writebf(pott,modesxp,iup,nprec,order=LINEAR)
! transform potential to real space
call fft(sfield,isign,mixup,sct,tfft,indx,inorder)
call cguard(sfield,nx,inorder)
! display potential
call displays(sfield,' POTENTIAL',ntime,999,0,nx,irc,inorder&
&)
if (irc==1) go to 2000
endif
endif
! transform current to fourier space
isign = -1
call fft(cu,isign,mixup,sct,tfft,indx,inorder)
! electromagnetic diagnostic
if (nte > 0) then
it = ntime/nte
if (ntime==nte*it) then
! calculate averaged radiative vector potential
vfield = 0.5*(vfield + cu)
call avrpot(vfield,byz,ffc,ci,nx,inorder)
! store selected fourier modes
call gtmodes(vfield,vpotr,nx,modesxe,inorder)
! write diagnostic output
call writebf(vpotr,modesxe,iue,nerec,order=LINEAR)
! transform radiative vector potential to real space
isign = 1
call fft(vfield,isign,mixup,sct,tfft,indx,inorder)
call cguard(vfield,nx,inorder)
! display radiative vector potential
call displayv(vfield,' RADIATIVE VPOTENTIAL',ntime,999,0,1, &
&nx,irc,inorder)
if (irc==1) go to 2000
endif
endif
! calculate electromagnetic fields in fourier space
if (ntime==0) then
! calculate initial darwin magnetic field
call ibpois(cu,byz,ffc,ci,wm,nx,inorder)
wf = 0.
! calculate initial darwin electric field
allocate(amu(2,nxe),ffe(nxeh))
! deposit momentum flux
call sguard(amu,zero,zero,nx,inorder)
call dmjpost(part,amu,np,qme,ts,inorder,djopt)
call aguard(amu,nx,inorder)
! solve for darwin electric field
isign = -1
call fft(amu,isign,mixup,sct,tfft,indx,inorder)
!
byze = cu
call dcuperp(byze,amu,nx,inorder)
call epois_init(ffe,ax,affp,wp0,ci,nx)
call iepois(byze,eyz,ffe,ci,wf,nx,inorder)
deallocate(amu,ffe)
dth = .5*dt
! calculate electromagnetic fields
else
call maxwel(eyz,byz,cu,ffc,ci,dt,wf,wm,nx,inorder)
endif
! vector potential diagnostic
if (nta > 0) then
it = ntime/nta
if (ntime==nta*it) then
! calculate vector potential in fourier space
call avpot(byz,vfield,nx,inorder)
! store selected fourier modes
call gtmodes(vfield,vpott,nx,modesxa,inorder)
! write diagnostic output
call writebf(vpott,modesxa,iua,narec,order=LINEAR)
! transform vector potential to real space
isign = 1
call fft(vfield,isign,mixup,sct,tfft,indx,inorder)
call cguard(vfield,nx,inorder)
! display vector potential
call displayv(vfield,' VECTOR POTENTIAL',ntime,999,0,1,nx, &
&irc,inorder)
if (irc==1) go to 2000
endif
endif
! calculate longitudinal electric field in fourier space
isign = -1
call pois(qe,fxe,isign,ffc,we,nx,inorder)
! add longitudinal and transverse electric fields
call emfield(fxyze,fxe,eyz,ffc,nx,inorder)
! copy magnetic field
call emfield(byze,byz,ffc,nx,inorder)
! transform force/charge to real space
isign = 1
call fft(fxyze,isign,mixup,sct,tfft,indx,inorder)
call cguard(fxyze,nx,inorder)
! transform magnetic field to real space
isign = 1
call fft(byze,isign,mixup,sct,tfft,indx,inorder)
! add external magnetic field
if (omt > 0.0) call baddext(byze,omy,omz,nx,inorder)
call cguard(byze,nx,inorder)
! push particles
 attention
wke = 0.
call push3(part,fxyze,byze,omx,np,qbme,dt,dth,wke,tpush,nx,ipbc, &
&inorder,popt)
! sort electrons
if (sortime > 0) then
if (mod(ntime,sortime)==0) then
call sortp(part,pt,ip,np,npic,tsort,inorder)
endif
endif
! energy diagnostic
if (ntw > 0) then
it = itime/ntw
if (itime==ntw*it) then
wef = we + wf + wm
ws = wef + wke
write (iuot,992) wef, wke, ws
write (iuot,993) we, wf, wm
itw = itw + 1
wt(itw,:) = (/wef,wke,zero,ws,we,wf,wm/)
endif
endif
itime = itime + 1
ntime = itime + itime0
 attention
call wtimer(tloop,ltime)
time = time + tloop
go to 500
2000 continue
!
! * * * end main iteration loop * * *
!
! energy diagnostic
if (ntw > 0) then
ts = t0 + dt*real(ntw)*(itime0-(itime0/ntw)*ntw)
call reset_graphs
call displayw(wt,ts,dt*real(ntw),itw,irc)
endif
! accumulate timings
write (iuot,*) 'electromagnetic code bbeps1'
write (iuot,*) 'main wall clock time = ', time, 'sec'
totpush = tpush + tdpost + tdjpost
write (iuot,*) 'electron push time = ', tpush, 'sec'
write (iuot,*) 'electron charge deposit time = ', tdpost, 'sec'
write (iuot,*) 'electron current deposit time = ', tdjpost, 'sec'
write (iuot,*) 'total electron push time = ', totpush, 'sec'
write (iuot,*) 'electron sort time = ', tsort
totpush = totpush + tsort
write (iuot,*) 'total electron time = ', totpush, 'sec'
write (iuot,*) 'total fft time=', tfft, 'sec'
time = time - (totpush + tfft)
write (iuot,*) 'other time=', time, 'sec'
! write final diagnostic metafile
fname = 'diag1.'//cdrun
open(unit=iudm,file=trim(fname),form='formatted',status='replace')
! potential diagnostics
if (ntp > 0) then
nprec = nprec - 1
ceng = affp
write (iudm,pot1d)
endif
! vector potential diagnostics
if (nta > 0) then
narec = narec - 1
ceng = affp
write (iudm,vpot1d)
endif
! electromagnetic diagnostics
if (nte > 0) then
nerec = nerec - 1
ceng = affp
write (iudm,em1d)
endif
! write out input file
write (iudm,input1)
write (iuot,*) ' * * * q.e.d. * * *'
close(unit=iudm)
close(unit=iuot)
! close graphics device
call close_graphs
stop
end program bbeps1