Hi,
thanks to the elaborate example on compas_fd from this thread Importing compas_fd to rhino8 ScriptEditor - #17 by tomvanmele
I am setting up a quick variation, I want to formfind a membrane over a series of arches, set up geometry image below
I am trying to set multiple Constraint in compas_fd.constraints.Constraint ( the series of arches). from the docs I see that Constraint only takes 1 object ? I am struggling to add a list of Constraint. I’m iterating through a list of contraint and on visualizing, the mesh is not updated
#imports
#imports
from compas.datastructures import Mesh
from compas.geometry import Point, Vector, Line, NurbsCurve
from compas.geometry import Sphere, Cylinder
from compas.scene import Scene
from compas.colors import Color
from compas_fd.solvers import fd_constrained_numpy
from compas_fd.constraints import Constraint
#mesh
mesh = Mesh.from_meshgrid(dx=40,dy=7, nx=40,ny=7)
# vertices, edges
vertices = mesh.vertices_attributes("xyz")
edges = list(mesh.edges())
# anchors/supports
supports = list(mesh.vertices_where(vertex_degree=2))
edge_vertices_0 = list(mesh.vertices_where(y=0,z=0))
edge_vertices_1 = list(mesh.vertices_where(y=7,z=0))
supports += edge_vertices_0 [5::6]
supports += edge_vertices_1 [5::6]
pts = [mesh.vertex_coordinates(ind) for ind in supports]
# loads
loads = [[0, 0, 0] for _ in range(mesh.number_of_vertices())]
# force densities
q = []
for edge in edges:
if mesh.is_edge_on_boundary(edge):
q.append(30)
else:
q.append(1.0)
# constraints
arches = []
v0 = [mesh.vertex_coordinates(ind) for ind in edge_vertices_0 [5::6]]
v1 = [mesh.vertex_coordinates(ind) for ind in edge_vertices_1 [5::6]]
for i,j in zip(v0,v1):
pt0 = Point(i[0],i[1],i[2])
pt1 = Point(j[0],j[1],j[2])
line = Line(pt0,pt1)
mid_point = line.midpoint
move = Point(mid_point[0],mid_point[1],mid_point[2]+3)
arch = NurbsCurve.from_points([i, [move[0],move[1],move[2]], j], degree=2)
arches.append(arch)
arch_constraint = []
for arch in arches:
constraint = Constraint(arch)
arch_constraint.append(constraint)
constraints = [None] * mesh.number_of_vertices()
print(len(constraints))
constrained = []
for arch in arch_constraint:
for vertex in mesh.vertices():
if vertex in supports:
continue
constraints[vertex] = arch
constrained.append(vertex)
print(len(constraints))
result = fd_constrained_numpy(
vertices=vertices,
fixed=list(set(supports + constrained)),
edges=edges,
forcedensities=q,
loads=loads,
constraints=constraints,
)
for vertex, attr in mesh.vertices(data=True):
attr["x"] = result.vertices[vertex, 0]
attr["y"] = result.vertices[vertex, 1]
attr["z"] = result.vertices[vertex, 2]
print(mesh)
scene = Scene()
scene.clear()
scene.add(mesh, disjoint=True)
for pt in pts:
scene.add(Point(pt[0],pt[1],pt[2]), layer="00_compas_fd_mesh_00::supports")
for arch in arches:
scene.add(arch, layer="00_compas_fd_mesh_00::arches")
for vertex in supports:
scene.add(mesh.vertex_point(vertex), color=Color.red())
for vertex in supports:
point = mesh.vertex_point(vertex)
vector = Vector(*result.residuals[vertex]) * -0.5
line = Line.from_point_and_vector(point, vector)
scene.add(line, color=Color.green())
# for index, edge in enumerate(mesh.edges()):
# if mesh.is_edge_on_boundary(edge):
# line = mesh.edge_line(edge)
# radius = 0.005 * result.forces[index]
# pipe = Cylinder.from_line_and_radius(line, radius)
# scene.add(pipe, color=Color.red())
scene.draw()
result below
I have a feeling I got something fundamentally wrong. Any suggestion would help
Thanks in advance!