我有以下看似简单的问题,但我还没有找到相关信息:
在fortran90中,是否可以将FFTW计划传递给子程序,以便允许在不同的地方重复使用计划"的代码?简单地将其作为INTEGER * 8变量传递的简单方法会产生混乱,这表明代码需要的不仅仅是普通的整数计划来执行傅里叶变换。
答案 0 :(得分:2)
FFTW有两种不同的Fortran接口。我假设FFTW3作为版本2已被弃用。
我强烈推荐使用Fortran 2003与C互操作性的现代Fortran接口。然后该平面的类型为type(c_ptr)
,它在内部模块iso_c_binding
中定义。
在旧版界面中,计划在最常见的64位平台上确实是integer*8
。
有许多示例如何在手册中使用该计划。有关旧版界面,请参阅http://www.fftw.org/doc/Fortran-Examples.html#Fortran-Examples,现代界面请参阅http://fftw.org/doc/Overview-of-Fortran-interface.html#Overview-of-Fortran-interface。
无论您选择哪种界面,都可以将plan
变量作为伪参数传递给子例程,函数以及您需要使用或存储的任何位置。
如果您在执行之前工作的计划时遇到问题,请确保它所引用的工作数组存在且已正确分配。在这方面,本地未保存的子程序数组是不安全的。
小心伪参数数组。它们可能仅在执行创建计划的子例程期间有效,因为它们作为副本传递。 target
参数对100%没有帮助,因为它可能仅在定义过程中有效。
- 重要编辑
http://www.fftw.org/doc/FFTW-Execution-in-Fortran.html#FFTW-Execution-in-Fortran
中解释了另一个问题尝试使用
call dfftw_execute_dft(plan, in, out)
(在传统界面中,现代界面中有一个等效物)。它也可能改善我之前解释过的两个段落的可能问题,因为即使在原始数组的副本的情况下,新的指针也会被传递并且也可以。
答案 1 :(得分:1)
为此,我经常编写一个Fortran模块,在其中放置计划和可分配的数组,这些数组将包含FFTW3的输入和输出。然后,我可以随便在任何地方使用模块。
以下是实际数据的三维FFT的示例:
MODULE modfft
IMPLICIT NONE
TYPE :: fftw3Needs
INTEGER(i4b) :: plan_forward, plan_backward ! plans for forward and inverse fft
REAL(dp), ALLOCATABLE, DIMENSION (:,:,:) :: in_forward, out_backward ! input of FFT and output (result) of inverse FFT
COMPLEX(dp), ALLOCATABLE, DIMENSION (:,:,:) :: out_forward, in_backward ! output (result) of FFT and input of inverse FFT
END TYPE
TYPE (fftw3Needs) :: fftw3
CONTAINS
SUBROUTINE init
CALL init_fftw3_plans! Where you initialize your plans with, e.g., dfftw_plan_dft_r2c_3d.
END SUBROUTINE init
SUBROUTINE deallocate_everything_fft
CALL dfftw_destroy_plan ( fftw3%plan_forward ) ! destroy FFTW3 plans
CALL dfftw_destroy_plan ( fftw3%plan_backward ) ! destroy FFTW3 plans
END SUBROUTINE deallocate_everything_fft
END MODULE modfft
请注意,这使用旧的Fortran界面。