试图在PyOpenCL中实现三维波动方程

时间:2014-12-16 03:33:23

标签: python opencl physics pyopencl

我试图在OpenCL中实现离散时间波方程。我认为我非常接近,但结果看起来就像我对热方程所期望的那样。我知道它们非常相似,但是当我实现2D波动方程(不使用OpenCL)时,我得到了明显的波前和反射。在下面的OpenCL内核中,一切都会扩散,直到它被洗掉。

 __kernel void wave_calc(
    __global float* height,
    __global float* height_old,
    const unsigned int len_x,
    const unsigned int len_y,
    const unsigned int len_z,
    const float dtxc_term)
{

    unsigned int x = get_global_id(0);
    unsigned int y = get_global_id(1);
    unsigned int z = get_global_id(2);
    int this_cell = x + len_y * (y + len_x * z);
    float laplacian;

    if (x==0 || x==(len_x-1) || y==0 || y==(len_y-1) || z==0 || z==(len_z-1)) {
       laplacian = 0;
       height_old[this_cell]  = height[this_cell];
       height[this_cell] = 0;
    }

    else if ( x < len_x-1 && y < len_y-1 && z < len_z-1 ){
        int n1 = x - 1 + len_y * (y + len_x * z);
        int n2 = x + 1 + len_y * (y + len_x * z);
        int n3 = x + len_y * (y - 1 + len_x * z);
        int n4 = x + len_y * (y + 1 + len_x * z);
        int n5 = x + len_y * (y + len_x * (z -1));
        int n6 = x + len_y * (y + len_x * (z + 1));

        laplacian = -6 * height[this_cell] +
                                    height[n1] +
                                    height[n2] +
                                    height[n3] +
                                    height[n4] +
                                    height[n5] +
                                    height[n6];

        height_old[this_cell]  = height[this_cell];
        height[this_cell] = (dtxc_term*laplacian+2*height[this_cell]) - height_old[this_cell];

    }  
}

(DTXC是((DT * DT)/(DX * DX))* C从主机传递的结果)

每一步我都会将高度复制回主机进行绘图,然后再次调用该函数。

 for i in np.arange(steps):
        #copy height from host to device
        cl.enqueue_copy(queue, d_height, h_height)
        #step once
        wave_calc(queue, field_3d.shape, None, d_height, d_height_old, LEN_X, LEN_Y, LEN_Z, DTXC)

        queue.finish()
        #copy height back
        cl.enqueue_copy(queue, h_height, d_height)

#do my plotting

任何想法/建议/居高临下的言论?所有人都将不胜感激。 :)

以下是回答乔尔问题的更新:

我在微积分方面表现不佳,但我正在2D中进行有效的C ++实现,并尝试将其应用于3D。下面是C ++。我做的唯一修改就是循环,因为3D中有6个相邻单元而不是4个。在这两种情况下,平面/立方体的外墙都设置为0:

for(int x=1; x<field.xRes()-1;x++) {
            for (int y=1; y<field.yRes()-1; y++) {

                    laplacian(x,y) = -4 * height(x,y) +
                    height(x-1,y) +
                    height(x+1,y) +
                    height(x,y-1) +
                    height(x,y+1);

            }
        }

const float dt = 0.001;
const float xLen = 1.0;
const float C = 1.0;
const float dx = xLen/xRes;

backup = height;
height = ((dt*dt)/(dx*dx))*C*laplacian+2*height;
height = height - heightOld;
heightOld = backup;

0 个答案:

没有答案