7. Modify Diagram

7.a: select support points

In TNA, after horizontal and vertical equilibrium is achieved, vertices can still be moved along the z-direction, because the horizontal equilibrium will not change. The supports at the boundaries carry loads in any direction, and if they are moved along Z, this will not change. Instead, the vertices in the middle of the shell can be used as support and moved along Z getting only a vertical reaction.

Here, vertices in the inner boundary will be moved to the ground (z=0) as supports. Select the vertices in the ThrustDiagram. Since ThrustDiagram and FormDiagram has exactly the same data-structure, they share the same vertex key. Anchor the selected vertices in the FormDiagram and set their z to 0. (the z value can also be different if the supports are not on the ground. ).

# ==============================================================================
#  Modify Thrust Diagram
# ==============================================================================
guids = compas_rhino.select_points(message='Select Points to Move')
compas_rhino.rs.HideObjects(guids)
points = compas_rhino.get_point_coordinates(guids)
gkey_key_dict = thrust.gkey_key()
for pt in points:
    vkey = gkey_key_dict[geometric_key(pt)]
    form.vertex_attribute(vkey, 'z', 0)
    form.vertex_attribute(vkey, 'is_anchor', True)

7.b: Recalculate Vertical Equilibrium

Then run vertical equilibrium again.

# ==============================================================================
# Recalculate Vertical Equilibirum
# ==============================================================================
thrustdata, scale = proxy.vertical_from_zmax_proxy(form.to_data(), zmax=zmax, kmax=kmax)
thrust = ThrustDiagram.from_data(thrustdata)

7.c: Draw Internal Forces

We can also visualize the forces in the edges.

from compas.geometry import Cylinder
from compas_rhino.artists import CylinderArtist

def draw_forces(thrust, layer, color=(255, 0, 0), scale=10, tol=0.001):
    for edge in thrust.edges_where({'_is_edge': True}):
        q = thrust.edge_attribute(edge, 'q')
        l = thrust.edge_length(*edge)  # noqa E741
        f = q * l
        radius = scale * f
        if radius < tol:
            continue
        mp = thrust.edge_midpoint(*edge)
        direction = thrust.edge_direction(*edge)
        height = l
        cylinder = Cylinder(((mp, direction), radius), height)
        artist = CylinderArtist(cylinder, layer=layer, color=color)
        artist.draw(u=16)


draw_forces(thrust, layer="CSD2::thrust", scale=0.01)

Last updated