def __init__(self, p1, p2, crosssection, x, number=0, gnn=(0, 0), stiffness=sTruss, dimension="3D"): self.Number = number # number in a global geometric system self.GlobalNodeNumbers = gnn # global node numbers self.P1 = p1 # 1st Point of the beam self.P2 = p2 # 2nd Point of the beam self.Dimension = dimension self.BeamType = "{}{}".format(stiffness, self.Dimension) self.DoFPerNode = self.__dof_per_node_mapping[self.BeamType] self.DOFS = dict() # global degree of freedoms according to the beam number in a global system # just needed if there is a global system # is a dictionary with entries for both nodes of the beam if self.Number > 0: self.DOFS.update(get_dofs_from_node(self.GlobalNodeNumbers[0], self.DoFPerNode)) self.DOFS.update(get_dofs_from_node(self.GlobalNodeNumbers[1], self.DoFPerNode)) if self.Dimension == "3D": self.Datum = Datum3D(self.P1, self.P2) elif self.Dimension == "2D": self.Datum = Datum2D(self.P1, self.P2) # datum object for the beam; both points are required for creation # detailed description in datum class file self.Geometry = Geometry(p1, p2, crosssection, x) # Geometry object; requires both points to calculate # the length, the cross section's type and the characteristic value for the corresponding cross section self.Material = Material # create the Material object; now: nothing else is required because E and # rho are constant self.Mass = self.calculatemass_a(self.Geometry.CrossSection.A) # calculate mass of the beam # select the stiffness type; now: only Truss stiffness is available if stiffness == "Truss": self.Stiffness = TrussStiffness(self, stiffness) elif stiffness == "Beam": self.Stiffness = BeamStiffness(self, stiffness) else: self.Stiffness = None
def __get_2d_beam_matrix(_gm, _d2, _x=1): # _a = (pi/4) ** _d ** 2 _ndofs = len(_gm.Nodes) * _gm.DoFsPerNode _k = [0] * _ndofs for _n in range(_ndofs): _k[_n] = [0] * _ndofs for _b in _gm.Beams: cb = _gm.Beams[_b] ek = get_beam_element_submatrix(cb, _d2[_b]) dl = cb.DOFS[list(cb.DOFS.keys())[0]] + cb.DOFS[list( cb.DOFS.keys())[1]] dl = [i - 1 for i in dl] for i in range(2 * _gm.DoFsPerNode): for j in range(2 * _gm.DoFsPerNode): _k[int(dl[i])][int(dl[j])] += ek[i][j] # * _x[_b] for _node in _gm.Bounds: _bd = get_dofs_from_node(_node, _gm.DoFsPerNode, zerobased=True) for _n in _bd[_node]: for _i in range(len(_k)): _k[int(_i)][int(_n)] = 0 for _j in range(len(_k[int(_n)])): _k[int(_n)][int(_j)] = 0 _k[int(_n)][int(_n)] = 1 return _k
def get_matrix(_gm, _a, _x): _ndofs = len(_gm.Nodes) * _gm.DoFsPerNode _k = make_zeros(_ndofs) for _n in range(_ndofs): _k[_n] = make_zeros(_ndofs) for _b in _gm.Beams: cb = _gm.Beams[_b] # ek = cb.Stiffness.K_dof.tolist() ek = get_beam_element_submatrix(cb, _a[_b]) dl = cb.DOFS[list(cb.DOFS.keys())[0]] + cb.DOFS[list( cb.DOFS.keys())[1]] dl = [i - 1 for i in dl] for i in range(2 * _gm.DoFsPerNode): for j in range(2 * _gm.DoFsPerNode): _k[int(dl[i])][int(dl[j])] += ek[i][j] * _x[_b] for _node in _gm.Bounds: _bd = get_dofs_from_node(_node, _gm.DoFsPerNode, zerobased=True) for _n in _bd[_node]: for _i in range(len(_k)): _k[int(_i)][int(_n)] = 0 for _j in range(len(_k[int(_n)])): _k[int(_n)][int(_j)] = 0 _k[int(_n)][int(_n)] = 1 return _k
def __init__(self, _nodes, _beams, _bounds, _loads, _eletype=sTruss): self.ElementType = _eletype self.DoFsPerNode = self.__dof_per_node_mapping[self.ElementType] self.deletionindices = list() self.Nodes = _nodes self.Beams = _beams self.Bounds = _bounds self.Loads = _loads self.BoundedNodes, self.FreeNodes = self.__get_nodes_types() self.Calculationindices = list() for node in self.FreeNodes: self.Calculationindices.extend(get_dofs_from_node(node, self.DoFsPerNode, zerobased=False)[node]) self.Kglob = get_complete_stiffness(self.Nodes, self.Beams, self.DoFsPerNode, self.ElementType) self.F = self.get_force_vector() _myU, _myK = self.__get_u() self.U = np.array(_myU) self.Kcal = _myK pass
def get_force_vector(self): _f = np.zeros((len(self.Nodes) * self.DoFsPerNode)) _myMap = dict() for node in self.Loads: _f_indices = (get_dofs_from_node(node, self.DoFsPerNode, zerobased=True))[node] _f_vals = self.Loads[node] _j = 0 for _i in _f_indices: _f[int(_i)] = _f_vals[_j] _j += 1 return _f
def __get_truss_matrix(_gm, _d, _x=1): # _a = (pi/4) * _d __nnodes = len(_gm.Nodes) __ndofs = __nnodes * _gm.DoFsPerNode _bk = dict() # k_alpha dict for every beam in geometric system for _b in _gm.Beams: _bk[_b] = get_truss_sub_matrix(_gm.Beams[_b], _d[_b]) _k = list() for i in range(__ndofs): _k.append([0] * __ndofs) def _fill_k(__k, _b, __sub_k): for __i in _b.DOFS: for __j in _b.DOFS: _igd = _b.DOFS[__i] _jgd = _b.DOFS[__j] _it = 0 for ___i in _igd: _jt = 0 for ___j in _jgd: if __i == __j: __k[int(___i) - 1][int(___j) - 1] += __sub_k[_it][_jt] # * __x else: __k[int(___i) - 1][int(___j) - 1] -= __sub_k[_it][_jt] # * __x _jt += 1 _it += 1 return __k for _b in _bk: _k = _fill_k(_k, _gm.Beams[_b], _bk[_b]) for _node in _gm.Bounds: _bd = get_dofs_from_node(_node, _gm.DoFsPerNode, zerobased=True) for _n in _bd[_node]: for _i in range(len(_k)): _k[int(_i)][int(_n)] = 0 for _j in range(len(_k[int(_n)])): _k[int(_n)][int(_j)] = 0 _k[int(_n)][int(_n)] = 1 return _k
def __get_u(self): _k = np.array(self.Kglob) _f = np.array(self.F) for _node in self.Bounds: _bd = get_dofs_from_node(_node, self.DoFsPerNode, zerobased=True) for __di in _bd[_node]: _k[int(__di), :] = 0 _k[:, int(__di)] = 0 for __dj in _bd[_node]: if __di == __dj: _k[int(__dj), int(__dj)] = 1 _u = np.linalg.solve(_k, _f) return _u, _k
def get_displacement_vector(self): _k = self.Kglob _f = self.F _u = np.zeros((len(self.Nodes) * self.DoFsPerNode, 1)) _indices = list() for node in self.Bounds: _indices = get_dofs_from_node(node, self.DoFsPerNode, zerobased=True) self.deletionindices.extend(_indices[node]) _f = np.delete(_f, self.deletionindices, axis=0) _k = np.delete(_k, self.deletionindices, axis=0) _k = np.delete(_k, self.deletionindices, axis=1) self.Kcal = _k self.Fcal = _f _k = np.round(_k, 3) _f = np.round(_f, 3) _u_cal = np.linalg.solve(_k, _f) self.Ucal = _u_cal _z = 0 for _i in self.Calculationindices: _u[int(_i-1)] = _u_cal[_z] _z += 1 # get a translation dict for u and u_cal _u_mapping = dict() # key: u_cal, value: u_glob _z = 1 for i in self.Calculationindices: _u_mapping[_z] = int(i) _z += 1 return _u, _u_mapping