Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_operator_splitting_pic_vp_2d2v.F90
Go to the documentation of this file.
1 
6 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 #include "sll_memory.h"
8 #include "sll_working_precision.h"
9 
10  use sll_m_collective, only: &
13 
14  use sll_m_control_variate, only: &
16 
17  use sll_m_operator_splitting, only: &
19 
20  use sll_m_particle_group_base, only: &
22 
23  use sll_m_pic_poisson_base, only: &
25 
26  use mpi, only: &
27  mpi_sum
28 
29  implicit none
30 
31  public :: &
34 
35  private
36 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
37 
40  class(sll_c_pic_poisson), pointer :: pic_poisson
41  class(sll_c_particle_group_base), pointer :: particle_group
42 
43 
44  ! For version with control variate
45  class(sll_t_control_variate), pointer :: control_variate => null()
46  sll_int32 :: i_weight
47 
48  contains
49  procedure :: operatort => advection_x_pic_vp_2d2v
50  procedure :: operatorv => advection_v_pic_vp_2d2v
51  procedure :: strang_splitting => strang_splitting_pic_vp_2d2v
52  procedure :: field_solver => field_solver_vp_2d2v
53  procedure :: charge_deposition => charge_deposition_vp_2d2v
54 
57 
58 contains
59 
60  !---------------------------------------------------------------------------!
62  subroutine strang_splitting_pic_vp_2d2v(this, dt)
63  class(sll_t_operator_splitting_pic_vp_2d2v), intent(inout) :: this
64  sll_real64, intent(in) :: dt
65 
66 
67  call this%operatorT(0.5_f64*dt)
68  call this%charge_deposition()
69  call this%field_solver()
70  call this%operatorV(dt)
71  call this%operatorT(0.5_f64*dt)
72 
73 
74  end subroutine strang_splitting_pic_vp_2d2v
75 
76  !---------------------------------------------------------------------------!
77 
78 
79  !---------------------------------------------------------------------------!
81  subroutine advection_x_pic_vp_2d2v(this, dt)
82  class(sll_t_operator_splitting_pic_vp_2d2v), intent(inout) :: this
83  sll_real64, intent(in) :: dt
84 
85 
86  !local variables
87  sll_int32 :: i_part
88  sll_real64 :: x_new(3), vi(3)
89  sll_real64 :: wi(this%particle_group%n_weights)
90 
91  ! X_new = X_old + dt * V
92  do i_part=1,this%particle_group%n_particles
93  x_new = this%particle_group%get_x(i_part) + dt * this%particle_group%get_v(i_part)
94  call this%particle_group%set_x(i_part, x_new)
95 
96  if (this%particle_group%n_weights == 3) then
97  vi = this%particle_group%get_v(i_part)
98  ! Update weights if control variate
99  wi = this%particle_group%get_weights(i_part)
100  wi(3) = this%control_variate%update_df_weight( x_new(1:2), vi(1:2), 0.0_f64, wi(1), wi(2))
101  call this%particle_group%set_weights(i_part, wi)
102  end if
103  end do
104 
105 
106  end subroutine advection_x_pic_vp_2d2v
107 
108  !---------------------------------------------------------------------------!
109  ! Push v
110  subroutine advection_v_pic_vp_2d2v(this, dt)
111  class(sll_t_operator_splitting_pic_vp_2d2v), intent(inout) :: this
112  sll_real64, intent(in) :: dt
113 
114  !local variables
115  sll_int32 :: i_part
116  sll_real64 :: v_new(3)
117  sll_real64 :: efield(2)
118  sll_real64 :: qm
119  sll_real64 :: xi(3)
120  sll_real64 :: wall(3)
121 
122 
123  ! V_new = V_old + dt *q/m* E
124  qm = this%particle_group%species%q_over_m();
125  do i_part=1,this%particle_group%n_particles
126  ! Evaluate efields at particle position
127  xi = this%particle_group%get_x(i_part)
128  call this%pic_poisson%evaluate_field_single(xi(1:2), [1,2], efield)
129  v_new = this%particle_group%get_v(i_part)
130  v_new(1:2) = v_new(1:2) + dt * qm * efield
131  call this%particle_group%set_v(i_part, v_new)
132 
133  ! Update particle weights
134  if (this%particle_group%n_weights == 3) then
135  ! Update weights if control variate
136  wall = this%particle_group%get_weights(i_part)
137  wall(3) = this%control_variate%update_df_weight( xi(1:2), v_new(1:2), 0.0_f64, wall(1), wall(2))
138  call this%particle_group%set_weights(i_part, wall)
139  end if
140  end do
141 
142 
143  end subroutine advection_v_pic_vp_2d2v
144 
145  !---------------------------------------------------------------------------!
146  ! Charge deposition
147  subroutine charge_deposition_vp_2d2v(this)
148  class(sll_t_operator_splitting_pic_vp_2d2v), intent(inout) :: this
149 
150  sll_int32 :: i_part
151  sll_real64 :: xi(3)
152  sll_real64 :: wi
153 
154  ! Assemble right-hand-side
155  call this%pic_poisson%reset()
156  do i_part = 1, this%particle_group%n_particles
157  xi = this%particle_group%get_x(i_part)
158  wi = this%particle_group%get_charge(i_part, this%i_weight)
159  call this%pic_poisson%add_charge(xi(1:2), wi)
160  end do
161  end subroutine charge_deposition_vp_2d2v
162 
163 
164  !---------------------------------------------------------------------------!
165  ! Solve Poisson's equation for the electric field
166  subroutine field_solver_vp_2d2v(this)
167  class(sll_t_operator_splitting_pic_vp_2d2v), intent(inout) :: this
168 
169  call this%pic_poisson%solve_fields()
170 
171  end subroutine field_solver_vp_2d2v
172 
173  !---------------------------------------------------------------------------!
176  this, &
177  pic_poisson, &
178  particle_group, &
179  control_variate, &
180  i_weight)
181  class(sll_t_operator_splitting_pic_vp_2d2v), intent(out):: this
182  class(sll_c_pic_poisson),pointer, intent(in) :: pic_poisson
183  class(sll_c_particle_group_base),pointer, intent(in) :: particle_group
184  class(sll_t_control_variate), optional, target, intent(in) :: control_variate
185  sll_int32, optional, intent(in) :: i_weight
186 
187  this%pic_poisson => pic_poisson
188  this%particle_group => particle_group
189 
190  this%i_weight = 1
191  if(present(i_weight)) this%i_weight = i_weight
192  if(present(control_variate)) this%control_variate => control_variate
193 
195 
196  !---------------------------------------------------------------------------!
199  class(sll_t_operator_splitting_pic_vp_2d2v), intent(inout) :: this
200 
201  this%pic_poisson => null()
202  this%particle_group => null()
203  this%control_variate => null()
204 
206 
207  !---------------------------------------------------------------------------!
210  (splitting, &
211  pic_poisson, &
212  particle_group, &
213  control_variate, &
214  i_weight)
215  class(sll_t_operator_splitting), pointer, intent(out):: splitting
216  class(sll_c_pic_poisson),pointer, intent(in) :: pic_poisson
217  class(sll_c_particle_group_base),pointer, intent(in) :: particle_group
218  class(sll_t_control_variate), optional, pointer, intent(in) :: control_variate
219  sll_int32, optional, intent(in) :: i_weight
220 
221  !local variables
222  sll_int32 :: ierr
223 
224  sll_allocate( sll_t_operator_splitting_pic_vp_2d2v :: splitting , ierr)
225 
226  select type( splitting )
228  call splitting%init(pic_poisson, particle_group, control_variate, i_weight)
229  end select
230 
232 
233 
234 
Combines values from all processes and distributes the result back to all processes.
Parallelizing facility.
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.
Particle pusher based on operator splitting for 2d2v Vlasov-Poisson.
subroutine, public sll_s_new_operator_splitting_pic_vp_2d2v(splitting, pic_poisson, particle_group, control_variate, i_weight)
Constructor for abstract type.
subroutine initialize_operator_splitting_pic_vp_2d2v(this, pic_poisson, particle_group, control_variate, i_weight)
Initialization function.
Base class of operator splitting library. It is only used with particle-in-cell method.
Base class for Poisson solver for particle methods.
real(kind=f64) function, dimension(size(particle, 2)) control_variate(particle)
Basic type of Poisson solver for PIC simulations.
    Report Typos and Errors