8 #include "sll_assert.h"
9 #include "sll_memory.h"
10 #include "sll_working_precision.h"
46 sll_int32 :: spline_degree
51 sll_real64 :: cell_integrals_0(4)
52 sll_real64 :: cell_integrals_1(3)
55 sll_real64,
pointer :: efield_dofs(:,:)
56 sll_real64,
pointer :: efield_dofs_mid(:,:)
57 sll_real64,
pointer :: bfield_dofs(:)
58 sll_real64,
allocatable :: bfield_dofs_mid(:)
59 sll_real64,
allocatable :: j_dofs(:,:)
60 sll_real64,
allocatable :: j_dofs_local(:,:)
79 sll_real64,
intent(in) :: dt
80 sll_int32,
intent(in) :: number_steps
83 print*,
'Lie splitting not implemented in sll_m_time_propagator_pic_vm_1d2v_boris.'
90 sll_real64,
intent(in) :: dt
91 sll_int32,
intent(in) :: number_steps
95 do i_step = 1, number_steps
97 self%bfield_dofs_mid = self%bfield_dofs
98 call self%maxwell_solver%compute_B_from_E( &
99 dt, self%efield_dofs_mid(:,2), self%bfield_dofs)
100 self%bfield_dofs_mid = (self%bfield_dofs_mid + self%bfield_dofs)*0.5_f64
114 self%efield_dofs = self%efield_dofs_mid
116 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,1), 1, self%efield_dofs_mid(:,1))
119 call self%maxwell_solver%compute_E_from_B(&
120 dt, self%bfield_dofs, self%efield_dofs_mid(:,2))
121 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,2), 2, self%efield_dofs_mid(:,2))
130 sll_real64,
intent(in) :: dt
133 sll_int32 :: i_part, i_sp
134 sll_real64 :: v_new(3), xi(3)
135 sll_real64 :: efield(2)
139 do i_sp =1, self%particle_group%n_species
140 qm = self%particle_group%group(i_sp)%species%q_over_m();
142 do i_part=1,self%particle_group%group(i_sp)%n_particles
144 xi = self%particle_group%group(i_sp)%get_x(i_part)
145 call self%kernel_smoother_1%evaluate &
146 (xi(1), self%efield_dofs_mid(:,1), efield(1))
147 call self%kernel_smoother_0%evaluate &
148 (xi(1), self%efield_dofs_mid(:,2), efield(2))
149 v_new = self%particle_group%group(i_sp)%get_v(i_part)
150 v_new(1:2) = v_new(1:2) + dt* qm * efield
151 call self%particle_group%group(i_sp)%set_v(i_part, v_new)
161 sll_real64,
intent(in) :: dt
164 sll_int32 :: i_part, i_sp
165 sll_real64 :: vi(3), v_new(3), xi(3)
166 sll_real64 :: bfield, m11, m12
169 do i_sp =1, self%particle_group%n_species
170 qmdt = self%particle_group%group(i_sp)%species%q_over_m()*0.5_f64*dt;
172 do i_part=1,self%particle_group%group(i_sp)%n_particles
173 vi= self%particle_group%group(i_sp)%get_v(i_part)
174 xi = self%particle_group%group(i_sp)%get_x(i_part)
175 call self%kernel_smoother_1%evaluate &
176 (xi(1), self%bfield_dofs_mid, bfield)
179 m11 = 1.0_f64/(1.0_f64 + bfield**2)
180 m12 = m11*bfield*2.0_f64
181 m11 = m11*(1-bfield**2)
183 v_new(1) = m11 * vi(1) + m12 * vi(2)
184 v_new(2) = - m12 * vi(1) + m11 * vi(2)
187 call self%particle_group%group(i_sp)%set_v(i_part, v_new)
197 sll_real64,
intent(in) :: dt
200 sll_int32 :: i_part, i_sp
201 sll_real64 :: x_new(3), vi(3), wi(1), x_old(3)
206 n_cells = self%kernel_smoother_0%n_dofs
209 self%j_dofs_local = 0.0_f64
215 do i_sp =1, self%particle_group%n_species
216 qoverm = self%particle_group%group(i_sp)%species%q_over_m();
217 do i_part=1,self%particle_group%group(i_sp)%n_particles
219 x_old = self%particle_group%group(i_sp)%get_x(i_part)
220 vi = self%particle_group%group(i_sp)%get_v(i_part)
223 x_new = x_old + dt * vi
226 wi = self%particle_group%group(i_sp)%get_charge(i_part)
235 call self%kernel_smoother_1%add_current( x_old(1), x_new(1), wi(1), self%j_dofs_local(:,1) )
236 if ( abs(vi(1)) > 1e-15_f64 )
then
237 call self%kernel_smoother_0%add_current( x_old(1), x_new(1), wi(1)*vi(2)/vi(1), self%j_dofs_local(:,2) )
239 call self%kernel_smoother_0%add_charge( [(x_old(1)+x_new(1))*0.5_f64], wi(1)*vi(2)*dt , &
240 self%j_dofs_local(:,2))
243 x_new(1) = modulo(x_new(1), self%Lx)
244 call self%particle_group%group(i_sp)%set_x(i_part, x_new)
249 self%j_dofs = 0.0_f64
252 n_cells, mpi_sum, self%j_dofs(:,1))
254 n_cells, mpi_sum, self%j_dofs(:,2))
276 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
277 sll_real64,
target,
intent(in) :: bfield_dofs(:)
278 sll_real64,
intent(in) :: x_min
279 sll_real64,
intent(in) :: lx
284 self%maxwell_solver => maxwell_solver
285 self%kernel_smoother_0 => kernel_smoother_0
286 self%kernel_smoother_1 => kernel_smoother_1
287 self%particle_group => particle_group
288 self%efield_dofs => efield_dofs
289 self%bfield_dofs => bfield_dofs
293 sll_assert( self%kernel_smoother_0%n_dofs == self%kernel_smoother_1%n_dofs )
295 sll_allocate(self%j_dofs(self%kernel_smoother_0%n_dofs,2), ierr)
296 sll_allocate(self%j_dofs_local(self%kernel_smoother_0%n_dofs,2), ierr)
297 sll_allocate(self%bfield_dofs_mid(self%kernel_smoother_1%n_dofs), ierr)
298 sll_allocate(self%efield_dofs_mid(self%kernel_smoother_1%n_dofs,2), ierr)
300 self%spline_degree = self%kernel_smoother_0%spline_degree
303 self%delta_x = self%Lx/real(self%kernel_smoother_1%n_dofs, f64)
305 self%cell_integrals_1 = [0.5_f64, 2.0_f64, 0.5_f64]
306 self%cell_integrals_1 = self%cell_integrals_1 / 3.0_f64
308 self%cell_integrals_0 = [1.0_f64,11.0_f64,11.0_f64,1.0_f64]
309 self%cell_integrals_0 = self%cell_integrals_0 / 24.0_f64
319 deallocate(self%j_dofs)
320 deallocate(self%j_dofs_local)
321 deallocate(self%bfield_dofs_mid)
322 deallocate(self%efield_dofs_mid)
323 self%maxwell_solver => null()
324 self%kernel_smoother_0 => null()
325 self%kernel_smoother_1 => null()
326 self%particle_group => null()
327 self%efield_dofs => null()
328 self%bfield_dofs => null()
337 sll_real64,
intent(in) :: dt
342 self%efield_dofs_mid = self%efield_dofs
345 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,1), 1, self%efield_dofs_mid(:,1))
348 call self%maxwell_solver%compute_E_from_B(&
349 dt*0.5_f64, self%bfield_dofs, self%efield_dofs_mid(:,2))
350 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,2), 2, self%efield_dofs_mid(:,2))
Combines values from all processes and distributes the result back to all processes.
type(sll_t_collective_t), pointer, public sll_v_world_collective
Control of subset assignment. Processes with the same color are in the same new communicator.
Module interface to solve Maxwell's equations in 1D.
Base class for kernel smoothers for accumulation and field evaluation in PIC.
Base class for Hamiltonian splittings.
Boris pusher in GEMPIC framework (spline finite elements)
subroutine push_x_accumulate_j(self, dt)
Pusher for x and accumulate current densities.
subroutine push_v_epart(self, dt)
Pusher for E \nabla_v part.
subroutine operator_boris(self, dt, number_steps)
Second order Boris pusher using staggered grid.
subroutine delete_pic_vm_1d2v_boris(self)
Destructor.
subroutine lie_boris(self, dt, number_steps)
Initialize the staggering.
subroutine push_v_bpart(self, dt)
Pusher for vxB part.
subroutine staggering_pic_vm_1d2v_boris(self, dt)
Propagate E_0 to E_{1/2} and x_0 to x_{1/2} to initialize the staggering.
subroutine initialize_pic_vm_1d2v_boris(self, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx)
Constructor.
Basic type of a kernel smoother used for PIC simulations.
Type for Hamiltonian splittings.
Solves 1d2v Vlasov-Maxwell with PIC and spline finite elements with Boris pusher.