-
Notifications
You must be signed in to change notification settings - Fork 0
Bridge
Tianhao Fu edited this page Nov 26, 2025
·
5 revisions
This section is mostly covered in Quick Start.
from bridger import *
cross_section = CIV102Beam()
bridge = BeamBridge(452, cross_section)The codebase inherently supports varying cross-sections. You can pass the cross-section as a function of position into VaryingBeamBridge. The following bridge has a side view as a trapezoid.
from bridger import *
material = Material()
params = {'top': 100.2, 'bottom': 60.7, 'thickness': 1.27, 'outreach': 28}
max_height = 180
min_height = 120
margin = 60
def cross_section(x: float) -> CrossSection:
if x <= margin or x >= 1250 - margin:
return CIV102Beam(**params, height=min_height)
return CIV102Beam(**params, height=max_height - ((max_height - min_height) / (625 + 1.5 * margin)) * abs(
x - 625 - 1.5 * margin))
bridge = VaryingBeamBridge(452, cross_section)
evaluator = Evaluator(bridge, material)
print(evaluator.maximum_load()) # (402.24314942828937, 'shear buckling')This year, the supporting positions are simply the ends. It is highly likely that you have more complicated reaction force positions. To adapt to those, you need to create a new class inheriting from BeamBridge and override only three methods: reaction_forces(), shear_forces(), and expanded_shear_forces().
For example, we can move the right supporting point (r_end) to the center.
from typing import override
import numpy as np
from bridger import BeamBridge
class CustomBridge(BeamBridge):
@override
def reaction_forces(self) -> tuple[float, float]:
r_end = 2 * float((self._wheel_positions * self._loads).sum()) / self._length
return self._train_load - r_end, r_end
@override
def shear_forces(self) -> list[float]:
r_start, r_end = self.reaction_forces()
v = [r_start]
for i, p in enumerate(self._loads):
if len(v) == i + 1 and self._wheel_positions[i] >= .5 * self._length:
v.append(v[-1] + r_end)
v.append(float(v[-1] - p))
return v
@override
def expanded_shear_forces(self, x: np.ndarray) -> np.ndarray:
v = np.zeros_like(x)
v0 = self.shear_forces()
v[:] = v0[0]
positions = list(self._wheel_positions) + [.5 * self._length]
positions.sort()
for i, pos in enumerate(positions):
v[x > pos] = v0[i + 1]
v[x > self._length] = v0[-1]
return vIf you find our work helpful, please cite our design report.
@techreport{team602civ102,
title = {CIV102 Bridge Project Design Report},
author = {Chan, D. and Zhou, J. and Saxena, N. and Fu, T.},
institution = {Faculty of Applied Science and Engineering, University of Toronto},
year = {2025},
month = {November},
type = {Course Project Report},
course = {CIV102: Structures and Materials},
note = {Team 602}
}