9 #include "sll_assert.h"
10 #include "sll_memory.h"
11 #include "sll_working_precision.h"
58 sll_int32 :: spline_degree
63 sll_real64 :: cell_integrals_0(4)
64 sll_real64 :: cell_integrals_1(3)
67 sll_real64,
pointer :: efield_dofs(:,:)
68 sll_real64,
pointer :: bfield_dofs(:)
69 sll_real64,
allocatable :: j_dofs(:,:)
70 sll_real64,
allocatable :: j_dofs_local(:,:)
71 sll_int32 :: n_species
73 logical :: jmean = .false.
74 sll_real64,
allocatable :: efield_filter(:,:)
75 sll_real64,
allocatable :: bfield_filter(:)
77 sll_real64,
allocatable :: efield_to_val(:,:)
78 sll_real64,
allocatable :: bfield_to_val(:)
86 logical :: tmp = .false.
108 call self%filter%apply( self%efield_dofs(:,1), self%efield_filter(:,1) )
109 call self%filter%apply( self%efield_dofs(:,2), self%efield_filter(:,2) )
110 call self%filter%apply( self%bfield_dofs, self%bfield_filter )
117 sll_real64,
intent(in) :: dt
118 sll_int32,
intent(in) :: number_steps
123 do i_step = 1, number_steps
124 call self%operatorHB(0.5_f64*dt)
125 call self%operatorHE(0.5_f64*dt)
126 call self%operatorHp2(0.5_f64*dt)
127 call self%operatorHp1(dt)
128 call self%operatorHp2(0.5_f64*dt)
129 call self%operatorHE(0.5_f64*dt)
130 call self%operatorHB(0.5_f64*dt)
139 sll_real64,
intent(in) :: dt
140 sll_int32,
intent(in) :: number_steps
144 do i_step = 1,number_steps
145 call self%operatorHE(dt)
146 call self%operatorHB(dt)
147 call self%operatorHp1(dt)
148 call self%operatorHp2(dt)
157 sll_real64,
intent(in) :: dt
158 sll_int32,
intent(in) :: number_steps
162 do i_step = 1,number_steps
163 call self%operatorHp2(dt)
164 call self%operatorHp1(dt)
165 call self%operatorHB(dt)
166 call self%operatorHE(dt)
181 sll_real64,
intent(in) :: dt
185 sll_real64 :: x_new(3), vi(3), wi(1), x_old(3), wp(3)
186 sll_int32 :: n_cells, i_sp
190 call self%maxwell_solver%transform_dofs( self%bfield_filter, self%bfield_to_val, 0 )
192 n_cells = self%kernel_smoother_0%n_dofs
204 self%j_dofs_local = 0.0_f64
208 do i_sp = 1,self%n_species
209 qoverm = self%particle_group%group(i_sp)%species%q_over_m();
210 do i_part=1,self%particle_group%group(i_sp)%n_particles
212 x_old = self%particle_group%group(i_sp)%get_x(i_part)
213 vi = self%particle_group%group(i_sp)%get_v(i_part)
216 x_new = x_old + dt * vi
219 wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)
221 call self%kernel_smoother_1%add_current_update_v( x_old, x_new, wi(1), qoverm, &
222 self%bfield_to_val, vi, self%j_dofs_local(:,1))
227 x_new(1) = modulo(x_new(1), self%Lx)
228 call self%particle_group%group(i_sp)%set_x(i_part, x_new)
229 call self%particle_group%group(i_sp)%set_v(i_part, vi)
231 if (self%particle_group%group(i_sp)%n_weights == 3)
then
233 wp = self%particle_group%group(i_sp)%get_weights(i_part)
234 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))
235 call self%particle_group%group(i_sp)%set_weights(i_part, wp)
241 self%j_dofs = 0.0_f64
244 n_cells, mpi_sum, self%j_dofs(:,1))
249 call self%filter%apply_inplace( self%j_dofs(:,1) )
254 if ( self%jmean .eqv. .true. )
then
255 self%j_dofs(:,1) = self%j_dofs(:,1) - sum(self%j_dofs(:,1))/real(self%kernel_smoother_0%n_dofs, f64)
258 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,1), 1, self%efield_dofs(:,1))
260 call self%filter%apply( self%efield_dofs(:,1), self%efield_filter(:,1) )
276 sll_real64,
intent(in) :: dt
279 sll_int32 :: i_part, n_cells, i_sp
280 sll_real64 :: vi(3), xi(3), wi(1), wp(3)
284 n_cells = self%kernel_smoother_0%n_dofs
286 self%j_dofs_local = 0.0_f64
288 call self%maxwell_solver%transform_dofs( self%bfield_filter, self%bfield_to_val, 2 )
290 do i_sp = 1, self%n_species
291 qm = self%particle_group%group(i_sp)%species%q_over_m();
293 do i_part=1,self%particle_group%group(i_sp)%n_particles
295 xi = self%particle_group%group(i_sp)%get_x(i_part)
296 call self%kernel_smoother_0%evaluate &
297 (xi(1), self%bfield_to_val, bfield)
298 vi = self%particle_group%group(i_sp)%get_v(i_part)
299 vi(1) = vi(1) + dt*qm*vi(2)*bfield
300 call self%particle_group%group(i_sp)%set_v(i_part, vi)
302 xi = self%particle_group%group(i_sp)%get_x(i_part)
305 wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)*vi(2)
307 call self%kernel_smoother_0%add_charge(xi(1:1), wi(1), self%j_dofs_local(:,2))
309 if (self%particle_group%group(i_sp)%n_weights == 3)
then
311 wp = self%particle_group%group(i_sp)%get_weights(i_part)
312 wp(3) = self%control_variate%cv(i_sp)%update_df_weight( xi(1:1), vi(1:2), 0.0_f64, wp(1), wp(2))
313 call self%particle_group%group(i_sp)%set_weights(i_part, wp)
318 self%j_dofs = 0.0_f64
321 n_cells, mpi_sum, self%j_dofs(:,2))
323 if ( self%jmean .eqv. .true. )
then
324 self%j_dofs(:,2) = self%j_dofs(:,2) - sum(self%j_dofs(:,2))/real(self%kernel_smoother_1%n_dofs, f64)
326 self%j_dofs(:,2) = self%j_dofs(:,2)*dt
329 call self%filter%apply_inplace( self%j_dofs(:,2) )
331 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,2), 2, self%efield_dofs(:,2))
334 call self%filter%apply( self%efield_dofs(:,2), self%efield_filter(:,2) )
346 sll_real64,
intent(in) :: dt
349 sll_int32 :: i_part, i_sp
350 sll_real64 :: v_new(3), xi(3), wp(3)
351 sll_real64 :: efield(2)
355 call self%maxwell_solver%transform_dofs( self%efield_filter(:,1), self%efield_to_val(:,1), 2 )
356 call self%maxwell_solver%transform_dofs( self%efield_filter(:,2), self%efield_to_val(:,2), 1 )
359 do i_sp = 1,self%n_species
360 qm = self%particle_group%group(i_sp)%species%q_over_m();
362 do i_part=1,self%particle_group%group(i_sp)%n_particles
363 v_new = self%particle_group%group(i_sp)%get_v(i_part)
365 xi = self%particle_group%group(i_sp)%get_x(i_part)
366 call self%kernel_smoother_0%evaluate &
367 (xi(1), self%efield_to_val(:,1), efield(1))
368 call self%kernel_smoother_0%evaluate &
369 (xi(1), self%efield_to_val(:,2), efield(2))
370 v_new = self%particle_group%group(i_sp)%get_v(i_part)
371 v_new(1:2) = v_new(1:2) + dt* qm * efield
372 call self%particle_group%group(i_sp)%set_v(i_part, v_new)
374 if (self%particle_group%group(i_sp)%n_weights == 3)
then
376 wp = self%particle_group%group(i_sp)%get_weights(i_part)
377 wp(3) = self%control_variate%cv(i_sp)%update_df_weight( xi(1:1), v_new(1:2), 0.0_f64, wp(1), wp(2))
378 call self%particle_group%group(i_sp)%set_weights(i_part, wp)
384 call self%maxwell_solver%compute_B_from_E( &
385 dt, self%efield_dofs(:,2), self%bfield_dofs)
386 call self%filter%apply( self%bfield_dofs, self%bfield_filter )
399 sll_real64,
intent(in) :: dt
402 call self%maxwell_solver%compute_E_from_B(&
403 dt, self%bfield_dofs, self%efield_dofs(:,2))
405 call self%filter%apply( self%efield_dofs(:,2), self%efield_filter(:,2) )
431 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
432 sll_real64,
target,
intent(in) :: bfield_dofs(:)
433 sll_real64,
intent(in) :: x_min
434 sll_real64,
intent(in) :: lx
436 logical,
optional,
intent(in) :: jmean
438 sll_int32,
optional,
intent(in) :: i_weight
443 self%maxwell_solver => maxwell_solver
444 self%kernel_smoother_0 => kernel_smoother_0
445 self%kernel_smoother_1 => kernel_smoother_1
447 self%n_species = particle_group%n_species
453 self%particle_group => particle_group
454 self%efield_dofs => efield_dofs
455 self%bfield_dofs => bfield_dofs
458 sll_assert( self%kernel_smoother_0%n_dofs == self%kernel_smoother_1%n_dofs )
460 sll_allocate(self%j_dofs(self%kernel_smoother_0%n_dofs,2), ierr)
461 sll_allocate(self%j_dofs_local(self%kernel_smoother_0%n_dofs,2), ierr)
462 sll_allocate(self%efield_filter(self%kernel_smoother_1%n_dofs,2), ierr)
463 sll_allocate(self%bfield_filter(self%kernel_smoother_0%n_dofs), ierr)
464 sll_allocate(self%efield_to_val(self%kernel_smoother_1%n_dofs,2), ierr)
465 sll_allocate(self%bfield_to_val(self%kernel_smoother_0%n_dofs), ierr)
467 self%spline_degree = self%kernel_smoother_0%spline_degree
470 self%delta_x = self%Lx/real(self%kernel_smoother_1%n_dofs,f64)
472 self%cell_integrals_1 = [0.5_f64, 2.0_f64, 0.5_f64]
473 self%cell_integrals_1 = self%cell_integrals_1 / 3.0_f64
475 self%cell_integrals_0 = [1.0_f64,11.0_f64,11.0_f64,1.0_f64]
476 self%cell_integrals_0 = self%cell_integrals_0 / 24.0_f64
478 self%filter => filter
480 call self%filter%apply( self%efield_dofs(:,1), self%efield_filter(:,1) )
481 call self%filter%apply( self%efield_dofs(:,2), self%efield_filter(:,2) )
482 call self%filter%apply( self%bfield_dofs, self%bfield_filter )
484 if (
present(jmean))
then
489 if (
present(i_weight)) self%i_weight = i_weight
490 if(
present(control_variate))
then
491 allocate(self%control_variate )
492 allocate(self%control_variate%cv(self%n_species) )
493 self%control_variate => control_variate
505 deallocate(self%j_dofs)
506 deallocate(self%j_dofs_local)
507 self%maxwell_solver => null()
508 self%kernel_smoother_0 => null()
509 self%kernel_smoother_1 => null()
510 self%particle_group => null()
511 self%efield_dofs => null()
512 self%bfield_dofs => null()
539 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
540 sll_real64,
target,
intent(in) :: bfield_dofs(:)
541 sll_real64,
intent(in) :: x_min
542 sll_real64,
intent(in) :: lx
544 logical,
optional,
intent(in) :: jmean
546 sll_int32,
optional,
intent(in) :: i_weight
554 if (
present(jmean) )
then
560 select type (splitting)
563 call splitting%init(&
577 call splitting%init(&
613 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
614 sll_real64,
target,
intent(in) :: bfield_dofs(:)
615 sll_real64,
intent(in) :: x_min
616 sll_real64,
intent(in) :: lx
618 logical,
optional,
intent(in) :: jmean
629 if (
present(jmean) )
then
635 select type (splitting)
637 call splitting%init(&
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.
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 Hamiltonian splitting for 1d2v Vlasov-Maxwell in the momentum conserving,...
subroutine initialize_pic_vm_1d2v(self, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, filter, jmean, control_variate, i_weight)
Constructor.
subroutine operatorhb_pic_vm_1d2v(self, dt)
Push H_B: Equations to be solved V_new = V_old \partial_t E_1 = 0 -> E_{1,new} = E_{1,...
subroutine operatorhp2_pic_vm_1d2v(self, dt)
Push Hp2: Equations to solve are X_new = X_old V_new,1 = V_old,1 + \int_0 h V_old,...
subroutine operatorhe_pic_vm_1d2v(self, dt)
Push H_E: Equations to be solved \partial_t f + E_1 \partial_{v_1} f + E_2 \partial_{v_2} f = 0 -> V_...
subroutine, public sll_s_new_time_propagator_pic_vm_1d2v_momentum(splitting, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, filter, jmean, control_variate, i_weight)
Constructor for allocatable abstract type.
subroutine operatorhp1_pic_vm_1d2v(self, dt)
Push Hp1: Equations to solve are \partial_t f + v_1 \partial_{x_1} f = 0 -> X_new = X_old + dt V_1 V_...
subroutine lie_splitting_back_pic_vm_1d2v(self, dt, number_steps)
Lie splitting (oposite ordering)
subroutine reinit_fields(self)
Finalization.
subroutine, public sll_s_new_time_propagator_pic_vm_1d2v_momentum_ptr(splitting, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, filter, jmean)
Constructor for pointer abstract type.
subroutine delete_pic_vm_1d2v(self)
Destructor.
subroutine strang_splitting_pic_vm_1d2v(self, dt, number_steps)
Strang splitting.
subroutine lie_splitting_pic_vm_1d2v(self, dt, number_steps)
Lie splitting.
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.