9 #include "sll_assert.h"
10 #include "sll_memory.h"
11 #include "sll_working_precision.h"
55 sll_int32 :: spline_degree
60 sll_real64 :: cell_integrals_0(4)
61 sll_real64 :: cell_integrals_1(3)
64 sll_real64,
pointer :: efield_dofs(:,:)
65 sll_real64,
pointer :: bfield_dofs(:)
66 sll_real64,
allocatable :: j_dofs(:,:)
67 sll_real64,
allocatable :: j_dofs_local(:,:)
68 sll_int32 :: n_species
70 logical :: electrostatic = .false.
72 logical :: jmean = .false.
73 sll_real64,
allocatable :: bfield_old(:)
81 sll_int32 :: n_sub_iter
106 sll_real64,
intent(in) :: dt
107 sll_int32,
intent(in) :: number_steps
111 if(self%electrostatic)
then
112 do i_step = 1, number_steps
116 do i_step = 1, number_steps
126 sll_real64,
intent(in) :: dt
127 sll_int32,
intent(in) :: number_steps
130 if(self%electrostatic)
then
131 do i_step = 1, number_steps
135 do i_step = 1,number_steps
146 sll_real64,
intent(in) :: dt
147 sll_int32,
intent(in) :: number_steps
151 if(self%electrostatic)
then
152 do i_step = 1, number_steps
156 do i_step = 1,number_steps
165 sll_real64,
intent(in) :: dt
167 sll_int32 :: i_sp, i_part
168 sll_real64 :: bfield, efield(2)
171 sll_real64 :: wi(1), vi(3), xi(3), wp(3), x_new(3)
172 sll_int32 :: n_cells, iter
174 dtau = dt/real(self%n_sub_iter, f64)
176 n_cells = self%kernel_smoother_0%n_dofs
179 self%bfield_old = self%bfield_dofs
180 call self%maxwell_solver%compute_B_from_E( &
181 dt, self%efield_dofs(:,2), self%bfield_dofs)
184 self%j_dofs_local = 0.0_f64
186 do i_sp = 1,self%n_species
187 qoverm = self%particle_group%group(i_sp)%species%q_over_m();
188 do i_part=1,self%particle_group%group(i_sp)%n_particles
190 xi = self%particle_group%group(i_sp)%get_x(i_part)
191 vi = self%particle_group%group(i_sp)%get_v(i_part)
194 wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)
198 call self%kernel_smoother_1%evaluate &
199 (xi(1), self%bfield_old, bfield)
200 vi(1) = vi(1) + dtau*qoverm*vi(2)*bfield
202 call self%kernel_smoother_1%evaluate &
203 (xi(1), self%efield_dofs(:,1), efield(1))
204 vi(1) = vi(1) + dt* qoverm * efield(1)
206 call self%kernel_smoother_0%add_charge(xi(1:1), wi(1)*vi(2)*dtau, self%j_dofs_local(:,2))
208 if (self%particle_group%group(i_sp)%n_weights == 3)
then
210 wp = self%particle_group%group(i_sp)%get_weights(i_part)
211 wp(3) = self%control_variate%cv(i_sp)%update_df_weight( xi(1:1), vi(1:2), 0.0_f64, wp(1), wp(2))
212 call self%particle_group%group(i_sp)%set_weights(i_part, wp)
215 wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)
219 x_new = xi + dtau * vi
221 call self%kernel_smoother_1%add_current_update_v( xi, x_new, wi(1), qoverm, &
222 self%bfield_dofs, vi, self%j_dofs_local(:,1))
227 call self%kernel_smoother_0%evaluate &
228 (xi(1), self%efield_dofs(:,2), efield(2))
229 vi(2) = vi(2) + dt* qoverm * efield(2)
231 x_new(1) = modulo(x_new(1), self%Lx)
233 if (self%particle_group%group(i_sp)%n_weights == 3)
then
235 wp = self%particle_group%group(i_sp)%get_weights(i_part)
236 wp(3) = self%control_variate%cv(i_sp)%update_df_weight( x_new(1:1), vi(1:2), 0.0_f64, wp(1), wp(2))
237 call self%particle_group%group(i_sp)%set_weights(i_part, wp)
240 do iter = 2, self%n_sub_iter
244 call self%kernel_smoother_1%evaluate &
245 (xi(1), self%bfield_dofs, bfield)
246 vi(1) = vi(1) + dtau*qoverm*vi(2)*bfield
248 call self%kernel_smoother_0%add_charge(xi(1:1), wi(1)*vi(2)*dtau, self%j_dofs_local(:,2))
250 if (self%particle_group%group(i_sp)%n_weights == 3)
then
252 wp = self%particle_group%group(i_sp)%get_weights(i_part)
253 wp(3) = self%control_variate%cv(i_sp)%update_df_weight( xi(1:1), vi(1:2), 0.0_f64, wp(1), wp(2))
254 call self%particle_group%group(i_sp)%set_weights(i_part, wp)
257 wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)
261 x_new = xi + dtau * vi
263 call self%kernel_smoother_1%add_current_update_v( xi, x_new, wi(1), qoverm, &
264 self%bfield_dofs, vi, self%j_dofs_local(:,1))
268 x_new(1) = modulo(x_new(1), self%Lx)
270 if (self%particle_group%group(i_sp)%n_weights == 3)
then
272 wp = self%particle_group%group(i_sp)%get_weights(i_part)
273 wp(3) = self%control_variate%cv(i_sp)%update_df_weight( x_new(1:1), vi(1:2), 0.0_f64, wp(1), wp(2))
274 call self%particle_group%group(i_sp)%set_weights(i_part, wp)
278 call self%particle_group%group(i_sp)%set_x(i_part, x_new)
279 call self%particle_group%group(i_sp)%set_v(i_part, vi)
284 self%j_dofs = 0.0_f64
287 n_cells, mpi_sum, self%j_dofs(:,1))
289 n_cells, mpi_sum, self%j_dofs(:,2))
290 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,1), 1, self%efield_dofs(:,1))
291 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,2), 2, self%efield_dofs(:,2))
292 call self%maxwell_solver%compute_E_from_B(&
293 dt, self%bfield_dofs, self%efield_dofs(:,2))
323 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
324 sll_real64,
target,
intent(in) :: bfield_dofs(:)
325 sll_real64,
intent(in) :: x_min
326 sll_real64,
intent(in) :: lx
327 sll_int32,
intent(in) :: n_sub_iter
329 logical,
optional,
intent(in) :: jmean
331 sll_int32,
optional,
intent(in) :: i_weight
332 logical,
optional :: electrostatic
336 if(
present(electrostatic) )
then
337 self%electrostatic = electrostatic
340 self%maxwell_solver => maxwell_solver
341 self%kernel_smoother_0 => kernel_smoother_0
342 self%kernel_smoother_1 => kernel_smoother_1
344 self%n_species = particle_group%n_species
346 self%particle_group => particle_group
347 self%efield_dofs => efield_dofs
348 self%bfield_dofs => bfield_dofs
351 sll_assert( self%kernel_smoother_0%n_dofs == self%kernel_smoother_1%n_dofs )
353 sll_allocate(self%j_dofs(self%kernel_smoother_0%n_dofs,2), ierr)
354 sll_allocate(self%j_dofs_local(self%kernel_smoother_0%n_dofs,2), ierr)
355 sll_allocate(self%bfield_old(self%kernel_smoother_0%n_dofs), ierr)
357 self%spline_degree = self%kernel_smoother_0%spline_degree
360 self%delta_x = self%Lx/real(self%kernel_smoother_1%n_dofs, f64)
362 self%cell_integrals_1 = [0.5_f64, 2.0_f64, 0.5_f64]
363 self%cell_integrals_1 = self%cell_integrals_1 / 3.0_f64
365 self%cell_integrals_0 = [1.0_f64,11.0_f64,11.0_f64,1.0_f64]
366 self%cell_integrals_0 = self%cell_integrals_0 / 24.0_f64
369 if (
present(jmean))
then
374 if (
present(i_weight)) self%i_weight = i_weight
375 if(
present(control_variate))
then
376 allocate(self%control_variate )
377 allocate(self%control_variate%cv(self%n_species) )
378 self%control_variate => control_variate
381 self%n_sub_iter = n_sub_iter
390 deallocate(self%j_dofs)
391 deallocate(self%j_dofs_local)
392 self%maxwell_solver => null()
393 self%kernel_smoother_0 => null()
394 self%kernel_smoother_1 => null()
395 self%particle_group => null()
396 self%efield_dofs => null()
397 self%bfield_dofs => null()
425 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
426 sll_real64,
target,
intent(in) :: bfield_dofs(:)
427 sll_real64,
intent(in) :: x_min
428 sll_real64,
intent(in) :: lx
429 sll_int32,
intent(in) :: n_sub_iter
431 logical,
optional,
intent(in) :: jmean
433 sll_int32,
optional,
intent(in) :: i_weight
434 logical,
optional :: electrostatic
441 if (
present(jmean) )
then
447 select type (splitting)
450 call splitting%init(&
464 electrostatic=electrostatic)
466 call splitting%init(&
478 electrostatic=electrostatic)
505 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
506 sll_real64,
target,
intent(in) :: bfield_dofs(:)
507 sll_real64,
intent(in) :: x_min
508 sll_real64,
intent(in) :: lx
509 sll_int32,
intent(in) :: n_sub_iter
511 logical,
optional,
intent(in) :: jmean
512 logical,
optional :: electrostatic
520 if (
present(jmean) )
then
526 select type (splitting)
528 call splitting%init(&
540 electrostatic=electrostatic)
Combines values from all processes and distributes the result back to all processes.
Binomial filter for smooting of fields.
type(sll_t_collective_t), pointer, public sll_v_world_collective
Control of subset assignment. Processes with the same color are in the same new communicator.
Module interface to solve Maxwell's equations in 1D.
Base class for kernel smoothers for accumulation and field evaluation in PIC.
Base class for Hamiltonian splittings.
Particle pusher based on the subcycling algorithm for the 1d2v Vlasov-Maxwell equation with splitting...
subroutine lie_splitting_back_pic_vm_1d2v(self, dt, number_steps)
Lie splitting (oposite ordering)
subroutine initialize_pic_vm_1d2v(self, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, n_sub_iter, filter, jmean, control_variate, i_weight, electrostatic)
Constructor.
subroutine, public sll_s_new_time_propagator_pic_vm_1d2v_zigsub(splitting, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, n_sub_iter, filter, jmean, control_variate, i_weight, electrostatic)
Constructor for allocatable abstract type.
subroutine lie_splitting_pic_vm_1d2v(self, dt, number_steps)
Lie splitting.
subroutine strang_splitting_pic_vm_1d2v(self, dt, number_steps)
Strang splitting.
subroutine operator_all(self, dt)
subroutine, public sll_s_new_time_propagator_pic_vm_1d2v_zigsub_ptr(splitting, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, n_sub_iter, filter, jmean, electrostatic)
Constructor for pointer abstract type.
subroutine reinit_fields(self)
subroutine delete_pic_vm_1d2v(self)
Destructor.
real(kind=f64) function, dimension(size(particle, 2)) control_variate(particle)
Basic type of a kernel smoother used for PIC simulations.
Type for Hamiltonian splittings.
Hamiltonian splitting type for Vlasov-Maxwell 1d2v.