Octopus
cube_function.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2011 M. Marques, A. Castro, A. Rubio, G. Bertsch, M. Oliveira
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
24 use debug_oct_m
25 use fft_oct_m
26 use global_oct_m
28 use math_oct_m
29 use mesh_oct_m
33 use mpi_oct_m
40 use types_oct_m
41
42 implicit none
43 private
44 public :: &
87
89 ! Components are public by default
90 integer :: batch_capacity = 1
91 integer :: batch_size = 1
93 real(real64), pointer, contiguous :: dRS(:, :, :, :) => null()
94 complex(real64), pointer, contiguous :: zRS(:, :, :, :) => null()
95 complex(real64), pointer, contiguous :: FS(:, :, :, :) => null()
97 real(real32), pointer, contiguous :: sRS(:, :, :, :) => null()
98 complex(real32), pointer, contiguous :: cRS(:, :, :, :) => null()
99 complex(real32), pointer, contiguous :: cFS(:, :, :, :) => null()
100 logical :: forced_alloc = .false.
101 logical :: in_device_memory = .false.
102 type(accel_mem_t) :: real_space_buffer
103 type(accel_mem_t) :: fourier_space_buffer
104 end type cube_function_t
105
106 interface dmesh_to_cube
107 module procedure dmesh_to_cube_1, dmesh_to_cube_2
108 end interface dmesh_to_cube
109
110 interface zmesh_to_cube
111 module procedure zmesh_to_cube_1, zmesh_to_cube_2
112 end interface zmesh_to_cube
113
114 interface dcube_to_mesh
115 module procedure dcube_to_mesh_1, dcube_to_mesh_2
116 end interface dcube_to_mesh
117
118 interface zcube_to_mesh
119 module procedure zcube_to_mesh_1, zcube_to_mesh_2
120 end interface zcube_to_mesh
121
122 interface smesh_to_cube
123 module procedure smesh_to_cube_1, smesh_to_cube_2
124 end interface smesh_to_cube
125
126 interface cmesh_to_cube
127 module procedure cmesh_to_cube_1, cmesh_to_cube_2
128 end interface cmesh_to_cube
129
130 interface scube_to_mesh
131 module procedure scube_to_mesh_1, scube_to_mesh_2
132 end interface scube_to_mesh
133
134 interface ccube_to_mesh
135 module procedure ccube_to_mesh_1, ccube_to_mesh_2
136 end interface ccube_to_mesh
137
138contains
139
144 subroutine cube_function_alloc_fs(cube, cf, force_alloc)
145 type(cube_t), target, intent(in) :: cube
146 type(cube_function_t), intent(inout) :: cf
147 logical, optional, intent(in) :: force_alloc
148
149 integer :: n1, n2, n3
150 logical :: is_allocated
151
152 push_sub(cube_function_alloc_fs)
153
154 assert(.not. associated(cf%fs))
155 assert(allocated(cube%fft))
156
157 cf%forced_alloc = optional_default(force_alloc, .false.)
158 ! cf has no init, so assign here; preserve cf%batch_size (active count) set by the caller
159 cf%batch_capacity = cube%batch_capacity
160
161 n1 = max(1, cube%fs_n(1))
162 n2 = max(1, cube%fs_n(2))
163 n3 = max(1, cube%fs_n(3))
164
165 is_allocated = .false.
166
167 select case (cube%fft%library)
168 case (fftlib_pfft)
169 if (.not. cf%forced_alloc) then
170 is_allocated = .true.
171 if (any(cube%fs_n(1:3) == 0)) then
172 cf%fs => cube%fft%fs_data(1:1,1:1,1:1,1:cf%batch_capacity)
173 else
174 cf%fs => cube%fft%fs_data(1:n3,1:n1,1:n2,1:cf%batch_capacity)
175 end if
176 else ! force allocate transposed with PFFT
177 is_allocated = .true.
178 safe_allocate(cf%fs(1:n3, 1:n1, 1:n2, 1:cf%batch_capacity))
179 end if
180 case (fftlib_accel)
181 if (cf%in_device_memory) then
182 is_allocated = .true.
183 call accel_create_buffer(cf%fourier_space_buffer, accel_mem_read_write, type_cmplx, &
184 int(cf%batch_capacity, int64) * product(int(cube%fs_n(1:3), int64)))
185 end if
187 case (fftlib_fftw)
188 if (.not. cf%forced_alloc) then
189 is_allocated = .true.
190 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)
191 end if
192 end select
194 if (.not. is_allocated) then
195 safe_allocate(cf%fs(1:cube%fs_n(1), 1:cube%fs_n(2), 1:cube%fs_n(3), 1:cf%batch_capacity))
196 end if
199 end subroutine cube_function_alloc_fs
200
203 subroutine cube_function_free_fs(cube, cf)
204 type(cube_t), intent(in) :: cube
205 type(cube_function_t), intent(inout) :: cf
206
207 logical :: deallocated
208
210
211 assert(allocated(cube%fft))
212
213 deallocated = .false.
214
215 select case (cube%fft%library)
216 case (fftlib_pfft)
217 if (.not. cf%forced_alloc) then
218 deallocated = .true.
219 nullify(cf%fs)
220 end if
222 if (cf%in_device_memory) then
223 deallocated = .true.
224 call accel_free_buffer(cf%fourier_space_buffer)
225 end if
226 case (fftlib_fftw)
227 if (.not. cf%forced_alloc) then
228 deallocated = .true.
229 nullify(cf%fs)
230 end if
231 end select
232
233 if (.not. deallocated) then
234 assert(associated(cf%fs))
235 safe_deallocate_p(cf%fs)
236 end if
237
238 pop_sub(cube_function_free_fs)
240
241 ! ---------------------------------------------------------
244 subroutine cube_function_alloc_fs_single(cube, cf)
245 type(cube_t), target, intent(in) :: cube
246 type(cube_function_t), intent(inout) :: cf
247
249
250 assert(.not. associated(cf%cFS))
251 assert(allocated(cube%fft))
252 assert(cube%fft%library == fftlib_fftw .or. cube%fft%library == fftlib_accel)
253 assert(cube%fft%single)
254
255 cf%batch_capacity = cube%batch_capacity
256
257 if (cube%fft%library == fftlib_accel .and. cf%in_device_memory) then
258 call accel_create_buffer(cf%fourier_space_buffer, accel_mem_read_write, type_cmplx_single, &
259 int(cf%batch_capacity, int64) * product(int(cube%fs_n(1:3), int64)))
260 else if (.not. cf%forced_alloc .and. cube%fft%aligned_memory) then
261 cf%cFS => cube%fft%cfs_data(1:cube%fs_n(1), 1:cube%fs_n(2), 1:cube%fs_n(3), 1:cf%batch_capacity)
262 else
263 safe_allocate(cf%cFS(1:cube%fs_n(1), 1:cube%fs_n(2), 1:cube%fs_n(3), 1:cf%batch_capacity))
264 end if
265
267 end subroutine cube_function_alloc_fs_single
268
269 ! ---------------------------------------------------------
270 subroutine cube_function_free_fs_single(cube, cf)
271 type(cube_t), intent(in) :: cube
272 type(cube_function_t), intent(inout) :: cf
273
275
276 if (cube%fft%library == fftlib_accel .and. cf%in_device_memory) then
277 call accel_free_buffer(cf%fourier_space_buffer)
278 else if (.not. cf%forced_alloc .and. cube%fft%aligned_memory) then
279 nullify(cf%cFS)
280 else
281 safe_deallocate_p(cf%cFS)
282 end if
283
285 end subroutine cube_function_free_fs_single
286
287
288 ! ---------------------------------------------------------
294 pure logical function cube_map_is_trivial(cube) result(trivial)
295 type(cube_t), intent(in) :: cube
296 trivial = cube%cube_map_present .and. allocated(cube%cube_map%map)
297 if (.not. trivial) return
298 ! is_trivial captures the mesh-side property; the additional checks
299 ! verify the cube dimensions match the mesh and the cube origin aligns
300 ! so that mesh point 1 lands at cube cell (1, 1, 1).
301 trivial = cube%cube_map%is_trivial .and. &
302 cube%cube_map%nmap == cube%rs_n(2) * cube%rs_n(3) .and. &
303 cube%cube_map%map(mcm_count, 1) == cube%rs_n(1) .and. &
304 cube%cube_map%map(1, 1) + cube%center(1) == 1 .and. &
305 cube%cube_map%map(2, 1) + cube%center(2) == 1 .and. &
306 cube%cube_map%map(3, 1) + cube%center(3) == 1
307 end function cube_map_is_trivial
308
309#include "undef.F90"
310#include "real.F90"
311#include "cube_function_inc.F90"
312
313#include "undef.F90"
314#include "complex.F90"
315#include "cube_function_inc.F90"
316
317#include "undef.F90"
318#include "real32.F90"
319#include "cube_function_inc.F90"
320
321#include "undef.F90"
322#include "complex32.F90"
323#include "cube_function_inc.F90"
324
325end module cube_function_oct_m
326
327
328!! Local Variables:
329!! mode: f90
330!! coding: utf-8
331!! End:
subroutine, public accel_free_buffer(this, async)
Definition: accel.F90:990
integer, parameter, public accel_mem_read_write
Definition: accel.F90:185
real(real64) function, public dcube_function_surface_average(cube, cf)
This function calculates the surface average of any function.
subroutine scube_to_mesh_1(cube, cf, mesh, mf)
Convert a single function from the cube to the mesh.
subroutine ccube_to_mesh_1(cube, cf, mesh, mf)
Convert a single function from the cube to the mesh.
complex(real64) function, public zcube_function_surface_average(cube, cf)
This function calculates the surface average of any function.
subroutine ccube_to_mesh_2(cube, cf, mesh, mf, mf_buffer)
Convert a set of functions from the cube to the mesh.
subroutine dcube_to_mesh_1(cube, cf, mesh, mf)
Convert a single function from the cube to the mesh.
subroutine, public dcube_function_rs2fs(cube, cf)
Fourier transform a cube function from real space to Fourier space.
subroutine zcube_to_mesh_2(cube, cf, mesh, mf, mf_buffer)
Convert a set of functions from the cube to the mesh.
subroutine scube_to_mesh_2(cube, cf, mesh, mf, mf_buffer)
Convert a set of functions from the cube to the mesh.
subroutine, public scube_function_rs2fs(cube, cf)
The next subroutines (domain-parallel mesh<->cube and submesh<->cube) are double-precision only; the ...
subroutine, public ccube_function_rs2fs(cube, cf)
The next subroutines (domain-parallel mesh<->cube and submesh<->cube) are double-precision only; the ...
subroutine, public dcube_to_submesh(cube, cf, sm, mf)
subroutine, public cube_function_free_fs(cube, cf)
Deallocates the Fourier space buffer of the cube function.
subroutine, public scube_function_alloc_rs(cube, cf, in_device, force_alloc)
Allocates locally the real space grid, if PFFT library is not used. Otherwise, it assigns the PFFT re...
subroutine, public ccube_function_alloc_rs(cube, cf, in_device, force_alloc)
The next subroutines (domain-parallel mesh<->cube and submesh<->cube) are double-precision only; the ...
subroutine, public scube_function_fs2rs(cube, cf)
Fourier transform a cube function from Fourier space to real space.
subroutine dmesh_to_cube_2(mesh, mf, cube, cf, mf_buffer)
Convert a set of functions from the mesh to the cube.
subroutine, public dcube_function_allgather(cube, cf, cf_local, order, gatherfs)
The next subroutines (domain-parallel mesh<->cube and submesh<->cube) are double-precision only; the ...
subroutine, public zcube_to_mesh_parallel(cube, cf, mesh, mf, map)
subroutine, public cube_function_alloc_fs_single(cube, cf)
Allocate the single-precision (complex32) Fourier-space buffer cfcFS. Host, serial,...
subroutine, public dcube_function_alloc_rs(cube, cf, in_device, force_alloc)
Allocates locally the real space grid, if PFFT library is not used. Otherwise, it assigns the PFFT re...
subroutine zmesh_to_cube_1(mesh, mf, cube, cf)
Convert a single function from the mesh to the cube.
subroutine, public zcube_to_submesh(cube, cf, sm, mf)
pure logical function, public cube_map_is_trivial(cube)
True when the cube_map describes a trivial mesh->cube identity: the mesh is X-fastest with one full-X...
subroutine smesh_to_cube_1(mesh, mf, cube, cf)
Convert a single function from the mesh to the cube.
subroutine, public zmesh_to_cube_parallel(mesh, mf, cube, cf, map)
The next subroutines (domain-parallel mesh<->cube and submesh<->cube) are double-precision only; the ...
subroutine, public dcube_function_free_rs(cube, cf)
Deallocates the real space grid.
subroutine, public ccube_function_free_rs(cube, cf)
Deallocates the real space grid.
subroutine dmesh_to_cube_1(mesh, mf, cube, cf)
Convert a single function from the mesh to the cube.
subroutine, public dsubmesh_to_cube(sm, mf, cube, cf)
The next two subroutines convert a function between a submesh and the cube.
subroutine zmesh_to_cube_2(mesh, mf, cube, cf, mf_buffer)
Convert a set of functions from the mesh to the cube.
subroutine smesh_to_cube_2(mesh, mf, cube, cf, mf_buffer)
Convert a set of functions from the mesh to the cube.
subroutine, public cube_function_alloc_fs(cube, cf, force_alloc)
Allocates the local part of the Fourier space grid on the cube function.
subroutine, public zsubmesh_to_cube(sm, mf, cube, cf)
The next two subroutines convert a function between a submesh and the cube.
subroutine, public zcube_function_allgather(cube, cf, cf_local, order, gatherfs)
The next subroutines (domain-parallel mesh<->cube and submesh<->cube) are double-precision only; the ...
subroutine, public dmesh_to_cube_parallel(mesh, mf, cube, cf, map)
The next subroutines (domain-parallel mesh<->cube and submesh<->cube) are double-precision only; the ...
subroutine, public zcube_function_fs2rs(cube, cf)
Fourier transform a cube function from Fourier space to real space.
subroutine, public dcube_function_fs2rs(cube, cf)
Fourier transform a cube function from Fourier space to real space.
subroutine dcube_to_mesh_2(cube, cf, mesh, mf, mf_buffer)
Convert a set of functions from the cube to the mesh.
subroutine, public zcube_function_free_rs(cube, cf)
Deallocates the real space grid.
subroutine, public ccube_function_fs2rs(cube, cf)
Fourier transform a cube function from Fourier space to real space.
subroutine cmesh_to_cube_2(mesh, mf, cube, cf, mf_buffer)
Convert a set of functions from the mesh to the cube.
subroutine, public scube_function_free_rs(cube, cf)
Deallocates the real space grid.
subroutine, public dcube_to_mesh_parallel(cube, cf, mesh, mf, map)
subroutine, public cube_function_free_fs_single(cube, cf)
subroutine, public zcube_function_rs2fs(cube, cf)
Fourier transform a cube function from real space to Fourier space.
subroutine cmesh_to_cube_1(mesh, mf, cube, cf)
Convert a single function from the mesh to the cube.
subroutine, public zcube_function_alloc_rs(cube, cf, in_device, force_alloc)
Allocates locally the real space grid, if PFFT library is not used. Otherwise, it assigns the PFFT re...
subroutine zcube_to_mesh_1(cube, cf, mesh, mf)
Convert a single function from the cube to the mesh.
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:183
integer, parameter, public fftlib_pfft
Definition: fft.F90:183
integer, parameter, public fftlib_fftw
Definition: fft.F90:183
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
integer, parameter, public mcm_count
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
Some general things and nomenclature:
Definition: par_vec.F90:173
This module is an helper to perform ring-pattern communications among all states.
type(type_t), parameter, public type_cmplx_single
Definition: types.F90:142
type(type_t), parameter, public type_cmplx
Definition: types.F90:137
int true(void)