C++ 不同尺寸的二维fftw泊松解算器

C++ 不同尺寸的二维fftw泊松解算器,c++,fftw,C++,Fftw,我正在尝试使用中提供的fft将泊松解算器扩展到各种boxsize L,因为原始作者和答案仅适用于L=2pi。主要的变化是f=g/(kx²+ky²),其中kx现在是i*2pi/L或(N-i)*2pi/L。它们是质询频率 对ky进行了类似的更改,但我的代码只适用于任何整数n的L=2n*pi。因此,对于其他L,如L=3pi或5pi,误差要大得多 我已经通过再次运行fft和ifft检查了代码,没有应用f=g/(kx²+ky²)。对于L的任何值来说都是非常好的,但是当我在代码中包含(kx²+ky²)时,问

我正在尝试使用中提供的fft将泊松解算器扩展到各种boxsize L,因为原始作者和答案仅适用于L=2pi。主要的变化是f=g/(kx²+ky²),其中kx现在是i*2pi/L或(N-i)*2pi/L。它们是质询频率

对ky进行了类似的更改,但我的代码只适用于任何整数n的L=2n*pi。因此,对于其他L,如L=3pi或5pi,误差要大得多

我已经通过再次运行fft和ifft检查了代码,没有应用f=g/(kx²+ky²)。对于L的任何值来说都是非常好的,但是当我在代码中包含(kx²+ky²)时,问题再次出现

我知道我一定错过了一些简单的事情。任何意见都是值得赞赏的,因为我没有想法。。。。多谢各位

这是完整的代码

#include <fstream>
#include <iostream> 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <fftw3.h>

using namespace std;

int main()
{
    int N = 64;
    int i, j ;
    double pi = 3.14159265359;
    double *X, *Y  ;
    X = (double*) malloc(N*sizeof(double));
    Y = (double*) malloc(N*sizeof(double));
    fftw_complex  *out1, *in2, *out2, *in1;
    fftw_plan     p1, p2;
    double L  = 4.*pi;  //only works for 2n*pi for integer n
    double dx = L/(N);

    in1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*(N*N) );
    out1 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*(N*N) );
    in2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*(N*N) );
    out2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*(N*N) );

    p1 = fftw_plan_dft_2d(N, N, in1, out1, FFTW_FORWARD,FFTW_MEASURE );
    p2 = fftw_plan_dft_2d(N, N, in2, out2, FFTW_BACKWARD,FFTW_MEASURE);

    for(i = 0; i < N; i++){
        X[i] = -(L/2) + i*dx ;
        for(j = 0; j < N; j++){
            Y[j] = -(L/2) + j*dx ;
            in1[i*N + j][0] = sin(X[i]) + sin(Y[j]) ; // row major ordering
            in1[i*N + j][1] = 0 ;
        }
    }

    fftw_execute(p1); // FFT forward

    for ( i = 0; i < N; i++){   // f = g / ( kx² + ky² )
        for( j = 0; j < N; j++){

            double fact=0;
            if(2*i<N){fact=pow((double)i*2*pi/L,2);}
            else{fact=pow((double)(N-i)*2*pi/L,2);} 

            if(2*j<N){fact+=pow((double)j*2*pi/L,2);}
            else{fact+=pow((double)(N-j)*2*pi/L,2);}

            if(fact!=0){
                in2[i*N + j][0] = out1[i*N + j][0]/fact;
                in2[i*N + j][1] = out1[i*N + j][1]/fact;
            }else{
                in2[i*N + j][0] = 0;
                in2[i*N + j][1] = 0;
            }
        }
    }

    fftw_execute(p2); //FFT backward

    // checking the results computed
    double erl1 = 0.;
    for ( i = 0; i < N; i++) {
        for( j = 0; j < N; j++){
            erl1 += fabs( in1[i*N + j][0] -  out2[i*N + j][0]/(N*N))*dx*dx; 
            //cout<< i <<" "<< j<<" "<< sin(X[i])+sin(Y[j])<<" "<<  out2[i*N+j][0]/(N*N) <<" "<< endl; // > output
        }
    }
    cout<< "error is "<< erl1 << endl ;  // L1 error

    fftw_destroy_plan(p1);
    fftw_destroy_plan(p2);
    fftw_free(out1);
    fftw_free(out2);
    fftw_free(in1); 
    fftw_free(in2);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int main()
{
int N=64;
int i,j;
双pi=3.14159265359;
双*X,*Y;
X=(双*)malloc(N*sizeof(双));
Y=(双*)malloc(N*sizeof(双));
fftw_复合体*out1、*in2、*out2、*in1;
fftw_计划p1、p2;
double L=4.*pi;//对于整数n,仅适用于2n*pi
双dx=L/(N);
in1=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*(N*N));
out1=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*(N*N));
in2=(fftw_复合体*)fftw_-malloc(sizeof(fftw_复合体)*(N*N));
out2=(fftw_复合体*)fftw_malloc(sizeof(fftw_复合体)*(N*N));
p1=fftw_平面图_dft_2d(N,N,in1,out1,fftw_正向,fftw_度量);
p2=fftw_平面图_dft_2d(N,N,in2,out2,fftw_向后,fftw_度量);
对于(i=0;i如果(2*看,我可能知道答案。因为只有当边界大小为L=2n*pi时,测试f=sinx+siny才是周期性的。对于所有其他L,解算器得出的解是周期性的,不再与f=sinx+siny相同。好的,我可能知道答案。因为只有当边界大小为L=2n*pi时,测试f=sinx+siny才是周期性的。对于在所有其他L中,解算器得出的解是周期性的,不再与f=sinx+siny相同。