我试图用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();
}
答案 0 :(得分:0)
在物理上和数学上都很复杂,但仍有许多常用的C ++调试技术仍然有效。
首先,有许多简单的边界条件允许精确解(全0 VORTG
必须产生常数STR
)。您是否检查过所有中间值是否具有此类简单输入的预期值?对于稍微复杂的边界条件,您可能无法为各种中间体提供精确值,但您仍可以检查符号是否正确。最后,您可能不知道某些边界条件的精确解,但您可能能够验证是否遵守了物理对称性。如果您可以镜像边界条件,则还应反映结果。是吗?