Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_advection_1d_spectral.F90
Go to the documentation of this file.
1 !**************************************************************
2 ! Copyright INRIA
3 ! Authors :
4 ! CALVI project team
5 !
6 ! This code SeLaLib (for Semi-Lagrangian-Library)
7 ! is a parallel library for simulating the plasma turbulence
8 ! in a tokamak.
9 !
10 ! This software is governed by the CeCILL-B license
11 ! under French law and abiding by the rules of distribution
12 ! of free software. You can use, modify and redistribute
13 ! the software under the terms of the CeCILL-B license as
14 ! circulated by CEA, CNRS and INRIA at the following URL
15 ! "http://www.cecill.info".
16 !**************************************************************
17 
22 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "sll_errors.h"
24 #include "sll_memory.h"
25 #include "sll_working_precision.h"
26 
28 
29  use sll_m_constants, only: sll_p_pi
30 
31  use sll_m_fft, only: &
37  sll_t_fft
38 
39  implicit none
40 
43 
44  private
45 !+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46 
48 
49  sll_int32 :: num_cells
50  sll_real64 :: eta_min
51  sll_real64 :: eta_max
52  sll_real64 :: delta_eta
53 
54  sll_real64, dimension(:), pointer :: d_dx
55  sll_real64, dimension(:), pointer :: kx
56 
57  type(sll_t_fft) :: fwx
58  type(sll_t_fft) :: bwx
59  sll_comp64, dimension(:), pointer :: fk
60 
61  contains
62 
63  procedure, pass(adv) :: init => advector_1d_spectral_init
64  procedure, pass(adv) :: advect_1d
65  procedure, pass(adv) :: advect_1d_constant
66  procedure, pass(adv) :: delete
67 
69 
70 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
71 contains
72 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
73 
74  function sll_f_new_advector_1d_spectral(num_cells, &
75  eta_min, &
76  eta_max &
77  ) result(adv)
78 
79  type(sll_t_advector_1d_spectral), pointer :: adv
80 
81  sll_int32, intent(in) :: num_cells
82  sll_real64, intent(in) :: eta_min
83  sll_real64, intent(in) :: eta_max
84 
85  sll_int32 :: error
86 
87  sll_allocate(adv, error)
88 
89  call adv%init(num_cells, eta_min, eta_max)
90 
92 
93  subroutine advector_1d_spectral_init(adv, num_cells, eta_min, eta_max)
94 
95  class(sll_t_advector_1d_spectral), intent(inout) :: adv
96  sll_int32, intent(in) :: num_cells
97  sll_real64, intent(in) :: eta_min
98  sll_real64, intent(in) :: eta_max
99 
100  sll_real64 :: kx0
101  sll_int32 :: i, error
102 
103  adv%eta_min = eta_min
104  adv%eta_max = eta_max
105  adv%num_cells = num_cells
106 
107  sll_clear_allocate(adv%d_dx(1:num_cells), error)
108  sll_allocate(adv%fk(1:num_cells/2 + 1), error)
109  adv%fk(1:num_cells/2 + 1) = cmplx(0.0, 0.0, kind=f64)
110 !$OMP CRITICAL
111  call sll_s_fft_init_r2c_1d(adv%fwx, num_cells, adv%d_dx, adv%fk)
112  call sll_s_fft_init_c2r_1d(adv%bwx, num_cells, adv%fk, adv%d_dx)
113 !$OMP END CRITICAL
114 
115  sll_clear_allocate(adv%kx(1:num_cells/2 + 1), error)
116 
117  kx0 = 2._f64*sll_p_pi/(eta_max - eta_min)
118 
119  adv%kx(1) = 1.0_f64
120  do i = 2, num_cells/2 + 1
121  adv%kx(i) = real(i - 1, f64)*kx0
122  end do
123 
124  end subroutine advector_1d_spectral_init
125 
126  subroutine advect_1d(adv, a, dt, input, output)
127 
128  class(sll_t_advector_1d_spectral) :: adv
129  sll_real64, dimension(:), intent(in) :: a
130  sll_real64, intent(in) :: dt
131  sll_real64, dimension(:), intent(in) :: input
132  sll_real64, dimension(:), intent(out) :: output
133 
134  character(len=*), parameter :: this_sub_name = 'advect_1d'
135  sll_int32 :: num_cells
136 
137  num_cells = adv%num_cells
138 
139  output = input
140  print *, size(a), dt
141  sll_error(this_sub_name, "Not implemented.")
142 
143  end subroutine advect_1d
144 
145  subroutine advect_1d_constant(adv, a, dt, input, output)
146 
147  class(sll_t_advector_1d_spectral) :: adv
148  sll_real64, intent(in) :: a
149  sll_real64, intent(in) :: dt
150  sll_real64, dimension(:), intent(in) :: input
151  sll_real64, dimension(:), intent(out) :: output
152 
153  sll_int32 :: i, num_cells
154 
155  num_cells = adv%num_cells
156 
157  adv%d_dx = input(1:num_cells)
158  call sll_s_fft_exec_r2c_1d(adv%fwx, adv%d_dx, adv%fk)
159 
160  !f = f^n exp(-i kx vx dt)
161  do i = 2, num_cells/2 + 1
162  adv%fk(i) = adv%fk(i)*cmplx(cos(adv%kx(i)*a*dt), &
163  -sin(adv%kx(i)*a*dt), kind=f64)
164  end do
165 
166  call sll_s_fft_exec_c2r_1d(adv%bwx, adv%fk, adv%d_dx)
167 
168  output(1:num_cells) = adv%d_dx/real(num_cells, f64)
169 
170  output(num_cells + 1) = output(1)
171 
172  end subroutine advect_1d_constant
173 
174  subroutine delete(adv)
175 
176  class(sll_t_advector_1d_spectral), intent(inout) :: adv
177 
178  call sll_s_fft_free(adv%fwx)
179  call sll_s_fft_free(adv%bwx)
180 
181  end subroutine delete
182 
Abstract class for advection.
type(sll_t_advector_1d_spectral) function, pointer, public sll_f_new_advector_1d_spectral(num_cells, eta_min, eta_max)
subroutine advect_1d(adv, a, dt, input, output)
subroutine advector_1d_spectral_init(adv, num_cells, eta_min, eta_max)
subroutine advect_1d_constant(adv, a, dt, input, output)
Fortran module where set some physical and mathematical constants.
real(kind=f64), parameter, public sll_p_pi
FFT interface for FFTW.
subroutine, public sll_s_fft_exec_r2c_1d(plan, array_in, array_out)
Compute fast Fourier transform in real to complex mode.
subroutine, public sll_s_fft_free(plan)
Delete a plan.
subroutine, public sll_s_fft_init_r2c_1d(plan, nx, array_in, array_out, normalized, aligned, optimization)
Create new 1d real to complex plan for forward FFT.
subroutine, public sll_s_fft_exec_c2r_1d(plan, array_in, array_out)
Compute fast Fourier transform in complex to real mode.
subroutine, public sll_s_fft_init_c2r_1d(plan, nx, array_in, array_out, normalized, aligned, optimization)
Create new 1d complex to real plan for backward FFT.
Type for FFT plan in SeLaLib.
    Report Typos and Errors