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