Editorial
def assemble_stiffness(element_matrices, connectivity, ndof):
# element_matrices: list of n×n lists
# connectivity: list of lists of global DOF indices
# ndof: total number of DOFs
# returns global K as nested lists
pass
1. Naïve Dense Assembly
Logic: Allocate a full ndof×ndof
matrix and for each element loop over its local DOFs to add ke[a][b]
into K[i][j]
.
def assemble_stiffness(element_matrices, connectivity, ndof):
K = [[0.0]*ndof for _ in range(ndof)]
for ke, dofs in zip(element_matrices, connectivity):
m = len(dofs)
for a in range(m):
i = dofs[a]
for b in range(m):
j = dofs[b]
K[i][j] += ke[a][b]
return K
# Example data
element_matrices = [
[[10, -10],
[-10, 10]],
[[20, -20],
[-20, 20]]
]
connectivity = [[0,1],[1,2]]
ndof = 3
K = assemble_stiffness(element_matrices, connectivity, ndof)
print(K) # [[10,-10,0],[-10,30,-20],[0,-20,20]]
Time Complexity: O(nel·m²) → O(ndof³) worst-case
Space Complexity: O(ndof²)
2. Dictionary-of-Keys (DOK) → Dense
Logic: First assemble only nonzero entries into a Python dict
keyed by (i,j)
, then allocate a full matrix and scatter the dict entries into it.
def assemble_stiffness(element_matrices, connectivity, ndof):
Kdok = {}
for ke, dofs in zip(element_matrices, connectivity):
m = len(dofs)
for a in range(m):
i = dofs[a]
for b in range(m):
j = dofs[b]
Kdok[(i,j)] = Kdok.get((i,j), 0.0) + ke[a][b]
K = [[0.0]*ndof for _ in range(ndof)]
for (i,j), v in Kdok.items():
K[i][j] = v
return K
# Example data
element_matrices = [
[[10, -10],
[-10, 10]],
[[20, -20],
[-20, 20]]
]
connectivity = [[0,1],[1,2]]
ndof = 3
K = assemble_stiffness(element_matrices, connectivity, ndof)
print(K) # [[10,-10,0],[-10,30,-20],[0,-20,20]]
Time Complexity: O(nel·m² + nnz)
Space Complexity: O(nnz + ndof²)
3. Triplets → Dense
Logic: Build three flat lists rows, cols, vals
of every nonzero contribution, then scatter them in one pass into a dense matrix.
def assemble_stiffness(element_matrices, connectivity, ndof):
rows, cols, vals = [], [], []
for ke, dofs in zip(element_matrices, connectivity):
m = len(dofs)
for a in range(m):
i = dofs[a]
for b in range(m):
j = dofs[b]
rows.append(i); cols.append(j); vals.append(ke[a][b])
K = [[0.0]*ndof for _ in range(ndof)]
for i, j, v in zip(rows, cols, vals):
K[i][j] += v
return K
# Example data
element_matrices = [
[[10, -10],
[-10, 10]],
[[20, -20],
[-20, 20]]
]
connectivity = [[0,1],[1,2]]
ndof = 3
K = assemble_stiffness(element_matrices, connectivity, ndof)
print(K) # [[10,-10,0],[-10,30,-20],[0,-20,20]]
Time Complexity: O(nel·m² + nnz)
Space Complexity: O(nnz + ndof²)