在有限差分格式上使用PARFOR

时间:2015-05-27 13:06:57

标签: matlab parallel-processing pde parfor

我试图用有限差分法求解非线性扩散方程。它基本上是两个嵌套的for循环,内部循环在网格上,外部循环推进方程式,有点像这样:

for i=1:(Nt-1)
    for j=2:(Nx-1)

        %%% simple diffusion equation
        c(2,i+1) = c(1,i) + D*dt/dx/dx*(cL(1,j-1)2*cL(1,j)+cL(1,j+1));

    end

    %re-impose BCs
    c(2,1)=1; 
    c(2,Nx)=1; 

    %save into solution matrix
    if mod(i,floor(Nt/sol_no))==0
        sol_c(sol_i+1,:) = c(2,:);
        t_axis(sol_i+1,1) = i*dt;
        sol_i=sol_i+1;
    end

    %flip rows 1 and 2
    c = flipud(c);

end

为了节省内存,c只是一个2×Nx的矩阵,我每次都会在每次增量时翻转,比如每100个实例保存到一个解决方案矩阵中。

请注意,为了清楚起见,我在这里使用了简单的扩散方程。问题在于,实际上我必须使用非常精细的网格(理想情况下大约200,000个点),以便考虑一些快速变化的系数,这些系数是空间的函数。这与稳定性标准相结合,严格限制了时间步长和总时间。

现在,我想优化我的代码,我认为一种方法是在内循环中使用parfor而不是for。 c(2,:)行中的每个元素仅依赖于行c(1,:)中的元素,所以这应该有效,对吧?但是当我尝试运行它时,它会永远运行并且不能产生任何东西。我没有在代码片段中显示它,但是当循环开始时所有变量都已经初始化,因此我不确定导致问题的是什么。我阅读了parfor文档,但我没有找到任何有用的内容。我怀疑它必须与切片有关,但我不确定如何解决它。此外,也许我错过了一些其他更有效的方法来解决这个问题,所以任何建议都值得赞赏。

编辑:我正在将我的代码的主旨添加到裸露的骨头上。 parfor的执行速度比for慢得多。

tic
gridpoints = 400000;
time_iter = 200;

c1 = ones(1,gridpoints);
c2 = ones(1,gridpoints);
x = linspace(0,1,gridpoints);
k = 1.0000001;


for j=1:time_iter

    parfor i=2:gridpoints-1
       c2(i) = c1(i-1) + k*c1(i) - c1(i+1);
    end

c1=c2;
end

toc

1 个答案:

答案 0 :(得分:1)

你可以完全消除内环,并使用Matlab的矢量化(使用你的第二个例子),这要快得多:

c2(2:end-1) = c1(1:end-2) + k * c1(2:end-1) - c1(3:end);

话虽这么说,你甚至可以完全消除c2:

c(2:end-1) = c(1:end-2) + k * c(2:end-1) - c(3:end);

并且可能想要在我们处理时添加边界条件:

c = [1; c(1:end-2) + k * c(2:end-1) - c(3:end); 1];

您还可以在外部循环外创建一个向量(idx = [2:gridpoints-1];)并相应地替换索引以阐明代码。

此外,如果您遇到稳定性问题,隐式方案可能更可取。