具有所有诺伊曼边界条件的 3D 泊松方程的 FFTW



我正在尝试使用 FFTW 库在 3D 中求解所有诺伊曼边界条件下的泊松方程。方程如下 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();
}
它在

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

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

最新更新