我目前正在实现一个小型有限元模拟。使用 Python/Numpy,我正在寻找一种有效的方法来创建全局刚度矩阵:
1)我认为应该使用coo_matrix()
从较小的单元刚度矩阵创建稀疏矩阵。但是,我可以扩展现有的 coo_matrix
,还是应该从最终的 i、j 和 v 列表创建它?
2) 目前,我正在使用列表推导式从较小的单元刚度矩阵创建 i 和 j 列表并将它们连接起来。有更好的方法来创建这些列表吗?
3) Tạo vectơ dữ liệu: Câu hỏi tương tự, danh sách Python có tốt hơn vectơ gọn gàng do khả năng mở rộng dễ dàng không?
4) Tất nhiên, tôi sẵn sàng đón nhận mọi đề xuất :). Cảm ơn!
Đây là một ví dụ nhỏ về kế hoạch hội nghị toàn cầu hiện tại của tôi để làm rõ ý định của tôi:
nhập numpy dưới dạng np
từ nhập scipy.sparse coo_matrix
# 2 nút, 3 dof mỗi nút
địa điểm = [0, 6]
nNodes = 2
dof=3
totSize = nNodes * dof
Ke = np.array([[1,1,1, 2,2,2],
[1,1,1, 2,2,2],
[1,1,1, 2,2,2],
[2,2,2, 3,3,3],
[2,2,2, 3,3,3],
[2,2,2,3,3,3]])
Tôi = []
J = []
#generate danh sách i và j theo hàng:
i = [ idx + u cho i trong phạm vi(totSize) cho idx tại các vị trí cho u trong phạm vi(dof) ]
j = [ idx + u cho idx tại các vị trí cho u trong phạm vi(dof) cho i trong phạm vi(totSize) ]
tôi += tôi
J += J
Dữ liệu = Ke.flatten()
cMatrix = coo_matrix( (Dữ liệu, (i,j)), )
Trong bài viết này tôi sẽ cố gắng tập trung vào việc tạo một danh sách Tôi
,j
và ma trận cuối cùng cMatrix
vấn đề hiệu suất độc đáo.
Theo các vòng lặp/danh sách hiểu này, về cơ bản bạn đang làm địa điểm
Và phạm vi (dof)
được thêm vào theo từng phần tử. Được chuyển sang NumPy, chúng tôi có thể tận dụng phát sóng
Ở đó. Cuối cùng, để mô phỏng lại các dẫn xuất này phạm vi (totSize)
, chúng ta có thể sử dụng np.tile
Ngói kết quả bổ sung cuối cùng. Chúng tôi sẽ sử dụng phiên bản này như một phiên bản phẳng của chỉ mục cột ma trận thưa thớt và một phiên bản phẳng được chuyển đổi của các hàng.
Vì vậy, việc thực hiện trông như thế này -
idx0 = (np.asarray(locations)[:,None] + np.arange(dof)).ravel()
J = np.tile(idx0[:,None],totSize)
cMatrix = coo_matrix( (Dữ liệu, (J.ravel('F'),J.ravel())), )
Tôi là một lập trình viên xuất sắc, rất giỏi!