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_3d3v_hs_trafo.F90
Go to the documentation of this file.
1 
6  !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 #include "sll_assert.h"
8 #include "sll_errors.h"
9 #include "sll_memory.h"
10 #include "sll_working_precision.h"
11 
12  use sll_m_collective, only: &
15 
16  use sll_m_control_variate, only: &
18 
19  use sll_m_time_propagator_base, only: &
21 
30 
31  use sll_m_initial_distribution, only: &
33 
34  use sll_m_mapping_3d, only: &
36 
37  use sll_m_maxwell_3d_base, only: &
39 
40  use mpi, only: &
41  mpi_sum
42 
43  use sll_m_particle_group_base, only: &
46 
49 
50  use sll_m_profile_functions, only: &
52 
53 
54 
55  implicit none
56 
57  public :: &
59 
60  private
61  !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
62 
65  class(sll_c_maxwell_3d_base), pointer :: maxwell_solver
66  class(sll_t_particle_array), pointer :: particle_group
67  class(sll_c_particle_mesh_coupling_3d), pointer :: particle_mesh_coupling
68  type( sll_t_mapping_3d ), pointer :: map
69 
70  sll_int32 :: spline_degree(3)
71  sll_real64 :: lx(3)
72  sll_real64 :: x_min(3)
73  sll_real64 :: x_max(3)
74  sll_int32 :: n_total0
75  sll_int32 :: n_total1
76 
77  sll_real64 :: betar(2)
78 
79  sll_real64, pointer :: phi_dofs(:)
80  sll_real64, pointer :: efield_dofs(:)
81  sll_real64, pointer :: bfield_dofs(:)
82  sll_real64, allocatable :: j_dofs(:)
83  sll_real64, allocatable :: j_dofs_local(:)
84  sll_int32 :: boundary_particles = 100
85  sll_int32 :: counter_left = 0
86  sll_int32 :: counter_right = 0
87  sll_real64, pointer :: rhob(:) => null()
88 
89  logical :: electrostatic = .false.
90  logical :: adiabatic_electrons = .false.
91  logical :: lindf = .false.
92 
93  sll_real64 :: iter_tolerance
94  sll_int32 :: max_iter
95 
96  ! For control variate
97  class(sll_t_control_variates), pointer :: control_variate => null()
98  sll_int32 :: i_weight = 1
99 
100 
101  contains
102  procedure :: operatorhp => operatorhp_pic_vm_3d3v_hs_trafo
103  procedure :: operatorhe => operatorhe_pic_vm_3d3v_hs_trafo
104  procedure :: operatorhb => operatorhb_pic_vm_3d3v_hs_trafo
105  procedure :: lie_splitting => lie_splitting_pic_vm_3d3v_hs_trafo
106  procedure :: lie_splitting_back => lie_splitting_back_pic_vm_3d3v_hs_trafo
107  procedure :: strang_splitting => strang_splitting_pic_vm_3d3v_hs_trafo
108 
109  procedure :: init => initialize_pic_vm_3d3v_hs_trafo
110  procedure :: init_from_file => initialize_file_pic_vm_3d3v_hs_trafo
111  procedure :: free => delete_pic_vm_3d3v_hs_trafo
112 
114 
115 contains
116 
117 
119  subroutine strang_splitting_pic_vm_3d3v_hs_trafo(self,dt, number_steps)
120  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent(inout) :: self
121  sll_real64, intent(in) :: dt
122  sll_int32, intent(in) :: number_steps
123  !local variables
124  sll_int32 :: i_step
125 
126  if(self%electrostatic) then
127  do i_step = 1, number_steps
128  call self%operatorHE(0.5_f64*dt)
129  call self%operatorHp(dt)
130  call self%operatorHE(0.5_f64*dt)
131  end do
132  else
133  do i_step = 1, number_steps
134  call self%operatorHB(0.5_f64*dt)
135  call self%operatorHE(0.5_f64*dt)
136  call self%operatorHp(dt)
137  call self%operatorHE(0.5_f64*dt)
138  call self%operatorHB(0.5_f64*dt)
139  end do
140  end if
141 
143 
145  subroutine lie_splitting_pic_vm_3d3v_hs_trafo(self,dt, number_steps)
146  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent(inout) :: self
147  sll_real64, intent(in) :: dt
148  sll_int32, intent(in) :: number_steps
149  !local variables
150  sll_int32 :: i_step
151 
152  if(self%electrostatic) then
153  do i_step = 1, number_steps
154  call self%operatorHE(dt)
155  call self%operatorHp(dt)
156  end do
157  else
158  do i_step = 1,number_steps
159  call self%operatorHB(dt)
160  call self%operatorHE(dt)
161  call self%operatorHp(dt)
162  end do
163  end if
164 
166 
167 
169  subroutine lie_splitting_back_pic_vm_3d3v_hs_trafo(self,dt, number_steps)
170  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent( inout ) :: self
171  sll_real64, intent( in ) :: dt
172  sll_int32, intent( in ) :: number_steps
173  !local variables
174  sll_int32 :: i_step
175 
176  if(self%electrostatic) then
177  do i_step = 1, number_steps
178  call self%operatorHp(dt)
179  call self%operatorHE(dt)
180  end do
181  else
182  do i_step = 1,number_steps
183  call self%operatorHp(dt)
184  call self%operatorHE(dt)
185  call self%operatorHB(dt)
186  end do
187  end if
188 
190 
191 
192  !---------------------------------------------------------------------------!
197  subroutine operatorhp_pic_vm_3d3v_hs_trafo(self, dt)
198  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent( inout ) :: self
199  sll_real64, intent( in ) :: dt
200  !local variables
201  sll_int32 :: i_part, i, j, i_sp
202  sll_real64 :: xi(3), xbar(3), xnew(3), xphys(3), vt(3), vi(3), vbar(3), vnew(3)
203  sll_real64 :: jmat(3,3)
204  sll_real64 :: qoverm, wi(1), wall(3)
205  sll_real64 :: err
206  sll_real64 :: qmdt
207  sll_real64 :: bfield(3), rhs(3)
208  sll_real64 :: c(3)
209 
210  self%j_dofs_local = 0.0_f64
211  do i_sp = 1, self%particle_group%n_species
212  qoverm = self%particle_group%group(i_sp)%species%q_over_m();
213  qmdt = qoverm*dt;
214  do i_part = 1, self%particle_group%group(i_sp)%n_particles
215  ! Read out particle position and velocity
216  xi = self%particle_group%group(i_sp)%get_x(i_part)
217  vi = self%particle_group%group(i_sp)%get_v(i_part)
218 
219  ! Evaulate B at particle position
220  call self%particle_mesh_coupling%evaluate &
221  (xi, [self%spline_degree(1), self%spline_degree(2)-1, self%spline_degree(3)-1], self%bfield_dofs(1:self%n_total0), bfield(1))
222  call self%particle_mesh_coupling%evaluate &
223  (xi, [self%spline_degree(1)-1, self%spline_degree(2), self%spline_degree(3)-1],self%bfield_dofs(self%n_total0+1:self%n_total0+self%n_total1), bfield(2))
224  call self%particle_mesh_coupling%evaluate &
225  (xi, [self%spline_degree(1)-1, self%spline_degree(2)-1, self%spline_degree(3)],self%bfield_dofs(self%n_total0+self%n_total1+1:self%n_total0+2*self%n_total1), bfield(3))
226  jmat=self%map%jacobian_matrix_inverse(xi)
227  if( self%map%inverse)then
228  xphys = self%map%get_x(xi)
229  xbar = xphys + dt * vi
230  xnew = self%map%get_xi(xbar)
231 
232  vt = (xnew - xi)/dt
233  !c = VT x bfield
234  c(1) = bfield(3)*vt(2) - bfield(2)*vt(3)
235  c(2) = bfield(1)*vt(3) - bfield(3)*vt(1)
236  c(3) = bfield(2)*vt(1) - bfield(1)*vt(2)
237 
238  !vnew = vi + sign * DF^{-T} * c
239  do j=1,3
240  vnew(j)= vi(j) + qmdt*(jmat(1,j)*c(1)+jmat(2,j)*c(2)+jmat(3,j)*c(3))
241  end do
242  err= maxval(abs(vi - vnew))
243 
244  i = 0
245  do while(i < self%max_iter .and. err > self%iter_tolerance)
246  xbar = 0.5_f64*(xnew+xi)
247  vbar = 0.5_f64*(vnew+vi)
248  call sll_s_compute_particle_boundary_simple( self%boundary_particles, self%counter_left, self%counter_right, xi, xbar )
249  if (xbar(1) >= 0._f64 .and. xbar(1) <= 1._f64) then
250  jmat = self%map%jacobian_matrix_inverse(xbar)
251  ! Evaulate B at particle position
252  call self%particle_mesh_coupling%evaluate &
253  (xbar, [self%spline_degree(1), self%spline_degree(2)-1, self%spline_degree(3)-1], self%bfield_dofs(1:self%n_total0), bfield(1))
254  call self%particle_mesh_coupling%evaluate &
255  (xbar, [self%spline_degree(1)-1, self%spline_degree(2), self%spline_degree(3)-1],self%bfield_dofs(self%n_total0+1:self%n_total0+self%n_total1), bfield(2))
256  call self%particle_mesh_coupling%evaluate &
257  (xbar, [self%spline_degree(1)-1, self%spline_degree(2)-1, self%spline_degree(3)],self%bfield_dofs(self%n_total0+self%n_total1+1:self%n_total0+2*self%n_total1), bfield(3))
258 
259  xbar = xphys + dt * vbar
260  xnew = self%map%get_xi(xbar)
261 
262  vt = (xnew - xi)/dt
263  !c = VT x bfield
264  c(1) = bfield(3)*vt(2) - bfield(2)*vt(3)
265  c(2) = bfield(1)*vt(3) - bfield(3)*vt(1)
266  c(3) = bfield(2)*vt(1) - bfield(1)*vt(2)
267 
268  !rhs = vi + sign * DF^{-T} * c
269  do j=1,3
270  rhs(j)= vi(j) + qmdt*(jmat(1,j)*c(1)+jmat(2,j)*c(2)+jmat(3,j)*c(3))
271  end do
272  err = maxval(abs(vnew - rhs))
273  vnew = rhs
274  end if
275  i = i + 1
276  end do
277  call sll_s_compute_particle_boundary_trafo( self%boundary_particles, self%counter_left, self%counter_right, self%map, xi, xnew, vnew )
278  else !Predictor-Corrector with loop for corrector step
279  !Transformation of the v coordinates, !VT = DF^{-1} * vi
280  do j=1,3
281  vt(j) = jmat(j,1)*vi(1) + jmat(j,2)*vi(2) + jmat(j,3)*vi(3)
282  end do
283  !c = VT x bfield
284  c(1)=bfield(3)*vt(2)-bfield(2)*vt(3)
285  c(2)=bfield(1)*vt(3)-bfield(3)*vt(1)
286  c(3)=bfield(2)*vt(1)-bfield(1)*vt(2)
287  !rhs = vi + sign * DF^{-T} * c
288  do j=1,3
289  vnew(j)= vi(j) + qmdt*(jmat(1,j)*c(1)+jmat(2,j)*c(2)+jmat(3,j)*c(3))
290  end do
291  !x^\star=\mod(x^n+dt*DF^{-1}(x^n)v^n,1)
292  xnew = xi + dt * vt
293 
294  err= max( maxval(abs(xi - xnew)), maxval(abs(vi - vnew)) )
295  i = 0
296  do while(i < self%max_iter .and. err > self%iter_tolerance)
297  xbar = 0.5_f64*(xnew+xi)
298  vbar = 0.5_f64*(vnew+vi)
299  call sll_s_compute_particle_boundary_simple( self%boundary_particles, self%counter_left, self%counter_right, xi, xbar)
300 
301  call self%particle_mesh_coupling%evaluate &
302  (xbar, [self%spline_degree(1), self%spline_degree(2)-1, self%spline_degree(3)-1], self%bfield_dofs(1:self%n_total0), bfield(1))
303  call self%particle_mesh_coupling%evaluate &
304  (xbar, [self%spline_degree(1)-1, self%spline_degree(2), self%spline_degree(3)-1],self%bfield_dofs(self%n_total0+1:self%n_total0+self%n_total1), bfield(2))
305  call self%particle_mesh_coupling%evaluate &
306  (xbar, [self%spline_degree(1)-1, self%spline_degree(2)-1, self%spline_degree(3)],self%bfield_dofs(self%n_total0+self%n_total1+1:self%n_total0+2*self%n_total1), bfield(3))
307 
308  jmat = self%map%jacobian_matrix_inverse( xbar )
309  !VT = DF^{-1} * vi
310  do j = 1, 3
311  vt(j) = jmat(j,1)*vbar(1) + jmat(j,2)*vbar(2)+ jmat(j,3)*vbar(3)
312  end do
313  xbar = xi + dt * vt
314  !c = VT x bfield
315  c(1)=bfield(3)*vt(2)-bfield(2)*vt(3)
316  c(2)=bfield(1)*vt(3)-bfield(3)*vt(1)
317  c(3)=bfield(2)*vt(1)-bfield(1)*vt(2)
318  !rhs = vi + sign * DF^{-T} * c
319  do j=1,3
320  rhs(j)= vi(j) + qmdt*(jmat(1,j)*c(1)+jmat(2,j)*c(2)+jmat(3,j)*c(3))
321  end do
322 
323  err = max( maxval(abs(xnew - xbar)), maxval(abs(vnew - rhs)) )
324  xnew = xbar
325  vnew = rhs
326  i = i + 1
327  end do
328  end if
329  ! Get charge for accumulation of j
330  wi = self%particle_group%group(i_sp)%get_charge(i_part, self%i_weight)
331  call sll_s_compute_particle_boundary_trafo_current( self%boundary_particles, self%counter_left, self%counter_right, self%map, self%particle_mesh_coupling, self%j_dofs_local, self%spline_degree, self%rhob, xi, xnew, vnew, wi )
332 
333 
334  call self%particle_group%group(i_sp)%set_x( i_part, xnew )
335  call self%particle_group%group(i_sp)%set_v( i_part, vnew )
336  ! Update particle weights
337  if (self%particle_group%group(i_sp)%n_weights == 3 ) then
338  wall = self%particle_group%group(i_sp)%get_weights(i_part)
339  wall(3) = self%control_variate%cv(i_sp)%update_df_weight( xnew, vnew, 0.0_f64, wall(1), wall(2) )
340  call self%particle_group%group(i_sp)%set_weights( i_part, wall )
341  end if
342  end do
343  end do
344 
345  self%j_dofs = 0.0_f64
346  ! MPI to sum up contributions from each processor
347  call sll_o_collective_allreduce( sll_v_world_collective, self%j_dofs_local, &
348  self%n_total1+2*self%n_total0, mpi_sum, self%j_dofs)
349 
350  if( self%adiabatic_electrons) then
351  call self%maxwell_solver%compute_phi_from_j( self%j_dofs, self%phi_dofs, self%efield_dofs )
352  else
353  call self%maxwell_solver%compute_E_from_j( self%betar(2)*self%j_dofs, self%efield_dofs )
354  end if
355 
356  end subroutine operatorhp_pic_vm_3d3v_hs_trafo
357 
358 
359  !---------------------------------------------------------------------------!
362  subroutine operatorhb_pic_vm_3d3v_hs_trafo ( self, dt )
363  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent( inout ) :: self
364  sll_real64, intent( in ) :: dt
365 
366  call self%maxwell_solver%compute_E_from_B( self%betar(1)*dt, self%bfield_dofs, self%efield_dofs)
367 
368  end subroutine operatorhb_pic_vm_3d3v_hs_trafo
369 
370 
371  !---------------------------------------------------------------------------!
375  subroutine operatorhe_pic_vm_3d3v_hs_trafo ( self, dt )
376  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent( inout ) :: self
377  sll_real64, intent( in ) :: dt
378  !local variables
379  sll_int32 :: i_part, j, i_sp
380  sll_real64 :: xi(3), vi(3), jmat(3,3)
381  sll_real64 :: efield(3), ephys(3), wall(self%i_weight), rx(3)
382  sll_real64 :: qoverm, q, m
383 
384  do i_sp = 1, self%particle_group%n_species
385  qoverm = self%particle_group%group(i_sp)%species%q_over_m();
386  q = self%particle_group%group(i_sp)%species%q
387  m = self%particle_group%group(i_sp)%species%m
388  do i_part = 1, self%particle_group%group(i_sp)%n_particles
389  ! Read out particle position and velocity
390  xi = self%particle_group%group(i_sp)%get_x(i_part)
391  vi = self%particle_group%group(i_sp)%get_v(i_part)
392 
393  ! Evaulate E at particle position and propagate v
394  call self%particle_mesh_coupling%evaluate &
395  (xi, [self%spline_degree(1)-1, self%spline_degree(2), self%spline_degree(3)], self%efield_dofs(1:self%n_total1), efield(1))
396  call self%particle_mesh_coupling%evaluate &
397  (xi, [self%spline_degree(1), self%spline_degree(2)-1, self%spline_degree(3)],self%efield_dofs(self%n_total1+1:self%n_total1+self%n_total0), efield(2))
398  call self%particle_mesh_coupling%evaluate &
399  (xi, [self%spline_degree(1), self%spline_degree(2), self%spline_degree(3)-1],self%efield_dofs(self%n_total1+self%n_total0+1:self%n_total1+2*self%n_total0), efield(3))
400 
401  jmat=self%map%jacobian_matrix_inverse_transposed(xi)
402  do j=1, 3
403  ephys(j) = jmat(j,1)* efield(1)+jmat(j,2)* efield(2)+jmat(j,3)* efield(3)
404  end do
405 
406  if( self%lindf .eqv. .false.) then
407  ! velocity update
408  vi = vi + dt* qoverm * ephys
409  call self%particle_group%group(i_sp)%set_v( i_part, vi )
410 
411  ! Update particle weights
412  if (self%particle_group%group(i_sp)%n_weights == 3 ) then
413  wall = self%particle_group%group(i_sp)%get_weights(i_part)
414  wall(3) = self%control_variate%cv(i_sp)%update_df_weight( xi, vi, 0.0_f64, wall(1), wall(2) )
415  call self%particle_group%group(i_sp)%set_weights( i_part, wall )
416  end if
417  else
418  ! Update particle weights
419  wall = self%particle_group%group(i_sp)%get_weights(i_part)
420  select type(p => self%control_variate%cv(i_sp)%control_variate_distribution_params)
422  rx = xi
423  rx(1) = self%map%get_x1(xi) + m*vi(2)/q
424  rx(1) = (rx(1)-self%x_min(1))/self%Lx(1)
425 
426  wall(1) = wall(1) + dt* (q/p%profile%T_i(rx(1)) *sum(ephys*vi) -&
427  ephys(2)*(p%profile%drho_0(rx(1))/p%profile%rho_0(rx(1))+(0.5_f64*m*sum(vi**2)/p%profile%T_i(rx(1)) - 1.5_f64)* p%profile%dT_i(rx(1))/p%profile%T_i(rx(1)) ) ) *&
428  self%control_variate%cv(i_sp)%control_variate(rx, vi, 0._f64)/p%eval_v_density(vi, xi, m)* self%map%jacobian(xi)
429  class default
430  wall(1) = wall(1) + dt* qoverm* sum(ephys*vi) * self%map%jacobian(xi)
431  end select
432  call self%particle_group%group(i_sp)%set_weights( i_part, wall )
433  end if
434  end do
435  end do
436 
437  if(self%electrostatic .eqv. .false.) then
438  call self%maxwell_solver%compute_B_from_E( dt, self%efield_dofs, self%bfield_dofs)
439  end if
440 
441  end subroutine operatorhe_pic_vm_3d3v_hs_trafo
442 
443 
444  !---------------------------------------------------------------------------!
447  self, &
448  maxwell_solver, &
449  particle_mesh_coupling, &
450  particle_group, &
451  phi_dofs, &
452  efield_dofs, &
453  bfield_dofs, &
454  x_min, &
455  Lx, &
456  map, &
457  boundary_particles, &
458  iter_tolerance, max_iter, &
459  betar, &
460  electrostatic, &
461  rhob, &
462  control_variate)
463  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent( out ) :: self
464  class(sll_c_maxwell_3d_base), target, intent( in ) :: maxwell_solver
465  class(sll_c_particle_mesh_coupling_3d), target, intent(in) :: particle_mesh_coupling
466  class(sll_t_particle_array), target, intent( in ) :: particle_group
467  sll_real64, target, intent( in ) :: phi_dofs(:)
468  sll_real64, target, intent( in ) :: efield_dofs(:)
469  sll_real64, target, intent( in ) :: bfield_dofs(:)
470  sll_real64, intent( in ) :: x_min(3)
471  sll_real64, intent( in ) :: lx(3)
472  type(sll_t_mapping_3d), target, intent( inout ) :: map
473  sll_int32, optional, intent( in ) :: boundary_particles
474  sll_real64, optional, intent( in ) :: iter_tolerance
475  sll_int32, optional, intent( in ) :: max_iter
476  sll_real64, optional, intent( in ) :: betar(2)
477  logical, optional, intent( in ) :: electrostatic
478  sll_real64, optional, target, intent( in ) :: rhob(:)
479  class(sll_t_control_variates), optional, target, intent(in) :: control_variate
480  !local variables
481  sll_int32 :: ierr
482 
483  if (present(iter_tolerance) ) then
484  self%iter_tolerance = iter_tolerance
485  self%max_iter = max_iter
486  else
487  self%iter_tolerance = 1d-12
488  self%max_iter = 10
489  end if
490 
491  if( present(electrostatic) )then
492  self%electrostatic = electrostatic
493  end if
494 
495  if (present(boundary_particles) ) then
496  self%boundary_particles = boundary_particles
497  end if
498 
499  if( present(rhob) )then
500  self%rhob => rhob
501  end if
502 
503  if( particle_group%group(1)%species%q > 0._f64) self%adiabatic_electrons = .true.
504 
505  self%maxwell_solver => maxwell_solver
506  self%particle_mesh_coupling => particle_mesh_coupling
507  self%particle_group => particle_group
508  self%phi_dofs => phi_dofs
509  self%efield_dofs => efield_dofs
510  self%bfield_dofs => bfield_dofs
511  self%n_total0 = self%maxwell_solver%n_total0
512  self%n_total1 = self%maxwell_solver%n_total1
513  self%spline_degree = self%particle_mesh_coupling%spline_degree
514  self%x_min = x_min
515  self%x_max = x_min + lx
516  self%Lx = lx
517  self%map => map
518 
519  sll_allocate( self%j_dofs(1:self%n_total1+self%n_total0*2), ierr )
520  sll_allocate( self%j_dofs_local(1:self%n_total1+self%n_total0*2), ierr )
521  self%j_dofs = 0.0_f64
522  self%j_dofs_local = 0.0_f64
523 
524  if (present(betar)) then
525  self%betar = betar
526  else
527  self%betar = 1.0_f64
528  end if
529 
530  if (present(control_variate)) then
531  allocate(self%control_variate )
532  allocate(self%control_variate%cv(self%particle_group%n_species) )
533  self%control_variate => control_variate
534  if(self%particle_group%group(1)%n_weights == 1 ) self%lindf = .true.
535  self%i_weight = self%particle_group%group(1)%n_weights
536  end if
537 
538  end subroutine initialize_pic_vm_3d3v_hs_trafo
539 
540 
543  self, &
544  maxwell_solver, &
545  particle_mesh_coupling, &
546  particle_group, &
547  phi_dofs, &
548  efield_dofs, &
549  bfield_dofs, &
550  x_min, &
551  Lx, &
552  map, &
553  filename, &
554  boundary_particles, &
555  betar, &
556  electrostatic, &
557  rhob, &
558  control_variate)
559  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent( out ) :: self
560  class(sll_c_maxwell_3d_base), target, intent( in ) :: maxwell_solver
561  class(sll_c_particle_mesh_coupling_3d), target, intent(in) :: particle_mesh_coupling
562  class(sll_t_particle_array), target, intent( in ) :: particle_group
563  sll_real64, target, intent( in ) :: phi_dofs(:)
564  sll_real64, target, intent( in ) :: efield_dofs(:)
565  sll_real64, target, intent( in ) :: bfield_dofs(:)
566  sll_real64, intent( in ) :: x_min(3)
567  sll_real64, intent( in ) :: lx(3)
568  type(sll_t_mapping_3d), target, intent( inout ) :: map
569  character(len=*), intent( in ) :: filename
570  sll_int32, optional, intent( in ) :: boundary_particles
571  sll_real64, optional, intent( in ) :: betar(2)
572  logical, optional :: electrostatic
573  sll_real64, optional, target, intent( in ) :: rhob(:)
574  class(sll_t_control_variates), optional, target, intent(in) :: control_variate
575  !local variables
576  sll_int32 :: input_file
577  sll_int32 :: io_stat
578  sll_real64 :: iter_tolerance
579  sll_int32 :: max_iter, boundary_particles_set
580  logical :: electrostatic_set
581  sll_real64 :: betar_set(2)
582 
583  namelist /time_iterate/ iter_tolerance, max_iter
584 
585  if( present(boundary_particles) )then
586  boundary_particles_set = boundary_particles
587  else
588  boundary_particles_set = 100
589  end if
590 
591  if( present(electrostatic) )then
592  electrostatic_set = electrostatic
593  else
594  electrostatic_set = .false.
595  end if
596 
597  if( present(betar) )then
598  betar_set = betar
599  else
600  betar_set = 1._f64
601  end if
602 
603  ! Read in solver tolerance
604  open(newunit = input_file, file=filename, status='old',iostat=io_stat)
605  if (io_stat /= 0) then
606  print*, 'sll_m_time_propagator_pic_vm_3d3v_hs_trafo: Input file does not exist. Set default tolerance.'
607  if( present( control_variate ) )then
608  call self%init( maxwell_solver, &
609  particle_mesh_coupling, &
610  particle_group, &
611  phi_dofs,&
612  efield_dofs, &
613  bfield_dofs, &
614  x_min, &
615  lx, &
616  map, &
617  boundary_particles_set, &
618  betar=betar_set,&
619  electrostatic = electrostatic_set, &
620  rhob = rhob, &
621  control_variate = control_variate)
622  else
623  call self%init( maxwell_solver, &
624  particle_mesh_coupling, &
625  particle_group, &
626  phi_dofs,&
627  efield_dofs, &
628  bfield_dofs, &
629  x_min, &
630  lx, &
631  map, &
632  boundary_particles_set, &
633  betar=betar_set,&
634  electrostatic = electrostatic_set, &
635  rhob = rhob)
636  end if
637  else
638  read(input_file, time_iterate,iostat=io_stat)
639  if (io_stat /= 0 ) then
640  if( present( control_variate ) )then
641  call self%init( maxwell_solver, &
642  particle_mesh_coupling, &
643  particle_group, &
644  phi_dofs,&
645  efield_dofs, &
646  bfield_dofs, &
647  x_min, &
648  lx, &
649  map, &
650  boundary_particles_set, &
651  betar=betar_set,&
652  electrostatic = electrostatic_set, &
653  rhob = rhob, &
654  control_variate = control_variate)
655  else
656  call self%init( maxwell_solver, &
657  particle_mesh_coupling, &
658  particle_group, &
659  phi_dofs,&
660  efield_dofs, &
661  bfield_dofs, &
662  x_min, &
663  lx, &
664  map, &
665  boundary_particles_set, &
666  betar=betar_set,&
667  electrostatic = electrostatic_set, &
668  rhob = rhob)
669  end if
670  else
671  if( present( control_variate ) )then
672  call self%init( maxwell_solver, &
673  particle_mesh_coupling, &
674  particle_group, &
675  phi_dofs,&
676  efield_dofs, &
677  bfield_dofs, &
678  x_min, &
679  lx, &
680  map, &
681  boundary_particles_set, &
682  iter_tolerance, max_iter, &
683  betar=betar_set,&
684  electrostatic = electrostatic_set, &
685  rhob = rhob, &
686  control_variate = control_variate)
687  else
688  call self%init( maxwell_solver, &
689  particle_mesh_coupling, &
690  particle_group, &
691  phi_dofs,&
692  efield_dofs, &
693  bfield_dofs, &
694  x_min, &
695  lx, &
696  map, &
697  boundary_particles_set, &
698  iter_tolerance, max_iter, &
699  betar=betar_set,&
700  electrostatic = electrostatic_set, &
701  rhob = rhob)
702  end if
703  end if
704  close(input_file)
705  end if
706 
707 
709 
710 
711  !---------------------------------------------------------------------------!
714  class(sll_t_time_propagator_pic_vm_3d3v_hs_trafo), intent( inout ) :: self
715 
716  deallocate( self%j_dofs )
717  deallocate( self%j_dofs_local )
718 
719  self%maxwell_solver => null()
720  self%particle_mesh_coupling => null()
721  self%particle_group => null()
722  self%phi_dofs => null()
723  self%efield_dofs => null()
724  self%bfield_dofs => null()
725  self%map => null()
726 
727 
728 
729  end subroutine delete_pic_vm_3d3v_hs_trafo
730 
731 
732 
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.
Parameters to define common initial distributions.
Module interfaces for coordinate transformation.
Module interface to solve Maxwell's equations in 3D.
Base class for kernel smoothers for accumulation and field evaluation in PIC.
functions for initial profile of the particle distribution function
Base class for Hamiltonian splittings.
Particle pusher based on antisymmetric splitting with AVF for 3d3v Vlasov-Maxwell with coordinate tra...
subroutine, public sll_s_compute_particle_boundary_simple(boundary_particles, counter_left, counter_right, xold, xnew)
compute new position
subroutine, public sll_s_compute_particle_boundary_trafo_current(boundary_particles, counter_left, counter_right, map, particle_mesh_coupling, j_dofs_local, spline_degree, rhob, xold, xnew, vi, wi)
Compute particle boundary and current with coordinate transformation.
subroutine, public sll_s_compute_particle_boundary_trafo(boundary_particles, counter_left, counter_right, map, xold, xnew, vi)
Compute particle boundary with coordinate transformation.
Particle pusher based on Hamiltonian splitting for 3d3v Vlasov-Maxwell with coordinate transformation...
subroutine strang_splitting_pic_vm_3d3v_hs_trafo(self, dt, number_steps)
Finalization.
subroutine initialize_pic_vm_3d3v_hs_trafo(self, maxwell_solver, particle_mesh_coupling, particle_group, phi_dofs, efield_dofs, bfield_dofs, x_min, Lx, map, boundary_particles, iter_tolerance, max_iter, betar, electrostatic, rhob, control_variate)
Constructor.
subroutine operatorhb_pic_vm_3d3v_hs_trafo(self, dt)
Push H_B: Equations to be solved $M_1 e^{n+1}=M_1 e^n+\Delta t C^\top M_2 b^n$.
subroutine initialize_file_pic_vm_3d3v_hs_trafo(self, maxwell_solver, particle_mesh_coupling, particle_group, phi_dofs, efield_dofs, bfield_dofs, x_min, Lx, map, filename, boundary_particles, betar, electrostatic, rhob, control_variate)
Constructor.
subroutine lie_splitting_back_pic_vm_3d3v_hs_trafo(self, dt, number_steps)
Lie splitting (oposite ordering)
subroutine lie_splitting_pic_vm_3d3v_hs_trafo(self, dt, number_steps)
Lie splitting.
subroutine operatorhe_pic_vm_3d3v_hs_trafo(self, dt)
Push H_E: Equations to be solved $V^{n+1}=V^n+\Delta t\mathbb{W}_{\frac{q}{m}} DF^{-\top}(\Xi^n) \mat...
subroutine operatorhp_pic_vm_3d3v_hs_trafo(self, dt)
Push H_p: Equations to be solved $\Xi^{n+1}=\Xi^n+ \Delta t DF^{-1}(\overline{\Xi})\overline{V}$,...
real(kind=f64) function, dimension(size(particle, 2)) control_variate(particle)
type collecting functions for analytical coordinate mapping
Hamiltonian splitting type for Vlasov-Maxwell 3d3v with coordinate transformation.
    Report Typos and Errors