FFTW для уравнения Пуассона в 3D со всеми граничными условиями Неймана

Я пытаюсь решить уравнение Пуассона в 3D со всеми граничными условиями Неймана, используя библиотеку FFTW. Уравнение записывается следующим образом: 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();

}

person Luc Nguyen    schedule 03.02.2015    source источник
comment
@Paul R: не могли бы вы дать мне совет?   -  person Luc Nguyen    schedule 05.02.2015
comment
@francis: не могли бы вы дать мне совет?   -  person Luc Nguyen    schedule 05.02.2015


Ответы (1)


Это довольно сложно как физически, так и математически, но все же многие из обычных методов отладки C++ по-прежнему действительны.

Во-первых, есть много простых граничных условий, которые позволяют получить точное решение (все нули VORTG должны давать константу STR). Вы проверили, все ли промежуточные значения имеют ожидаемые значения для таких простых входных данных? Для несколько более сложных граничных условий вы, возможно, не сможете подобрать точные значения для различных промежуточных звеньев, но вы все равно сможете проверить правильность знаков. И, наконец, вы можете не знать точного решения для некоторого граничного условия, но вы можете подтвердить, что физические симметрии соблюдаются. Если вы можете отразить свои граничные условия, результаты также должны быть отражены. Они?

person MSalters    schedule 03.02.2015
comment
Я проверил другую задачу с точным решением, я могу ее контролировать, но в моем реальном случае я не могу ее контролировать. VORTG имеет некоторые ненулевые значения в центре вычислительной области, другое значение равно нулю. Моя вычислительная область похожа на куб с 6 поверхностями, имеющими граничное условие Неймана нулей. Поэтому я использую FFTW_REDFT00. Я уже пробовал с той же проблемой в 2D, и он работал правильно, но в 3D он работал неправильно. Мой результат может быть не зеркальным, но граница должна удовлетворять. Любые ваши советы для меня удовольствие и честь. Большое спасибо. - person Luc Nguyen; 03.02.2015
comment
Согласно М.Салтерсу, если VORTG полностью равен нулю, STR получает постоянное значение. Однако VORTG имеет некоторое значение (не равное нулям) в середине расчетной области, STR до всего остается постоянным значением. Почему это происходит? Я использовал конечно другой метод для решения этого уравнения, я получил значение STR, которое не является постоянным. Пожалуйста, дайте мне совет, если у вас есть идеальный. Большое спасибо. - person Luc Nguyen; 04.02.2015
comment
@Luc: я не понимаю твоих комментариев. Вы действительно пытались вызвать свою функцию с нулевым VORTG? Каков был реальный результат? Верна ли моя догадка, что математически STR должна иметь одно постоянное значение? - person MSalters; 04.02.2015
comment
Я уже пробовал с нулевым VORTG и получил постоянную STR со всеми нулями. Прошу прощения за мой неясный комментарий. Это одна подпрограмма в моей программе, и для решения моей проблемы требуется много времени. Поэтому мне нужно добавить fftw это уравнение. VORTG - это входное значение из одного текстового файла с некоторым значением, которое не равно нулю, и мне нужно получить STR, решив это уравнение. Но когда я запускаю свою программу, STR равен нулю, даже VORTG не равен нулю. Я не знаю, где я получаю ошибку. Я хотел бы опубликовать файл tex и программу здесь, но я не знаю, как я могу это опубликовать? - person Luc Nguyen; 04.02.2015
comment
@ MSalters: VORTG представляет собой вектор в 3D с размерами NxNxN, похожими на куб, и имеет некоторое значение, не равное нулю в середине куба. Если это возможно, сообщите мне свой адрес электронной почты, и я отправлю вам txt-файл. Мой адрес электронной почты: [email protected] Большое спасибо. - person Luc Nguyen; 04.02.2015
comment
Я не достаточно эксперт, извините. У вас есть медленный, но работающий алгоритм? Это дает вам еще один вариант отладки вашего алгоритма на основе FFTW. Можете ли вы выяснить причину разных выходов для простого одиночного входа? - person MSalters; 04.02.2015
comment
@ MSalters: Большое спасибо за вашу помощь. Да, моя программа настолько медленная, что использует метод конечных разностей (FDM) для решения уравнения Пуассона. Это должен быть один выход для одного входа, как при использовании FDM. Но когда я сравниваю результат двух методов (FDM и FFT), которые действительно дают разницу. - person Luc Nguyen; 04.02.2015