Я написал простую тестовую программу для реализации FFTW с MPI в домене 2d (с помощью Fortran). Область «Ny x Nx» широта и разделена во втором («x») индексе.Неверный вывод через fftw_mpi_r2c_2d и fftw_mpi_c2r_2d
После правильного (я верю?) Объявления и распределения переменных и планов я вызываю функцию fftw_mpi r2c_2d, а затем я преобразовываю его вывод с помощью fftw_mpi c2r_2d, чтобы проверить, не получаю ли я исходный ввод. Кажется, что часть r2c_2d работает нормально. Тем не менее, я не получаю исходный ввод после преобразования назад (отдельно нормализации) с помощью функции c2r_2d: результирующий вектор отображает «нули» по индексам (:, j) с j, соответствующими кратным «Ny/2», , Что я делаю не так? Благодаря!
Вот выдержка из кода:
Program TEST
use, intrinsic :: iso_c_binding
Implicit none
include 'mpif.h'
include 'fftw3-mpi.f03'
Integer*8,parameter :: nx=16, ny=16
!MPI
integer*8 :: ipe,npe
integer*8 ::mpi_realtype,icomm=mpi_comm_world,istat(mpi_status_size),ierr
! FFTW VARIABLES DECLARATION
type(C_PTR) :: p1, p2, cdatar, cdatac
integer(C_INTPTR_T) :: alloc_local, local_L, local_L_offset, local_M, local_M_offset
real(C_DOUBLE), pointer :: faux(:,:) ! real input 2d function
complex(C_DOUBLE), pointer :: gaux(:,:) ! complex output of 2d FFTW (transposed)
! MPI initialization
call mpi_init(ierr)
call mpi_comm_rank(icomm,ipe,ierr)
call mpi_comm_size(icomm,npe,ierr)
! FFTW ALLOCATIONS AND PLANS
call fftw_mpi_init()
alloc_local = fftw_mpi_local_size_2d(ny/2+1,nx &
,MPI_COMM_WORLD, local_L, local_L_offset)
cdatac = fftw_alloc_complex(alloc_local)
call c_f_pointer(cdatac, gaux, [nx,local_L]) !transposed
alloc_local = fftw_mpi_local_size_2d(nx,ny/2+1, MPI_COMM_WORLD, &
local_M, local_M_offset)
cdatar = fftw_alloc_real(2*alloc_local)
call c_f_pointer(cdatar, faux, [ny,local_M])
! Create plans
p1 = fftw_mpi_plan_dft_r2c_2d(nx,ny,faux,gaux, MPI_COMM_WORLD, &
ior(FFTW_MEASURE, FFTW_MPI_TRANSPOSED_OUT))
p2 = fftw_mpi_plan_dft_c2r_2d(nx,ny,gaux,faux, MPI_COMM_WORLD, &
ior(FFTW_MEASURE, FFTW_MPI_TRANSPOSED_IN))
! EXECUTE FFTW
call random_number(faux)
print *, "real input:", real(faux(1,:))
call fftw_mpi_execute_dft_r2c(p1,faux,gaux)
call fftw_mpi_execute_dft_c2r(p2, gaux, faux)
print *, "real output:", real(faux(1,:))/(nx*ny)
call fftw_destroy_plan(p1)
call fftw_destroy_plan(p2)
call mpi_finalize(ierr)
End Program TEST
Не используйте настоящие (8) и сложные (8), они не переносимы. По меньшей мере два компилятора откажутся от него по умолчанию. Аргументы процедуры FFTW объявляются как реальные (c_double) и сложные (c_double), так почему бы не сделать это? (Я не утверждаю, что это вызывает вашу ошибку, это не так.) –
Вы прочитали руководство о формате c2r и почему хранится только половина массива? http://www.fftw.org/doc/Real_002ddata-DFT-Array-Format.html#Real_002ddata-DFT-Array-Format –
И, пожалуйста, не показывайте выдержку из кода, покажите [mcve]. –