如何完成稀疏矩阵?

计算科学 matlab 稀疏矩阵
2021-12-15 04:28:54

我正在尝试通过无网格方法求解方程。形状函数(及其衍生物)具有紧凑的支持域。因此,在用于数值积分的给定积分单元上,只有少数形状函数具有非零值。同时,对于属于一个单元的每个积分点,非零形函数的个数和索引可能不同。因此,我无法像典型的 FEM 代码那样构建局部刚度矩阵,因为它们的大小是未知的。并且不可能构造一些数组然后使用稀疏命令进行组装。我使用 sparse 命令定义刚度矩阵,如下:K

K=sparse(NDOF,NDOF)

然后尝试在计算过程中Kij

for j=1:ngauss
    //subroutint to "find v" here
    [fi, fix, fiy]=shape(xg,yg,v);
    for i=1:length(fi)
        sub_K=fiy*fiy(i)+fix*fix(i));                 
        K(v(i),v(:))=K(v(i),v(:))+sparse(weight(j)*areaj*sub_K);
    end
end

其中v是非零形状函数的索引数组。但是这种使用稀疏命令的速度太慢了。有什么建议或任何其他方式吗?

1个回答

有两种简单的解决方案可以加快矩阵组装速度:

方法一

正如基里尔所提到的,您可能希望使用以下形式sparse(i,j,v),其中i,jv是定义 的向量K(i(k),j(k)) = v(k)这将要求您重写部分代码。

方法二

另一种方法是预先分配稀疏矩阵存储。发生的情况是,当您使用 时K=sparse(NDOF,NDOF),没有为矩阵保留内存,因此,每次将新元素添加到稀疏矩阵时 - 都会发生重新分配(不完全正确,但非常接近)。K

您可能想要使用K = spalloc(NDOF,NDOF,NNZ)(参见,Matlab 帮助spalloc)。这将从一开始就分配存储空间,并避免循环内不必要的重新分配。但是,您必须找到或估计NNZ(非零条目的数量)。如果你可以使用一点额外的内存,你可以为每个点找到(上限 - 不会发生重新分配)或 varage (安全选择)#non-zero 形状函数并使用它。或者,您可以通过运行代码而不评估形状函数并将值分配给矩阵元素来找到 NNZ 元素的确切数量。max