Skip to content

Commit

Permalink
Merge pull request #8 from ExCALIBUR-NEPTUNE/substepping
Browse files Browse the repository at this point in the history
Substepping
  • Loading branch information
benmcmillanwarwick authored Feb 24, 2021
2 parents c1289bf + afbe20e commit 5261eb5
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 22 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ jobs:
export PYTHONPATH=$PYTHONPATH:$(pwd)
python3 minepoch_py/test.py
- name: Test-substep
run: |
cp Data/two_stream_substep.deck Data/input.deck
./bin/epoch3d
export PYTHONPATH=$PYTHONPATH:$(pwd)
python3 minepoch_py/test.py
- name: Test-Parallel
run: |
cp Data/two_stream.deck Data/input.deck
Expand Down
5 changes: 5 additions & 0 deletions Data/two_stream_substep.deck
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
&CONTROL
problem = 'two_stream',
stdout_frequency = 25,
global_substeps = 2,
/
2 changes: 1 addition & 1 deletion src/deck/deck.f90
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ SUBROUTINE read_deck
allow_cpu_reduce, timer_collect, use_balance, use_random_seed, &
npart_global, nsteps, t_end, dt_multiplier, dlb_threshold, &
stdout_frequency, particle_push_start_time, n_species, &
fixed_fields
fixed_fields, global_substeps

IF (first) THEN
! Set the default problem here
Expand Down
1 change: 1 addition & 0 deletions src/housekeeping/setup.F90
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ SUBROUTINE setup_single_species(species)
species%count_update_step = 0
species%immobile = .FALSE.
species%is_driftkinetic = .FALSE.
species%nsubstep = global_substeps
NULLIFY(species%next)
NULLIFY(species%prev)
NULLIFY(species%ext_temp_x_min)
Expand Down
61 changes: 40 additions & 21 deletions src/particles.F90
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ MODULE particles
END TYPE fields_eval_tmps

! Some numerical factors needed for various particle-fields routines.
REAL(num) :: idtyz, idtxz, idtxy
REAL(num) :: i_yz, i_xz, i_xy ! can't store these as particle steps may vary
REAL(num) :: idx, idy, idz


Expand Down Expand Up @@ -129,7 +129,7 @@ SUBROUTINE push_particles
! Particle weighting multiplication factor
REAL(num) :: cf2
REAL(num), PARAMETER :: fac = (1.0_num / 24.0_num)**c_ndims

INTEGER :: isubstep
TYPE(particle), POINTER :: current, next
TYPE(particle_species), POINTER :: species, next_species

Expand All @@ -156,9 +156,9 @@ SUBROUTINE push_particles
dtfac = 0.5_num * dt * fac
third = 1.0_num / 3.0_num

idtyz = idt * idy * idz * fac
idtxz = idt * idx * idz * fac
idtxy = idt * idx * idy * fac
i_yz = idy * idz * fac
i_xz = idx * idz * fac
i_xy = idx * idy * fac

next_species => species_list
DO ispecies = 1, n_species
Expand All @@ -170,7 +170,9 @@ SUBROUTINE push_particles
IF (species%is_driftkinetic) THEN
CALL push_particles_dk0(species)
ELSE
CALL push_particles_lorentz_split
DO isubstep=1,species%nsubstep
CALL push_particles_lorentz_split(dt/species%nsubstep)
END DO
END IF

ENDDO
Expand All @@ -181,6 +183,10 @@ SUBROUTINE push_particles
contains

SUBROUTINE push_particles_lorentz
REAL(num) :: idtyz, idtxz, idtxy
idtyz = idt * idy * idz * fac
idtxz = idt * idx * idz * fac
idtxy = idt * idx * idy * fac

current => species%attached_list%head

Expand Down Expand Up @@ -434,18 +440,27 @@ SUBROUTINE push_particles_lorentz

END SUBROUTINE push_particles_lorentz

SUBROUTINE push_particles_lorentz_split
SUBROUTINE push_particles_lorentz_split(dt_sub)
REAL(num), intent(IN) :: dt_sub
TYPE(fields_eval_tmps) :: st_half
REAL(num), DIMENSION(3) :: part_pos_t1p5, pos_half, Bvec, Evec
REAL(num) :: weight_back
REAL(num) :: weight_back, part_qfac
REAL(num), DIMENSION(3) :: force, part_v
REAL(num) :: idt, dto2, dtco2, idt0
REAL(num) :: dtfac

idt = 1.0_num / dt_sub
idt0= 1.0_num / dt
dto2 = dt_sub / 2.0_num
dtco2 = c * dto2
dtfac = 0.5_num * dt_sub * fac

IF (species%solve_fluid) CALL initstep_fluid

current => species%attached_list%head

IF (.NOT. particles_uniformly_distributed) THEN
part_weight = species%weight
part_weight = species%weight
ENDIF

!DEC$ VECTOR ALWAYS
Expand All @@ -455,7 +470,8 @@ SUBROUTINE push_particles_lorentz_split
part_weight = current%weight
ENDIF

part_q = current%charge
part_q = current%charge
part_qfac = part_q * idt0
part_mc = c * current%mass
ipart_mc = 1.0_num / part_mc
cmratio = part_q * dtfac * ipart_mc
Expand Down Expand Up @@ -525,9 +541,6 @@ SUBROUTINE push_particles_lorentz_split
! calculated current.
IF(species%use_deltaf) THEN
weight_back = current%pvol * f0(species, current, current%mass)
fcx = idtyz * (part_weight - weight_back)
fcy = idtxz * (part_weight - weight_back)
fcz = idtxy * (part_weight - weight_back)
END IF

! Now advance to t+1.5dt to calculate current. This is detailed in
Expand All @@ -538,7 +551,7 @@ SUBROUTINE push_particles_lorentz_split
!Current deposition uses position at t+0.5dt and t+1.5dt, particle
!assumed to travel in direct line between these locations. Second order
!in time for evaluation of current at t+dt
CALL current_deposition_store(st_half,part_pos_t1p5,(part_weight*part_q),.false.)
CALL current_deposition_store(st_half,part_pos_t1p5,(part_weight*part_qfac),.false.)

if (species%solve_fluid) then
part_v = (/part_ux, part_uy,part_uz/)
Expand Down Expand Up @@ -575,8 +588,10 @@ SUBROUTINE push_particles_dk0(species)

REAL(num) :: part_mu, part_u, bdotBmag
REAL(num) :: part_u_0,part_u_h, dudt
REAL(num) :: part_q, part_weight
REAL(num) :: part_q, part_weight, part_qfac
INTEGER(i8) :: ipart
REAL(num) :: idt
idt = 1.0_num/dt


current => species%attached_list%head
Expand All @@ -593,6 +608,7 @@ SUBROUTINE push_particles_dk0(species)
ENDIF

part_q = current%charge
part_qfac= part_q * idt
! Do nonrelativistic drift-kinetics for the moment.
part_u = current%part_p(1)
part_mu = current%part_p(2)
Expand Down Expand Up @@ -620,7 +636,7 @@ SUBROUTINE push_particles_dk0(species)
!Do current deposition using lowest order current. (current at t_{N+1})
!Before we apply this current, E+B need to be stored in a temporary;
!this is the lowest order current.
CALL current_deposition_store(st_0,pos_0,(part_weight*part_q),.true.)
CALL current_deposition_store(st_0,pos_0,(part_weight*part_qfac),.true.)


current => next
Expand All @@ -642,9 +658,11 @@ SUBROUTINE push_particles_dk1(species)

REAL(num) :: part_mu, part_u, bdotBmag
REAL(num) :: part_u_h, dudt_1
REAL(num) :: part_q, part_weight
REAL(num) :: part_q, part_weight, part_qfac
INTEGER(i8) :: ipart

REAL(num) :: idt
idt = 1.0_num/dt

current => species%attached_list%head

IF (.NOT. particles_uniformly_distributed) THEN
Expand All @@ -659,6 +677,7 @@ SUBROUTINE push_particles_dk1(species)
ENDIF

part_q = current%charge
part_qfac= part_q * idt
! Do nonrelativistic drift-kinetics for the moment.
part_u = current%part_p(1)
part_mu = current%part_p(2)
Expand Down Expand Up @@ -922,9 +941,9 @@ SUBROUTINE current_deposition_store(st,pos,chargeweight,drift_switch)
zmin = sf_min + (dcellz - 1) / 2
zmax = sf_max + (dcellz + 1) / 2

fjx = idtyz * chargeweight
fjy = idtxz * chargeweight
fjz = idtxy * chargeweight
fjx = i_yz * chargeweight
fjy = i_xz * chargeweight
fjz = i_xy * chargeweight

jzh = 0.0_num
DO iz = zmin, zmax
Expand Down
3 changes: 3 additions & 0 deletions src/shared_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ MODULE shared_data
LOGICAL :: is_driftkinetic
LOGICAL :: use_deltaf = .FALSE.
LOGICAL :: solve_fluid = .FALSE.
INTEGER :: nsubstep = 1

! Injection of particles
REAL(num) :: npart_per_cell
Expand Down Expand Up @@ -393,6 +394,8 @@ MODULE shared_data
LOGICAL, DIMENSION(c_dir_x:c_dir_z,0:c_stagger_max) :: stagger
INTEGER(i8) :: push_per_field = 5

INTEGER :: global_substeps = 1

! Absorption diagnostic
REAL(num) :: laser_inject_local = 0.0_num
REAL(num) :: laser_absorb_local = 0.0_num
Expand Down

0 comments on commit 5261eb5

Please sign in to comment.