Skip to content

Nodes and bars

The order that always works: a section, the nodes, the bar that joins them, the supports. Keep what each create_* call returns and pass that on; do not look up what you just made. A call that takes a node or a bar accepts either the object or its id as text: model.pin(n1) and model.pin('N1') are the same.

  • In the same reply, use the objects the create_* calls returned.
  • In a later reply those variables no longer exist: use the id as text ('N1', 'B1'), read with the geometry tool. Do not guess an id: see Id below.

Nodes

Node: add

Create a new node with create_node. A node is (x, y) in metres; y is up. The call returns the node:

n1 = model.create_node(0.0, 0.0)
n2 = model.create_node(7.0, 0.0)                         # 7 m to the right
row = [model.create_node(x, 0.0) for x in (0.0, 5.0, 10.0)]

Node: edit

Move a node, or rename it. A node's coordinates are plain attributes; the bars on it follow:

model.nodes['N2'].x = 6.0
model.nodes['N2'].y = 1.5

To rename it (the bars that use it follow): model.rename_node('N2', 'A').

Node: remove

Delete a node with remove_node:

model.remove_node('N3')       # a node, and everything hanging on it:
                              # its supports, loads and the bars that use it

Remove a bar first if the nodes should stay. Removing a node removes the bars attached to it.

Bars

Bar: add a bar (a 7 m beam)

Create a new bar between two nodes, with a section:

sec = model.create_rc_section('S1', b=0.3, h=0.5)    # section (it makes its material)
n1 = model.create_node(0.0, 0.0)
n2 = model.create_node(7.0, 0.0)
bar = model.create_bar_element(sec, n1, n2)           # section first, then the two nodes
model.pin(n1)                                         # supports: see the Supports tutorial
model.roller(n2, free='x')

The section must exist before the bar: create_bar_element('Sec', ...) with no section called Sec leaves the bar without one. Create it first (create_rc_section, create_steel_section), or read the names that exist with the geometry tool.

sec = model.create_steel_section('S2', 'IPE300', grade='S355')

Bar: add a continuous beam

sec = model.create_rc_section('S1', b=0.3, h=0.5)
nodes = [model.create_node(x, 0.0) for x in (0.0, 5.0, 10.0, 15.0)]
for a, b in zip(nodes, nodes[1:]):
    model.create_bar_element(sec, a, b)
model.pin(nodes[0])
model.roller(nodes[1:], free='x')

pin, fix and roller take a node or a list of nodes.

Bar: add a portal frame

sec = model.create_rc_section('S1', b=0.3, h=0.5)
a = model.create_node(0.0, 0.0)
b = model.create_node(0.0, 3.5)       # y is up
c = model.create_node(6.0, 3.5)
d = model.create_node(6.0, 0.0)
for i, j in ((a, b), (b, c), (c, d)):
    model.create_bar_element(sec, i, j)
model.fix([a, d])

Bar: add a standard structure in one call

For a beam, frame, truss, wall or slab of a standard kind, model.create_from_template(kind, **params) builds geometry and supports together; see the Templates page. Use the calls above for anything else, or to add to what is already there.

Bar: edit

Change a bar: rename it, give it another section or material (see Materials and sections), or move its end nodes (see Node: edit). Do not index the model's dictionaries with numbers: model.nodes and model.bar_elements_by_id are dictionaries keyed by the id as text, not lists. model.nodes[0] is a KeyError.

# wrong: model.create_bar_element('S1', model.nodes[0], model.nodes[1])
# right: use the objects create_node returned, or the ids as text
bar = model.create_bar_element('S1', 'N1', 'N2')

To rename a bar: model.rename_bar_element('B1', 'Beam1'). To give it another section or material, see Sections: edit in Materials and sections.

Bar: remove

Delete a bar with remove_element:

model.remove_element('B1')            # a bar; its nodes stay

Hinges

Hinge: add

A hinge is a property of the bar's end, not a support: hinge_i releases the moment at the bar's first node, hinge_j at its second. Use it for "a hinge at the start of the second span" or for a Gerber beam. Do not confuse it with model.pin(n), which is a support.

When the bar is created:

sec = model.create_rc_section('S1', b=0.3, h=0.5)
n1 = model.create_node(0.0, 0.0)
n2 = model.create_node(5.0, 0.0)
n3 = model.create_node(10.0, 0.0)
model.create_bar_element(sec, n1, n2)
model.create_bar_element(sec, n2, n3, hinge_i=True)   # hinge at n2, on the second bar
model.pin([n1, n2, n3])

On a bar that already exists. Read the bar's nodes first (geometry tool) to know which end is which:

model.bar_elements_by_id['B2'].hinge_i = True     # releases the moment where B2 starts (N2)

Put the hinge on one of the two bars that meet at the node, not on both.

Hinge: edit

To change which end of the bar has the hinge:

model.bar_elements_by_id['B2'].hinge_i = False
model.bar_elements_by_id['B2'].hinge_j = True

Hinge: remove

Delete a hinge by setting the flag back:

model.bar_elements_by_id['B2'].hinge_i = False    # back to a rigid joint

Ids

Id: bar and node ids are numbered in the order they are created

create_bar_element without id gives B1, B2, ... in the order of the calls, so in a frame whose columns are made first B1 is a column. Do not write an id you did not see. Keep the object the call returned, or give the bar an id of your own:

sec = model.create_rc_section('S1', b=0.3, h=0.5)
n1 = model.create_node(0.0, 0.0)
n2 = model.create_node(0.0, 4.0)
n3 = model.create_node(6.0, 4.0)
model.create_bar_element(sec, n1, n2)                    # B1, a column
beam = model.create_bar_element(sec, n2, n3, id='BEAM')  # the one that will be loaded
model.create_load_case('G')
model.create_uniform_load(beam, 'G', 10, 'down')

If the request says "the bar", "that node" or "the support at N2", find the id with the geometry tool first. A wrong id raises an error and changes nothing.