One of the two computer models used in the Numerical Turbulent Transport Project is a gyrokinetic code, which is a reduced particle-in-cell (PIC) code that follows the trajectories of guiding centers of particles, neglecting the rapid rotation around the magnetic field. Particle-in-Cell codes integrate the trajectories of many particles subject to electromagnetic forces, both external and self-generated. These forces are calculated from a set of field equations (usually Maxwell's equations or a subset) on a grid. The particle's coordinates are described by continuous variables. The source terms in Maxwell's equations (charge and/or current density) are calculated on a grid by inverse interpolation. After the field equations have been solved on the grid, the forces on the particles are found by interpolation from the grid.
dimension part(idimp,np), q(nx), fx(nx)
data qme, dt /-1.,.2/
call push1 (part,fx,qtme,dt,wke,idimp,np,nx)
call dpost1 (part,q,qme,np,idimp,nx)
where an array of particles (part), charge density field (q), electric field (fx), and various constants describing the particles, are used in advancing particles (push1) and depositing charge (dpost).
Even in this simple example, the code would be clearer and easier to manipulate if the particle and field information were encapsulated into logically related units:
USE plasma_module
TYPE (species) :: electrons, ions
TYPE (fields) :: charge_density, electric_field
REAL :: dt = .2
call plasma_push1 (electrons, electric_field, dt)
call plasma_dpost1 (electrons, charge_density)
In this Fortran 90 example the collection of electrons, with their properties, are localized to the definition of the species class. The parameters have been simplified, they represent problem related abstractions and many details of the implementation have been information-hidden. These are important concepts in object-oriented programming and design. The paper:
MODULE species_class
USE species_descriptor_class
TYPE species
PRIVATE
TYPE (species_descriptor) :: descriptor
REAL, DIMENSION(:,:), POINTER :: coordinates
END TYPE species
INTERFACE new
MODULE PROCEDURE species_init
END INTERFACE
CONTAINS
! Initialization of particle species
SUBROUTINE species_init(this,species_args,idimp,nop)
TYPE (species), INTENT(inout) :: this
TYPE (species_descriptor), INTENT(in) :: species_args
INTEGER, INTENT(in) :: idimp,nop
! code details omitted...
END SUBROUTINE species_init
! Advance species particles
SUBROUTINE push1 (this,fx,dt)
TYPE (species), INTENT(inout) :: this
REAL, DIMENSION (:), INTENT(in) :: fx
REAL, INTENT(in) :: dt
! code details omitted...
END SUBROUTINE push1
END MODULE species_class
The species object can be created and initialized by calling the overloaded function new. The species is defined with two components, a descriptor specifying species properties and a pointer to a dynamically allocated two-dimensional array of reals. The use statement allows data and functions from the species_descriptor_class to be used in building the species_class. Although inheritance is not natively supported in Fortran 90 some forms can be constructed, including composition inheritance and some forms of sub-typing inheritance.