Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_time_propagator_pic_vm_1d2v_momentum.F90
Go to the documentation of this file.
1 
8 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 #include "sll_assert.h"
10 #include "sll_memory.h"
11 #include "sll_working_precision.h"
12 
13  use sll_m_collective, only: &
16 
17  use sll_m_binomial_filter, only: &
19 
20  use sll_m_control_variate, only: &
22 
23  use sll_m_time_propagator_base, only: &
25 
28 
29  use sll_m_maxwell_1d_base, only: &
31 
32  use sll_m_maxwell_1d_fem, only : &
34 
35  use sll_m_particle_group_base, only: &
37 
38  use mpi, only: &
39  mpi_sum
40 
41  implicit none
42 
43  public :: &
47 
48  private
49 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50 
53  class(sll_c_maxwell_1d_base), pointer :: maxwell_solver
54  class(sll_c_particle_mesh_coupling_1d), pointer :: kernel_smoother_0
55  class(sll_c_particle_mesh_coupling_1d), pointer :: kernel_smoother_1
56  class(sll_t_particle_array), pointer :: particle_group
57 
58  sll_int32 :: spline_degree
59  sll_real64 :: lx
60  sll_real64 :: x_min
61  sll_real64 :: delta_x
62 
63  sll_real64 :: cell_integrals_0(4)
64  sll_real64 :: cell_integrals_1(3)
65 
66 
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
72 
73  logical :: jmean = .false.
74  sll_real64, allocatable :: efield_filter(:,:)
75  sll_real64, allocatable :: bfield_filter(:)
76 
77  sll_real64, allocatable :: efield_to_val(:,:)
78  sll_real64, allocatable :: bfield_to_val(:)
79 
80  type(sll_t_binomial_filter), pointer :: filter
81 
82  ! For version with control variate
84  sll_int32 :: i_weight
85 
86  logical :: tmp = .false.
87 
88  contains
89  procedure :: operatorhp1 => operatorhp1_pic_vm_1d2v
90  procedure :: operatorhp2 => operatorhp2_pic_vm_1d2v
91  procedure :: operatorhe => operatorhe_pic_vm_1d2v
92  procedure :: operatorhb => operatorhb_pic_vm_1d2v
93  procedure :: lie_splitting => lie_splitting_pic_vm_1d2v
94  procedure :: lie_splitting_back => lie_splitting_back_pic_vm_1d2v
95  procedure :: strang_splitting => strang_splitting_pic_vm_1d2v
96  procedure :: reinit_fields
97 
98  procedure :: init => initialize_pic_vm_1d2v
99  procedure :: free => delete_pic_vm_1d2v
100 
102 
103 contains
104 
105  subroutine reinit_fields( self )
106  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
107 
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 )
111 
112  end subroutine reinit_fields
113 
115  subroutine strang_splitting_pic_vm_1d2v(self,dt, number_steps)
116  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
117  sll_real64, intent(in) :: dt
118  sll_int32, intent(in) :: number_steps
119 
120  sll_int32 :: i_step
121 
122 
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)
131 
132  end do
133 
134  end subroutine strang_splitting_pic_vm_1d2v
135 
137  subroutine lie_splitting_pic_vm_1d2v(self,dt, number_steps)
138  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
139  sll_real64, intent(in) :: dt
140  sll_int32, intent(in) :: number_steps
141 
142  sll_int32 :: i_step
143 
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)
149  end do
150 
151 
152  end subroutine lie_splitting_pic_vm_1d2v
153 
155  subroutine lie_splitting_back_pic_vm_1d2v(self,dt, number_steps)
156  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
157  sll_real64, intent(in) :: dt
158  sll_int32, intent(in) :: number_steps
159 
160  sll_int32 :: i_step
161 
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)
167  end do
168 
169  end subroutine lie_splitting_back_pic_vm_1d2v
170 
171 
172  !---------------------------------------------------------------------------!
179  subroutine operatorhp1_pic_vm_1d2v(self, dt)
180  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
181  sll_real64, intent(in) :: dt
182 
183  !local variables
184  sll_int32 :: i_part
185  sll_real64 :: x_new(3), vi(3), wi(1), x_old(3), wp(3)
186  sll_int32 :: n_cells, i_sp
187  sll_real64 :: qoverm
188 
189 
190  call self%maxwell_solver%transform_dofs( self%bfield_filter, self%bfield_to_val, 0 )
191 
192  n_cells = self%kernel_smoother_0%n_dofs
193 
194  ! Here we have to accumulate j and integrate over the time interval.
195  ! At each k=1,...,n_grid, we have for s \in [0,dt]:
196  ! j_k(s) = \sum_{i=1,..,N_p} q_i N((x_k+sv_{1,k}-x_i)/h) v_k,
197  ! where h is the grid spacing and N the normalized B-spline
198  ! In order to accumulate the integrated j, we normalize the values of x to the grid spacing, calling them y, we have
199  ! j_k(s) = \sum_{i=1,..,N_p} q_i N(y_k+s/h v_{1,k}-y_i) v_k.
200  ! Now, we want the integral
201  ! \int_{0..dt} j_k(s) d s = \sum_{i=1,..,N_p} q_i v_k \int_{0..dt} N(y_k+s/h v_{1,k}-y_i) ds = \sum_{i=1,..,N_p} q_i v_k \int_{0..dt} N(y_k + w v_{1,k}-y_i) dw
202 
203 
204  self%j_dofs_local = 0.0_f64
205 
206  ! For each particle compute the index of the first DoF on the grid it contributes to and its position (normalized to cell size one). Note: j_dofs(_local) does not hold the values for j itself but for the integrated j.
207  ! Then update particle position: X_new = X_old + dt * V
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
211  ! Read out particle position and velocity
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)
214 
215  ! Then update particle position: X_new = X_old + dt * V
216  x_new = x_old + dt * vi
217 
218  ! Get charge for accumulation of j
219  wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)
220 
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))
223  ! Accumulate rho for Poisson diagnostics
224  !call self%kernel_smoother_0%add_charge( x_new, wi(1), &
225  ! self%j_dofs_local(:,2))
226 
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)
230 
231  if (self%particle_group%group(i_sp)%n_weights == 3) then
232  ! Update weights if control variate
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)
236  end if
237 
238  end do
239  end do
240 
241  self%j_dofs = 0.0_f64
242  ! MPI to sum up contributions from each processor
243  call sll_o_collective_allreduce( sll_v_world_collective, self%j_dofs_local(:,1), &
244  n_cells, mpi_sum, self%j_dofs(:,1))
245 
246  !call filter( self%j_dofs(:,1), self%j_dofs_local(:,1), n_cells )
247  !call filter( self%j_dofs_local(:,1), self%j_dofs(:,1), n_cells )
248  !self%j_dofs(:,1) = self%j_dofs_local(:,1)
249  call self%filter%apply_inplace( self%j_dofs(:,1) )
250 
251  !write(41,*) self%j_dofs(:,1)
252  !stop
253 
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)
256  end if
257  ! Update the electric field.
258  call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,1), 1, self%efield_dofs(:,1))
259 
260  call self%filter%apply( self%efield_dofs(:,1), self%efield_filter(:,1) )
261 
262  end subroutine operatorhp1_pic_vm_1d2v
263 
264 
265 
266 
267  !---------------------------------------------------------------------------!
274  subroutine operatorhp2_pic_vm_1d2v(self, dt)
275  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
276  sll_real64, intent(in) :: dt
277 
278  !local variables
279  sll_int32 :: i_part, n_cells, i_sp
280  sll_real64 :: vi(3), xi(3), wi(1), wp(3)
281  sll_real64 :: bfield
282  sll_real64 :: qm
283 
284  n_cells = self%kernel_smoother_0%n_dofs
285 
286  self%j_dofs_local = 0.0_f64
287 
288  call self%maxwell_solver%transform_dofs( self%bfield_filter, self%bfield_to_val, 2 )
289 
290  do i_sp = 1, self%n_species
291  qm = self%particle_group%group(i_sp)%species%q_over_m();
292  ! Update v_1
293  do i_part=1,self%particle_group%group(i_sp)%n_particles
294  ! Evaluate bfield at particle position (splines of order p)
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)
301 
302  xi = self%particle_group%group(i_sp)%get_x(i_part)
303 
304  ! Scale vi by weight to combine both factors for accumulation of integral over j
305  wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)*vi(2)
306 
307  call self%kernel_smoother_0%add_charge(xi(1:1), wi(1), self%j_dofs_local(:,2))
308 
309  if (self%particle_group%group(i_sp)%n_weights == 3) then
310  ! Update weights if control variate
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)
314  end if
315  end do
316  end do
317 
318  self%j_dofs = 0.0_f64
319  ! MPI to sum up contributions from each processor
320  call sll_o_collective_allreduce( sll_v_world_collective, self%j_dofs_local(:,2), &
321  n_cells, mpi_sum, self%j_dofs(:,2))
322  ! Update the electric field. Also, we still need to scale with 1/Lx ! TODO: Which scaling?
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)
325  end if
326  self%j_dofs(:,2) = self%j_dofs(:,2)*dt!/self%Lx
327 
328 
329  call self%filter%apply_inplace( self%j_dofs(:,2) )
330 
331  call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,2), 2, self%efield_dofs(:,2))
332 
333 
334  call self%filter%apply( self%efield_dofs(:,2), self%efield_filter(:,2) )
335 
336  end subroutine operatorhp2_pic_vm_1d2v
337 
338  !---------------------------------------------------------------------------!
344  subroutine operatorhe_pic_vm_1d2v(self, dt)
345  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
346  sll_real64, intent(in) :: dt
347 
348  !local variables
349  sll_int32 :: i_part, i_sp
350  sll_real64 :: v_new(3), xi(3), wp(3)
351  sll_real64 :: efield(2)
352  sll_real64 :: qm
353 
354  ! Modification for momentum preserving scheme
355  call self%maxwell_solver%transform_dofs( self%efield_filter(:,1), self%efield_to_val(:,1), 2 ) ! use 0 here usually
356  call self%maxwell_solver%transform_dofs( self%efield_filter(:,2), self%efield_to_val(:,2), 1 )
357 
358 
359  do i_sp = 1,self%n_species
360  qm = self%particle_group%group(i_sp)%species%q_over_m();
361  ! V_new = V_old + dt * E
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)
364  ! Evaluate efields at particle position
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)
373 
374  if (self%particle_group%group(i_sp)%n_weights == 3) then
375  ! Update weights if control variate
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)
379  end if
380  end do
381  end do
382 
383  ! Update bfield
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 )
387 
388  end subroutine operatorhe_pic_vm_1d2v
389 
390 
391  !---------------------------------------------------------------------------!
397  subroutine operatorhb_pic_vm_1d2v(self, dt)
398  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(inout) :: self
399  sll_real64, intent(in) :: dt
400 
401  ! Update efield2
402  call self%maxwell_solver%compute_E_from_B(&
403  dt, self%bfield_dofs, self%efield_dofs(:,2))
404 
405  call self%filter%apply( self%efield_dofs(:,2), self%efield_filter(:,2) )
406 
407  end subroutine operatorhb_pic_vm_1d2v
408 
409 
410  !---------------------------------------------------------------------------!
413  self, &
414  maxwell_solver, &
415  kernel_smoother_0, &
416  kernel_smoother_1, &
417  particle_group, &
418  efield_dofs, &
419  bfield_dofs, &
420  x_min, &
421  Lx, &
422  filter, &
423  jmean, &
424  control_variate, &
425  i_weight)
426  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent(out) :: self
427  class(sll_c_maxwell_1d_base), target, intent(in) :: maxwell_solver
428  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_0
429  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_1
430  class(sll_t_particle_array), target, intent(in) :: particle_group
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
435  type( sll_t_binomial_filter ), intent( in ), target :: filter
436  logical, optional, intent(in) :: jmean
437  class(sll_t_control_variates), optional, target, intent(in) :: control_variate
438  sll_int32, optional, intent(in) :: i_weight
439 
440  !local variables
441  sll_int32 :: ierr
442 
443  self%maxwell_solver => maxwell_solver
444  self%kernel_smoother_0 => kernel_smoother_0
445  self%kernel_smoother_1 => kernel_smoother_1
446 
447  self%n_species = particle_group%n_species
448  !allocate( sll_t_time_propagator_pic_vm_1d2v_momentum :: self%particle_group(self%n_species) )
449  !do j=1,self%n_species
450  ! self%particle_group(j) => particle_group(j)
451  !end do
452 
453  self%particle_group => particle_group
454  self%efield_dofs => efield_dofs
455  self%bfield_dofs => bfield_dofs
456 
457  ! Check that n_dofs is the same for both kernel smoothers.
458  sll_assert( self%kernel_smoother_0%n_dofs == self%kernel_smoother_1%n_dofs )
459 
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)
466 
467  self%spline_degree = self%kernel_smoother_0%spline_degree
468  self%x_min = x_min
469  self%Lx = lx
470  self%delta_x = self%Lx/real(self%kernel_smoother_1%n_dofs,f64)
471 
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
474 
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
477 
478  self%filter => filter
479 
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 )
483 
484  if (present(jmean)) then
485  self%jmean = jmean
486  end if
487 
488  self%i_weight = 1
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
494  !do j=1,self%n_species
495  ! self%control_variate%cv(j) => control_variate%cv(j)
496  !end do
497  end if
498  end subroutine initialize_pic_vm_1d2v
499 
500  !---------------------------------------------------------------------------!
502  subroutine delete_pic_vm_1d2v(self)
503  class(sll_t_time_propagator_pic_vm_1d2v_momentum), intent( inout ) :: self
504 
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()
513 
514  end subroutine delete_pic_vm_1d2v
515 
516 
517  !---------------------------------------------------------------------------!
520  splitting, &
521  maxwell_solver, &
522  kernel_smoother_0, &
523  kernel_smoother_1, &
524  particle_group, &
525  efield_dofs, &
526  bfield_dofs, &
527  x_min, &
528  Lx, &
529  filter, &
530  jmean, &
531  control_variate, &
532  i_weight)
533  class(sll_c_time_propagator_base), allocatable, intent(out) :: splitting
534  class(sll_c_maxwell_1d_base), target, intent(in) :: maxwell_solver
535  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_0
536  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_1
537  class(sll_t_particle_array), target, intent(in) :: particle_group
538  !class(sll_c_particle_group_base),target, intent(in) :: particle_group(:) !< Particle group
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
543  type( sll_t_binomial_filter ), intent( in ), target :: filter
544  logical, optional, intent(in) :: jmean
545  class(sll_t_control_variates), optional, target, intent(in) :: control_variate
546  sll_int32, optional, intent(in) :: i_weight
547 
548  !local variables
549  sll_int32 :: ierr
550  logical :: jmean_val
551 
552  sll_allocate(sll_t_time_propagator_pic_vm_1d2v_momentum :: splitting, ierr)
553 
554  if (present(jmean) ) then
555  jmean_val = jmean
556  else
557  jmean_val = .false.
558  end if
559 
560  select type (splitting)
562  if (present(control_variate) ) then
563  call splitting%init(&
564  maxwell_solver, &
565  kernel_smoother_0, &
566  kernel_smoother_1, &
567  particle_group, &
568  efield_dofs, &
569  bfield_dofs, &
570  x_min, &
571  lx, &
572  filter, &
573  jmean_val, &
574  control_variate, &
575  i_weight)
576  else
577  call splitting%init(&
578  maxwell_solver, &
579  kernel_smoother_0, &
580  kernel_smoother_1, &
581  particle_group, &
582  efield_dofs, &
583  bfield_dofs, &
584  x_min, &
585  lx, &
586  filter, &
587  jmean_val)
588  end if
589  end select
590 
592 
593  !---------------------------------------------------------------------------!
596  splitting, &
597  maxwell_solver, &
598  kernel_smoother_0, &
599  kernel_smoother_1, &
600  particle_group, &
601  efield_dofs, &
602  bfield_dofs, &
603  x_min, &
604  Lx, &
605  filter, &
606  jmean)
607  class(sll_c_time_propagator_base), pointer, intent(out) :: splitting
608  class(sll_c_maxwell_1d_base), target, intent(in) :: maxwell_solver
609  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_0
610  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_1
611  !class(sll_c_particle_group_base),target, intent(in) :: particle_group(:) !< Particle group
612  class(sll_t_particle_array), target, intent(in) :: particle_group
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
617  type( sll_t_binomial_filter ), intent( in ), target :: filter
618  logical, optional, intent(in) :: jmean
619 
620 
621 
622  !local variables
623  sll_int32 :: ierr
624  logical :: jmean_val
625 
626  sll_allocate(sll_t_time_propagator_pic_vm_1d2v_momentum :: splitting, ierr)
627 
628 
629  if (present(jmean) ) then
630  jmean_val = jmean
631  else
632  jmean_val = .false.
633  end if
634 
635  select type (splitting)
637  call splitting%init(&
638  maxwell_solver, &
639  kernel_smoother_0, &
640  kernel_smoother_1, &
641  particle_group, &
642  efield_dofs, &
643  bfield_dofs, &
644  x_min, &
645  lx, &
646  filter, &
647  jmean_val)
648  end select
649 
651 
652 
Combines values from all processes and distributes the result back to all processes.
Binomial filter for smooting of fields.
Parallelizing facility.
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, 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 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)
    Report Typos and Errors