8 #include "sll_assert.h"
9 #include "sll_memory.h"
10 #include "sll_working_precision.h"
51 sll_int32 :: spline_degree
56 sll_real64,
pointer :: efield_dofs(:,:)
57 sll_real64,
pointer :: bfield_dofs(:)
58 sll_real64,
allocatable :: j_dofs(:,:)
59 sll_real64,
allocatable :: j_dofs_local(:,:)
61 logical :: electrostatic = .false.
63 sll_int32 :: max_iter = 1
64 sll_real64 :: iter_tolerance = 1d-10
85 sll_real64,
intent(in) :: dt
86 sll_int32,
intent(in) :: number_steps
90 if(self%electrostatic)
then
91 do i_step = 1, number_steps
92 call self%operatorHE(0.5_f64*dt)
93 call self%operatorHp(dt)
94 call self%operatorHE(0.5_f64*dt)
97 do i_step = 1, number_steps
98 call self%operatorHB(0.5_f64*dt)
99 call self%operatorHE(0.5_f64*dt)
100 call self%operatorHp(dt)
101 call self%operatorHE(0.5_f64*dt)
102 call self%operatorHB(0.5_f64*dt)
112 sll_real64,
intent(in) :: dt
113 sll_int32,
intent(in) :: number_steps
117 if(self%electrostatic)
then
118 do i_step = 1, number_steps
119 call self%operatorHE(dt)
120 call self%operatorHp(dt)
123 do i_step = 1,number_steps
124 call self%operatorHE(dt)
125 call self%operatorHB(dt)
126 call self%operatorHp(dt)
137 sll_real64,
intent(in) :: dt
138 sll_int32,
intent(in) :: number_steps
142 if(self%electrostatic)
then
143 do i_step = 1, number_steps
144 call self%operatorHp(dt)
145 call self%operatorHE(dt)
148 do i_step = 1,number_steps
149 call self%operatorHp(dt)
150 call self%operatorHB(dt)
151 call self%operatorHE(dt)
167 sll_real64,
intent(in) :: dt
169 sll_int32 :: i_part, i_sp, i
170 sll_real64 :: x_new(3), v_new(3), vi(3), wi(1), xi(3), xbar(3), vbar(3)
172 sll_real64 :: jmatrix(3,3)
173 sll_real64 :: qmdt, err
174 sll_real64 :: bfield, rhs(2)
177 n_cells = self%kernel_smoother_0%n_dofs
180 self%j_dofs_local = 0.0_f64
182 do i_sp = 1, self%particle_group%n_species
183 qmdt = self%particle_group%group(i_sp)%species%q_over_m()*dt;
184 do i_part=1,self%particle_group%group(i_sp)%n_particles
186 xi = self%particle_group%group(i_sp)%get_x(i_part)
187 vi = self%particle_group%group(i_sp)%get_v(i_part)
190 jmatrix=self%map%jacobian_matrix_inverse([xi(1), 0._f64, 0._f64])
193 x_new(1) = xi(1) + dt * jmatrix(1,1)*vi(1)
195 call self%kernel_smoother_1%evaluate &
196 (xi(1), self%bfield_dofs, bfield)
199 v_new(1) = vi(1) + qmdt*jmatrix(1,1)*bfield*vi(2)
200 v_new(2) = vi(2) - qmdt*bfield*jmatrix(1,1)*vi(1)
203 err= max( abs(xi(1) - x_new(1)), maxval(abs(vi(1:2) - v_new(1:2))) )
205 do while(i < self%max_iter .and. err > self%iter_tolerance)
206 xbar(1) = modulo(0.5_f64*(x_new(1)+xi(1)), 1._f64)
207 vbar = 0.5_f64*(v_new+vi)
209 jmatrix = self%map%jacobian_matrix_inverse( [xbar(1),0._f64,0._f64] )
211 call self%kernel_smoother_1%evaluate &
212 (xbar(1), self%bfield_dofs, bfield)
214 xbar(1) = xi(1) + dt * jmatrix(1,1)*vbar(1)
216 rhs(1) = vi(1) + qmdt*jmatrix(1,1)*bfield*vbar(2)
217 rhs(2) = vi(2) - qmdt*bfield*jmatrix(1,1)*vbar(1)
219 err = max(abs(x_new(1) - xbar(1)), maxval(abs(v_new(1:2) - rhs(1:2))) )
225 wi = self%particle_group%group(i_sp)%get_charge(i_part)
227 if ( abs(vbar(1))> 1d-16 )
then
228 call self%kernel_smoother_1%add_current( xi(1), x_new(1), wi(1), self%j_dofs_local(:,1) )
229 call self%kernel_smoother_0%add_current( xi(1), x_new(1), wi(1)*vbar(2)/(jmatrix(1,1)*vbar(1)), self%j_dofs_local(:,2) )
231 call self%kernel_smoother_0%add_charge( xi(1), wi(1)*dt*vbar(2), self%j_dofs_local(:,2) )
234 x_new(1) = modulo(x_new(1), 1._f64)
235 call self%particle_group%group(i_sp)%set_x(i_part, x_new)
236 call self%particle_group%group(i_sp)%set_v( i_part, v_new )
241 self%j_dofs = 0.0_f64
244 n_cells, mpi_sum, self%j_dofs(:,1))
247 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,1), 1, self%efield_dofs(:,1))
250 n_cells, mpi_sum, self%j_dofs(:,2))
252 call self%maxwell_solver%compute_E_from_j(self%j_dofs(:,2), 2, self%efield_dofs(:,2))
265 sll_real64,
intent(in) :: dt
267 sll_int32 :: i_part, i_sp
268 sll_real64 :: vi(3), xi(3)
269 sll_real64 :: efield(2)
270 sll_real64 :: qoverm, jmat(3,3)
272 do i_sp = 1, self%particle_group%n_species
273 qoverm = self%particle_group%group(i_sp)%species%q_over_m();
275 do i_part=1,self%particle_group%group(i_sp)%n_particles
276 xi = self%particle_group%group(i_sp)%get_x(i_part)
277 vi = self%particle_group%group(i_sp)%get_v(i_part)
280 call self%kernel_smoother_1%evaluate &
281 (xi(1), self%efield_dofs(:,1), efield(1))
282 call self%kernel_smoother_0%evaluate &
283 (xi(1), self%efield_dofs(:,2), efield(2))
285 jmat = self%map%jacobian_matrix_inverse_transposed( [xi(1), 0._f64, 0._f64] )
287 vi(1) = vi(1) + dt* qoverm * jmat(1,1)* efield(1)
288 vi(2) = vi(2) + dt* qoverm * jmat(2,2)*efield(2)
289 call self%particle_group%group(i_sp)%set_v(i_part, vi)
294 if(self%electrostatic .eqv. .false.)
then
295 call self%maxwell_solver%compute_B_from_E( &
296 dt, self%efield_dofs(:,2), self%bfield_dofs)
310 sll_real64,
intent(in) :: dt
313 call self%maxwell_solver%compute_E_from_B(&
314 dt, self%bfield_dofs, self%efield_dofs(:,2))
338 sll_real64,
target,
intent(in) :: efield_dofs(:,:)
339 sll_real64,
target,
intent(in) :: bfield_dofs(:)
340 sll_real64,
intent(in) :: x_min
341 sll_real64,
intent(in) :: lx
343 logical,
optional :: electrostatic
347 if(
present(electrostatic) )
then
348 self%electrostatic = electrostatic
351 self%maxwell_solver => maxwell_solver
352 self%kernel_smoother_0 => kernel_smoother_0
353 self%kernel_smoother_1 => kernel_smoother_1
354 self%particle_group => particle_group
355 self%efield_dofs => efield_dofs
356 self%bfield_dofs => bfield_dofs
360 sll_assert( self%kernel_smoother_0%n_dofs == self%kernel_smoother_1%n_dofs )
362 sll_allocate(self%j_dofs(self%kernel_smoother_0%n_dofs,2), ierr)
363 sll_allocate(self%j_dofs_local(self%kernel_smoother_0%n_dofs,2), ierr)
365 self%spline_degree = self%kernel_smoother_0%spline_degree
368 self%delta_x = 1._f64/real(self%kernel_smoother_1%n_dofs,f64)
378 deallocate(self%j_dofs)
379 deallocate(self%j_dofs_local)
380 self%maxwell_solver => null()
381 self%kernel_smoother_0 => null()
382 self%kernel_smoother_1 => null()
383 self%particle_group => null()
384 self%efield_dofs => null()
385 self%bfield_dofs => null()
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 interfaces for coordinate transformation.
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.
Particle pusher based on Hamiltonian splitting for 1d2v Vlasov-Maxwell with coordinate transformation...
subroutine strang_splitting_pic_vm_1d2v(self, dt, number_steps)
Finalization.
subroutine delete_pic_vm_1d2v(self)
Destructor.
subroutine lie_splitting_back_pic_vm_1d2v(self, dt, number_steps)
Lie splitting (oposite ordering)
subroutine operatorhb_pic_vm_1d2v(self, dt)
Push H_B: Equations to be solved V_new = V_old \partial_t E_1 = 0 -> E_{1,new} = E_{1,...
subroutine operatorhp_pic_vm_1d2v(self, dt)
Push Hp1: Equations to solve are \partial_t f + v_1 \partial_{x_1} f = 0 -> X_new = X_old + dt V_1 V_...
subroutine operatorhe_pic_vm_1d2v(self, dt)
Push H_E: Equations to be solved \partial_t f + E_1 \partial_{v_1} f + E_2 \partial_{v_2} f = 0 -> V_...
subroutine initialize_pic_vm_1d2v(self, maxwell_solver, kernel_smoother_0, kernel_smoother_1, particle_group, efield_dofs, bfield_dofs, x_min, Lx, map, electrostatic)
Constructor.
subroutine lie_splitting_pic_vm_1d2v(self, dt, number_steps)
Lie splitting.
type collecting functions for analytical coordinate mapping
Basic type of a kernel smoother used for PIC simulations.
Type for Hamiltonian splittings.
Hamiltonian splitting type for Vlasov-Maxwell 1d2v.