1 #ifndef DOXYGEN_SHOULD_SKIP_THIS
3 module sll_m_vp_cartesian_2d
5 #include "sll_memory.h"
6 #include "sll_working_precision.h"
7 #include "sll_field_2d.h"
16 sll_t_distribution_function_2d
25 use sll_m_time_splitting,
only: &
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
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
44 type(app_field_params) :: params
46 procedure, pass(this) :: operator1 => advection_x
47 procedure, pass(this) :: operator2 => advection_v
48 end type vp_cartesian_2d
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
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
63 this%interpx => interpx
64 this%interpv => interpv
66 end subroutine vp_cartesian_2d_initialize
68 subroutine advection_x(this, dt)
69 class(vp_cartesian_2d) :: this
70 sll_real64,
intent(in) :: dt
72 sll_real64,
dimension(:),
pointer :: f1d
73 sll_real64 :: displacement
75 sll_real64 :: vmin, vmax, delta_v
77 associate(mesh => this%dist_func%transf%mesh)
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
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)
92 subroutine advection_v(this, dt)
93 class(vp_cartesian_2d) :: this
94 sll_real64,
intent(in) :: dt
97 sll_real64,
dimension(this%Ncx) :: rho, efield, e_app
98 sll_real64,
dimension(:),
pointer :: f1d
99 sll_real64 :: displacement
103 sll_real64 :: xmin, xmax, delta_x
104 sll_real64 :: vmin, vmax, delta_v
106 time = this%current_time
108 associate(mesh => this%dist_func%transf%mesh)
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
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)
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)
139 elemental function f_equilibrium(v)
140 sll_real64,
intent(in) :: v
141 sll_real64 :: f_equilibrium
143 f_equilibrium = 1.0_f64/sqrt(2*sll_p_pi)*exp(-0.5_f64*v*v)
144 end function f_equilibrium
146 subroutine pf_envelope(S, t, params)
158 sll_real64,
intent(out) :: s
159 sll_real64,
intent(in) :: t
160 type(app_field_params),
intent(in) :: params
162 sll_real64 :: t0, twl, twr, tflat, tl, tr
163 sll_real64 :: epsilon
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
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)
187 end subroutine pf_envelope
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.