-
Notifications
You must be signed in to change notification settings - Fork 0
/
assembler.py
71 lines (57 loc) · 2.51 KB
/
assembler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import numpy as np
from beam_element import Beam2D
from node2D import Node2D
from node2D_load import Node2DLoad
from structure import Structure
class Assembler:
"""
Class takes a structure and assembles its degrees of freedom into a
global stiffness matrix
"""
def __init__(self, structure: Structure) -> None:
self.structure = structure
self.__dof_map = structure.get_dof_map()
def assemble_k_global(self) -> list:
"""
Assemble the global stiffness matrix and return the result
"""
# find the number of active degrees of freedom
num_dofs = max(max(x) for x in self.__dof_map)
# initialize global stiffness matrix
k_global = np.zeros((num_dofs, num_dofs))
element: Beam2D
for element in self.structure.elements:
# calculate the elements stiffness matrix
k_element = element.k_global()
# obtain the element connectivity array
con_array = self.get_connectivity_array(element)
for i in range(len(con_array)):
for j in range(len(con_array)):
if not con_array[i] == 0 and not con_array[j] == 0:
k_global[con_array[i] - 1][con_array[j] - 1] += k_element[i][j]
return k_global
def assemble_load_vector(self) -> list:
"""
Assemble the system load vector and return the result
"""
# find the number of active degrees of freedom
num_dofs = max(max(x) for x in self.__dof_map)
# initialize the system load vector
load_vec = np.zeros(num_dofs)
# assemble the load vector
load: Node2DLoad
for load in self.structure.node_loads:
for dof in range(self.structure.dofs_per_node): # The dof map will only have rows
# equal to the number of dofs per node
eq_no = self.__dof_map[dof][load.node.get_ID()]
if not eq_no == 0: # an equation number of zero denotes an inactive dof
load_vec[eq_no - 1] += load[dof]
return load_vec
def get_connectivity_array(self, element: Beam2D):
con_array = []
nodes = element.get_nodes()
node: Node2D
for node in nodes: # columns in map are node ids
for dof in range(self.structure.dofs_per_node): # rows in map are dofs
con_array.append(self.__dof_map[dof][node.get_ID()])
return con_array