【问题标题】:Poisson equation using FFTW with rectanguar domain使用具有矩形域的 FFTW 的泊松方程
【发布时间】:2015-03-19 01:44:24
【问题描述】:

我正在尝试通过使用具有矩形域(-4

#include <stdio.h>
#include <math.h>
#include <cmath>
#include <fftw3.h>
#include <iostream>
#include <vector>

using namespace std;
int main() {

    int N1=64;
    int N2=32;

    double pi = 3.141592653589793;
    double L1  = 8.0;
    double dx = L1/(double)(N1-1);
    double L2= 4.0;
    double dy=L2/(double)(N2-1);

    std::vector<double> in1(N1*N2,0.0);
    std::vector<double> in2(N1*N2,0.0);
    std::vector<double> out1(N1*N2,0.0);
    std::vector<double> out2(N1*N2,0.0);
    std::vector<double> X(N1,0.0);
    std::vector<double> Y(N2,0.0);


    fftw_plan p, q;
    int i,j;
    p = fftw_plan_r2r_2d(N1,N2, in1.data(), out1.data(), FFTW_REDFT00, FFTW_REDFT00, FFTW_EXHAUSTIVE);
    q = fftw_plan_r2r_2d(N1,N2, in2.data(), out2.data(), FFTW_REDFT00, FFTW_REDFT00, FFTW_EXHAUSTIVE);

    int l=-1;
    for(i = 0;i <N1;i++){
        X[i] =-4.0+(double)i*dx ;           
        for(j = 0;j<N2;j++){
            l=l+1;
            Y[j] =-2.0+ (double)j*dy ;
            in1[l]= cos(pi*X[i]) + cos(pi*Y[j]) ; // row major ordering
        }
    }

    fftw_execute(p);

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

            if(2*i<N1){
                fact=((double)i*i);
            }else{
                fact=((double)(N1-i)*(N1-i));
            }
            if(2*j<N2){
                fact+=((double)j*j);
            }else{
                fact+=((double)(N2-j)*(N2-j));
            }
            if(fact!=0){
                in2[l] = out1[l]/fact;
            }else{
                in2[l] = 0.0;
            }
        }
    }

    fftw_execute(q);
    l=-1;
    double erl1 = 0.;
    for ( i = 0; i < N1; i++) {
        for( j = 0; j < N2; j++){
            l=l+1;

            erl1 += fabs( in1[l]-  8.*out2[l]/((double)(N1-1))/((double)(N2-1))); 
            printf("%3d %10.5f %10.5f\n", l, in1[l], 8.*out2[l]/((double)(N1-1))/((double)(N2-1)));

        }
    }

    cout<<"error=" <<erl1 <<endl ;  
    fftw_destroy_plan(p); fftw_destroy_plan(q); fftw_cleanup();



    return 0;
}

【问题讨论】:

    标签: c++ fftw poisson


    【解决方案1】:

    在傅立叶空间中,频率 k_x 和 k_y 必须取决于域的大小。由于域是矩形的,因此它变得很重要。

    试试:

    double invL1s=1.0/(L1*L1);
    double invL2s=1.0/(L2*L2);
    ...
            if(2*i<N1){
                fact=((double)i*i)*invL1s;
            }else{
                fact=((double)(N1-i)*(N1-i))*invL1s;
            }
            if(2*j<N2){
                fact+=((double)j*j)*invL2s;
            }else{
                fact+=((double)(N2-j)*(N2-j))*invL2s;
            }
    

    输出应该更接近预期的输出(比例因子除外)。

    【讨论】:

    • 我现在真的很开心。我不知道该如何感谢你,弗朗西斯。它太棒了,太棒了。如果你成为我的朋友,我会更幸运。非常感谢你的帮助。最后,还有一件事,你能给我建议我应该阅读哪些参考资料或链接,并了解更多关于“傅立叶空间,频率 k_x 和 k_y”的信息吗?
    • k_xk_ywave numberspatial frequencies。空间周期信号f(x) 的离散傅里叶变换在波数k_x 处写入:ff(k_x)=sum{f(x)exp(2i pi k_x x)}。如果x 是距离,则k_x 必须是距离的倒数。见topex.ucsd.edu/geodynamics/01fourier.pdf如果你觉得答案有帮助,你可以点击接受按钮:你将获得学者徽章,回答者获得声望。 It+upvoting 是在这个网站上说“谢谢”的一种方式!
    • 再次为你投票。它也适用于 3 维。
    • 如果解决了,考虑接受答案。 meta.stackexchange.com/questions/5234/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多