Domanda

I'm trying to simulate waves by numerically integrating the wave equation using euler integration (just until I get the kinks worked out, then I'll switch to runge-kutta). I'm using an array of floats as a grid. Then I create a disturbance by changing the value of the grid at one point. Now, instead of radiating in all directions away from this point, the wave only travels in one direction, towards the upper-left, i.e. towards decreasing x and y. So, my question is how do I make the wave radiate out?

Here's my code

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.
        }
    }
}
È stato utile?

Soluzione

Just for the sake of somebody else coming here for the same problem. The usual way to convert the Laplacian to a finite difference expression on a regular grid is:

∆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)]

where idx2 and idy2 are the inverse squares of the grid spacing in dimension x and y respectively. In the case when the grid spacing in both dimensions is the same, this simplifies to:

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

The multiplicative coefficient can be removed by hiding it inside other coefficients, e.g. c, by changing their units of measurement:

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

By the way, there cannot be 2D spherical waves since spheres are 3D objects. 2D waves are called circular waves.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top