def cablenet_fd_numpy(cablenet): """Compute the equilibrium shape of a cablenet using the force density method. Parameters ---------- cablenet : compas_fofin.cablenet.Cablenet The cablenet data structure. """ key_index = cablenet.key_index() xyz = cablenet.get_vertices_attributes('xyz') edges = [(key_index[u], key_index[v]) for u, v in cablenet.edges()] fixed = [ key_index[key] for key in cablenet.vertices_where({'is_anchor': True}) ] q = cablenet.get_edges_attribute('q', 1.0) loads = cablenet.get_vertices_attributes(('px', 'py', 'pz'), (0.0, 0.0, 0.0)) xyz, q, f, l, r = fd_numpy(xyz, edges, fixed, q, loads) for key, attr in cablenet.vertices(True): index = key_index[key] cablenet.set_vertex_attributes(key, 'xyz', xyz[index]) cablenet.set_vertex_attributes(key, ('rx', 'ry', 'rz'), r[index]) for index, (u, v, attr) in enumerate(cablenet.edges(True)): attr['f'] = f[index][0] attr['l'] = l[index][0]
def find_form(mesh): vertices = [ mesh.vertex_coordinates(vkey) for vkey in sorted(list(mesh.vertices())) ] edges = list(mesh.edges()) fixed = mesh.vertices_on_boundary() q = [1.0] * len(edges) loads = [[0.0, 0.0, 50.0 / len(vertices)]] * len(vertices) xyz, q, f, l, r = fd_numpy(vertices, edges, fixed, q, loads) for vkey, coordinates in zip(sorted(list(mesh.vertices())), xyz): mesh_move_vertex_to(mesh, coordinates, vkey)
def relax_boundary_openings(form, fixed): k_i = form.key_index() xyz = form.vertices_attributes('xyz') edges = [(k_i[u], k_i[v]) for u, v in form.edges()] fixed = [k_i[key] for key in fixed] q = form.edges_attribute('q') loads = form.vertices_attributes(('px', 'py', 'pz')) xyz, q, f, l, r = fd_numpy(xyz, edges, fixed, q, loads) for key in form.vertices(): index = k_i[key] form.vertex_attributes(key, 'xyz', xyz[index])
def find_form(mesh, total_load): vertices = [mesh.vertex_coordinates(vkey) for vkey in mesh.vertices()] edges = list(mesh.edges()) fixed = mesh.vertices_on_boundary() q = [1.0] * len(edges) #total_area = mesh.area() loads = [[0.0, 0.0, total_load / mesh.number_of_vertices()] ] * mesh.number_of_vertices() xyz, q, f, l, r = fd_numpy(vertices, edges, fixed, q, loads) for vkey, coordinates in zip(mesh.vertices(), xyz): mesh_move_vertex_to(mesh, coordinates, vkey)
def relax(self): from compas.numerical import fd_numpy key_index = self.key_index() xyz = self.vertices_attributes('xyz') loads = [[0.0, 0.0, 0.0] for _ in xyz] fixed = [ key_index[key] for key in self.vertices_where({'is_fixed': True}) ] edges = [(key_index[u], key_index[v]) for u, v in self.edges()] q = self.edges_attribute('q') xyz, q, f, l, r = fd_numpy(xyz, edges, fixed, q, loads) for key in self.vertices(): index = key_index[key] self.vertex_attributes(key, 'xyz', xyz[index])
def relax_boundary_openings(form): k_i = form.key_index() xyz = form.get_vertices_attributes(('x', 'y', 'z')) edges = [(k_i[u], k_i[v]) for u, v in form.edges()] fixed = [k_i[key] for key in form.vertices_where({'is_fixed': True})] q = form.get_edges_attribute('q') loads = form.get_vertices_attributes(('px', 'py', 'pz'), (0.0, 0.0, 0.0)) xyz, q, f, l, r = fd_numpy(xyz, edges, fixed, q, loads) for key, attr in form.vertices(True): index = k_i[key] attr['x'] = xyz[index][0] attr['y'] = xyz[index][1] attr['z'] = xyz[index][2]
def relax_boundary_openings(form, fixed): """""" k_i = form.key_index() xyz = form.vertices_attributes('xyz') edges = [(k_i[u], k_i[v]) for u, v in form.edges()] fixed = [k_i[key] for key in fixed] q = form.edges_attribute('q') loads = form.vertices_attributes(('px', 'py', 'pz')) xyz, q, f, l, r = fd_numpy(xyz, edges, fixed, q, loads) for key, attr in form.vertices(True): index = k_i[key] attr['x'] = xyz[index][0] attr['y'] = xyz[index][1] attr['z'] = xyz[index][2]
xyz = network.get_vertices_attributes(('x', 'y', 'z')) loads = network.get_vertices_attributes(('px', 'py', 'pz')) q = network.get_edges_attribute('q') # use a key-index map to reference items in the numerical data key_index = network.key_index() fixed = [key for key in network.vertices() if network.vertex[key]['is_anchor']] fixed = [key_index[key] for key in fixed] edges = [(key_index[u], key_index[v]) for u, v in network.edges()] # run the force density method res = fd_numpy(xyz, edges, fixed, q, loads) xyz = res[0] # update the network for key in network.vertices(): index = key_index[key] network.vertex[key]['x'] = xyz[index][0] network.vertex[key]['y'] = xyz[index][1] network.vertex[key]['z'] = xyz[index][2] # display the result artist = NetworkArtist(network, layer="TEMP") artist.draw_vertices(radius=0.05)
attr['z'] = 5.0 # preprocess k_i = mesh.key_index() xyz = mesh.get_vertices_attributes(('x', 'y', 'z')) loads = mesh.get_vertices_attributes(('px', 'py', 'pz')) q = mesh.get_edges_attribute('q') fixed = mesh.vertices_where({'is_anchor': True}) fixed = [k_i[k] for k in fixed] edges = [(k_i[u], k_i[v]) for u, v in mesh.edges()] # compute equilibrium # update the mesh geometry xyz, q, f, l, r = fd_numpy(xyz, edges, fixed, q, loads) for key, attr in mesh.vertices(True): index = k_i[key] attr['x'] = xyz[index, 0] attr['y'] = xyz[index, 1] attr['z'] = xyz[index, 2] # visualisae the result # color the vertices according to their elevation plotter = MeshPlotter(mesh) zmax = max(mesh.get_vertices_attribute('z')) plotter.draw_vertices(
def ForceDensitySolver(formData, flt_TtlSWLd, bool_LdsRdistrByTrib=True, iMax_LdsRedistr=5): _formDiag = FormDiagram.from_data(formData) _dctMap__Ind_to_VKey = _formDiag.IndexToVKey(bool_ExclExt=False) _dctMap__VKey_to_Ind = _formDiag.VKeyToIndex(bool_ExclExt=False) _vKeysL_Vertices = _formDiag.VertexKeys(bool_ExclExt=False) _coordsL_Vertices = _formDiag.RetrieveCoordinates(_vKeysL_Vertices) _eKeysL_Edges = _formDiag.EdgeKeys(bool_ExclExt=False, bool_Ind=False) _eIndKeysL_Edges = _formDiag.EdgeKeys(bool_ExclExt=False, bool_Ind=True) _vIndKeysL_Anchs = [ _dctMap__VKey_to_Ind[_vKey] for _vKey in list(_formDiag.anchors()) ] _fltsL_Q = _formDiag.get_edges_attribute('q', 1.0) _vecsL_ApldLds = _formDiag.get_vertices_attributes(['px', 'py', 'pz']) _vecsA_TtlLds = array(_vecsL_ApldLds, dtype=float64) _vecsA_ApldLds = array(_vecsL_ApldLds, dtype=float64) _LdUpdtr = LoadUpdater(_formDiag, _vecsA_ApldLds, thickness=1.0, density=flt_TtlSWLd) _coordsL_Vertices_0 = deepcopy(_coordsL_Vertices) _fltsL_Q_0 = _fltsL_Q _iMax = 10 _cDctStructSolvOprDta = {'res': {'all': {}}} _i = 0 while _i < _iMax: ##Update Loads _coordsAr_Vertices_0 = array(_coordsL_Vertices_0, dtype=float64) _LdUpdtr(_vecsA_TtlLds, _coordsAr_Vertices_0) _vecsL_TtlLds = _vecsA_TtlLds.tolist() _coordsL_Vertices_1, _fltsL_Q_1, _fltsL_EdgeForces, _fltsL_EdgeLgths, _flt_ResidForces = fd_numpy( _coordsL_Vertices_0, _eIndKeysL_Edges, _vIndKeysL_Anchs, _fltsL_Q_0, _vecsL_TtlLds) UpdateFormDiagramVertices(_formDiag, _coordsL_Vertices_1, _dctMap__Ind_to_VKey) _cDctFDRes = { 'lds': _vecsL_TtlLds, 'coords': _coordsL_Vertices_1, 'q': _fltsL_Q_1, 'f': _fltsL_EdgeForces, 'lgths': _fltsL_EdgeLgths, 'fResid': _flt_ResidForces } _cDctFDRes_Prtl = { _kV: [_v[0] for _v in _lA] for _kV, _lA in _cDctFDRes.items() if _kV not in ['lds', 'coords'] } _cDctFDRes.update(_cDctFDRes_Prtl) ##Remove the listed values _cDctStructSolvOprDta['res']['all'][int(_i)] = _cDctFDRes if bool_LdsRdistrByTrib == False: break elif _i >= iMax_LdsRedistr - 1: break _coordsL_Vertices_0 = _coordsL_Vertices_1 _i += 1 _i_FnlIter = max(list(_cDctStructSolvOprDta['res']['all'].keys())) _formDiag.SetEdgesAttributeWithValues( str_AttrNm='f', dtaL_AttrVals=_cDctStructSolvOprDta['res']['all'][_i_FnlIter]['f'], eKeysL=_eKeysL_Edges) _formDiag.SetEdgesAttributeWithValues( str_AttrNm='q', dtaL_AttrVals=_cDctStructSolvOprDta['res']['all'][_i_FnlIter]['q'], eKeysL=_eKeysL_Edges) _formDiag.SetEdgesAttributeWithValues( str_AttrNm='l', dtaL_AttrVals=_cDctStructSolvOprDta['res']['all'][_i_FnlIter]['lgths'], eKeysL=_eKeysL_Edges) _formDiag.SetVerticesAttributesWithValues( strsL_AttrsNms=['px', 'py', 'pz'], dtaLL_AttrsVals=_cDctStructSolvOprDta['res']['all'][_i_FnlIter]['lds'], vKeysL=_vKeysL_Vertices) _formDiag.SetVerticesAttributeWithValues( str_AttrNm='fR', dtaL_AttrVals=_cDctStructSolvOprDta['res']['all'][_i_FnlIter] ['fResid'], vKeysL=_vKeysL_Vertices) _formData = _formDiag.to_data() return _formData, _cDctStructSolvOprDta
# compile numerical data vertex_index = mesh.vertex_index() X = mesh.vertices_attributes('xyz') P = mesh.vertices_attributes(['px', 'py', 'pz']) Q = mesh.edges_attribute('q') fixed = [ vertex_index[vertex] for vertex in mesh.vertices_where({'is_anchor': True}) ] edges = [(vertex_index[u], vertex_index[v]) for u, v in mesh.edges()] # compute equilibrium X, Q, F, L, R = fd_numpy(X, edges, fixed, Q, P) # update network for vertex in mesh.vertices(): index = vertex_index[vertex] mesh.vertex_attributes(vertex, 'xyz', X[index]) mesh.vertex_attributes(vertex, ['rx', 'ry', 'rz'], R[index]) for index, edge in enumerate(mesh.edges()): mesh.edge_attribute(edge, 'q', Q[index][0]) mesh.edge_attribute(edge, 'f', F[index][0]) mesh.to_json(FILE)