Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_vp_cartesian_2d.F90
Go to the documentation of this file.
1 #ifndef DOXYGEN_SHOULD_SKIP_THIS
2 
3 module sll_m_vp_cartesian_2d
4 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
5 #include "sll_memory.h"
6 #include "sll_working_precision.h"
7 #include "sll_field_2d.h"
8 
9  use sll_m_cartesian_meshes, only: &
11 
12  use sll_m_constants, only: &
13  sll_p_pi
14 
15  use sll_m_distribution_function, only: &
16  sll_t_distribution_function_2d
17 
18  use sll_m_interpolators_1d_base, only: &
20 
21  use sll_m_poisson_1d_periodic, only: &
24 
25  use sll_m_time_splitting, only: &
26  sll_c_time_splitting
27 
28  implicit none
29 
30  private
31 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
32 
33  type :: app_field_params
34  sll_real64 :: edrmax, tflat, tl, tr, twl, twr, t0
35  sll_real64 :: kmode, omegadr
36  logical :: turn_drive_off, driven
37  end type app_field_params
38 
39  type, extends(sll_c_time_splitting) :: vp_cartesian_2d
40  class(sll_c_interpolator_1d), pointer :: interpx, interpv
41  type(sll_t_distribution_function_2d), pointer :: dist_func
42  type(sll_t_poisson_1d_periodic), pointer :: poisson_1d
43  sll_int32 :: ncx, ncv
44  type(app_field_params) :: params
45  contains
46  procedure, pass(this) :: operator1 => advection_x
47  procedure, pass(this) :: operator2 => advection_v
48  end type vp_cartesian_2d
49 
50 contains
51 
52  subroutine vp_cartesian_2d_initialize(this, dist_func, poisson_1d, Ncx, Ncv, interpx, interpv, params)
53  type(vp_cartesian_2d) :: this
54  type(sll_t_distribution_function_2d), target :: dist_func
55  type(sll_t_poisson_1d_periodic), target :: poisson_1d
56  sll_int32 :: ncx, ncv
57  class(sll_c_interpolator_1d), pointer :: interpx, interpv
58  type(app_field_params) :: params
59  this%dist_func => dist_func
60  this%poisson_1d => poisson_1d
61  this%Ncx = ncx
62  this%Ncv = ncv
63  this%interpx => interpx
64  this%interpv => interpv
65  this%params = params
66  end subroutine vp_cartesian_2d_initialize
67 
68  subroutine advection_x(this, dt)
69  class(vp_cartesian_2d) :: this
70  sll_real64, intent(in) :: dt
71  ! local variables
72  sll_real64, dimension(:), pointer :: f1d
73  sll_real64 :: displacement
74  sll_int32 :: j
75  sll_real64 :: vmin, vmax, delta_v
76 
77  associate(mesh => this%dist_func%transf%mesh)
78 
79  vmin = this%dist_func%transf%x2_at_node(1, 1)
80  vmax = this%dist_func%transf%x2_at_node(1, this%Ncv + 1)
81  delta_v = (vmax - vmin)/mesh%num_cells2
82 
83  end associate
84 
85  do j = 1, this%Ncv + 1
86  displacement = -(vmin + (j - 1)*delta_v)*dt
87  f1d => field_data(this%dist_func) (:, j)
88  call this%interpx%interpolate_array_disp_inplace(this%Ncx + 1, f1d, displacement)
89  end do
90  end subroutine
91 
92  subroutine advection_v(this, dt)
93  class(vp_cartesian_2d) :: this
94  sll_real64, intent(in) :: dt
95  ! local variables
96  sll_real64 :: time
97  sll_real64, dimension(this%Ncx) :: rho, efield, e_app
98  sll_real64, dimension(:), pointer :: f1d
99  sll_real64 :: displacement
100  sll_real64 :: adr
101  sll_real64 :: arg
102  sll_int32 :: i
103  sll_real64 :: xmin, xmax, delta_x
104  sll_real64 :: vmin, vmax, delta_v
105 
106  time = this%current_time
107 
108  associate(mesh => this%dist_func%transf%mesh)
109 
110  xmin = this%dist_func%transf%x1_at_node(1, 1)
111  xmax = this%dist_func%transf%x1_at_node(this%Ncx + 1, 1)
112  delta_x = (xmax - xmin)/mesh%num_cells1
113  vmin = this%dist_func%transf%x2_at_node(1, 1)
114  vmax = this%dist_func%transf%x2_at_node(1, this%Ncv + 1)
115  delta_v = (vmax - vmin)/mesh%num_cells2
116 
117  end associate
118 
119  ! compute electric field
120  !-----------------------
121 
122  rho = 1.0_f64 - delta_v*sum(field_data(this%dist_func), dim=2)
123  call sll_o_solve(this%poisson_1d, efield, rho)
124  if (this%params%driven) then
125  call pf_envelope(adr, time, this%params)
126  do i = 1, this%Ncx + 1
127  arg = this%params%kmode*real(i - 1, 8)*delta_x - this%params%omegadr*time
128  e_app(i) = this%params%Edrmax*adr*this%params%kmode*sin(arg)
129  end do
130  end if
131  ! do advection for given electric field
132  do i = 1, this%Ncx + 1
133  displacement = (efield(i) + e_app(i))*0.5_f64*dt
134  f1d => field_data(this%dist_func) (i, :)
135  call this%interpv%interpolate_array_disp_inplace(this%Ncv + 1, f1d, displacement)
136  end do
137  end subroutine
138 
139  elemental function f_equilibrium(v)
140  sll_real64, intent(in) :: v
141  sll_real64 :: f_equilibrium
142 
143  f_equilibrium = 1.0_f64/sqrt(2*sll_p_pi)*exp(-0.5_f64*v*v)
144  end function f_equilibrium
145 
146  subroutine pf_envelope(S, t, params)
147 
148  ! DESCRIPTION
149  ! -----------
150  ! S: the wave form at a given point in time. This wave form is
151  ! not scaled (its maximum value is 1).
152  ! t: the time at which the envelope is being evaluated
153  ! tflat, tL, tR, twL, twR, tstart, t0: the parameters defining the
154  ! envelope, defined in the main portion of this program.
155  ! turn_drive_off: 1 if the drive should be turned off after a time
156  ! tflat, and 0 otherwise
157 
158  sll_real64, intent(out) :: s
159  sll_real64, intent(in) :: t
160  type(app_field_params), intent(in) :: params
161  ! local variables
162  sll_real64 :: t0, twl, twr, tflat, tl, tr
163  sll_real64 :: epsilon
164 
165  tflat = params%tflat
166  tr = params%tR
167  tl = params%tL
168  twl = params%twL
169  twr = params%twR
170  t0 = params%t0
171  ! The envelope function is defined such that it is zero at t0,
172  ! rises to 1 smoothly, stay constant for tflat, and returns
173  ! smoothly to zero.
174  if (params%turn_drive_off) then
175  epsilon = 0.5*(tanh((t0 - tl)/twl) - tanh((t0 - tr)/twr))
176  s = 0.5*(tanh((t - tl)/twl) - tanh((t - tr)/twr)) - epsilon
177  s = s/(1 - epsilon)
178  else
179  epsilon = 0.5*(tanh((t0 - tl)/twl) + 1.0_f64)
180  s = 0.5*(tanh((t - tl)/twl) + 1.0_f64) - epsilon
181  s = s/(1.0_f64 - epsilon)
182  end if
183  if (s < 0) then
184  s = 0.0_f64
185  end if
186  return
187  end subroutine pf_envelope
188 
189 end module sll_m_vp_cartesian_2d
190 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
sll_o_solve the Poisson equation on 1d mesh and compute the potential
Cartesian mesh basic types.
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
Implements the distribution function types.
Module for 1D interpolation and reconstruction.
Module to sll_o_solve Poisson equation on one dimensional mesh using FFT transform.
Abstract class for 1D interpolation and reconstruction.
    Report Typos and Errors