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_ecsim.F90
Go to the documentation of this file.
1 
6  !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 #include "sll_assert.h"
8 #include "sll_memory.h"
9 #include "sll_working_precision.h"
10 
11  use sll_m_collective, only: &
14 
15  use sll_m_time_propagator_base, only: &
17 
20 
21  use sll_m_particle_group_base, only: &
23 
24  use sll_m_low_level_bsplines, only: &
25  sll_s_uniform_bsplines_eval_basis
26 
29 
30  use mpi, only: &
31  mpi_sum
32 
33  use sll_m_linear_operator_ecsim, only : &
35 
36  use sll_m_linear_solver_mgmres, only : &
38 
39  use sll_m_spline_fem_utilities, only : &
41 
42  implicit none
43 
44  public :: &
46 
47  private
48  !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
49 
52  class(sll_c_particle_mesh_coupling_1d), pointer :: kernel_smoother_0
53  class(sll_c_particle_mesh_coupling_1d), pointer :: kernel_smoother_1
54  class(sll_t_particle_array), pointer :: particle_group
55  sll_int32 :: spline_degree
56  sll_real64 :: lx
57  sll_real64 :: x_min
58  sll_real64 :: domain(2)
59  sll_real64 :: delta_x
60  sll_int32 :: n_dofs
61 
62  sll_real64 :: cell_integrals_0(4)
63  sll_real64 :: cell_integrals_1(3)
64 
65 
66  sll_real64, pointer :: efield_dofs(:,:)
67  sll_real64, allocatable :: efield_dofs_local(:)
68  sll_real64, pointer :: bfield_dofs(:)
69  sll_real64, allocatable :: j_dofs(:,:)
70  sll_real64, allocatable :: j_dofs_local(:,:)
71  sll_real64, allocatable :: rho_dofs(:)
72  sll_real64, allocatable :: rho_dofs_local(:)
73 
74 
75  sll_real64, allocatable :: mass_line_0(:)
76  sll_real64, allocatable :: mass_line_1(:)
77 
78  sll_real64, allocatable :: m1(:,:),m2(:,:),m4(:,:)
79  sll_real64, allocatable :: m1_local(:,:),m2_local(:,:),m4_local(:,:)
80  type(sll_t_linear_operator_ecsim) :: linear_operator
81  type(sll_t_linear_solver_mgmres) :: linear_solver
82 
83 contains
84  procedure :: advect_x => advect_x_pic_vm_1d2v_ecsim
85  procedure :: advect_e => advect_e_pic_vm_1d2v_ecsim
86 
87  procedure :: lie_splitting => lie_splitting_pic_vm_1d2v_ecsim
88  procedure :: lie_splitting_back => lie_splitting_back_pic_vm_1d2v_ecsim
89  procedure :: strang_splitting => strang_splitting_pic_vm_1d2v_ecsim
90 
91  procedure :: init => initialize_pic_vm_1d2v_ecsim
92  procedure :: init_from_file => initialize_file_pic_vm_1d2v_ecsim
93  procedure :: free => delete_pic_vm_1d2v_ecsim
94 
96 
97 
98 contains
99 
101 subroutine strang_splitting_pic_vm_1d2v_ecsim(self,dt, number_steps)
102  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(inout) :: self
103  sll_real64, intent(in) :: dt
104  sll_int32, intent(in) :: number_steps
105  ! local variable
106  sll_int32 :: i_step
107 
108  do i_step = 1, number_steps
109  call self%advect_x(dt*0.5_f64)
110  call self%advect_e(dt)
111  call self%advect_x(dt*0.5_f64)
112  end do
113 
114 
115 
117 
119 subroutine lie_splitting_pic_vm_1d2v_ecsim(self,dt, number_steps)
120  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(inout) :: self
121  sll_real64, intent(in) :: dt
122  sll_int32, intent(in) :: number_steps
123  ! local variable
124  sll_int32 :: i_step
125 
126  do i_step = 1, number_steps
127  call self%advect_x(dt)
128  call self%advect_e(dt)
129 
130  end do
131 
132 end subroutine lie_splitting_pic_vm_1d2v_ecsim
133 
135 subroutine lie_splitting_back_pic_vm_1d2v_ecsim(self,dt, number_steps)
136  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(inout) :: self
137  sll_real64, intent(in) :: dt
138  sll_int32, intent(in) :: number_steps
139  ! local variable
140  sll_int32 :: i_step
141 
142  do i_step = 1, number_steps
143  call self%advect_e(dt)
144  call self%advect_x(dt)
145  end do
146 
148 
149 !---------------------------------------------------------------------------!
150 subroutine advect_x_pic_vm_1d2v_ecsim ( self, dt )
151  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(inout) :: self
152  sll_real64, intent(in) :: dt
153  ! local variables
154  sll_int32 :: i_part, i_sp
155  sll_real64 :: xi(3), vi(3)
156 
157  do i_sp = 1,self%particle_group%n_species
158  do i_part=1,self%particle_group%group(i_sp)%n_particles
159  ! Read out particle position and velocity
160  xi = self%particle_group%group(i_sp)%get_x(i_part)
161  vi = self%particle_group%group(i_sp)%get_v(i_part)
162 
163  xi(1) = xi(1) + dt * vi(1)
164  xi(1) = modulo(xi(1), self%Lx)
165  call self%particle_group%group(i_sp)%set_x ( i_part, xi )
166  end do
167  end do
168 
169 end subroutine advect_x_pic_vm_1d2v_ecsim
170 
171 !---------------------------------------------------------------------------!
172 subroutine advect_e_pic_vm_1d2v_ecsim ( self, dt )
173  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(inout) :: self
174  sll_real64, intent(in) :: dt
175  ! local variables
176  sll_int32 :: i_part, i_sp
177  sll_real64 :: vi(3),v_new(3), xi(3), wi
178  sll_real64 :: qm, beta
179  sll_real64 :: mu
180  sll_real64 :: efield(2), bfield
181  sll_real64 :: scratch(3*self%n_dofs)
182  sll_real64 :: rhs(3*self%n_dofs)
183 
184 
185  self%linear_operator%dt=dt
186  self%linear_operator%dx=self%delta_x
187  ! Set to zero
188  self%j_dofs_local = 0.0_f64
189  self%j_dofs = 0.0_f64
190  self%rho_dofs_local = 0.0_f64
191  self%rho_dofs = 0.0_f64
192  self%m1=0.0_f64
193  self%m2=0.0_f64
194  self%m4=0.0_f64
195  self%m1_local=0.0_f64
196  self%m2_local=0.0_f64
197  self%m4_local=0.0_f64
198  rhs=0.0_f64
199  scratch=0.0_f64
200  bfield=0.0_f64
201  efield=0.0_f64
202 
203  ! First particle loop
204  do i_sp = 1, self%particle_group%n_species
205  qm = self%particle_group%group(i_sp)%species%q_over_m();
206  beta=qm*dt* 0.5_f64;
207  do i_part = 1,self%particle_group%group(i_sp)%n_particles
208  ! Read out particle position and velocity
209  vi = self%particle_group%group(i_sp)%get_v(i_part)
210  xi = self%particle_group%group(i_sp)%get_x(i_part)
211 
212  ! Get charge for accumulation of j
213  wi = self%particle_group%group(i_sp)%get_charge(i_part)
214  call self%kernel_smoother_1%evaluate &
215  (xi(1), self%bfield_dofs, bfield)
216  mu=(1+(beta*bfield)**2.0_f64)
217 
218  ! Accumulate jx
219  call self%kernel_smoother_1%add_charge( xi(1), wi*(vi(1)+vi(2)*beta* bfield)/mu, self%j_dofs_local(:,1) )
220 
221  ! Accumulate jy
222  call self%kernel_smoother_0%add_charge( xi(1), wi*(vi(2)-vi(1)*beta* bfield)/mu, self%j_dofs_local(:,2) )
223 
224  !Compute particle-mass matrices m1,m2,m4
225  call self%kernel_smoother_1%add_particle_mass( xi(1), (beta*wi)/mu,self%m1_local)
226 
227  call add_particle_mass_mixed_spline_1d(self, self%kernel_smoother_0, self%spline_degree, self%spline_degree-1, xi(1), -(beta**2.0_f64*wi*bfield)/mu,self%m2_local)
228 
229  call self%kernel_smoother_0%add_particle_mass( xi(1), (beta*wi)/mu,self%m4_local)
230 
231  end do
232  end do
233 
234 
235 
236  ! MPI to sum up contributions from each processor
237  call sll_o_collective_allreduce( sll_v_world_collective, self%j_dofs_local(:,1), &
238  self%kernel_smoother_1%n_dofs, mpi_sum, self%j_dofs(:,1) )
239  call sll_o_collective_allreduce( sll_v_world_collective, self%j_dofs_local(:,2), &
240  self%kernel_smoother_1%n_dofs, mpi_sum, self%j_dofs(:,2) )
241  call sll_o_collective_allreduce( sll_v_world_collective, self%m1_local, &
242  self%kernel_smoother_1%n_dofs*self%spline_degree, mpi_sum, self%m1 )
243  call sll_o_collective_allreduce( sll_v_world_collective, self%m2_local, &
244  self%kernel_smoother_0%n_dofs*2*self%spline_degree, mpi_sum, self%m2 )
245  call sll_o_collective_allreduce( sll_v_world_collective, self%m4_local, &
246  self%kernel_smoother_0%n_dofs* (self%spline_degree+1), mpi_sum, self%m4 )
247 
248  ! maxwell equations solved for fields at next timestep
249  call righthandside( self, dt, rhs)
250  call self%linear_solver%set_guess([self%efield_dofs(:,1),self%efield_dofs(:,2),self%bfield_dofs])
251  call self%linear_solver%solve(rhs, scratch)
252 
253 
254  self%efield_dofs(:,1)=0.5_f64*(scratch(1:self%n_dofs)+self%efield_dofs(:,1))
255  self%efield_dofs(:,2)=0.5_f64*(scratch(self%n_dofs+1:2*self%n_dofs)+self%efield_dofs(:,2))
256  bfield=0.0_f64
257  efield=0.0_f64
258  ! Second particle loop for v update
259  do i_sp = 1, self%particle_group%n_species
260  qm = self%particle_group%group(i_sp)%species%q_over_m();
261  beta=qm*dt* 0.5_f64;
262  do i_part = 1,self%particle_group%group(i_sp)%n_particles
263  ! Read out particle position and velocity
264  vi = self%particle_group%group(i_sp)%get_v(i_part)
265  xi = self%particle_group%group(i_sp)%get_x(i_part)
266  ! evaluate fields at particle position
267  call self%kernel_smoother_1%evaluate &
268  (xi(1), self%bfield_dofs, bfield)
269  mu=1+(beta*bfield)**2.0_f64
270  call self%kernel_smoother_1%evaluate &
271  (xi(1), self%efield_dofs(:,1), efield(1))
272  call self%kernel_smoother_0%evaluate &
273  (xi(1), self%efield_dofs(:,2), efield(2))
274 
275  !calculate v**(n+1/2)
276  v_new(1)=(vi(1)+beta*efield(1)+beta*bfield*(vi(2)+beta*efield(2)))/mu
277  v_new(2)=(vi(2)+beta*efield(2)-beta*bfield*(vi(1)+beta*efield(1)))/mu
278 
279 
280  v_new(1)=2.0_f64*v_new(1)-vi(1)
281  v_new(2)=2.0_f64*v_new(2)-vi(2)
282 
283  call self%particle_group%group(i_sp)%set_v(i_part, v_new)
284  end do
285  end do
286 
287  ! update fields
288  self%efield_dofs(:,1)= scratch(1:self%n_dofs)
289  self%efield_dofs(:,2)= scratch(self%n_dofs+1:2*self%n_dofs)
290  self%bfield_dofs= scratch(2*self%n_dofs+1:3*self%n_dofs)
291 
292 
293 end subroutine advect_e_pic_vm_1d2v_ecsim
294 
295 
297 subroutine add_particle_mass_mixed_spline_1d(self, kernel_smoother, degree1, degree2, position, marker_charge, particle_mass)
298  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(inout) :: self
299  class(sll_c_particle_mesh_coupling_1d), intent( in ) :: kernel_smoother
300  sll_int32, intent( in ) :: degree1
301  sll_int32, intent( in ) :: degree2
302  sll_real64, intent( in ) :: position(self%kernel_smoother_1%dim)
303  sll_real64, intent( in ) :: marker_charge
304  sll_real64, intent( inout ) :: particle_mass(:,:)
305  !local variables
306  sll_int32 :: i1, column
307  sll_int32 :: index1d, index
308  sll_real64 :: xi(1)
309  sll_real64 :: spline_val1(degree1+1)
310  sll_real64 :: spline_val2(degree2+1)
311 
312  sll_assert( size(particle_mass,1) == degree1+degree2+1 )
313  sll_assert( size(particle_mass,2) == kernel_smoother%n_dofs )
314 
315  xi(1) = (position(1) - self%x_min)/self%delta_x
316  index = ceiling(xi(1))
317  xi(1) = xi(1) - real(index-1, f64)
318  index = index - degree1
319 
320 
321  call sll_s_uniform_bsplines_eval_basis(degree1, xi(1), spline_val1)
322  call sll_s_uniform_bsplines_eval_basis(degree2, xi(1), spline_val2)
323 
324  do i1 = 1, degree1+1
325  index1d = modulo(index+i1-2,kernel_smoother%n_cells)+1 !index-degree1:index
326  do column = 1, degree2+1
327  particle_mass(column+degree1+1-i1, index1d) = particle_mass(column+degree1+1-i1, index1d)+ &
328  marker_charge * spline_val1(i1) * spline_val2(column)
329  end do
330  end do
331 
334 
336 subroutine righthandside (self,dt,rhs)
337  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(inout) :: self
338  sll_real64, intent(in) :: dt
339  sll_real64, intent(out):: rhs(3*self%n_dofs)
340  ! local variables
341  sll_int32 :: row, column
342  sll_real64 :: scratch(self%n_dofs+1) ! scratch data
343  ! set to zero
344  scratch=0.0_f64
345  do row=1, self%n_dofs
346  ! multiply field-dofs with diagonal entries of mass and particle-mass matrix and substract current
347  rhs(row) = (self%mass_line_1(1)-0.5_f64*dt*self%m1(1,row))*self%efield_dofs(row,1)-dt*self%j_dofs(row,1)
348  rhs(self%n_dofs+row)= (self%mass_line_0(1)-0.5_f64*dt*self%m4(1,row))*self%efield_dofs(row,2)-dt*self%j_dofs(row,2)
349  scratch(row)=self%mass_line_1(1)*self%bfield_dofs(row)
350  do column = 2, self%spline_degree
351  rhs(row) = rhs(row) +&
352  self%mass_line_1(column) * &
353  (self%efield_dofs(modulo(row+column-2,self%n_dofs)+1,1) +&
354  self%efield_dofs(modulo(row-column,self%n_dofs)+1,1))-&
355  0.5_f64*dt*self%m1(column,row) * &
356  self%efield_dofs(modulo(row+column-2,self%n_dofs)+1,1)-&
357  0.5_f64*dt*self%m1(column,modulo(row-column,self%n_dofs)+1) * &
358  self%efield_dofs(modulo(row-column,self%n_dofs)+1,1)
359 
360  scratch(row)=scratch(row)+&
361  self%mass_line_1(column) * &
362  (self%bfield_dofs(modulo(row+column-2,self%n_dofs)+1) +&
363  self%bfield_dofs(modulo(row-column,self%n_dofs)+1))
364  end do
365  do column = 2, self%spline_degree+1
366  rhs(self%n_dofs+row) = rhs(self%n_dofs+row) +&
367  self%mass_line_0(column) * &
368  (self%efield_dofs(modulo(row+column-2,self%n_dofs)+1,2) +&
369  self%efield_dofs(modulo(row-column,self%n_dofs)+1,2))-&
370  0.5_f64*dt*self%m4(column,row)*&
371  self%efield_dofs(modulo(row+column-2,self%n_dofs)+1,2)-&
372  0.5_f64*dt*self%m4(column,modulo(row-column,self%n_dofs)+1)*&
373  self%efield_dofs(modulo(row-column,self%n_dofs)+1,2)
374  end do
375  ! multiply efields with entries of m2 and m3
376  do column = 1, 2*self%spline_degree
377  rhs(row) = rhs(row) + &
378  0.5_f64*dt*self%m2(7-column,modulo(column-4+row-1,self%n_dofs)+1) *&
379  self%efield_dofs(modulo(row+column-self%spline_degree-2,self%n_dofs)+1,2)
380  rhs(row+self%n_dofs) = rhs(row+self%n_dofs) - &
381  0.5_f64*dt*self%m2(column,row) *&
382  self%efield_dofs(modulo(row+column-self%spline_degree-1,self%n_dofs)+1,1)
383  end do
384  end do
385  scratch(self%n_dofs+1)=scratch(1)
386  do row=1, self%n_dofs
387  ! update efield with curl of bfield
388  rhs(self%n_dofs+row)= rhs(self%n_dofs+row)+&
389  0.5_f64*dt/self%delta_x*(scratch(row)-scratch(row+1))
390  ! update bfield with curl of efield
391  rhs(2*self%n_dofs+row)=self%bfield_dofs(row)-&
392  0.5_f64*dt/self%delta_x*(self%efield_dofs(row,2)-self%efield_dofs(modulo(row-2,self%n_dofs)+1,2))
393 
394  end do
395 end subroutine righthandside
396 
397 
400  self, &
401  kernel_smoother_0, &
402  kernel_smoother_1, &
403  particle_group, &
404  efield_dofs, &
405  bfield_dofs, &
406  x_min, &
407  Lx, &
408  filename )
409  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(out) :: self
410  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_0
411  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_1
412  class(sll_t_particle_array), target, intent(in) :: particle_group
413  sll_real64, target, intent(in) :: efield_dofs(:,:)
414  sll_real64, target, intent(in) :: bfield_dofs(:)
415  sll_real64, intent(in) :: x_min
416  sll_real64, intent(in) :: lx
417  character(len=*), intent(in) :: filename
418 
419  sll_int32 :: input_file
420  sll_int32 :: io_stat
421  sll_real64 :: maxwell_tolerance
422 
423  namelist /time_solver/ maxwell_tolerance
424 
425  ! Read in solver tolerance
426  open(newunit = input_file, file=filename, status='old',iostat=io_stat)
427  if (io_stat /= 0) then
428  print*, 'sll_m_time_propagator_pic_vm_1d2v_ecsim: Input file does not exist. Set default tolerance.'
429  call self%init( kernel_smoother_0, &
430  kernel_smoother_1, &
431  particle_group, &
432  efield_dofs, &
433  bfield_dofs, &
434  x_min, &
435  lx )
436  else
437  read(input_file, time_solver)
438  call self%init( kernel_smoother_0, &
439  kernel_smoother_1, &
440  particle_group, &
441  efield_dofs, &
442  bfield_dofs, &
443  x_min, &
444  lx, &
445  solver_tolerance=maxwell_tolerance)
446  close(input_file)
447  end if
448 
449 
451 
452 
453 !---------------------------------------------------------------------------!
456  self, &
457  kernel_smoother_0, &
458  kernel_smoother_1, &
459  particle_group, &
460  efield_dofs, &
461  bfield_dofs, &
462  x_min, &
463  Lx, &
464  solver_tolerance )
465  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent(out) :: self
466  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_0
467  class(sll_c_particle_mesh_coupling_1d), target, intent(in) :: kernel_smoother_1
468  class(sll_t_particle_array), target, intent(in) :: particle_group
469  sll_real64, target, intent(in) :: efield_dofs(:,:)
470  sll_real64, target, intent(in) :: bfield_dofs(:)
471  sll_real64, intent(in) :: x_min
472  sll_real64, intent(in) :: lx
473  sll_real64, intent(in), optional :: solver_tolerance
474  !local variable
475  sll_int32 :: ierr
476 
477 
478  self%kernel_smoother_0 => kernel_smoother_0
479  self%kernel_smoother_1 => kernel_smoother_1
480  self%particle_group => particle_group
481  self%efield_dofs => efield_dofs
482  self%bfield_dofs => bfield_dofs
483 
484  ! Check that n_dofs is the same for both kernel smoothers.
485  sll_assert( self%kernel_smoother_0%n_dofs == self%kernel_smoother_1%n_dofs )
486  sll_allocate(self%j_dofs(self%kernel_smoother_0%n_dofs,2), ierr)
487  sll_allocate(self%j_dofs_local(self%kernel_smoother_0%n_dofs,2), ierr)
488 
489  self%spline_degree = self%kernel_smoother_0%spline_degree
490  self%x_min = x_min
491  self%Lx = lx
492  self%domain=[x_min,x_min+lx]
493  self%delta_x = self%Lx/real(self%kernel_smoother_1%n_dofs, f64)
494  self%n_dofs=self%kernel_smoother_1%n_dofs
495 
496  self%cell_integrals_1 = [0.5_f64, 2.0_f64, 0.5_f64]
497  self%cell_integrals_1 = self%cell_integrals_1 / 3.0_f64
498 
499  self%cell_integrals_0 = [1.0_f64,11.0_f64,11.0_f64,1.0_f64]
500  self%cell_integrals_0 = self%cell_integrals_0 / 24.0_f64
501 
502 
503  allocate( self%mass_line_0( self%spline_degree +1) )
504  allocate( self%mass_line_1( self%spline_degree ) )
505  call sll_s_spline_fem_mass_line ( self%spline_degree, self%mass_line_0 )
506  call sll_s_spline_fem_mass_line ( self%spline_degree-1, self%mass_line_1 )
507 
508  ! Scale with dx
509  self%mass_line_0 = self%mass_line_0 * self%delta_x
510  self%mass_line_1 = self%mass_line_1 * self%delta_x
511 
512 
513  sll_allocate(self%rho_dofs(self%kernel_smoother_0%n_dofs), ierr)
514  sll_allocate(self%rho_dofs_local(self%kernel_smoother_0%n_dofs), ierr)
515  sll_allocate(self%efield_dofs_local(self%kernel_smoother_1%n_dofs), ierr)
516 
517  allocate(self%m1(self%spline_degree,self%kernel_smoother_1%n_dofs))
518  allocate(self%m2(2*self%spline_degree,self%kernel_smoother_0%n_dofs))
519  allocate(self%m4(self%spline_degree+1,self%kernel_smoother_0%n_dofs))
520  allocate(self%m1_local(self%spline_degree,self%kernel_smoother_1%n_dofs))
521  allocate(self%m2_local(2*self%spline_degree,self%kernel_smoother_0%n_dofs))
522  allocate(self%m4_local(self%spline_degree+1,self%kernel_smoother_0%n_dofs))
523  call self%linear_operator%create(self%n_dofs, self%spline_degree, self%mass_line_0,self%mass_line_1, self%m1, self%m2, self%m4)
524 
525 
526  call self%linear_solver%create(self%linear_operator)
527  if (present(solver_tolerance)) then
528  self%linear_solver%rtol= solver_tolerance
529  self%linear_solver%atol= solver_tolerance
530  else
531  self%linear_solver%rtol= 1d-12
532  self%linear_solver%atol= 1d-12
533  end if
534  !self%linear_solver%verbose=.true.
535 end subroutine initialize_pic_vm_1d2v_ecsim
536 
537 !---------------------------------------------------------------------------!
539 subroutine delete_pic_vm_1d2v_ecsim(self)
540  class(sll_t_time_propagator_pic_vm_1d2v_ecsim), intent( inout ) :: self
541 
542  deallocate(self%j_dofs)
543  deallocate(self%j_dofs_local)
544  deallocate(self%m1)
545  deallocate(self%m2)
546  deallocate(self%m4)
547  deallocate(self%m1_local)
548  deallocate(self%m2_local)
549  deallocate(self%m4_local)
550  self%kernel_smoother_0 => null()
551  self%kernel_smoother_1 => null()
552  self%particle_group => null()
553  self%efield_dofs => null()
554  self%bfield_dofs => null()
555 
556 
557  call self%linear_operator%free()
558  call self%linear_solver%free()
559 
560 end subroutine delete_pic_vm_1d2v_ecsim
561 
562 
563 
564 
565 
Combines values from all processes and distributes the result back to all processes.
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.
real(kind=f64) function, dimension(2, 1:npoints), public sll_f_gauss_legendre_points_and_weights(npoints, a, b)
Returns a 2d array of size (2,npoints) containing gauss-legendre points and weights in the interval [...
module for a sequential gmres
Low level arbitrary degree splines.
Base class for kernel smoothers for accumulation and field evaluation in PIC.
Utilites for Maxwell solver's with spline finite elements.
subroutine, public sll_s_spline_fem_mass_line(degree, mass_line)
Computes the mass line for a mass matrix with degree splines.
Base class for Hamiltonian splittings.
Particle pusher based on Lapentas splitting in Ecsim for 1d2v Vlasov-Poisson.
subroutine initialize_pic_vm_1d2v_ecsim(self, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, solver_tolerance)
Constructor.
subroutine righthandside(self, dt, rhs)
calculation of the righthandside of the system of maxwellequations for halftimestep
subroutine lie_splitting_pic_vm_1d2v_ecsim(self, dt, number_steps)
Lie splitting.
subroutine strang_splitting_pic_vm_1d2v_ecsim(self, dt, number_steps)
Finalization.
subroutine add_particle_mass_mixed_spline_1d(self, kernel_smoother, degree1, degree2, position, marker_charge, particle_mass)
Add charge of one particle for splines of different degrees.
subroutine initialize_file_pic_vm_1d2v_ecsim(self, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, filename)
Constructor.
subroutine lie_splitting_back_pic_vm_1d2v_ecsim(self, dt, number_steps)
Lie splitting.
    Report Typos and Errors