为一个非常病态的矩阵设计一个预条件子

计算科学 并行计算 迭代法 显卡 预处理 条件数
2021-12-01 14:46:31

我是一位数值方法知识有限的物理学家,我正试图加快一个非常病态问题的反演(rcond>1030)。重复使用相同的稀疏方阵,因此我们当前的设置依赖于一次性 LU 分解和三角求解器。

我有一个非常强大的 GPU 可供我使用,并且想使用它(将 CUDA 与 Cusparse、Magma 一起使用……)。我目前的理解是,三角形求解器本质上是非常连续的,在并行 SIMD 架构上不能很好地工作,但另一方面,迭代求解器在 GPU 上工作得很好,遗憾的是我的问题远非条件恶劣。

由于矩阵使用了大量时间,因此花费一些时间来计算预处理器似乎是要走的路。因此,我正在寻找设计适合并行求解器的预处理器的方法。

如果你们想看看它,我已经包含了一个指向我正在使用的矩阵的链接。

Big Matrix
size=114708*114708
one-based_numbering
34Mb

小矩阵
大小=12890*12890
one-based_numbering
3Mb

还有一个用 Matlab 加载矩阵的脚本:

n=12890;
%n=114708;
fileID = fopen('SmallMatrix.txt','r');
%fileID = fopen('BigMatrix.txt','r');
dataArray = textscan(fileID,'%f%f%f%[^\n\r]', 'Delimiter',' ', 'MultipleDelimsAsOne', true);
fclose(fileID);
U1 = dataArray{:, 1};
U2 = dataArray{:, 2};
V = dataArray{:, 3};
s=sparse(U1,U2,V,n,n);
figure;
spy(s);

编辑:尽管条件数非常高,但我使用的直接求解器(matlab、mumps、umfpack 和 superlu)解决它没有问题。在matlab中,

cond(s)
x=rand(n,1);
y=s\x;
norm(s*y-x)

退货,

1.4996e+34
2.7318e-10

Edit2:这是我的矩阵可能具有的结构(非常大的值总是在对角线上):

(0.12.13.24.11.12180.21030)

和 RHS:

(3.140.3)
解决方案是:
(1.35441.41170)

这是非常病态的,但每个直接求解器都完全可以接受。这只是施加边界条件的一种简单方法(我不得不承认,不是很优雅)

Edit3:按照 Brian Borchers 和 Tobias 的建议,我已经从我的矩阵和 RHS 中删除了我的非常大的值出现的所有行和列。从某种意义上说,它的效果很好,给定 RHS 的解决方案是相同的,并且条件数更合理105. 这是用于执行此操作的脚本:

%Creating the new matrix
sCopy=s;
nRemoved=nnz(abs(sCopy)>10^29);
for index=1:n-nRemoved
    while abs(sCopy(index,index))>10^29
        sCopy(index,:)=[];   
        sCopy(:,index)=[];  
    end
end
nnz(abs(sCopy)>10^29)

%Updating the  RHS
[i,j,]=find(abs(s)>10^29);
NewRHS=RHS;
NewRHS(i)=[];

有了这个,我的主要询问仍然存在,条件数仍然太高,迭代方法无法收敛。

1个回答

我找到了一个似乎适合我的问题的求解器。我非常病态的矩阵实际上是在双向非结构化网格上的泊松方程的 FEM 离散化。几何多网格方法(多 V 周期)的第一个结果显示 CPU 上的弱缩放非常好。而且由于大部分时间都花在将大型稀疏矩阵与向量相乘(在精细网格上),我希望 GPU 性能还可以。