0001有限元法C程序设计如何用一维内存来存储矩阵

总体刚度矩阵是由每一个单元刚度矩阵叠加而成的,因此首先申请一个内存区域给总刚,假设结构结点数是Nn,二维问题每个结点2个自由度,因此总的自由度是2*Nn。那么总刚就是一个2*Nn*2*Nn的二维矩阵。尽管用c++中的二维数组来表示更符合逻辑,例如Kg[2*Nn][ 2*Nn],但这无法实现动态内存分配,不利于代码的通用性。

实际上对于计算机而言,不论是一维向量、二维矩阵,还是高纬度的张量,其元素在内存中都是一维存储。以二维矩阵为例。一个N行*M列的矩阵,元素的总数就是N*M。可以有两种存储方式。我们称为“按行存储”和“按列存储”。

“按行存储”就是先把矩阵中一行的元素存储完,再存储下一行,直到矩阵中所有的元素都存储完。如果把每一行的元素首位相连,就构成一个总数为N*M的一维数组Kg。如果用K[i][j]表示矩阵中第i行第j列的元素,那么它在一维存储空间的位置就是Kg[i*M+j]。(注意c++中数组的索引从0开始,即Kg[0]表示数组的第一个元素)。因为i每增加一个数,相当于跨过包含M个元素的一行数据,在位置上直接跳过了M个元素,所以在i这个指标上要乘以列数M。

“按列存储”就是矩阵先把一列的元素存储完,在存储下一列,直到矩阵中所有的元素都存储完。如果把每一列的元素首尾相连,同样构成一个总数为N*M的一维数组Kg。如果用K[i][j]表示矩阵中第i行第j列的元素,那么它在一维存储空间的位置就是Kg[i +j*N]。因为j每增加一个数,相当于跨过包含N个元素的一列数据,在位置上直接跳过了N个元素,所以在j这个指标上要乘以列数N。

对于高纬度的数组或者张量,也可以用上述方法进行存储。例如一个三维素组K[i][j][m]。假设三个维度的自由度数量为Ni,Nj,Nm,那么元素总数是Ni*Nj*Nm。K[i][j][m]在一维存储空间的位置是Kg[i +j*Mi+m*Ni*Nj]。如果是个N维数组,每个维度的自由度数量是Ni,那么N维数组的元素总数是N1*N2*N3*….*NN。元素K[id1][id2][id3]。。。[idn]在一维数组中的元素就是Kg[id1+id2*N1+id3*N1*N2+…..+idn*N1*N2*N3*…*Nn-1]。