# Module: FFT Fast fourier transform related variables and subroutines. :::{admonition} Cluster distributed FFT :class: important In intel MKL, the MPI slicing happens along the first dimension in C, or the last dimension in Fortran. Note, this is the most natural way to do the slicing, because you want to keep the contingent data in memory on the same core. In the Mu-PRO PhaseFieldSDK, since we also support thin-film boundary conditions in many of our solvers and in most cases x dimension is larger than z, thus it is not a good choice to slice along the Z direction. As a result, all of the real space allocated arrays in Mu-PRO PhaseFieldSDK is defined as **(z, y, x)** rather than (x, y, z), so that the slicing happens along the x dimension instead of z. ::: ```{important} FFT module is also the base for many other modules. You must call the `mupro_fft_setup` subroutine before you can use the solvers in the SDK. ``` :Name: mod_mupro_fft :Depends on: [mod_mupro_size](size.md), [mod_mupro_print](print.md) :Defined variables: None :Defined types: [type_mupro_FFContext](#type_mupro_FFContext) :Defined subroutines: [mupro_fft_setup](#mupro_fft_setupcontext), [mupro_fft_forward](#mupro_fft_forward), [mupro_fft_backward](#mupro_fft_backward) ,[mupro_fitted_derivative](#mupro_fitted_derivative), [mupro_fitted_curvature](#mupro_fitted_curvature) ## Defined Types ### type_mupro_FFTContext | Variable | Type | Meaning | | :------: | :---: | :----------------------------------------------------- | | Rn1 | int32 | Size of real space x dimension on the current core | | Rn2 | int32 | Size of real space y dimension on the current core | | Rn3 | int32 | Size of real space z dimension on the current core | | Cn1 | int32 | Size of fourier space x dimension on the current core | | Cn2 | int32 | Size of fourier space y dimension on the current core | | Cn3 | int32 | Size of fourier space z dimension on the current core | | lstart | int32 | Starting index of the data along x on the current core | ```{important} MPI slicing in FFT only happens along the last dimension of Fortran array, so to have such slicing happens along the x direction, we have to define the x as the last dimension, y as the second to last, and so on. To give an example, the dimension for polarization is (3,z,y,x). ``` ```{note} Since MPI slicing happens along the last dimension of Fortran array (which is x in our convention), so $\text{Rn3}=\text{nz}$, $\text{Rn2}=\text{ny}$, $\text{Rn1}\neq \text{nx}$, and $\text{lstartR} = \text{0}$ for rank 0, and $\text{lstartR}\neq \text{0}$ for other ranks. ``` ## Defined Subroutines ### mupro_fft_setup Initialize cluster distributed FFT, so that we can use forward and backward functions afterwards. > call mupro_fft_setup(context) ```{important} You must call this fft setup subroutine after [mupro_size_setup](base#mupro_size_setup) and [mupro_mpi_setup](base#mupro_mpi_setup) but before all other subroutines that involves 3D data. ``` | Argument | Type(Intent) | Meaning | | :------: | :-----------------------------------------------------------: | :------------------------------------- | | context | [type_mupro_FFTContext, intent(OUT)](#type_mupro_FFTContext)  | The initialized FFT system information | ### mupro_fft_forward(real_space, fourier_space ) Forward fft from real space to fourier space. | Argument | Type(Intent) | Meaning | | :-----------: | :---------------------------------------------------: | :-------------------- | | real_space | real(kind=rdp),intent(in),dimension(Rn3,Rn2,Rn1)  | Data in real space | | fourier_space | complex(kind=rdp),intent(out),dimension(Cn3,Cn2,Cn1)  | Data in fourier space | ### mupro_fft_backward(fourier_space, real_space ) Backward fft from fourier space to real space. | Argument | Type(Intent) | Meaning | | :-----------: | :--------------------------------------------------: | :-------------------- | | fourier_space | complex(kind=rdp),intent(in),dimension(Cn3,Cn2,Cn1)  | Data in fourier space | | real_space | real(kind=rdp),intent(out),dimension(Rn3,Rn2,Rn1)  | Data in real space | ### mupro_fitted_derivative(data, derivative, order, direction) Calculate derivate of 3D data. This function can be called in both thin film and bulk cases. In the thin film case, due to the sudden change in data across the film interface and surface, a special fitting step is included, which is also why the subroutine is called mupro_fitted_derivative. | Argument | Type(Intent) | Meaning | | :-------: | :----------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | data | real(kind=rdp),intent(in),dimension(Rn3,Rn2,Rn1)  | Data in real space | | derivate | real(kind=rdp),intent(out),dimension(3, Rn3,Rn2,Rn1 )  | Derivative in real space, in the order of $\frac{d}{dx}$, $\frac{d}{dy}$, $\frac{d}{dz}$ | | order | integer,intent(in)  | Order for the fitting along z direction in the thin film case, you can choose from 0 to 4 | | direction | integer,intent(in)  | The direction to calculate derivative, 1: only $\frac{d}{dx}$, 2: only $\frac{d}{dy}$, 3: only $\frac{d}{dz}$, 4: all derivates, 5: $\frac{d}{dx}$ and $\frac{d}{dy}$ | ### mupro_fitted_curvature(data, curvature, order, direction) Calculate curvature of 3D data. This function can be called in both thin film and bulk cases. In the thin film case, due to the sudden change in data across the film interface and surface, a special fitting step is included, which is also why the subroutine is called mupro_fitted_curvature. | Argument | Type(Intent) | Meaning | | :-------: | :----------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | data | real(kind=rdp),intent(in),dimension(Rn3,Rn2,Rn1)  | Data in real space | | derivate | real(kind=rdp),intent(out),dimension(6, Rn3,Rn2,Rn1 )  | Curvature in real space, in the order of $\frac{d^2}{dx^2}$, $\frac{d^2}{dy^2}$, $\frac{d^2}{dz^2}$, $\frac{d^2}{dydz}$ , $\frac{d^2}{dxdz}$, $\frac{d^2}{dxdy}$ | | order | integer,intent(in)  | Order for the fitting along z direction in the thin film case, you can choose from 0 to 4 | | direction | integer,intent(in)  | The direction to calculate Curvature, 1 for $\frac{d^2}{dxdy}$, 2 for $\frac{d^2}{dxdz}$, 4 for $\frac{d^2}{dydz}$, 8 for $\frac{d^2}{dz^2}$, 16 for $\frac{d^2}{dy^2}$, 32 for $\frac{d^2}{dx^2}$. To request multiple second derivatives these numbers should be added together |