Abaqus 刚度矩阵的导出与转换¶
约 1132 个字 226 行代码 4 张图片 预计阅读时间 7 分钟
Abaqus 的导出刚度矩阵方式是在 INP 文件中添加关键词,然后导出为 mtx 文件,但是这个 mtx 文件呢,不怎么“好看”,也就是矩阵形式不直观,不如像 Matlab、csv 文件那样全矩阵的形式来的直接,那我们现在就把它搞直接一点,方便人为观察。
本期内容主要包括:
- Abaqus 中各种刚度矩阵如何导出?
- 如何转换 mtx 文件为全矩阵的形式?
注意⚠️: 用到的脚本语言为 Python,原理搞明白后不限于编程语言。
1 刚度矩阵的导出¶
在 Abaqus/Standard 分析步类型中,可以通过在 inp 文件中添加关键词的形式将每一分析步、增量步的刚度矩阵、质量矩阵、载荷列阵输出到外部文件中。
Tip
对于非协调单元和杂交单元 Abaqus 只能输出单元质量矩阵
1.1 单元刚度矩阵¶
在 inp 文件中*End Step前面添加关键词:
*ELEMENT MATRIX OUTPUT, ELSET={stiff_elset}, STIFFNESS=YES, OUTPUT FILE=USER DEFINED, FILE NAME=ELEMK
- 需要指定输出刚度矩阵的单元集
- STIFFNESS=YES,表示打开刚度矩阵开关
- OUTPUT FILE=USER DEFINED, FILE NAME=ELEMK,这里我指定了输出文件的名字,也就是导出后的单元刚度矩阵文件为 ELEMK.mtx
打开 ELEMK.mtx 将会看到这样的情况:
单元集中每个刚度矩阵都被输出到了一个文件中,看上去有点乱,实则“乱中有序”,且听木木给你娓娓道来~
- 第一行就不用多解释了吧,单元号、分析步号、增量步号
- 第二行单元型号
- 第三行:单元节点数、线性单元
- 第四行:单元连接节点在全局中的编号,比如说我们看到的这个 C3D8R单元的八个节点是第 2521、2522、2543、2542、2479、2480、2501、2500 号节点
- *MATRIX,TYPE=STIFFNESS说明这是刚度矩阵
- 下面的数据行正是刚度矩阵的具体值了,Abaqus 是按照下三角矩阵存储刚度矩阵的
Abaqus 在输出大规模刚度矩阵、质量矩阵时,为节省存储空间和加快读写,常采用 存储下三角部分 的稀疏矩阵存储格式。因为刚度矩阵 \(K\) 是对称的,即 \(K_{ij}=K_{ji}\),所以只需存储矩阵的下三角区域(包括主对角线),即可完整恢复全矩阵。
来一个具体的例子吧,看下面的矩阵:
存储为一维数组(按行展平):[k11, k12, k22, k13, k23, k33]。
1.2 单元质量矩阵¶
关键词:
这里我都指定的输出文件名字,不再赘述。需要注意的是,当材料属性中有 密度 这个参数的时候才会输出质量矩阵,而且主要用于动力类型的分析步中,静力分析不需要质量矩阵。
1.3 分布荷载矩阵¶
关键词:
需要注意的是,当你施加分布荷载(如表面压强)的时候才会输出单元的分布等效节点荷载列阵,你如果施加节点力的形式,那就不用等效了,Abaqus 也就不会输出分布荷载列阵。
1.4 整体矩阵¶
整体矩阵的输出有点不太相同,需要单独再写一个分析步:
*STEP, NAME=MATRIX
*MATRIX GENERATE,STIFFNESS,MASS
*MATRIX OUTPUT,,STIFFNESS,MASS, FORMAT=COORDINATE
*END STEP
- 这里同时写入了刚度矩阵和质量矩阵,按需写入即可
- 我新增了FORMAT=COORDINATE,意思是输出的整体矩阵以 三元组 的形式展现
这样的形式会不会更直观呢,前两列是行列号,第三列是该位置的具体值。
2 转换 mtx 文件¶
对于下三角的矩阵形式,比如elemK.mtx:
点击展开查看文件
66559038.461538 ,
-30048076.923077 , 66559038.461538
-30048076.923077 , 30048076.923077 , 66559038.461538
41840673.076923 , -6009615.3846154 , -30048076.923077 , 66559038.461538
6009615.3846154 , -18255480.769231 , -6009615.3846154 , 30048076.923077
66559038.461538 ,
-30048076.923077 , 6009615.3846154 , 41840673.076923 , -30048076.923077
-30048076.923077 , 66559038.461538
18028846.153846 , -6009615.3846154 , -6009615.3846154 , 41840673.076923
30048076.923077 , -6009615.3846154 , 66559038.461538
6009615.3846154 , -42067307.692308 , -30048076.923077 , 30048076.923077
41840673.076923 , -6009615.3846154 , 30048076.923077 , 66559038.461538
6009615.3846154 , -30048076.923077 , -42067307.692308 , 6009615.3846154
6009615.3846154 , -18255480.769231 , 30048076.923077 , 30048076.923077
66559038.461538 ,
41840673.076923 , -30048076.923077 , -6009615.3846154 , 18028846.153846
6009615.3846154 , -6009615.3846154 , 41840673.076923 , 6009615.3846154
30048076.923077 , 66559038.461538
-30048076.923077 , 41840673.076923 , 6009615.3846154 , -6009615.3846154
-42067307.692308 , 30048076.923077 , -6009615.3846154 , -18255480.769231
-6009615.3846154 , -30048076.923077 , 66559038.461538
6009615.3846154 , -6009615.3846154 , -18255480.769231 , 6009615.3846154
30048076.923077 , -42067307.692308 , 30048076.923077 , 6009615.3846154
41840673.076923 , 30048076.923077 , -30048076.923077 , 66559038.461538
-18255480.769231 , 6009615.3846154 , 6009615.3846154 , -42067307.692308
-30048076.923077 , 6009615.3846154 , -65879134.615385 , -30048076.923077
-30048076.923077 , -42067307.692308 , 6009615.3846154 , -30048076.923077
66559038.461538 ,
-6009615.3846154 , 41840673.076923 , 30048076.923077 , -30048076.923077
-42067307.692308 , 6009615.3846154 , -30048076.923077 , -65879134.615385
-30048076.923077 , -6009615.3846154 , 18028846.153846 , -6009615.3846154
30048076.923077 , 66559038.461538
-6009615.3846154 , 30048076.923077 , 41840673.076923 , -6009615.3846154
-6009615.3846154 , 18028846.153846 , -30048076.923077 , -30048076.923077
-65879134.615385 , -30048076.923077 , 6009615.3846154 , -42067307.692308
30048076.923077 , 30048076.923077 , 66559038.461538
-42067307.692308 , 30048076.923077 , 6009615.3846154 , -18255480.769231
-6009615.3846154 , 6009615.3846154 , -42067307.692308 , -6009615.3846154
-30048076.923077 , -65879134.615385 , 30048076.923077 , -30048076.923077
41840673.076923 , 6009615.3846154 , 30048076.923077 , 66559038.461538
30048076.923077 , -42067307.692308 , -6009615.3846154 , 6009615.3846154
41840673.076923 , -30048076.923077 , 6009615.3846154 , 18028846.153846
6009615.3846154 , 30048076.923077 , -65879134.615385 , 30048076.923077
-6009615.3846154 , -18255480.769231 , -6009615.3846154 , -30048076.923077
66559038.461538 ,
-6009615.3846154 , 6009615.3846154 , 18028846.153846 , -6009615.3846154
-30048076.923077 , 41840673.076923 , -30048076.923077 , -6009615.3846154
-42067307.692308 , -30048076.923077 , 30048076.923077 , -65879134.615385
30048076.923077 , 6009615.3846154 , 41840673.076923 , 30048076.923077
-30048076.923077 , 66559038.461538
-65879134.615385 , 30048076.923077 , 30048076.923077 , -42067307.692308
-6009615.3846154 , 30048076.923077 , -18255480.769231 , -6009615.3846154
-6009615.3846154 , -42067307.692308 , 30048076.923077 , -6009615.3846154
18028846.153846 , 6009615.3846154 , 6009615.3846154 , 41840673.076923
-30048076.923077 , 6009615.3846154 , 66559038.461538
30048076.923077 , -65879134.615385 , -30048076.923077 , 6009615.3846154
18028846.153846 , -6009615.3846154 , 6009615.3846154 , 41840673.076923
30048076.923077 , 30048076.923077 , -42067307.692308 , 6009615.3846154
-6009615.3846154 , -42067307.692308 , -30048076.923077 , -30048076.923077
41840673.076923 , -6009615.3846154 , -30048076.923077 , 66559038.461538
30048076.923077 , -30048076.923077 , -65879134.615385 , 30048076.923077
6009615.3846154 , -42067307.692308 , 6009615.3846154 , 30048076.923077
41840673.076923 , 6009615.3846154 , -6009615.3846154 , 18028846.153846
-6009615.3846154 , -30048076.923077 , -42067307.692308 , -6009615.3846154
6009615.3846154 , -18255480.769231 , -30048076.923077 , 30048076.923077
66559038.461538 ,
-42067307.692308 , 6009615.3846154 , 30048076.923077 , -65879134.615385
-30048076.923077 , 30048076.923077 , -42067307.692308 , -30048076.923077
-6009615.3846154 , -18255480.769231 , 6009615.3846154 , -6009615.3846154
41840673.076923 , 30048076.923077 , 6009615.3846154 , 18028846.153846
-6009615.3846154 , 6009615.3846154 , 41840673.076923 , -6009615.3846154
-30048076.923077 , 66559038.461538
-6009615.3846154 , 18028846.153846 , 6009615.3846154 , -30048076.923077
-65879134.615385 , 30048076.923077 , -30048076.923077 , -42067307.692308
-6009615.3846154 , -6009615.3846154 , 41840673.076923 , -30048076.923077
30048076.923077 , 41840673.076923 , 6009615.3846154 , 6009615.3846154
-42067307.692308 , 30048076.923077 , 6009615.3846154 , -18255480.769231
-6009615.3846154 , 30048076.923077 , 66559038.461538
30048076.923077 , -6009615.3846154 , -42067307.692308 , 30048076.923077
30048076.923077 , -65879134.615385 , 6009615.3846154 , 6009615.3846154
18028846.153846 , 6009615.3846154 , -30048076.923077 , 41840673.076923
-6009615.3846154 , -6009615.3846154 , -18255480.769231 , -6009615.3846154
30048076.923077 , -42067307.692308 , -30048076.923077 , 6009615.3846154
41840673.076923 , -30048076.923077 , -30048076.923077 , 66559038.461538
通过下面脚本可以转化为全矩阵的形式,用 python 打印出的 24 行 24 列可能不是很直观,行列数有点多,可以直接输出到 csv 文件中,看上去更直观一点。
import numpy as np
def read_lower_triangular_mtx(file_path):
# 读取所有浮点数(忽略换行和逗号)
with open(file_path, 'r') as f:
lines = f.readlines()
data = []
for line in lines:
# 跳过空行或关键词行
if line.strip() == "" or line.strip().startswith("*"):
continue
# 按逗号或空格分隔,逐个提取
parts = [p.strip() for p in line.replace(',', ' ').split()]
for p in parts:
if p != '':
data.append(float(p))
return np.array(data)
def lower_tri_to_full(data):
# 由下三角数据长度,计算矩阵阶数 n
from math import sqrt
n = int((-1 + sqrt(1 + 8 * len(data))) / 2)
K = np.zeros((n, n))
idx = 0
for j in range(n):
for i in range(j, n):
K[i, j] = data[idx]
K[j, i] = data[idx] # 对称
idx += 1
return K
# ========== 主流程 ==========
file_path = "elemK.mtx"
csv_path = "K_full.csv"
data = read_lower_triangular_mtx(file_path)
K = lower_tri_to_full(data)
np.savetxt(csv_path, K, delimiter=",", fmt="%.8g")
输出至 csv 中:
当然我们也可以输出为 mat 文件,导入到 matlab 中:
import numpy as np
import scipy.io as sio
import scipy.sparse as sp
def read_lower_triangular_mtx(file_path):
"""读取 Abaqus 下三角刚度矩阵数据"""
with open(file_path, 'r') as f:
lines = f.readlines()
data = []
for line in lines:
if line.strip() == "" or line.strip().startswith("*"):
continue
parts = [p.strip() for p in line.replace(',', ' ').split()]
for p in parts:
if p != '':
data.append(float(p))
return np.array(data)
def lower_tri_to_full(data):
"""由下三角数据恢复全矩阵"""
from math import sqrt
n = int((-1 + sqrt(1 + 8 * len(data))) / 2)
K = np.zeros((n, n))
idx = 0
for j in range(n):
for i in range(j, n):
K[i, j] = data[idx]
K[j, i] = data[idx]
idx += 1
return K
if __name__ == "__main__":
file_path = "elemK.mtx" # Input stiffness matrix file
csv_path = "K_full.csv" # Output csv file
mat_path = "K_full.mat" # Output mat file
# === User config: dense or sparse mat file ===
save_sparse_mat = False # Set True for sparse, False for dense
# === Read and reconstruct matrix ===
data = read_lower_triangular_mtx(file_path)
K = lower_tri_to_full(data)
print(f"Matrix size: {K.shape[0]} x {K.shape[1]}")
np.savetxt(csv_path, K, delimiter=",", fmt="%.8g")
# === Save to .mat file ===
if save_sparse_mat:
K_sparse = sp.csr_matrix(K)
sio.savemat(mat_path, {'K': K_sparse})
else:
sio.savemat(mat_path, {'K': K})
这里我增加了输出的 mat 文件为全矩阵或者稀疏矩阵的开关,save_sparse_mat = True表示格式为稀疏矩阵,save_sparse_mat = False表示输出格式为全矩阵。
对于三元组的形式,也可以通过下面脚本转换为 mat 文件或者 csv 文件:
import numpy as np
import scipy.io as sio
import scipy.sparse as sp
def read_triplet_file(file_path):
"""
读取三元组稀疏矩阵文件,返回行、列、值数组和自动检测的矩阵大小
"""
rows, cols, vals = [], [], []
max_i, max_j = 0, 0
with open(file_path, 'r') as f:
for line in f:
if line.strip() == '' or line.startswith('*'):
continue
parts = line.strip().split()
if len(parts) < 3:
continue
i, j, v = int(parts[0]), int(parts[1]), float(parts[2])
rows.append(i - 1) # Matlab/Python index offset
cols.append(j - 1)
vals.append(v)
max_i = max(max_i, i)
max_j = max(max_j, j)
nrow, ncol = max_i, max_j
return np.array(rows), np.array(cols), np.array(vals), nrow, ncol
if __name__ == "__main__":
file_path = "C3D8_STIF2.mtx" # Your triplet file
csv_path = "K_triplet.csv"
mat_path = "K_triplet.mat"
# === 读取三元组数据 ===
rows, cols, vals, nrow, ncol = read_triplet_file(file_path)
print(f"Detected matrix shape: {nrow} x {ncol}, nonzeros: {len(vals)}")
# === 构建稀疏矩阵 ===
K_sparse = sp.coo_matrix((vals, (rows, cols)), shape=(nrow, ncol))
# === 保存为matlab稀疏格式 ===
sio.savemat(mat_path, {'K': K_sparse})
# === 保存为csv(全矩阵,稀疏元素补0,慎用大矩阵!) ===
K_dense = K_sparse.toarray()
np.savetxt(csv_path, K_dense, delimiter=",", fmt="%.8g")