具有所有Neumann边界条件的三维泊松方程的FFTW

时间:2015-02-03 04:43:08

标签: c++ fftw poisson

我试图用FFTW库解决所有Neumman边界条件下的三维泊松方程。 该方程如下:d ^ STR / dx ^ 2 + d ^ STR / dy ^ 2 + d ^ 2STR / dz ^ 2 = -VORTG。 在我看来,计算out2的步骤是正确的。但是,我不确定计算STR的步骤。 你能给我一些建议吗? 非常感谢你。

    void poisson3d(vector<vector<vector<double> > > &STR, vector<vector<vector<double> > > &VORTG)
{
    double pi = 3.141592653589793;
    double XMIN=-2.0;
    double XMAX=2.0;
    double YMIN=-2.0;
    double YMAX=2.0;
    double ZMIN=-2.0;
    double ZMAX=2.0;
    double dd=(XMAX-XMIN)*(YMAX-YMIN)*(ZMAX-ZMIN)/pi/pi/pi;

    std::vector<double> in1(N*N*N,0.0);
    std::vector<double> in2(N*N*N,0.0);
    std::vector<double> out1(N*N*N,0.0);
    std::vector<double> out2(N*N*N,0.0);

    fftw_plan p, q;
    int i,j,k;
    p = fftw_plan_r2r_3d(N, N, N, in1.data(), out1.data(), FFTW_REDFT00 ,FFTW_REDFT00, FFTW_REDFT00, FFTW_ESTIMATE);
    q = fftw_plan_r2r_3d(N, N, N, in2.data(), out2.data(), FFTW_REDFT00 ,FFTW_REDFT00, FFTW_REDFT00, FFTW_ESTIMATE);

    int l=-1;double max=0;
    for (i = 0;i <N;i++)        
        for (j = 0;j<N;j++)
            for (k=0;k<N;k++){ 
                l=l+1;
            in1[l]= VORTG[i][j][k];

            }

    fftw_execute(p);

    l=-1;
    for ( i = 0; i < N; i++){   // f = g / ( kx² + ky² )  
        for( j = 0; j < N; j++){
            for (k=0; k<N; k++){
                l=l+1;
            double fact=0;
            in2[l]=0;

            if(2*i<N){
                fact=((double)i*i);
            }else{
                fact=((double)(N-i)*(N-i));
            }
            if(2*j<N){
                fact+=((double)j*j);
            }else{
                fact+=((double)(N-j)*(N-j));
            }
                if(2*k<N){
                    fact+=((double)k*k);
                }else{
                    fact+=((double)(N-k)*(N-k));
                }

            if(fact!=0){
                in2[l] = out1[l]/fact;
            }else{
                in2[l] = 0.0;
            }

            }
        }
    }

    fftw_execute(q);

    for ( i = 0; i < N; i++) {
        for( j = 0; j < N; j++){
            for (k=0;k<N;k++){
                STR[i][j][k]= dd*out2[l]/((double)2.0*(N-1))/((double)2.0*(N-1))/((double)2.0*(N-1)); 
            }
        }
    }

    fftw_destroy_plan(p); fftw_destroy_plan(q); fftw_cleanup();

}

1 个答案:

答案 0 :(得分:0)

在物理上和数学上都很复杂,但仍有许多常用的C ++调试技术仍然有效。

首先,有许多简单的边界条件允许精确解(全0 VORTG必须产生常数STR)。您是否检查过所有中间值是否具有此类简单输入的预期值?对于稍微复杂的边界条件,您可能无法为各种中间体提供精确值,但您仍可以检查符号是否正确。最后,您可能不知道某些边界条件的精确解,但您可能能够验证是否遵守了物理对称性。如果您可以镜像边界条件,则还应反映结果。是吗?