Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_fdistribu4d_dk.F90
Go to the documentation of this file.
1 !-----------------------------------------------------------
2 ! SELALIB
3 !-----------------------------------------------------------
4 !
5 ! MODULE: sll_m_fdistribu4d_dk
6 !
9 !
10 ! DESCRIPTION:
11 !
17 !-----------------------------------------------------------
19 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
20 #include "sll_assert.h"
21 #include "sll_memory.h"
22 #include "sll_working_precision.h"
23 
25  sll_p_hermite, &
26  sll_p_periodic
27 
31 
32  use sll_m_constants, only: &
33  sll_p_pi
34 
35  use sll_m_cubic_splines, only: &
46 
47  implicit none
48 
49  public :: &
56 
57  private
58 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
59 
60  sll_real64, dimension(1) :: whatever ! dummy params array
61 
62 contains
63 
64  !----------------------------------------
65  ! sech = cosh^-1 definition
66  !----------------------------------------
67  function sech(x)
68  sll_real64, intent(in) :: x
69  sll_real64 :: sech
70 
71  sech = 1._f64/cosh(x)
72  end function sech
73 
74  !---------------------------------------- -----------------------
75  ! Initialization of the radial density profiles
76  !---------------------------------------- -----------------------
77  subroutine init_n0_r(r_peak, inv_Ln, deltarn, n0_rmin, &
78  r_grid, n0_1d)
79  sll_real64, intent(in) :: r_peak
80  sll_real64, intent(in) :: inv_ln
81  sll_real64, intent(in) :: deltarn
82  sll_real64, intent(in) :: n0_rmin
83  sll_real64, dimension(:), intent(in) :: r_grid
84  sll_real64, dimension(:), intent(inout) :: n0_1d
85 
86  sll_int32 :: ir, nr
87  sll_real64 :: dr, lr
88  sll_real64 :: etai, etai_mid
89  sll_real64 :: tmp
90  sll_real64 :: n0norm_tmp
91  sll_real64 :: deltarn_norm
92 
93  nr = size(r_grid, 1)
94  lr = r_grid(nr) - r_grid(1)
95  dr = r_grid(2) - r_grid(1)
96 
97  deltarn_norm = deltarn*lr
98 
99  !*** compute ns0 solution of : ***
100  !*** 2/(n0(r)+n0(r-1))*(n0(r)-n0(r-1))/dr ***
101  !*** = -(1/Ln0)*cosh^-2(r-rpeak/deltar) ***
102  !*** where (1/Ln) = kappa_n0/R ***
103  n0_1d(1) = n0_rmin
104  do ir = 2, nr
105  etai = r_grid(ir - 1)
106  etai_mid = etai + dr*0.5_f64
107  tmp = -inv_ln* &
108  sech((etai_mid - r_peak)/deltarn_norm)**2
109  tmp = 0.5_f64*dr*tmp
110  n0_1d(ir) = (1._f64 + tmp)/(1._f64 - tmp)*n0_1d(ir - 1)
111  end do
112 
113  !*** normalisation of the density at int(n0(r)rdr)/int(rdr) ***
114  ! -> computation of int(n0(r)rdr)
115  n0norm_tmp = 0._f64
116  do ir = 2, nr - 1
117  n0norm_tmp = n0norm_tmp + n0_1d(ir)*r_grid(ir)
118  end do
119  n0norm_tmp = n0norm_tmp + 0.5_f64* &
120  (n0_1d(1)*r_grid(1) + n0_1d(nr)*r_grid(nr))
121  ! -> division by int(rdr)
122  n0norm_tmp = n0norm_tmp*2._f64*dr/ &
123  (r_grid(nr)**2 - r_grid(1)**2)
124 
125  n0_1d(1:nr) = n0_1d(1:nr)/n0norm_tmp
126  end subroutine init_n0_r
127 
128  !---------------------------------------- -----------------------
129  ! Initialization of the profiles
130  ! solution of the following equation
131  !
132  ! 1 d T(r) = - kappa cosh^(-2)( (r- rx)/delta )
133  ! T(r) dr
134  !
135  ! kappa = params(1)
136  ! delta = params(2)
137  ! rx = params(3)
138  !---------------------------------------- -----------------------
139  function sll_f_profil_xy_exacte(x, y, params_profil)
140 
141  sll_real64, intent(in) :: x
142  sll_real64, intent(in) :: y
143  sll_real64, dimension(:), intent(in) ::params_profil
144  sll_real64 :: sll_f_profil_xy_exacte
145  sll_real64 :: kappa
146  sll_real64 :: delta
147  sll_real64 :: rx
148  sll_real64 :: r
149 
150  kappa = params_profil(1)
151  delta = params_profil(2)
152  rx = params_profil(3)
153  r = sqrt(x**2 + y**2)
154  sll_f_profil_xy_exacte = exp(-kappa*delta*tanh((r - rx)/delta))
155 
156  end function sll_f_profil_xy_exacte
157 
158  !---------------------------------------- -----------------------
159  ! Initialization of the profiles
160  ! solution of the following equation
161  !
162  ! 1 d T(r) = - kappa cosh^(-2)( (r- rx)/delta )
163  ! T(r) dr
164  !
165  ! kappa = params(1)
166  ! delta = params(2)
167  ! rx = params(3)
168  !---------------------------------------- -----------------------
169  function sll_f_init_exact_profile_r(r, params_profil)
170 
171  sll_real64, intent(in) :: r
172  sll_real64, dimension(:), intent(in) :: params_profil
173 
174  sll_real64 :: sll_f_init_exact_profile_r
175  sll_real64 :: kappa
176  sll_real64 :: delta
177  sll_real64 :: rx
178 
179  kappa = params_profil(1)
180  delta = params_profil(2)
181  rx = params_profil(3)
182  sll_f_init_exact_profile_r = exp(-kappa*delta*tanh((r - rx)/delta))
183 
184  end function sll_f_init_exact_profile_r
185 
186  !---------------------------------------------------------------
187  ! Initialization of the radial temperature profiles
188  !---------------------------------------------------------------
189  subroutine init_t_r(r_peak, inv_LT, &
190  deltarT, T_rmin, T_scal, r_grid, T_1d)
191  sll_real64, intent(in) :: r_peak
192  sll_real64, intent(in) :: inv_lt
193  sll_real64, intent(in) :: deltart
194  sll_real64, intent(in) :: t_rmin
195  sll_real64, intent(in) :: t_scal
196  sll_real64, dimension(:), intent(in) :: r_grid
197  sll_real64, dimension(:), intent(inout) :: t_1d
198 
199  sll_int32 :: ir, nr
200  sll_real64 :: dr, lr
201  sll_real64 :: etai, etai_mid
202  sll_real64 :: tmp
203  sll_real64 :: w0, w1, tnorm_tmp
204  sll_real64 :: deltart_norm
205 
206  nr = size(r_grid, 1)
207  lr = r_grid(nr) - r_grid(1)
208  dr = r_grid(2) - r_grid(1)
209  deltart_norm = deltart*lr
210 
211  !*** compute Ts solution of : ***
212  !*** 2/(Ts(r)+Ts(r-1))*(Ts(r)-Ts(r-1))/dr ***
213  !*** = -(1/LTs)*cosh^-2(r-rpeak/deltar) ***
214  !*** where (1/LT) = kappa_Ts/R ***
215  t_1d(1) = t_rmin
216  do ir = 2, nr
217  etai = r_grid(ir - 1)
218  etai_mid = etai + dr*0.5_f64
219  tmp = -inv_lt* &
220  sech((etai_mid - r_peak)/deltart_norm)**2
221  tmp = 0.5_f64*dr*tmp
222  t_1d(ir) = (1._f64 + tmp)/(1._f64 - tmp)*t_1d(ir - 1)
223  end do
224 
225  !*** normalisation of the temperature to 1 at r=rpeak ***
226  ir = int((r_peak - r_grid(1))/dr)
227  w1 = (r_peak - r_grid(ir))/dr
228  w0 = 1._f64 - w1
229  tnorm_tmp = w0*t_1d(ir) + w1*t_1d(ir + 1)
230  t_1d(1:nr) = (t_1d(1:nr)/tnorm_tmp)/t_scal
231  end subroutine init_t_r
232 
233  !---------------------------------------------------------------
234  ! Initialisation of the magnetic field B(r,theta)
235  !---------------------------------------------------------------
236  subroutine sll_s_init_brtheta(r_grid, theta_grid, B_rtheta)
237  sll_real64, dimension(:), intent(in) :: r_grid
238  sll_real64, dimension(:), intent(in) :: theta_grid
239  sll_real64, dimension(:, :), intent(inout) :: b_rtheta
240 
241  sll_int32 :: ir, itheta
242  sll_int32 :: nr, ntheta
243 
244  nr = size(r_grid, 1)
245  ntheta = size(theta_grid, 1)
246 
247  do itheta = 1, ntheta
248  do ir = 1, nr
249  b_rtheta(ir, itheta) = 1._f64
250  end do
251  end do
252  end subroutine sll_s_init_brtheta
253 
254  !---------------------------------------------------------------
255  ! Computation of the equilibrium distribution function for
256  ! drift-kinetic 4D simulation
257  ! feq(r,vpar) = n0(r)/(2*pi*Ti(r))**(1/2) *
258  ! exp(-0.5*vpar**2/Ti(r))
259  ! where n0 and Ti are respectively the initial density
260  ! and temperature profiles
261  !---------------------------------------------------------------
262  function compute_feq_val(r, vpar, n0_r, Ti_r) &
263  result(val)
264 
265  sll_real64 :: val ! sll_DK_initializer_4d
266  sll_real64, intent(in) :: r
267  sll_real64, intent(in) :: vpar
268  sll_real64, intent(in) :: n0_r
269  sll_real64, intent(in) :: ti_r
270 
271  sll_assert(r >= 0.0)
272  val = n0_r/sqrt(2._f64*sll_p_pi*ti_r)* &
273  exp(-0.5_f64*vpar**2/ti_r)
274  end function compute_feq_val
275 
276  !----------------------------------------------------
277  ! Initialization of the 2D array for the equilibrium
278  ! distribution function feq(r,vpar)
279  ! feq(r,vpar) = n0(r)/(2*pi*Ti(r))**(1/2) *
280  ! exp(-0.5*vpar**2/Ti(r))
281  !----------------------------------------------------
282  subroutine sll_s_init_fequilibrium(Nr, Nvpar, &
283  r_grid, vpar_grid, n0_1d, Ti_1d, feq_2d)
284  sll_int32, intent(in) :: nr
285  sll_int32, intent(in) :: nvpar
286  sll_real64, dimension(:), intent(in) :: r_grid
287  sll_real64, dimension(:), intent(in) :: vpar_grid
288  sll_real64, dimension(:), intent(in) :: n0_1d
289  sll_real64, dimension(:), intent(in) :: ti_1d
290  sll_real64, dimension(:, :), intent(out) :: feq_2d
291 
292  sll_int32 :: ir, ivpar
293  sll_real64 :: r, vpar, n0_r, ti_r
294 
295  do ivpar = 1, nvpar
296  vpar = vpar_grid(ivpar)
297  do ir = 1, nr
298  r = r_grid(ir)
299  n0_r = n0_1d(ir)
300  ti_r = ti_1d(ir)
301  feq_2d(ir, ivpar) = compute_feq_val(r, vpar, n0_r, ti_r)
302  end do
303  end do
304  end subroutine sll_s_init_fequilibrium
305 
306  !----------------------------------------------------
307  ! Compute func(x,y) from func(r)
308  !----------------------------------------------------
309  subroutine function_xy_from_r(r_grid, func_r, &
310  xgrid_2d, ygrid_2d, func_xy)
311  sll_real64, dimension(:), intent(in) :: r_grid
312  sll_real64, dimension(:), intent(in) :: func_r
313  sll_real64, dimension(:, :), intent(in) :: xgrid_2d
314  sll_real64, dimension(:, :), intent(in) :: ygrid_2d
315  sll_real64, dimension(:, :), intent(out) :: func_xy
316 
317  sll_int32 :: nr, npt1, npt2
318  sll_int32 :: ix, iy
319  sll_real64 :: r, x, y
320 
321  type(sll_t_cubic_spline_1d) :: sp1d_r
322 
323  nr = size(r_grid, 1)
324  npt1 = size(xgrid_2d, 1)
325  npt2 = size(xgrid_2d, 2)
326 
327  call sll_s_cubic_spline_1d_init(sp1d_r, npt1, &
328  r_grid(1), r_grid(nr), sll_p_hermite)
329  call sll_s_cubic_spline_1d_compute_interpolant(func_r, sp1d_r)
330 
331  do iy = 1, npt2
332  do ix = 1, npt1
333  x = xgrid_2d(ix, iy)
334  y = ygrid_2d(ix, iy)
335  r = sll_f_polar_eta1(x, y, (/0.0_f64/)) ! params doesn't matter for sll_f_polar_eta1
336  r = min(max(r, r_grid(1)), r_grid(nr))
337  func_xy(ix, iy) = sll_f_cubic_spline_1d_eval(r, sp1d_r)
338  end do
339  end do
340  call sll_s_cubic_spline_1d_free(sp1d_r)
341  end subroutine function_xy_from_r
342 
343  !----------------------------------------------------
344  ! Compute func(x,y) from func(r,theta)
345  !----------------------------------------------------
346  subroutine sll_s_function_xy_from_rtheta(r_grid, theta_grid, &
347  func_rtheta, xgrid_2d, ygrid_2d, func_xy)
348  sll_real64, dimension(:), intent(in) :: r_grid
349  sll_real64, dimension(:), intent(in) :: theta_grid
350  sll_real64, dimension(:, :), intent(in) :: func_rtheta
351  sll_real64, dimension(:, :), intent(in) :: xgrid_2d
352  sll_real64, dimension(:, :), intent(in) :: ygrid_2d
353  sll_real64, dimension(:, :), intent(out) :: func_xy
354 
355  sll_int32 :: nr, ntheta
356  sll_int32 :: npt1, npt2
357  sll_int32 :: ix, iy
358  sll_real64 :: r, theta, x, y
359 
360  type(sll_t_cubic_spline_2d) :: sp2d_rtheta
361 
362  nr = size(r_grid, 1)
363  ntheta = size(theta_grid, 1)
364  npt1 = size(xgrid_2d, 1)
365  npt2 = size(xgrid_2d, 2)
366 
367  call sll_s_cubic_spline_2d_init(sp2d_rtheta, &
368  npt1, npt2, &
369  r_grid(1), r_grid(nr), &
370  theta_grid(1), theta_grid(ntheta), &
371  sll_p_hermite, sll_p_periodic)
372  call sll_s_cubic_spline_2d_compute_interpolant(func_rtheta, sp2d_rtheta)
373 
374  do iy = 1, npt2
375  do ix = 1, npt1
376  x = xgrid_2d(ix, iy)
377  y = ygrid_2d(ix, iy)
378  r = sll_f_polar_eta1(x, y, whatever)
379  r = min(max(r, r_grid(1)), r_grid(nr))
380  theta = sll_f_polar_eta2(x, y, whatever)
381  theta = modulo(theta, 2._f64*sll_p_pi)
382  func_xy(ix, iy) = sll_f_cubic_spline_2d_eval(r, theta, sp2d_rtheta)
383  end do
384  end do
385  call sll_s_cubic_spline_2d_free(sp2d_rtheta)
386  end subroutine sll_s_function_xy_from_rtheta
387 
388  !----------------------------------------------------
389  ! Initialization of the 3D array for the equilibrium
390  ! distribution function feq(x,y,vpar)
391  ! feq(x,y,vpar) = n0(x,y)/(2*pi*Ti(x,y))**(1/2) *
392  ! exp(-0.5*vpar**2/Ti(x,y))
393  !----------------------------------------------------
394  subroutine sll_s_init_fequilibrium_xy(xgrid_2d, ygrid_2d, &
395  vpar_grid, n0_xy, Ti_xy, feq_xyvpar)
396  sll_real64, dimension(:, :), intent(in) :: xgrid_2d
397  sll_real64, dimension(:, :), intent(in) :: ygrid_2d
398  sll_real64, dimension(:), intent(in) :: vpar_grid
399  sll_real64, dimension(:, :), intent(in) :: n0_xy
400  sll_real64, dimension(:, :), intent(in) :: ti_xy
401  sll_real64, dimension(:, :, :), intent(out) :: feq_xyvpar
402 
403  sll_int32 :: npt1, npt2, nvpar
404  sll_int32 :: ix, iy, ivpar
405 
406  npt1 = size(xgrid_2d, 1)
407  npt2 = size(ygrid_2d, 2)
408  nvpar = size(vpar_grid, 1)
409 
410  do ivpar = 1, nvpar
411  do iy = 1, npt2
412  do ix = 1, npt1
413  feq_xyvpar(ix, iy, ivpar) = n0_xy(ix, iy)* &
414  exp(-0.5_f64*vpar_grid(ivpar)**2/ti_xy(ix, iy)) &
415  /sqrt(2._f64*sll_p_pi*ti_xy(ix, iy))
416  end do
417  end do
418  end do
419  end subroutine sll_s_init_fequilibrium_xy
420 
421 end module sll_m_fdistribu4d_dk
Functions for analytic coordinate transformations.
function, public sll_f_polar_eta1(x1, x2, params)
inverse mapping
function, public sll_f_polar_eta2(x1, x2, params)
inverse mapping
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
Provides capabilities for data and derivative interpolation with cubic B-splines and different bounda...
subroutine, public sll_s_cubic_spline_2d_compute_interpolant(data, spline)
Computes the spline coefficients for the given data. The coeffcients are first computed in the second...
subroutine, public sll_s_cubic_spline_1d_compute_interpolant(f, spline)
Computes the cubic spline coefficients corresponding to the 1D data array 'f'.
subroutine, public sll_s_cubic_spline_1d_init(self, num_points, xmin, xmax, bc_type, sl, sr, fast_algorithm)
Returns a pointer to a heap-allocated cubic spline object.
real(kind=f64) function, public sll_f_cubic_spline_1d_eval(x, spline)
returns the value of the interpolated image of the abscissa x, using the spline coefficients stored i...
real(kind=f64) function, public sll_f_cubic_spline_2d_eval(x1, x2, spline)
Returns the interpolated value of the image of the point (x1,x2) using the spline decomposition store...
subroutine, public sll_s_cubic_spline_1d_free(spline)
deallocate the sll_t_cubic_spline_1d object
subroutine, public sll_s_cubic_spline_2d_init(this, num_pts_x1, num_pts_x2, x1_min, x1_max, x2_min, x2_max, x1_bc_type, x2_bc_type, const_slope_x1_min, const_slope_x1_max, const_slope_x2_min, const_slope_x2_max, x1_min_slopes, x1_max_slopes, x2_min_slopes, x2_max_slopes)
subroutine, public sll_s_cubic_spline_2d_free(spline)
Initialisation of the distribution functioinit_fequilibrium_xyn for the drift-kinetic 4D simulation.
real(kind=f64) function compute_feq_val(r, vpar, n0_r, Ti_r)
real(kind=f64), dimension(1) whatever
subroutine, public sll_s_init_brtheta(r_grid, theta_grid, B_rtheta)
subroutine, public sll_s_init_fequilibrium(Nr, Nvpar, r_grid, vpar_grid, n0_1d, Ti_1d, feq_2d)
real(kind=f64) function sech(x)
real(kind=f64) function, public sll_f_profil_xy_exacte(x, y, params_profil)
subroutine, public sll_s_init_fequilibrium_xy(xgrid_2d, ygrid_2d, vpar_grid, n0_xy, Ti_xy, feq_xyvpar)
subroutine init_n0_r(r_peak, inv_Ln, deltarn, n0_rmin, r_grid, n0_1d)
real(kind=f64) function, public sll_f_init_exact_profile_r(r, params_profil)
subroutine function_xy_from_r(r_grid, func_r, xgrid_2d, ygrid_2d, func_xy)
subroutine init_t_r(r_peak, inv_LT, deltarT, T_rmin, T_scal, r_grid, T_1d)
subroutine, public sll_s_function_xy_from_rtheta(r_grid, theta_grid, func_rtheta, xgrid_2d, ygrid_2d, func_xy)
basic type for one-dimensional cubic spline data.
Basic type for one-dimensional cubic spline data.
    Report Typos and Errors