8 #include "sll_assert.h"
9 #include "sll_memory.h"
10 #include "sll_working_precision.h"
51 sll_int32 :: spline_degree
53 sll_real64 :: x_min(2)
59 sll_real64,
pointer :: efield_dofs(:)
60 sll_real64,
pointer :: bfield_dofs(:)
61 sll_real64,
allocatable :: j_dofs(:)
62 sll_real64,
allocatable :: j_dofs_local(:)
66 sll_int32 :: i_weight = 1
89 sll_real64,
intent(in) :: dt
90 sll_int32,
intent(in) :: number_steps
94 do i_step = 1, number_steps
95 call self%operatorHB(0.5_f64*dt)
96 call self%operatorHE(0.5_f64*dt)
97 call self%operatorHp3(0.5_f64*dt)
98 call self%operatorHp2(0.5_f64*dt)
99 call self%operatorHp1(dt)
100 call self%operatorHp2(0.5_f64*dt)
101 call self%operatorHp3(0.5_f64*dt)
102 call self%operatorHE(0.5_f64*dt)
103 call self%operatorHB(0.5_f64*dt)
112 sll_real64,
intent(in) :: dt
113 sll_int32,
intent(in) :: number_steps
117 do i_step = 1,number_steps
118 call self%operatorHE(dt)
119 call self%operatorHB(dt)
120 call self%operatorHp1(dt)
121 call self%operatorHp2(dt)
122 call self%operatorHp3(dt)
131 sll_real64,
intent(in) :: dt
132 sll_int32,
intent(in) :: number_steps
136 do i_step = 1,number_steps
137 call self%operatorHp3(dt)
138 call self%operatorHp2(dt)
139 call self%operatorHp1(dt)
140 call self%operatorHB(dt)
141 call self%operatorHE(dt)
157 sll_real64,
intent(in) :: dt
160 sll_int32 :: i_part, i_sp
161 sll_real64 :: x_new(3), vi(3), wi(1), x_old(3), wall(3)
164 sll_int32 :: i_weight
166 i_weight = self%i_weight
168 n_cells = self%maxwell_solver%n_total
180 self%j_dofs_local = 0.0_f64
184 do i_sp = 1, self%particle_group%n_species
185 qoverm = self%particle_group%group(i_sp)%species%q_over_m();
186 do i_part=1,self%particle_group%group(i_sp)%n_particles
188 x_old = self%particle_group%group(i_sp)%get_x(i_part)
189 vi = self%particle_group%group(i_sp)%get_v(i_part)
192 x_new(1) = x_old(1) + dt * vi(1)
193 x_new(2:3) = x_old(2:3)
196 wi = self%particle_group%group(i_sp)%get_charge(i_part, i_weight)
198 call self%particle_mesh_coupling%add_current_update_v_component1( x_old, x_new(1), wi(1), qoverm, &
199 self%bfield_dofs, vi, self%j_dofs_local)
201 x_new(1) = modulo(x_new(1), self%Lx(1))
202 call self%particle_group%group(i_sp)%set_x(i_part, x_new)
203 call self%particle_group%group(i_sp)%set_v(i_part, vi)
206 if (self%particle_group%group(i_sp)%n_weights == 3 )
then
207 wall = self%particle_group%group(i_sp)%get_weights(i_part)
208 wall(3) = self%control_variate%cv(i_sp)%update_df_weight( x_new, vi, 0.0_f64, wall(1), wall(2) )
209 call self%particle_group%group(i_sp)%set_weights( i_part, wall )
214 self%j_dofs = 0.0_f64
217 n_cells, mpi_sum, self%j_dofs)
220 call self%maxwell_solver%compute_E_from_j(self%j_dofs, 1, self%efield_dofs(1:self%ntotal))
228 sll_real64,
intent(in) :: dt
231 sll_int32 :: i_part, i_sp
232 sll_real64 :: x_new(3), vi(3), wi(1), x_old(3), wall(3)
235 sll_int32 :: i_weight
237 i_weight = self%i_weight
239 n_cells = self%maxwell_solver%n_total
241 self%j_dofs_local = 0.0_f64
245 do i_sp = 1, self%particle_group%n_species
246 qoverm = self%particle_group%group(i_sp)%species%q_over_m();
247 do i_part=1,self%particle_group%group(i_sp)%n_particles
249 x_old = self%particle_group%group(i_sp)%get_x(i_part)
250 vi = self%particle_group%group(i_sp)%get_v(i_part)
253 x_new(2) = x_old(2) + dt * vi(2)
257 wi = self%particle_group%group(i_sp)%get_charge(i_part, i_weight)
259 call self%particle_mesh_coupling%add_current_update_v_component2( x_old, x_new(2), wi(1), qoverm, &
260 self%bfield_dofs, vi, self%j_dofs_local)
262 x_new(2) = modulo(x_new(2), self%Lx(2))
263 call self%particle_group%group(i_sp)%set_x(i_part, x_new)
264 call self%particle_group%group(i_sp)%set_v(i_part, vi)
268 if (self%particle_group%group(i_sp)%n_weights == 3 )
then
269 wall = self%particle_group%group(i_sp)%get_weights(i_part)
270 wall(3) = self%control_variate%cv(i_sp)%update_df_weight( x_new, vi, 0.0_f64, wall(1), wall(2) )
271 call self%particle_group%group(i_sp)%set_weights( i_part, wall )
277 self%j_dofs = 0.0_f64
280 n_cells, mpi_sum, self%j_dofs)
283 call self%maxwell_solver%compute_E_from_j(self%j_dofs, 2, self%efield_dofs(self%ntotal+1:2*self%ntotal))
291 sll_real64,
intent(in) :: dt
294 sll_int32 :: i_part, i_sp
295 sll_real64 :: vi(3), wi(1), x_old(3), wall(3)
298 sll_real64 :: bfield(2)
299 sll_int32 :: i_weight
301 i_weight = self%i_weight
303 n_cells = self%maxwell_solver%n_total
305 self%j_dofs_local = 0.0_f64
309 do i_sp = 1, self%particle_group%n_species
310 qoverm = self%particle_group%group(i_sp)%species%q_over_m();
311 do i_part=1,self%particle_group%group(i_sp)%n_particles
313 x_old = self%particle_group%group(i_sp)%get_x(i_part)
314 vi = self%particle_group%group(i_sp)%get_v(i_part)
316 wi = self%particle_group%group(i_sp)%get_charge(i_part, i_weight)
318 call self%particle_mesh_coupling%evaluate &
319 (x_old(1:2), [self%spline_degree, self%spline_degree-1], &
320 self%bfield_dofs(1:self%ntotal), bfield(1))
321 call self%particle_mesh_coupling%evaluate &
322 (x_old(1:2), [self%spline_degree-1, self%spline_degree], &
323 self%bfield_dofs(self%ntotal+1:self%ntotal*2), bfield(2))
325 vi(1) = vi(1) - dt *qoverm*vi(3)*bfield(2)
326 vi(2) = vi(2) + dt *qoverm*vi(3)*bfield(1)
329 call self%particle_mesh_coupling%add_charge( x_old(1:2), wi(1)*vi(3), &
330 [self%spline_degree, self%spline_degree], self%j_dofs_local )
332 call self%particle_group%group(i_sp)%set_v(i_part, vi)
336 if (self%particle_group%group(i_sp)%n_weights == 3 )
then
337 wall = self%particle_group%group(i_sp)%get_weights(i_part)
338 wall(3) = self%control_variate%cv(i_sp)%update_df_weight( x_old, vi, 0.0_f64, wall(1), wall(2) )
339 call self%particle_group%group(i_sp)%set_weights( i_part, wall )
345 self%j_dofs = 0.0_f64
348 n_cells, mpi_sum, self%j_dofs)
351 self%j_dofs = self%j_dofs*dt
352 call self%maxwell_solver%compute_E_from_j(self%j_dofs, 3, self%efield_dofs(2*self%ntotal+1:3*self%ntotal))
365 sll_real64,
intent(in) :: dt
368 sll_int32 :: i_part, i_sp
369 sll_real64 :: v_new(3), xi(3), wall(3)
370 sll_real64 :: efield(3)
372 sll_int32 :: i_weight
374 i_weight = self%i_weight
380 do i_sp = 1, self%particle_group%n_species
381 qm = self%particle_group%group(i_sp)%species%q_over_m();
383 do i_part=1,self%particle_group%group(i_sp)%n_particles
384 v_new = self%particle_group%group(i_sp)%get_v(i_part)
386 xi = self%particle_group%group(i_sp)%get_x(i_part)
389 call self%particle_mesh_coupling%evaluate &
390 (xi(1:2), [self%spline_degree-1, self%spline_degree], &
391 self%efield_dofs(1:self%ntotal), efield(1))
392 call self%particle_mesh_coupling%evaluate &
393 (xi(1:2), [self%spline_degree, self%spline_degree-1], &
394 self%efield_dofs(self%ntotal+1:2*self%ntotal), efield(2))
395 call self%particle_mesh_coupling%evaluate &
396 (xi(1:2), [self%spline_degree, self%spline_degree], &
397 self%efield_dofs(2*self%ntotal+1:3*self%ntotal), efield(3))
399 v_new = v_new + dt* qm * efield
400 call self%particle_group%group(i_sp)%set_v(i_part, v_new)
404 if (self%particle_group%group(i_sp)%n_weights == 3 )
then
405 wall = self%particle_group%group(i_sp)%get_weights(i_part)
406 wall(3) = self%control_variate%cv(i_sp)%update_df_weight( xi, v_new, 0.0_f64, wall(1), wall(2) )
407 call self%particle_group%group(i_sp)%set_weights( i_part, wall )
413 call self%maxwell_solver%compute_B_from_E( &
414 dt, self%efield_dofs, self%bfield_dofs)
427 sll_real64,
intent(in) :: dt
430 call self%maxwell_solver%compute_E_from_B(&
431 dt*self%betar, self%bfield_dofs, self%efield_dofs)
441 particle_mesh_coupling, &
453 sll_real64,
pointer,
intent(in) :: efield_dofs(:)
454 sll_real64,
pointer,
intent(in) :: bfield_dofs(:)
455 sll_real64,
intent(in) :: x_min(2)
456 sll_real64,
intent(in) :: lx(2)
458 sll_real64,
optional,
intent(in) :: betar
462 self%maxwell_solver => maxwell_solver
463 self%particle_mesh_coupling => particle_mesh_coupling
464 self%particle_group => particle_group
465 self%efield_dofs => efield_dofs
466 self%bfield_dofs => bfield_dofs
468 self%ntotal =self%particle_mesh_coupling%n_dofs
469 sll_allocate(self%j_dofs(self%ntotal), ierr)
470 sll_allocate(self%j_dofs_local(self%ntotal), ierr)
472 self%spline_degree = self%particle_mesh_coupling%spline_degree
476 if (
present(control_variate))
then
477 allocate(self%control_variate )
478 allocate(self%control_variate%cv(particle_group%n_species) )
479 self%control_variate => control_variate
483 if (
present(betar))
then
496 deallocate(self%j_dofs)
497 deallocate(self%j_dofs_local)
498 self%maxwell_solver => null()
499 self%particle_mesh_coupling => null()
500 self%particle_group => null()
501 self%efield_dofs => null()
502 self%bfield_dofs => null()
512 particle_mesh_coupling, &
524 sll_real64,
pointer,
intent(in) :: efield_dofs(:)
525 sll_real64,
pointer,
intent(in) :: bfield_dofs(:)
526 sll_real64,
intent(in) :: x_min(2)
527 sll_real64,
intent(in) :: lx(2)
529 sll_real64,
intent( in ),
optional :: betar
536 select type (splitting)
539 if (
present(betar) )
then
540 call splitting%init(&
542 particle_mesh_coupling, &
551 call splitting%init(&
553 particle_mesh_coupling, &
562 if (
present(betar) )
then
563 call splitting%init(&
565 particle_mesh_coupling, &
573 call splitting%init(&
575 particle_mesh_coupling, &
593 particle_mesh_coupling, &
603 sll_real64,
pointer,
intent(in) :: efield_dofs(:)
604 sll_real64,
pointer,
intent(in) :: bfield_dofs(:)
605 sll_real64,
intent(in) :: x_min(2)
606 sll_real64,
intent(in) :: lx(2)
612 select type (splitting)
614 call splitting%init(&
616 particle_mesh_coupling, &
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 2D The linear systems are solved based on FFT diagno...
Particle mesh coupling for 3d with splines of arbitrary degree placed on a uniform tensor product mes...
Base class for Hamiltonian splittings.
Particle pusher based on Hamiltonian splitting for 2d3v Vlasov-Maxwell.
subroutine operatorhe_pic_vm_2d3v_hs(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, public sll_s_new_time_propagator_pic_vm_2d3v_hs(splitting, maxwell_solver, particle_mesh_coupling, particle_group, efield_dofs, bfield_dofs, x_min, Lx, control_variate, betar)
Constructor for allocatable abstract type.
subroutine lie_splitting_back_pic_vm_2d3v_hs(self, dt, number_steps)
Lie splitting (oposite ordering)
subroutine delete_pic_vm_2d3v_hs(self)
Destructor.
subroutine initialize_pic_vm_2d3v_hs(self, maxwell_solver, particle_mesh_coupling, particle_group, efield_dofs, bfield_dofs, x_min, Lx, control_variate, betar)
Constructor.
subroutine lie_splitting_pic_vm_2d3v_hs(self, dt, number_steps)
Lie splitting.
subroutine, public sll_s_new_time_propagator_pic_vm_2d3v_hs_ptr(splitting, maxwell_solver, particle_mesh_coupling, particle_group, efield_dofs, bfield_dofs, x_min, Lx)
Constructor for pointer abstract type.
subroutine operatorhp2_pic_vm_2d3v_hs(self, dt)
Push Hp2: Equations to solve are.
subroutine operatorhb_pic_vm_2d3v_hs(self, dt)
Push H_B: Equations to be solved V_new = V_old \partial_t E_1 = 0 -> E_{1,new} = E_{1,...
subroutine operatorhp1_pic_vm_2d3v_hs(self, dt)
Push Hp1: Equations to solve are TODO: UPDATE \partial_t f + v_1 \partial_{x_1} f = 0 -> X_new = X_ol...
subroutine operatorhp3_pic_vm_2d3v_hs(self, dt)
Push Hp3: Equations to solve are.
subroutine strang_splitting_pic_vm_2d3v_hs(self, dt, number_steps)
Finalization.
real(kind=f64) function, dimension(size(particle, 2)) control_variate(particle)
Particle mesh coupling in 3d based on (arbitrary degree) spline on a tensor product uniform mesh.
Type for Hamiltonian splittings.
Hamiltonian splitting type for Vlasov-Maxwell 1d2v.