def fd(vertices, edges, fixed, q, loads, rtype='list'): num_v = len(vertices) free = list(set(range(num_v)) - set(fixed)) xyz = asarray(vertices, dtype=float).reshape((-1, 3)) q = asarray(q, dtype=float).reshape((-1, 1)) p = asarray(loads, dtype=float).reshape((-1, 3)) C = connectivity_matrix(edges, 'csr') Ci = C[:, free] Cf = C[:, fixed] Ct = C.transpose() Cit = Ci.transpose() Q = diags([q.flatten()], [0]) A = Cit.dot(Q).dot(Ci) b = p[free] - Cit.dot(Q).dot(Cf).dot(xyz[fixed]) xyz[free] = spsolve(A, b) l = normrow(C.dot(xyz)) f = q * l r = p - Ct.dot(Q).dot(C).dot(xyz) if rtype == 'list': return [xyz.tolist(), q.ravel().tolist(), f.ravel().tolist(), l.ravel().tolist(), r.tolist()] if rtype == 'dict': return {'xyz': xyz.tolist(), 'q' : q.ravel().tolist(), 'f' : f.ravel().tolist(), 'l' : l.ravel().tolist(), 'r' : r.tolist()} return xyz, q, f, l, r
def inc_mat(self): """ constructs incident C matrix for form diagram """ edg_dic = self.dic_attr['edg_dic'] C = connectivity_matrix(list(edg_dic.values()), rtype='csc') c_inc = C.transpose() self.dic_attr['c_inc'] = c_inc
def bar_properties(bars, ver_coor): """ returns connectivity matirx, bar lenghts and bar direction cosines (coor_diff/len) bars: the paired list of lists of vertices ver_coor: vertex coordinates of the bars """ C=connectivity_matrix(bars, rtype='csr') xy=ver_coor.copy() uv=C.dot(xy) # coordinate difference bars_len=np.sqrt(np.sum(np.square(uv), axis=1)) norm_dir=uv/bars_len[:, np.newaxis] # [[sin_1 cos_1],[sin_2 cos_2]...] return C, bars_len, np.round_(norm_dir, 2)
def _create_arrays(network): """ Create arrays needed for dr_solver. Parameters: network (obj): Network to analyse. Returns: array: Constraint conditions. array: Nodal loads Px, Py, Pz. array: Resultant nodal loads. array: Sx, Sy, Sz shear force components. array: x, y, z co-ordinates. array: Nodal velocities Vx, Vy, Vz. array: Edges' initial forces. array: Edges' initial lengths. list: Compression only edges. list: Tension only edges. array: Connectivity matrix. array: Transposed connectivity matrix. array: Axial stiffnesses. array: Network edges' start points. array: Network edges' end points. array: Mass matrix. list: Edge adjacencies (rows). list: Edge adjacencies (columns). list: Edge adjacencies (values). array: Young's moduli. array: Edge areas. """ # Vertices n = network.number_of_vertices() B = zeros((n, 3)) P = zeros((n, 3)) X = zeros((n, 3)) S = zeros((n, 3)) V = zeros((n, 3)) k_i = network.key_index() for key in network.vertices(): i = k_i[key] vertex = network.vertex[key] B[i, :] = vertex['B'] P[i, :] = vertex['P'] X[i, :] = [vertex[j] for j in 'xyz'] Pn = normrow(P) # Edges m = len(network.edges()) E = zeros((m, 1)) A = zeros((m, 1)) s0 = zeros((m, 1)) l0 = zeros((m, 1)) u = [] v = [] ind_c = [] ind_t = [] edges = [] uv_i = network.uv_index() for ui, vi in network.edges(): i = uv_i[(ui, vi)] edge = network.edge[ui][vi] edges.append([k_i[ui], k_i[vi]]) u.append(k_i[ui]) v.append(k_i[vi]) E[i] = edge['E'] A[i] = edge['A'] s0[i] = edge['s0'] if edge['l0']: l0[i] = edge['l0'] else: l0[i] = network.edge_length(ui, vi) if edge['ct'] == 'c': ind_c.append(i) elif edge['ct'] == 't': ind_t.append(i) f0 = s0 * A ks = E * A / l0 # Arrays C = connectivity_matrix(edges, 'csr') Ct = C.transpose() M = mass_matrix(Ct, E, A, l0, f0, c=1, tiled=False) rows, cols, vals = find(Ct) return B, P, Pn, S, X, V, f0, l0, ind_c, ind_t, C, Ct, ks, array(u), array( v), M, rows, cols, vals, E, A
def create_arrays(network): """ Create arrays for DR solver. Parameters: network (obj): Network to analyse. Returns: array: Nodal co-ordinates x, y, z. array: Constraint conditions Bx, By, Bz. array: Nodal loads Px, Py, Pz. array: Resultant nodal loads. array: Shear force components Sx, Sy, Sz. array: Nodal velocities Vx, Vy, Vz. array: Edge Young's moduli. array: Edge areas. array: Connectivity matrix. array: Transposed connectivity matrix. array: Edge initial forces. array: Edge initial lengths. list: Compression only edges indices. list: Tension only edges indices. array: Network edges' start points. array: Network edges' end points. array: Mass matrix. array: Edge axial stiffnesses. """ # Vertices vertices = list(network.vertices()) n = len(vertices) X = zeros((n, 3)) B = zeros((n, 3)) P = zeros((n, 3)) S = zeros((n, 3)) V = zeros((n, 3)) k_i = network.key_index() for key in vertices: i = k_i[key] vertex = network.vertex[key] X[i, :] = [vertex[j] for j in 'xyz'] B[i, :] = vertex.get('B', [1, 1, 1]) P[i, :] = vertex.get('P', [0, 0, 0]) Pn = normrow(P) # Edges edges = list(network.edges()) m = len(edges) E = zeros((m, 1)) A = zeros((m, 1)) s0 = zeros((m, 1)) l0 = zeros((m, 1)) u = zeros(m, dtype=int64) v = zeros(m, dtype=int64) ind_c = [] ind_t = [] uv_i = network.uv_index() for c, uv in enumerate(edges): ui, vi = uv i = uv_i[(ui, vi)] edge = network.edge[ui][vi] E[i] = edge.get('E', 0) A[i] = edge.get('A', 0) l0[i] = edge.get('l0', network.edge_length(ui, vi)) s0[i] = edge.get('s0', 0) ct = edge.get('ct', None) if ct == 'c': ind_c.append(i) elif ct == 't': ind_t.append(i) u[c] = k_i[ui] v[c] = k_i[vi] f0 = s0 * A ks = E * A / l0 # Faces (unconfirmed testing formulation) faces = list(network.faces()) if faces: for face in faces: fdata = network.facedata[face] Eh = fdata.get('E', 0) Ah = network.face_area(face) th = fdata.get('t', 0) for ui, vi in network.face_edges(face): i = uv_i[(ui, vi)] ks[i] += 1.5 * Eh * Ah * th / l0[i]**2 # Arrays C = connectivity_matrix([[k_i[ui], k_i[vi]] for ui, vi in edges], 'csr') Ct = C.transpose() M = mass_matrix(Ct, ks, f0, c=1, tiled=False) return X, B, P, Pn, S, V, E, A, C, Ct, f0, l0, ind_c, ind_t, u, v, M, ks
def dr(vertices, edges, fixed, loads, qpre, fpre, lpre, linit, E, radius, ufunc=None, **kwargs): # -------------------------------------------------------------------------- # configuration # -------------------------------------------------------------------------- kmax = kwargs.get('kmax', 10000) dt = kwargs.get('dt', 1.0) tol1 = kwargs.get('tol1', 1e-3) tol2 = kwargs.get('tol2', 1e-6) coeff = Coeff(kwargs.get('c', 0.1)) ca = coeff.a cb = coeff.b # -------------------------------------------------------------------------- # attribute lists # -------------------------------------------------------------------------- num_v = len(vertices) num_e = len(edges) free = list(set(range(num_v)) - set(fixed)) # -------------------------------------------------------------------------- # attribute arrays # -------------------------------------------------------------------------- xyz = array(vertices, dtype=float).reshape((-1, 3)) # m p = array(loads, dtype=float).reshape((-1, 3)) # kN qpre = array(qpre, dtype=float).reshape((-1, 1)) fpre = array(fpre, dtype=float).reshape((-1, 1)) # kN lpre = array(lpre, dtype=float).reshape((-1, 1)) # m linit = array(linit, dtype=float).reshape((-1, 1)) # m E = array(E, dtype=float).reshape((-1, 1)) # kN/mm2 => GPa radius = array(radius, dtype=float).reshape((-1, 1)) # mm # -------------------------------------------------------------------------- # sectional properties # -------------------------------------------------------------------------- A = 3.14159 * radius**2 # mm2 EA = E * A # kN # -------------------------------------------------------------------------- # create the connectivity matrices # after spline edges have been aligned # -------------------------------------------------------------------------- C = connectivity_matrix(edges, 'csr') Ct = C.transpose() Ci = C[:, free] Cit = Ci.transpose() Ct2 = Ct.copy() Ct2.data **= 2 # -------------------------------------------------------------------------- # if none of the initial lengths are set, # set the initial lengths to the current lengths # -------------------------------------------------------------------------- if all(linit == 0): linit = normrow(C.dot(xyz)) # -------------------------------------------------------------------------- # initial values # -------------------------------------------------------------------------- q = ones((num_e, 1), dtype=float) l = normrow(C.dot(xyz)) f = q * l v = zeros((num_v, 3), dtype=float) r = zeros((num_v, 3), dtype=float) # -------------------------------------------------------------------------- # acceleration # -------------------------------------------------------------------------- def a(t, v): dx = v * t xyz[free] = xyz0[free] + dx[free] r[free] = p[free] - D.dot(xyz) return cb * r / mass # -------------------------------------------------------------------------- # start iterating # -------------------------------------------------------------------------- for k in xrange(kmax): q_fpre = fpre / l q_lpre = f / lpre q_EA = EA * (l - linit) / (linit * l) q_lpre[isinf(q_lpre)] = 0 q_lpre[isnan(q_lpre)] = 0 q_EA[isinf(q_EA)] = 0 q_EA[isnan(q_EA)] = 0 q = qpre + q_fpre + q_lpre + q_EA Q = diags([q[:, 0]], [0]) D = Cit.dot(Q).dot(C) mass = 0.5 * dt**2 * Ct2.dot(qpre + q_fpre + q_lpre + EA / linit) xyz0 = xyz.copy() # ---------------------------------------------------------------------- # RK # ---------------------------------------------------------------------- v0 = ca * v.copy() dv = rk2(a, v0, dt) v = v0 + dv dx = v * dt xyz[free] = xyz0[free] + dx[free] # update uvw = C.dot(xyz) l = normrow(uvw) f = q * l r = p - Ct.dot(Q).dot(uvw) # crits crit1 = norm(r[free]) crit2 = norm(dx[free]) # ufunc if ufunc: ufunc(k, crit1, crit2) # convergence if crit1 < tol1: break if crit2 < tol2: break print(k) return xyz, q, f, l, r
# make a network from sample data network = Network.from_obj(compas.get_data('grid_irregular.obj')) # extract vertex coordinates and connectivity matrix # and convert to Matlab matrices key_index = network.key_index() xyz = network.get_vertices_attributes('xyz') xyz = matlab.double(xyz) edges = [(key_index[u], key_index[v]) for u, v in network.edges()] C = connectivity_matrix(edges, rtype='list') C = matlab.double(C) # compute coordinate differences in Matlab # # using an engine function # uv = matlab.engine.mtimes(C, xyz) # using workspace data matlab.engine.workspace['C'] = C matlab.engine.workspace['xyz'] = xyz uv = matlab.engine.eval('C * xyz') # compute edge lengths in Python