如何从点源模拟2D球面波?

时间:2014-03-15 20:27:50

标签: c++ simulation physics

我正在尝试通过使用欧拉积分对波动方程进行数值积分来模拟波浪(直到我得到扭结,然后我将切换到runge-kutta)。我正在使用一系列花车作为网格。然后我通过在一点改变网格的值来创建干扰。现在,代替在远离该点的所有方向上辐射,波仅沿一个方向行进,朝向左上方,即朝向减小的x和y。所以,我的问题是如何让波辐射出来?

这是我的代码

void Wave::dudx(float *input,float *output) //calculate du/dx
{
    for(int y=0;y<this->height;y++)
    {
        for(int x=0;x<this->width;x++)
        {
            output[x+y*this->width]=(this->getPoint((x+1)%this->width,y)-this->getPoint(x,y)); //getPoint returns the value of the grid at (x,y)
        }
    }
}

void Wave::dudy(float *input,float *output) //calculate du/dy
{
    for(int x=0;x<this->width;x++)
    {
        for(int y=0;y<this->height;y++)
        {
            output[x+y*this->width]=(this->getPoint(x,(y+1)%this->height)-this->getPoint(x,y));
        }
    }
}

void Wave::simulate(float dt)
{
    float c=6.0f;

    //calculate the spatial derivatives
    this->dudx(this->points,this->buffer);
    this->dudx(this->buffer,this->d2udx2);

    this->dudy(this->points,this->buffer);
    this->dudy(this->buffer,this->d2udy2);

    for(int y=0;y<this->height;y++)
    {
        for(int x=0;x<this->width;x++)
        {
            this->points[x+y*this->width]+=c*c*(this->d2udx2[x+y*this->width]+this->d2udy2[x+y*this->width])*dt*dt; //I know that I can calculate c*c and dt*dt once, but I want to make it clear what I'm doing.
        }
    }
}

1 个答案:

答案 0 :(得分:1)

只是为了其他人来这里遇到同样的问题。将拉普拉斯算子转换为规则网格上的有限差分表达式的常用方法是:

∆u(x,y) -> idx2*[u(x+1,y) + u(x-1,y) - 2*u(x,y)] +
           idy2*[u(x,y+1) + u(x,y-1) - 2*u(x,y)]

其中idx2idy2分别是维度 x y 中网格间距的倒数平方。在两个维度中的网格间距相同的情况下,这简化为:

∆u(x,y) -> igs2*[u(x+1,y) + u(x-1,y) + u(x,y+1) + u(x,y-1) - 4*u(x,y)]

可以通过将乘法系数隐藏在其他系数内来消除乘法系数。 c,通过更改其计量单位:

∆u(x,y) -> u(x+1,y) + u(x-1,y) + u(x,y+1) + u(x,y-1) - 4*u(x,y)

顺便说一下,由于球体是3D物体,所以不能有2D球面波。 2D波称为圆波