Geometry
SimDesign provides two geometry classes for defining a building’s structural layout before performing simulated design:
StandardGeometry— programmatically constructed rectangular grids with optional bay and storey modifications.CustomGeometry— layouts loaded from an Excel file (including those previously exported fromStandardGeometry).
The sections below progress from a simple uniform grid to increasingly complex configurations and finally show how to use a custom geometry in design.
Simple uniform geometry
A regular 4 × 4 bay, 4-storey frame with constant bay widths and storey heights.
from pathlib import Path
from simdesign.rcmrf import StandardGeometry
regular_frame = StandardGeometry(
num_storeys=4,
storey_height=3.0,
num_bays_x=4,
bay_width_x=5.0,
num_bays_y=4,
bay_width_y=3.5,
)
regular_frame.add_infills()
# Place a staircase bay starting at grid position (0, 0)
regular_frame.set_continuous_stairs_rectangles(
stair_loc=(0, 0),
stairs_width_x=2,
stairs_width_y=4,
)
# Export to Excel for later use as a CustomGeometry input
regular_frame.write_mesh_to_xlsx(Path("uniform-geometry.xlsx"))
# Add stair elements and visualise
regular_frame.add_new_elements_for_stairs()
regular_frame.show_mesh()
regular_frame.export_mesh_to_html(Path("uniform-geometry.html"))
Note
add_new_elements_for_stairs()
must always be called after all geometry modifications are complete and
before the geometry object is used in design.
Non-uniform geometry
Individual floor heights and bay widths can be modified after construction to introduce non-uniformity.
from pathlib import Path
from simdesign.rcmrf import StandardGeometry
regular_frame = StandardGeometry(
num_storeys=4,
storey_height=3.0,
num_bays_x=4,
bay_width_x=5.0,
num_bays_y=4,
bay_width_y=3.5,
)
regular_frame.set_continuous_stairs_rectangles(
stair_loc=(0, 0),
stairs_width_x=2,
stairs_width_y=4,
)
# Raise the ground-floor height to 4 m (floor_id=1 is the ground floor)
regular_frame.modify_floor_height(floor_id=1, height=4.0)
# Widen the fourth bay in the Y direction
regular_frame.modify_bay_width(bay_id=3, width=5.0, direction="y")
regular_frame.write_mesh_to_xlsx(Path("nonuniform-geometry.xlsx"))
regular_frame.add_new_elements_for_stairs(infills=False)
regular_frame.show_mesh()
regular_frame.export_mesh_to_html(Path("nonuniform-geometry.html"))
L-shaped geometry
An L-shaped footprint is obtained by removing bays from a regular grid using
remove_rectangle().
Each bay is identified by its grid indices [ix, iy, iz] (x-bay, y-bay,
storey level, all starting from 1 for the first storey).
from pathlib import Path
from simdesign.rcmrf import StandardGeometry
regular_frame = StandardGeometry(
num_storeys=5,
storey_height=3.0,
num_bays_x=5,
bay_width_x=4.0,
num_bays_y=5,
bay_width_y=4.0,
)
# Remove the upper-right 3×3 block of bays on every storey
bays_to_remove = [
[ix, iy, iz]
for iz in range(1, 6)
for ix in [2, 3, 4]
for iy in [2, 3, 4]
]
for grid_ids in bays_to_remove:
regular_frame.remove_rectangle(
grid_ids, remove_lines=True, remove_points=True
)
regular_frame.set_continuous_stairs_rectangles(
stairs_loc=(0, 0), stairs_width_x=4, stairs_width_y=4
)
regular_frame.modify_floor_height(floor_id=1, height=4.0)
regular_frame.write_mesh_to_xlsx(Path("l-shape-geometry.xlsx"))
regular_frame.add_new_elements_for_stairs(infills=False)
regular_frame.show_mesh()
regular_frame.export_mesh_to_html(Path("l-shape-geometry.html"))
Note
remove_lines=True, remove_points=True also deletes grid lines and nodes
that become isolated after the bay is removed. Use remove_lines=False,
remove_points=False when adjacent bays still share those elements and they
should be retained.
Complex geometry with custom elements
Custom lines and points can be added to the mesh after standard operations, enabling geometries that cannot be expressed purely through grid modifications.
from pathlib import Path
from simdesign.rcmrf import StandardGeometry
regular_frame = StandardGeometry(
num_storeys=4,
storey_height=3.0,
num_bays_x=4,
bay_width_x=4.0,
num_bays_y=4,
bay_width_y=4.0,
)
# Remove two bays on storey 1 without deleting shared elements
for grid_ids in [[1, 0, 1], [2, 0, 1]]:
regular_frame.remove_rectangle(
grid_ids, remove_lines=False, remove_points=False
)
# Remove two bays on storeys 1–2 with full cleanup
for grid_ids in [[3, 3, 2], [3, 3, 1]]:
regular_frame.remove_rectangle(
grid_ids, remove_lines=True, remove_points=True
)
# Add a vertical element at a corner that was removed from the grid
grids = regular_frame.system_grid_data
x = grids.x.ord_by_id(4)
y = grids.y.ord_by_id(4)
z_bottom = grids.z.ord_by_id(0)
z_top = grids.z.ord_by_id(3)
pt_bottom = regular_frame.add_new_point([x, y, z_bottom])
pt_top = regular_frame.find_point_by_coordinates([x, y, z_top])
regular_frame.add_new_line([pt_bottom, pt_top])
regular_frame.set_continuous_stairs_rectangles(
stairs_bay_loc=(0, 0), stairs_width_x=2, stairs_width_y=4
)
regular_frame.add_new_elements_for_stairs(infills=False)
regular_frame.modify_floor_height(floor_id=1, height=4.0)
regular_frame.show_mesh()
regular_frame.export_mesh_to_html(Path("complex-geometry.html"))
Loading and modifying geometry from file
A geometry exported with
write_mesh_to_xlsx()
can be reloaded as a CustomGeometry
object, uniformised, and further modified before use in design.
from pathlib import Path
from simdesign.rcmrf import CustomGeometry
custom_frame = CustomGeometry(Path("uniform-geometry.xlsx"))
# Overwrite all bay widths and storey heights with uniform values
custom_frame.uniformise(
bay_width_x=4.0, bay_width_y=4.0, storey_height=3.0
)
# Redefine the staircase location
custom_frame.set_continuous_stairs_rectangles(
stairs_loc=(0, 0), stairs_width_x=2, stairs_width_y=4
)
# Raise the ground floor
custom_frame.modify_floor_height(floor_id=1, height=4.0)
custom_frame.add_new_elements_for_stairs()
custom_frame.show_mesh()
custom_frame.export_mesh_to_html(Path("modified-custom-geometry.html"))
Using custom geometry in design
For a complete example of using a
CustomGeometry or a
StandardGeometry object in the full
BED workflow (BDIM → BNSM → pushover), see
Design.