-- -- Patricia Fasel -- Los Alamos National Laboratory -- 1990 August -- -- Copyright, 1990, The Regents of the University of California. -- This software was produced under a U.S. Government contract (W-7405-ENG-36) -- by the Los Alamos National Laboratory, which is operated by the University -- of California for the U.S. Department of Energy. The U.S. Government is -- licensed to use, reproduce, and distribute this software. Permission is -- granted to the public to copy and use this software without charge, provided -- that this notice and any statement of authorship are reproduced on all -- copies. Neither the Government nor the University makes any warranty, -- express or implied, or assumes any liability for the use of this software. module Pic (pic) where import PicType import Consts import Utils import ChargeDensity import Potential import ElecField import PushParticle import Array--1.3 -- PIC, particle in cell, a basic electrodynamics application -- Given an initial configuration of particles, follow how they move under the -- electric field they induce -- Torroidal boundary conditions are assumed, so wrap in both dimensions -- given nPart the number of particles considered -- given nStep the number of time steps to put the particles through -- given nCell the dimension of the matrix of cells pic :: Indx -> [Char] pic nPart = show dt' where partHeap = initParticles nPart dt = 0.001 phi = initPhi partHeap (dt', phi', partHeap') = timeStep partHeap phi dt 0 nStep -- during each time step perform the following calculations -- calculate the charge density (rho), using position of particles -- calculate the new potential (phi), by solving Laplace's equation -- del2(phi) = rho , using rho and phi of last timestep -- calculate the electric field, E = del(phi), using phi of this time step -- push each particle some distance and velocity using electric field, for a -- timestep deltaTime, small enough that no particle moves more than the -- width of a cell -- an NxN mesh is used to represent value of x and y in the interval [0,1] -- so delta_x = delta_y = 1/n -- -- phi ((0,0), (n,n)) = electrostatic potential at grid point (i,j) -- rho ((0,0), (n,n)) = charge density at grid point (i,j) -- xElec ((0,0), (n,n)) = x component of electric field between (i,j) (i,j+1) -- yElec ((0,0), (n,n)) = y component of electric field between (i,j) (i+1,j) -- [xyPos] = (x,y) coordinate of particle displacement in units of delta_x -- [xyVel] = (x,y) coordinate of particle velocity in units of delta_x/sec timeStep :: ParticleHeap -> Phi -> Value -> Indx -> Indx -> (Value, Phi, ParticleHeap) timeStep partHeap phi dt depth step | step == 0 = (dt, phi, partHeap) | otherwise = timeStep partHeap' phi' dt' depth' (step-1) where rho = chargeDensity partHeap phi' = potential phi rho depth 1 xyElec = elecField phi' (maxVel, maxAcc, partHeap') =pushParticle partHeap xyElec dt 0 0 dt' = (sqrt (maxVel*maxVel + 2*maxAcc) - maxVel) / maxAcc depth' = (depth+1) `rem` maxDepth initParticles :: Indx -> ParticleHeap initParticles nPart = (xyPos, xyVel) where nCellD = fromIntegral nCell nPartD = fromIntegral (nPart+1) xyPos = [(xPos,yPos) | i <- [1..nPart], xPos <- [nCellD * genRand (fromIntegral i/ nPartD)], yPos <- [nCellD * genRand xPos]] xyVel = [(0.0,0.0) | i <- [1..nPart]] initPhi :: ParticleHeap -> Phi initPhi partHeap = potential phi0 rho maxDepth 1 where rho = chargeDensity partHeap phi0 = array ((0,0), (n,n)) [((i,j), 0.0) | i <- [0..n], j <- [0..n]] n = nCell-1