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_cl_helper.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_time_propagator_base, only: &
14 
15  use sll_m_mapping_3d, only: &
17 
20 
21 
22  implicit none
23 
24  public :: &
34 
35  private
36  !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
37 
38  sll_int32, parameter :: sll_p_boundary_particles_periodic = 0
39  sll_int32, parameter :: sll_p_boundary_particles_singular = 1
40  sll_int32, parameter :: sll_p_boundary_particles_reflection = 2
41  sll_int32, parameter :: sll_p_boundary_particles_absorption = 3
42 
45  class(sll_c_particle_mesh_coupling_3d), pointer :: particle_mesh_coupling
46  type( sll_t_mapping_3d ), pointer :: map
47 
48  sll_real64, allocatable :: j_dofs_local(:)
49  sll_real64, allocatable :: efield_dofs_work(:)
50 
51  sll_int32 :: spline_degree(3)
52  sll_real64 :: lx(3)
53  sll_real64 :: x_min(3)
54  sll_real64 :: x_max(3)
55  sll_int32 :: boundary_particles = sll_p_boundary_particles_periodic
56 
57 
58  sll_real64, pointer :: rhob(:) => null()
59  sll_int32 :: counter_left = 0
60  sll_int32 :: counter_right = 0
61 
63 
64 contains
65 
67  subroutine sll_s_compute_matrix_inverse( x, y, bf, jm, sign)
68  sll_real64, intent( in ) :: x(:)
69  sll_real64, intent( out ) :: y(:)
70  sll_real64, intent( in ) :: bf(3)
71  sll_real64, intent( in ) :: jm(3,3)
72  sll_real64, intent( in ) :: sign
73  !local variables
74  sll_real64 :: a,b,c,d,e,f,g,h,i
75  sll_real64 :: det
76 
77  a = 1-sign*( jm(1,1)*(jm(2,1)*bf(3)-jm(3,1)*bf(2)) + jm(2,1)*(jm(3,1)*bf(1)-jm(1,1)*bf(3)) + jm(3,1)*(jm(1,1)*bf(2)-jm(2,1)*bf(1)) )
78  d = -sign*( jm(1,2)*(jm(2,1)*bf(3)-jm(3,1)*bf(2)) + jm(2,2)*(jm(3,1)*bf(1)-jm(1,1)*bf(3)) + jm(3,2)*(jm(1,1)*bf(2)-jm(2,1)*bf(1)) )
79  g = -sign*( jm(1,3)*(jm(2,1)*bf(3)-jm(3,1)*bf(2)) + jm(2,3)*(jm(3,1)*bf(1)-jm(1,1)*bf(3)) + jm(3,3)*(jm(1,1)*bf(2)-jm(2,1)*bf(1)) )
80 
81  b = -sign*( jm(1,1)*(jm(2,2)*bf(3)-jm(3,2)*bf(2)) + jm(2,1)*(jm(3,2)*bf(1)-jm(1,2)*bf(3)) + jm(3,1)*(jm(1,2)*bf(2)-jm(2,2)*bf(1)) )
82  e = 1-sign*( jm(1,2)*(jm(2,2)*bf(3)-jm(3,2)*bf(2)) + jm(2,2)*(jm(3,2)*bf(1)-jm(1,2)*bf(3)) + jm(3,2)*(jm(1,2)*bf(2)-jm(2,2)*bf(1)) )
83  h = -sign*( jm(1,3)*(jm(2,2)*bf(3)-jm(3,2)*bf(2)) + jm(2,3)*(jm(3,2)*bf(1)-jm(1,2)*bf(3)) + jm(3,3)*(jm(1,2)*bf(2)-jm(2,2)*bf(1)) )
84 
85  c = -sign*( jm(1,1)*(jm(2,3)*bf(3)-jm(3,3)*bf(2)) + jm(2,1)*(jm(3,3)*bf(1)-jm(1,3)*bf(3)) + jm(3,1)*(jm(1,3)*bf(2)-jm(2,3)*bf(1)) )
86  f = -sign*( jm(1,2)*(jm(2,3)*bf(3)-jm(3,3)*bf(2)) + jm(2,2)*(jm(3,3)*bf(1)-jm(1,3)*bf(3)) + jm(3,2)*(jm(1,3)*bf(2)-jm(2,3)*bf(1)) )
87  i = 1-sign*( jm(1,3)*(jm(2,3)*bf(3)-jm(3,3)*bf(2)) + jm(2,3)*(jm(3,3)*bf(1)-jm(1,3)*bf(3)) + jm(3,3)*(jm(1,3)*bf(2)-jm(2,3)*bf(1)) )
88 
89  det = a*e*i + b*f*g + c*d*h - c*e*g - a*f*h - b*d*i
90 
91  y(1) = ( x(1)*(e*i - f*h) + x(2)*(c*h - b*i) + x(3)*(b*f - c*e) )/det
92  y(2) = ( x(1)*(f*g - d*i) + x(2)*(a*i - c*g) + x(3)*(c*d - a*f) )/det
93  y(3) = ( x(1)*(d*h - e*g) + x(2)*(b*g - a*h) + x(3)*(a*e - b*d) )/det
94 
95  end subroutine sll_s_compute_matrix_inverse
96 
97 
99  subroutine compute_particle_boundary( self, xold, xnew, vi )
100  class(sll_t_time_propagator_pic_vm_3d3v_cl_helper), intent( inout ) :: self
101  sll_real64, intent( inout ) :: xold(3)
102  sll_real64, intent( inout ) :: xnew(3)
103  sll_real64, intent( inout ) :: vi(3)
104  !local variables
105  sll_real64 :: xbar
106 
107  if(xnew(1) < self%x_min(1) .or. xnew(1) > self%x_max(1) )then
108  if(xnew(1) < self%x_min(1) )then
109  xbar = self%x_min(1)
110  self%counter_left = self%counter_left+1
111  else if(xnew(1) > self%x_max(1))then
112  xbar = self%x_max(1)
113  self%counter_right = self%counter_right+1
114  end if
115 
116 
117  select case(self%boundary_particles)
119  xnew(1) = 2._f64*xbar-xnew(1)
120  vi(1) = -vi(1)
123  xnew(1) = self%x_min(1) + modulo(xnew(1)-self%x_min(1), self%Lx(1))
124  case default
125  print*,'error: boundary case missing', self%boundary_particles
126  end select
127  end if
128  xnew(2:3) = self%x_min(2:3) + modulo(xnew(2:3)-self%x_min(2:3), self%Lx(2:3))
129 
130  end subroutine compute_particle_boundary
131 
132 
134  subroutine compute_particle_boundary_trafo( self, xold, xnew, vi )
135  class(sll_t_time_propagator_pic_vm_3d3v_cl_helper), intent( inout ) :: self
136  sll_real64, intent( inout ) :: xold(3)
137  sll_real64, intent( inout ) :: xnew(3)
138  sll_real64, intent( inout ) :: vi(3)
139  !local variables
140  sll_real64 :: xmid(3), xt(3), xbar, dx
141  sll_real64 :: jmatrix(3,3)
142 
143  if(xnew(1) < 0._f64 .or. xnew(1) > 1._f64 )then
144  if(xnew(1) < 0._f64 )then
145  xbar = 0._f64
146  self%counter_left = self%counter_left+1
147  else if(xnew(1) > 1._f64)then
148  xbar = 1._f64
149  self%counter_right = self%counter_right+1
150  end if
151  dx = (xbar- xold(1))/(xnew(1)-xold(1))
152  xmid = xold + dx * (xnew-xold)
153  xmid(1) = xbar
154 
155  select case(self%boundary_particles)
157  if(xnew(1) < 0._f64 )then
158  xnew(1) = -xnew(1)
159  xnew(2) = xnew(2) + 0.5_f64
160  else if(xnew(1) > 1._f64 )then
161  jmatrix = self%map%jacobian_matrix_inverse_transposed(xmid)
162  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
163  xnew(1) = 2._f64 - xnew(1)
164  xnew(2) = 1._f64 - xnew(2)
165  end if
167  xt = xmid
168  xt(2:3) = modulo(xt(2:3),1._f64)
169  jmatrix = self%map%jacobian_matrix_inverse_transposed(xt)
170  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
171  xnew(1) = 2._f64*xbar-xnew(1)
174  xnew(1) = modulo(xnew(1), 1._f64)
175  case default
176  print*,'error: boundary case missing', self%boundary_particles
177  end select
178  else if(xnew(1) < -1._f64 .or. xnew(1) > 2._f64 ) then
179  print*, xnew
180  sll_error("particle boundary", "particle out of bound")
181  end if
182  xnew(2:3) = modulo(xnew(2:3), 1._f64)
183 
184  end subroutine compute_particle_boundary_trafo
185 
186 
188  subroutine compute_particle_boundary_trafo_current( self, xold, xnew, vi, wi )
189  class(sll_t_time_propagator_pic_vm_3d3v_cl_helper), intent( inout ) :: self
190  sll_real64, intent( in ) :: xold(3)
191  sll_real64, intent( inout ) :: xnew(3)
192  sll_real64, intent( inout ) :: vi(3)
193  sll_real64, intent( in ) :: wi(1)
194  !local variables
195  sll_real64 :: xmid(3), xt(3), vt(3), xbar, dx
196  sll_real64 :: jmatrix(3,3)
197 
198  if(xnew(1) < 0._f64 .or. xnew(1) > 1._f64 )then
199  if(xnew(1) < 0._f64 )then
200  xbar = 0._f64
201  self%counter_left = self%counter_left+1
202  else if(xnew(1) > 1._f64)then
203  xbar = 1._f64
204  self%counter_right = self%counter_right+1
205  end if
206 
207  dx = (xbar- xold(1))/(xnew(1)-xold(1))
208  xmid = xold + dx * (xnew-xold)
209  xmid(1) = xbar
210  vt = (xmid - xold)*wi(1)
211  call self%particle_mesh_coupling%add_current( xold, xmid, vt, self%j_dofs_local )
212  select case(self%boundary_particles)
214  call self%particle_mesh_coupling%add_charge(xmid, wi(1), self%spline_degree, self%rhob)
215  xmid(2) = xbar + (1._f64-2._f64*xbar)*xmid(2) + 0.5_f64-0.5_f64*xbar
216  call self%particle_mesh_coupling%add_charge(xmid, -wi(1), self%spline_degree, self%rhob)
217  xnew(1) = 2._f64*xbar-xnew(1)
218  xnew(2) = xbar + (1._f64-2._f64*xbar)*xnew(2) + 0.5_f64-0.5_f64*xbar
219 
220  if(xnew(1) > 1._f64 )then
221  xt = xmid
222  xt(2:3) = modulo(xt(2:3),1._f64)
223  jmatrix = self%map%jacobian_matrix_inverse_transposed(xt)
224  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
225  end if
227  xt = xmid
228  xt(2:3) = modulo(xt(2:3),1._f64)
229  jmatrix = self%map%jacobian_matrix_inverse_transposed(xt)
230  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
231  xnew(1) = 2._f64*xbar-xnew(1)
233  call self%particle_mesh_coupling%add_charge(xmid, wi(1), self%spline_degree, self%rhob)
235  xnew(1) = modulo(xnew(1), 1._f64)
236  xmid(1) = 1._f64-xbar
237  case default
238  print*,'error: boundary case missing', self%boundary_particles
239  end select
240  if(xnew(1) >= 0._f64 .and. xnew(1) <= 1._f64) then
241  vt = (xnew - xmid)*wi(1)
242  call self%particle_mesh_coupling%add_current( xmid, xnew, vt, self%j_dofs_local )
243  end if
244  else if(xnew(1) < -1._f64 .or. xnew(1) > 2._f64)then
245  print*, xnew
246  sll_error("particle boundary", "particle out of bound")
247  else
248  vt = (xnew - xold)*wi(1)
249  call self%particle_mesh_coupling%add_current( xold, xnew, vt, self%j_dofs_local )
250  end if
251  xnew(2:3) = modulo(xnew(2:3), 1._f64)
252 
254 
255 
257  subroutine compute_particle_boundary_current_trafo_evaluate( self, xold, xnew, vi, wi, sign )
258  class(sll_t_time_propagator_pic_vm_3d3v_cl_helper), intent( inout ) :: self
259  sll_real64, intent( in ) :: xold(3)
260  sll_real64, intent( inout ) :: xnew(3)
261  sll_real64, intent( inout ) :: vi(3)
262  sll_real64, intent( in ) :: wi(1)
263  sll_real64, intent( in ) :: sign
264  !local variables
265  sll_real64 :: xmid(3), xt(3), vt(3), xbar, dx
266  sll_real64 :: jmatrix(3,3), jmat(3,3), efield(3)
267  sll_int32 :: j
268 
269  if(xnew(1) < 0._f64 .or. xnew(1) > 1._f64 )then
270  if(xnew(1) < 0._f64 )then
271  xbar = 0._f64
272  self%counter_left = self%counter_left+1
273  else if(xnew(1) > 1._f64)then
274  xbar = 1._f64
275  self%counter_right = self%counter_right+1
276  end if
277  dx = (xbar- xold(1))/(xnew(1)-xold(1))
278  xmid = xold + dx * (xnew-xold)
279  xmid(1) = xbar
280  vt = (xmid - xold)*wi(1)
281  call self%particle_mesh_coupling%add_current_evaluate( xold, xmid, vt, self%efield_dofs_work, &
282  self%j_dofs_local, efield )
283  jmat = self%map%jacobian_matrix_inverse_transposed(xold)
284  xt = xmid
285  xt(2:3) = modulo(xt(2:3), 1._f64)
286  jmatrix = self%map%jacobian_matrix_inverse_transposed(xt)
287  do j = 1, 3
288  vi(j) = vi(j) + dx*sign *0.5_f64*((jmatrix(j,1)+jmat(j,1))*efield(1) + (jmatrix(j,2)+jmat(j,2))*efield(2) + (jmatrix(j,3)+ jmat(j,3))*efield(3))
289  end do
290  select case(self%boundary_particles)
292  call self%particle_mesh_coupling%add_charge(xmid, wi(1), self%spline_degree, self%rhob)
293  xmid(2) = xbar + (1._f64-2._f64*xbar)*xmid(2) + 0.5_f64-0.5_f64*xbar
294  xt(2:3) = modulo(xt(2:3), 1._f64)
295  jmatrix = self%map%jacobian_matrix_inverse_transposed(xt)
296  call self%particle_mesh_coupling%add_charge(xmid, -wi(1), self%spline_degree, self%rhob)
297  xnew(1) = 2._f64*xbar-xnew(1)
298  xnew(2) = xbar + (1._f64-2._f64*xbar)*xnew(2) + 0.5_f64-0.5_f64*xbar
299  if(xnew(1) > 1._f64 )then
300  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
301  end if
303  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
304  xnew(1) = 2._f64*xbar-xnew(1)
306  call self%particle_mesh_coupling%add_charge(xmid, wi(1), self%spline_degree, self%rhob)
308  xnew(1) = modulo(xnew(1), 1._f64)
309  xmid(1) = 1._f64-xbar
310  case default
311  print*,'error: boundary case missing', self%boundary_particles
312  end select
313  vt = (xnew - xmid)*wi(1)
314  call self%particle_mesh_coupling%add_current_evaluate( xmid, xnew, vt, self%efield_dofs_work, &
315  self%j_dofs_local, efield )
316  xnew(2:3) = modulo(xnew(2:3), 1._f64)
317  jmat = self%map%jacobian_matrix_inverse_transposed(xnew)
318  do j = 1, 3
319  vi(j) = vi(j) + (1._f64-dx)*sign *0.5_f64*((jmatrix(j,1)+jmat(j,1))*efield(1) + (jmatrix(j,2)+jmat(j,2))*efield(2) + (jmatrix(j,3)+ jmat(j,3))*efield(3))
320  end do
321  else if(xnew(1) < -1._f64 .or. xnew(1) > 2._f64)then
322  print*, xnew
323  sll_error("particle boundary", "particle out of bound")
324  else
325  vt = (xnew - xold)*wi(1)
326  call self%particle_mesh_coupling%add_current_evaluate( xold, xnew, vt, self%efield_dofs_work, &
327  self%j_dofs_local, efield )
328  jmat = self%map%jacobian_matrix_inverse_transposed(xold)
329  xnew(2:3) = modulo(xnew(2:3), 1._f64)
330  jmatrix = self%map%jacobian_matrix_inverse_transposed(xnew)
331  do j = 1, 3
332  vi(j) = vi(j) + sign *0.5_f64*((jmatrix(j,1)+jmat(j,1))*efield(1) + (jmatrix(j,2)+jmat(j,2))*efield(2) + (jmatrix(j,3)+ jmat(j,3))*efield(3))
333  end do
334  end if
335 
336 
337 
338 
340 
341 
342 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1
344  subroutine sll_s_compute_particle_boundary_simple( boundary_particles, counter_left, counter_right, xold, xnew )
345  sll_int32, intent( in ) :: boundary_particles
346  sll_int32, intent( inout ) :: counter_left
347  sll_int32, intent( inout ) :: counter_right
348  sll_real64, intent( inout ) :: xold(3)
349  sll_real64, intent( inout ) :: xnew(3)
350  !local variables
351  sll_real64 :: xbar
352 
353  if(xnew(1) < -1._f64 .or. xnew(1) > 2._f64 ) then
354  print*, xnew
355  sll_error("particle boundary", "particle out of bound")
356  else if(xnew(1) < 0._f64 .or. xnew(1) > 1._f64 )then
357  if(xnew(1) < 0._f64 )then
358  xbar = 0._f64
359  counter_left = counter_left+1
360  else if(xnew(1) > 1._f64)then
361  xbar = 1._f64
362  counter_right = counter_right+1
363  end if
364  select case(boundary_particles)
366  if(xnew(1) < 0._f64 )then
367  xnew(1) = -xnew(1)
368  xnew(2) = xnew(2) + 0.5_f64
369  else if(xnew(1) > 1._f64 )then
370  xnew(1) = 2._f64 - xnew(1)
371  xnew(2) = 1._f64 - xnew(2)
372  end if
374  xnew(1) = 2._f64*xbar-xnew(1)
377  xnew(1) = modulo(xnew(1), 1._f64)
378  case default
379  xnew(1) = modulo(xnew(1), 1._f64)
380  end select
381  end if
382  xnew(2:3) = modulo(xnew(2:3), 1._f64)
383 
385 
386 
388  subroutine sll_s_compute_particle_boundary_trafo( boundary_particles, counter_left, counter_right, map, xold, xnew, vi )
389  sll_int32, intent( in ) :: boundary_particles
390  sll_int32, intent( inout ) :: counter_left
391  sll_int32, intent( inout ) :: counter_right
392  type( sll_t_mapping_3d ), intent( inout ) :: map
393  sll_real64, intent( inout ) :: xold(3)
394  sll_real64, intent( inout ) :: xnew(3)
395  sll_real64, intent( inout ) :: vi(3)
396  !local variables
397  sll_real64 :: xmid(3), xt(3), xbar, dx
398  sll_real64 :: jmatrix(3,3)
399 
400  if(xnew(1) < 0._f64 .or. xnew(1) > 1._f64 )then
401  if(xnew(1) < 0._f64 )then
402  xbar = 0._f64
403  counter_left = counter_left+1
404  else if(xnew(1) > 1._f64)then
405  xbar = 1._f64
406  counter_right = counter_right+1
407  end if
408  dx = (xbar- xold(1))/(xnew(1)-xold(1))
409  xmid = xold + dx * (xnew-xold)
410  xmid(1) = xbar
411 
412  select case(boundary_particles)
414  if(xnew(1) < 0._f64 )then
415  xnew(1) = -xnew(1)
416  xnew(2) = xnew(2) + 0.5_f64
417  else if(xnew(1) > 1._f64 )then
418  jmatrix = map%jacobian_matrix_inverse_transposed(xmid)
419  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
420  xnew(1) = 2._f64 - xnew(1)
421  xnew(2) = 1._f64 - xnew(2)
422  end if
424  xt = xmid
425  xt(2:3) = modulo(xt(2:3),1._f64)
426  jmatrix = map%jacobian_matrix_inverse_transposed(xt)
427  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
428  xnew(1) = 2._f64*xbar-xnew(1)
431  xnew(1) = modulo(xnew(1), 1._f64)
432  case default
433  xnew(1) = modulo(xnew(1), 1._f64)
434  end select
435  else if(xnew(1) < -1._f64 .or. xnew(1) > 2._f64 ) then
436  print*, xnew
437  sll_error("particle boundary", "particle out of bound")
438  end if
439  xnew(2:3) = modulo(xnew(2:3), 1._f64)
440 
442 
443 
445  subroutine 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 )
446  sll_int32, intent( in ) :: boundary_particles
447  sll_int32, intent( inout ) :: counter_left
448  sll_int32, intent( inout ) :: counter_right
449  type( sll_t_mapping_3d ), intent( inout ) :: map
450  class(sll_c_particle_mesh_coupling_3d), intent( inout ) :: particle_mesh_coupling
451  sll_real64, intent( inout ) :: j_dofs_local(:)
452  sll_int32, intent( in ) :: spline_degree(3)
453  sll_real64, intent( inout ) :: rhob(:)
454  sll_real64, intent( in ) :: xold(3)
455  sll_real64, intent( inout ) :: xnew(3)
456  sll_real64, intent( inout ) :: vi(3)
457  sll_real64, intent( in ) :: wi(1)
458  !local variables
459  sll_real64 :: xmid(3), xt(3), vh(3), xbar, dx
460  sll_real64 :: jmatrix(3,3)
461 
462  if(xnew(1) < 0._f64 .or. xnew(1) > 1._f64 )then
463  if(xnew(1) < 0._f64 )then
464  xbar = 0._f64
465  counter_left = counter_left+1
466  else if(xnew(1) > 1._f64)then
467  xbar = 1._f64
468  counter_right = counter_right+1
469  end if
470 
471  dx = (xbar- xold(1))/(xnew(1)-xold(1))
472  xmid = xold + dx * (xnew-xold)
473  xmid(1) = xbar
474  vh = (xmid - xold)*wi(1)
475  call particle_mesh_coupling%add_current( xold, xmid, vh, j_dofs_local )
476  select case(boundary_particles)
478  call particle_mesh_coupling%add_charge(xmid, wi(1), spline_degree, rhob)
479  xmid(2) = xbar + (1._f64-2._f64*xbar)*xmid(2) + 0.5_f64-0.5_f64*xbar
480  call particle_mesh_coupling%add_charge(xmid, -wi(1), spline_degree, rhob)
481  xnew(1) = 2._f64*xbar-xnew(1)
482  xnew(2) = xbar + (1._f64-2._f64*xbar)*xnew(2) + 0.5_f64-0.5_f64*xbar
483 
484  if(xnew(1) > 1._f64 )then
485  xt = xmid
486  xt(2:3) = modulo(xt(2:3),1._f64)
487  jmatrix = map%jacobian_matrix_inverse_transposed(xt)
488  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
489  end if
491  xt = xmid
492  xt(2:3) = modulo(xt(2:3),1._f64)
493  jmatrix = map%jacobian_matrix_inverse_transposed(xt)
494  vi = vi-2._f64*(vi(1)*jmatrix(1,1)+vi(2)*jmatrix(2,1)+vi(3)*jmatrix(3,1))*jmatrix(:,1)/sum(jmatrix(:,1)**2)
495  xnew(1) = 2._f64*xbar-xnew(1)
497  call particle_mesh_coupling%add_charge(xmid, wi(1), spline_degree, rhob)
499  xnew(1) = modulo(xnew(1), 1._f64)
500  xmid(1) = 1._f64-xbar
501  case default
502  xnew(1) = modulo(xnew(1), 1._f64)
503  xmid(1) = 1._f64-xbar
504  end select
505  else if(xnew(1) < -1._f64 .or. xnew(1) > 2._f64 ) then
506  print*, xnew
507  sll_error("particle boundary", "particle out of bound")
508  else
509  xmid = xold
510  end if
511  vh = (xnew - xmid)*wi(1)
512  call particle_mesh_coupling%add_current( xmid, xnew, vh, j_dofs_local )
513  xnew(2:3) = modulo(xnew(2:3), 1._f64)
514 
516 
517 
Module interfaces for coordinate transformation.
Base class for kernel smoothers for accumulation and field evaluation in PIC.
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_matrix_inverse(x, y, bf, jm, sign)
invert matrix
subroutine compute_particle_boundary_trafo(self, xold, xnew, vi)
compute particle boundary with coordinate transformation
subroutine compute_particle_boundary_current_trafo_evaluate(self, xold, xnew, vi, wi, sign)
compute particle boundary and current with coordinate transformation and evaluate efield
subroutine compute_particle_boundary_trafo_current(self, 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.
subroutine compute_particle_boundary(self, xold, xnew, vi)
Compute particle boundary.
type collecting functions for analytical coordinate mapping
    Report Typos and Errors