Octopus
fourier_space.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19#include "global.h"
20
22 use accel_oct_m
23 use cube_oct_m
25 use debug_oct_m
26 use global_oct_m
27 use, intrinsic :: iso_fortran_env
28 use math_oct_m
31 use fft_oct_m
32#ifdef HAVE_OPENMP
33 use omp_lib
34#endif
35#ifdef HAVE_PFFT
36 use pfft_oct_m
37#endif
39 use space_oct_m
40 use types_oct_m
41 use xc_cam_oct_m
42
43 implicit none
44 private
45 public :: &
58
60 private
61 real(real64), allocatable :: dop(:, :, :)
62 complex(real64), allocatable :: zop(:, :, :)
63 logical :: in_device_memory = .false.
64 type(accel_mem_t) :: op_buffer
65 logical :: real_op
66
67 !Parameters used to generate this kernel
68 real(real64), allocatable, public :: qq(:)
69 real(real64), public :: singularity = m_zero
70 real(real64), public :: mu = m_zero
71 real(real64), public :: alpha = m_zero
72 real(real64), public :: beta = m_zero
73
74 contains
75 procedure :: init =>fourier_space_op_t_init
76 end type fourier_space_op_t
77
78 real(real64), parameter :: TOL_VANISHING_Q = 1e-6_real64
79
80contains
81
83 subroutine fourier_space_op_t_init(this, space, qq, cam, singularity)
84 class(fourier_space_op_t), intent(inout) :: this
85 class(space_t), intent(in) :: space
86 real(real64), intent(in) :: qq(:)
87 type(xc_cam_t), intent(in) :: cam
88 real(real64), optional, intent(in) :: singularity
89
90 real(real64), parameter :: vanishing_q = 1.0e-5_real64
91
93
94 safe_allocate(this%qq(1:space%dim))
95
96 this%qq(1:space%periodic_dim) = qq(1:space%periodic_dim)
97 this%qq(space%periodic_dim+1:space%dim) = vanishing_q
98 this%singularity = optional_default(singularity, m_zero)
99 this%mu = cam%omega
100 this%alpha = cam%alpha
101 this%beta = cam%beta
102
104
105 end subroutine fourier_space_op_t_init
106
107 ! ---------------------------------------------------------
111 subroutine cube_function_alloc_fs(cube, cf, force_alloc)
112 type(cube_t), target, intent(in) :: cube
113 type(cube_function_t), intent(inout) :: cf
114 logical, optional, intent(in) :: force_alloc
115
116 integer :: n1, n2, n3
117 logical :: is_allocated
118
119 push_sub(cube_function_alloc_fs)
120
121 assert(.not. associated(cf%fs))
122 assert(allocated(cube%fft))
123
124 cf%forced_alloc = optional_default(force_alloc, .false.)
125 ! cf has no init, so assign here; preserve cf%batch_size (active count) set by the caller
126 cf%batch_capacity = cube%batch_capacity
127
128 n1 = max(1, cube%fs_n(1))
129 n2 = max(1, cube%fs_n(2))
130 n3 = max(1, cube%fs_n(3))
131
132 is_allocated = .false.
133
134 select case (cube%fft%library)
135 case (fftlib_pfft)
136 if (.not. cf%forced_alloc) then
137 is_allocated = .true.
138 if (any(cube%fs_n(1:3) == 0)) then
139 cf%fs => cube%fft%fs_data(1:1,1:1,1:1,1:cf%batch_capacity)
140 else
141 cf%fs => cube%fft%fs_data(1:n3,1:n1,1:n2,1:cf%batch_capacity)
142 end if
143 else ! force allocate transposed with PFFT
144 is_allocated = .true.
145 safe_allocate(cf%fs(1:n3, 1:n1, 1:n2, 1:cf%batch_capacity))
146 end if
147 case (fftlib_accel)
148 if (cf%in_device_memory) then
149 is_allocated = .true.
150 call accel_create_buffer(cf%fourier_space_buffer, accel_mem_read_write, type_cmplx, &
151 int(cf%batch_capacity, int64) * product(int(cube%fs_n(1:3), int64)))
152 end if
153
155 if (.not. cf%forced_alloc) then
156 is_allocated = .true.
157 cf%fs => cube%fft%fs_data(1:cube%fs_n(1), 1:cube%fs_n(2), 1:cube%fs_n(3), 1:cf%batch_capacity)
158 end if
159 end select
161 if (.not. is_allocated) then
162 safe_allocate(cf%fs(1:cube%fs_n(1), 1:cube%fs_n(2), 1:cube%fs_n(3), 1:cf%batch_capacity))
163 end if
168
169 ! ---------------------------------------------------------
171 subroutine cube_function_free_fs(cube, cf)
172 type(cube_t), intent(in) :: cube
173 type(cube_function_t), intent(inout) :: cf
174
175 logical :: deallocated
176
177 push_sub(cube_function_free_fs)
179 assert(allocated(cube%fft))
180
181 deallocated = .false.
182
183 select case (cube%fft%library)
184 case (fftlib_pfft)
185 if (.not. cf%forced_alloc) then
186 deallocated = .true.
187 nullify(cf%fs)
188 end if
189 case (fftlib_accel)
190 if (cf%in_device_memory) then
191 deallocated = .true.
192 call accel_free_buffer(cf%fourier_space_buffer)
193 end if
194 case (fftlib_fftw)
195 if (.not. cf%forced_alloc) then
196 deallocated = .true.
197 nullify(cf%fs)
198 end if
199 end select
200
201 if (.not. deallocated) then
202 assert(associated(cf%fs))
203 safe_deallocate_p(cf%fs)
204 end if
205
207 end subroutine cube_function_free_fs
208
209
210 ! ---------------------------------------------------------
211 subroutine fourier_space_op_end(this)
212 type(fourier_space_op_t), intent(inout) :: this
213
214 push_sub(fourier_space_op_end)
215
216 if (this%in_device_memory) then
217 call accel_free_buffer(this%op_buffer)
218 this%in_device_memory = .false.
219 end if
220 safe_deallocate_a(this%dop)
221 safe_deallocate_a(this%zop)
222 safe_deallocate_a(this%qq)
223
224 pop_sub(fourier_space_op_end)
225 end subroutine fourier_space_op_end
226
227#include "undef.F90"
228#include "real.F90"
229#include "fourier_space_inc.F90"
230
231#include "undef.F90"
232#include "complex.F90"
233#include "fourier_space_inc.F90"
234
235end module fourier_space_oct_m
236
237
238!! Local Variables:
239!! mode: f90
240!! coding: utf-8
241!! End:
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:1006
integer, parameter, public accel_mem_read_write
Definition: accel.F90:186
Fast Fourier Transform module. This module provides a single interface that works with different FFT ...
Definition: fft.F90:120
integer, parameter, public fftlib_accel
Definition: fft.F90:179
integer, parameter, public fftlib_pfft
Definition: fft.F90:179
integer, parameter, public fftlib_fftw
Definition: fft.F90:179
subroutine, public zfourier_space_op_apply(this, cube, cf)
Applies a multiplication factor to the Fourier space grid. This is a local function.
subroutine, public zfourier_space_op_init(this, cube, op, in_device, op_move)
The operator can be provided either through op (which is copied) or through op_move (an allocatable t...
subroutine, public dfourier_space_op_apply(this, cube, cf)
Applies a multiplication factor to the Fourier space grid. This is a local function.
subroutine, public fourier_space_op_end(this)
subroutine, public zcube_function_fs2rs(cube, cf)
subroutine fourier_space_op_t_init(this, space, qq, cam, singularity)
Initialise a Fourier space Op instance.
subroutine, public dcube_function_fs2rs(cube, cf)
subroutine, public cube_function_free_fs(cube, cf)
Deallocates the Fourier space grid.
subroutine, public dfourier_space_op_init(this, cube, op, in_device, op_move)
The operator can be provided either through op (which is copied) or through op_move (an allocatable t...
subroutine, public zcube_function_rs2fs(cube, cf)
The following routines convert the function between real space and Fourier space Note that the dimens...
subroutine, public cube_function_alloc_fs(cube, cf, force_alloc)
Allocates locally the Fourier space grid, if PFFT library is not used. Otherwise, it assigns the PFFT...
subroutine, public dcube_function_rs2fs(cube, cf)
The following routines convert the function between real space and Fourier space Note that the dimens...
real(real64), parameter, public m_zero
Definition: global.F90:200
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
The low level module to work with the PFFT library. http:
Definition: pfft.F90:128
type(type_t), parameter, public type_cmplx
Definition: types.F90:136
int true(void)