Report Typos and Errors    
Semi-Lagrangian Library
Modular library for kinetic and gyrokinetic simulations of plasmas in fusion energy devices.
sll_m_linear_solver_spline_mass_2d_fft.F90
Go to the documentation of this file.
1 
10 #include "sll_working_precision.h"
11 #include "sll_errors.h"
12 
13  use sll_m_linear_solver_abstract, only : &
15 
16  use sll_m_fft
17 
18  implicit none
19  private
20 
22 
23 
26 
27  sll_int32 :: n_dofs(2)
28 
29  sll_real64 :: factor = 1.0_f64
30 
31  sll_real64, allocatable :: eig_values_1(:)
32  sll_real64, allocatable :: eig_values_2(:)
33 
34  type(sll_t_fft) :: fft1
35  type(sll_t_fft) :: fft2
36  type(sll_t_fft) :: ifft1
37  type(sll_t_fft) :: ifft2
38 
39 
40  contains
41 
42  procedure :: read_from_file => read_from_file_mass1
43  procedure :: set_verbose => set_verbose_mass1
44  procedure :: solve_real => solve_real_mass1
45  procedure :: solve_complex => solve_complex_mass1
46  procedure :: print_info => print_info_mass1
47  procedure :: create => create_mass1
48  procedure :: free => free_mass1
49 
51 
52 contains
53 
54  subroutine create_mass1( self, n_dofs, eig_values_1, eig_values_2)
55  class( sll_t_linear_solver_spline_mass_2d_fft), intent( inout ) :: self
56  sll_int32, intent( in ) :: n_dofs(2)
57  sll_real64, intent( in ) :: eig_values_1(:)
58  sll_real64, intent( in ) :: eig_values_2(:)
59  !local variables
60  sll_comp64 :: array1d_x(n_dofs(1)), array1d_y(n_dofs(2))
61 
62  self%n_dofs = n_dofs
63 
64  allocate(self%eig_values_1(n_dofs(1)))
65  self%eig_values_1 = eig_values_1
66  allocate(self%eig_values_2(n_dofs(2)))
67  self%eig_values_2 = eig_values_2
68 
69  call sll_s_fft_init_c2c_1d( self%fft1, n_dofs(1), array1d_x, array1d_x, sll_p_fft_forward)
70  call sll_s_fft_init_c2c_1d( self%fft2, n_dofs(2), array1d_y, array1d_y, sll_p_fft_forward)
71  call sll_s_fft_init_c2c_1d( self%ifft1, n_dofs(1), array1d_x, array1d_x, &
72  sll_p_fft_backward, normalized=.true.)
73  call sll_s_fft_init_c2c_1d( self%ifft2, n_dofs(2), array1d_y, array1d_y, &
74  sll_p_fft_backward, normalized=.true.)
75 
76  end subroutine create_mass1
77 
78  subroutine solve_real_mass1(self, rhs, unknown)
79  class( sll_t_linear_solver_spline_mass_2d_fft), intent( inout ) :: self
80  real(kind=f64), intent(in ) :: rhs(:)
81  real(kind=f64), intent( out) :: unknown(:)
82 
83  sll_int32 :: ind, i, j, n_dofs(2)
84  sll_comp64 :: scratch(self%n_dofs(1), self%n_dofs(2))
85  sll_comp64 :: array1d_x(self%n_dofs(1)), array1d_y(self%n_dofs(2))
86 
87  n_dofs = self%n_dofs
88 
89  ! Fourier transform
90  ind=0
91  !do k=1,n_dofs(3)
92  do j=1,n_dofs(2)
93  do i=1,n_dofs(1)
94  ind = ind+1
95  array1d_x(i) = cmplx( rhs(ind), 0_f64, kind=f64)
96  end do
97  call sll_s_fft_exec_c2c_1d( self%fft1, array1d_x, array1d_x)
98  do i=1,n_dofs(1)
99  scratch(i,j) = array1d_x(i)
100  end do
101  end do
102  !end do
103  !do k=1,n_dofs(3)
104  do i=1,n_dofs(1)
105  do j=1,n_dofs(2)
106  array1d_y(j) = scratch(i,j)
107  end do
108  call sll_s_fft_exec_c2c_1d( self%fft2, array1d_y, array1d_y)
109  do j=1,n_dofs(2)
110  scratch(i,j) = array1d_y(j)
111  end do
112  end do
113  !end do
114 
115  ! Multiply by inverse mass
116  do j=1,n_dofs(2)
117  do i=1,n_dofs(1)
118 
119  scratch(i,j) = scratch(i,j)/ &
120  cmplx(self%eig_values_1(i)* &
121  self%eig_values_2(j)* &
122  self%factor, 0.0_f64, f64)
123 
124  end do
125  end do
126 
127 
128  ! Inverse Fourier transform
129 
130  !do k=1,n_dofs(3)
131  do i=1,n_dofs(1)
132  do j=1,n_dofs(2)
133  array1d_y(j) = scratch(i,j)
134  end do
135  call sll_s_fft_exec_c2c_1d( self%ifft2, array1d_y, array1d_y)
136  do j=1,n_dofs(2)
137  scratch(i,j) = array1d_y(j)
138  end do
139  end do
140  !end do
141 
142  ind=0
143  !do k=1,n_dofs(3)
144  do j=1,n_dofs(2)
145  do i=1,n_dofs(1)
146  array1d_x(i) = scratch(i,j)
147  end do
148  call sll_s_fft_exec_c2c_1d( self%ifft1, array1d_x, array1d_x)
149 
150  do i=1,n_dofs(1)
151  ind = ind+1
152  unknown(ind) = real( array1d_x(i), kind=f64 )
153  end do
154  end do
155  !end do
156 
157  end subroutine solve_real_mass1
158 
159 
160 
161 
162  subroutine solve_complex_mass1(self, rhs, unknown)
163  class( sll_t_linear_solver_spline_mass_2d_fft), intent( in ) :: self
164  complex(kind=f64), intent(in ) :: rhs(:)
165  complex(kind=f64), intent( out) :: unknown(:)
166 
167  sll_error('solve_complex', 'Procedure not implemented.')
168 
169  end subroutine solve_complex_mass1
170 
171  subroutine read_from_file_mass1(self, filename)
172  class( sll_t_linear_solver_spline_mass_2d_fft), intent( inout ) :: self
173  character(len=*), intent( in ) :: filename
174 
175  end subroutine read_from_file_mass1
176 
177  subroutine print_info_mass1(self)
178  class( sll_t_linear_solver_spline_mass_2d_fft), intent( in ) :: self
179 
180  end subroutine print_info_mass1
181 
182  subroutine set_verbose_mass1( self, verbose )
183  class( sll_t_linear_solver_spline_mass_2d_fft), intent( inout ) :: self
184  logical, intent( in ) :: verbose
185 
186  self%verbose = verbose
187 
188  end subroutine set_verbose_mass1
189 
190 
191  subroutine free_mass1(self)
192  class( sll_t_linear_solver_spline_mass_2d_fft), intent( inout ) :: self
193 
194  end subroutine free_mass1
195 
FFT interface for FFTW.
integer, parameter, public sll_p_fft_forward
Flag to specify forward FFT (negative sign) [value -1].
subroutine, public sll_s_fft_exec_c2c_1d(plan, array_in, array_out)
Compute fast Fourier transform in complex to complex mode.
subroutine, public sll_s_fft_init_c2c_1d(plan, nx, array_in, array_out, direction, normalized, aligned, optimization)
Create new 1d complex to complex plan.
integer, parameter, public sll_p_fft_backward
Flag to specify backward FFT (positive sign) [value 1].
module for abstract linear solver
Invert a circulant matrix based on diagonalization in Fourier space (2d version)
subroutine create_mass1(self, n_dofs, eig_values_1, eig_values_2)
Type for FFT plan in SeLaLib.
Data type for a linear solver inverting a 2d tensor product of circulant matrices based on FFT.
    Report Typos and Errors