我通过使用fftw,傅里叶变换它,乘以适当的并采用逆傅立叶变换计算了sin的第一,第二和第三导数(2.0 * pi * j / lambda)(j从0变化到255)。使用的计划不合适,具有虚拟输入和输出阵列。结果数组的实部是分析结果的一半。我通过选择适当的kx / ky值来处理衍生物时处理混叠。只需取fftw和逆fftw就可以正确地返回原始数组。
fftw返回的值是所有衍生物的分析值的一半。
如果我在x方向上做同样的事情(i而不是j),获得的值仅对于x的一阶导数是正确的,y导数是非零的(因为变化只是零在x)和laplacian和biharmonic(第四导数wrt x和y)是错误的。
在这两种情况下,导数的虚部都是非零和大的。
我使用r2c和c2r尝试了不同的计划,但这也给出了错误的值。
任何建议都会有所帮助!
void psiderivcalc(double *psi, double *dx, double *dy, double *del2, double *dxdel2, double *dydel2, double *del4)
{ int i,j,ir,ir1,k;
fftw_complex *fdx, *fdy, *fdxdel2, *fdydel2, *fdel2, *fdel4, *out, *bt, *in;
fftw_plan p, q;
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
bt = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
fdx = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
fdy = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
fdxdel2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
fdydel2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
fdel2 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) *N);
fdel4 = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
p = fftw_plan_dft_2d(lx, ly, in, bt, FFTW_FORWARD,FFTW_MEASURE);
q = fftw_plan_dft_2d(lx, ly, bt, out, FFTW_BACKWARD,FFTW_MEASURE);
for(i = 0; i < lx; i++)
{
for(j = 0; j < ly; j++)
{
ir = j*lx + i;
in[ir] = psi[ir] + 0.0*I;
}
}
fftw_execute(p);
double kx, ky, pref;
int y1, x1, y2, x2;
kx = 2.0*pi/lx;
ky = 2.0*pi/ly;
for(i=0;i<lx;i++)
{
for(j = 0; j < ly; j++)
{
ir = j*lx + i;
if(i<lx/2)
{
x1 = i;
x2 = i;
}
else if(i==lx/2.0)
{
x1 = 0;
x2 = i;
}
else
{
x1 = i - lx;
x2 = x1;
}
if(j<ly/2)
{
y1 = i;
y2 = i;
}
else if(j==ly/2)
{
y1 = 0;
y2 = j;
}
else
{
y1 = j - ly;
y2 = y1;
}
pref = -1.0*(pow((kx*x2),2.0) + pow((ky*y2),2.0));
fdx[ir] = -1.0*kx*x1*I*bt[ir];
fdy[ir] = -1.0*ky*y1*I*bt[ir];
fdel2[ir] = pref*bt[ir];
fdxdel2[ir] = -1.0*kx*I*x1*pref*bt[ir];
fdydel2[ir] = -1.0*ky*I*y1*pref*bt[ir];
fdel4[ir] = pref*pref*bt[ir];
}
}
for(i = 0;i < lx; i++)
{
for(j = 0;j < ly; j++)
{
ir = j*lx + i;
bt[ir] = fdx[ir];
}
}
fftw_execute(q);
for(i = 0;i < lx; i++)
{
for(j = 0;j < ly; j++)
{
ir = j*lx + i;
dx[ir] = creal(out[ir]) / (double)N;
}
}
我通过在执行计划q之前每次更改bt [ir]并在执行之后输出[ir],找到与dx [ir](一阶导数wrt x)相同的其他导数。 del2是laplacian,dxdel2是laplacian wrt x的衍生物,del4是biharmonic。
psi [ir]在将其传递给函数之前已正确初始化为j中的正弦函数。
for(i = 0; i < lx; i++)
{
for(j = 0; j < ly; j++)
{
ir = j*lx + i;
psi[ir] = sin(2.0*pi*j/lambda);
}
}
这是del2(fftw),del2a(分析),dx,dxa和ir(索引)的输出示例。 lambda = 8,lx = 16,ly = 16,N = lx * ly,因此sin函数在该域中是周期性的。
0.308425 -0.616850 0.000000 0.000000 175
-0.218090 -0.436179 0.000000 0.000000 191
-0.000000 -0.000000 0.000000 0.000000 207
0.218090 0.436179 0.000000 0.000000 223
0.308425 0.616850 0.000000 0.000000 239
0.218090 0.436179 0.000000 0.000000 255
答案 0 :(得分:0)
麻烦来自以下几行:
if(j<ly/2)
{
y1 = i; // should be j !!!
y2 = i; // should be j !!!
}
另外,请注意衍生品的标志:
fdx[ir] = -1.0*kx*x1*I*bt[ir]; // should be a + !
fdy[ir] = -1.0*ky*y1*I*bt[ir]; // should be a + !