Spaces:
Sleeping
Sleeping
Upload 7 files
Browse files- README.md +51 -8
- app.py +37 -10
- continuous_beam.py +31 -3
- example_design.py +103 -0
- test_design.py +54 -0
README.md
CHANGED
|
@@ -1,14 +1,57 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version:
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
-
license: mit
|
| 11 |
-
short_description: RC beam design
|
| 12 |
---
|
| 13 |
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: "Continuous Beam RC Design"
|
| 3 |
+
emoji: "🏗️"
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
sdk: gradio
|
| 7 |
+
sdk_version: "4.0.0"
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
|
|
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
+
# Continuous Beam RC Design App
|
| 13 |
+
|
| 14 |
+
A comprehensive continuous beam reinforced concrete design application using finite element analysis and ACI code provisions.
|
| 15 |
+
|
| 16 |
+
## Features
|
| 17 |
+
|
| 18 |
+
- **Finite Element Analysis**: Accurate structural analysis for up to 10 spans
|
| 19 |
+
- **ACI Code Compliance**: Reinforcement design according to ACI 318
|
| 20 |
+
- **Multiple Loading Types**:
|
| 21 |
+
- Distributed loads (kN/m)
|
| 22 |
+
- Point loads (kN)
|
| 23 |
+
- Mixed loading patterns
|
| 24 |
+
- **Comprehensive Results**:
|
| 25 |
+
- Bending Moment Diagrams (BMD)
|
| 26 |
+
- Shear Force Diagrams (SFD)
|
| 27 |
+
- Reinforcement layout
|
| 28 |
+
- Stirrup spacing details
|
| 29 |
+
- **Professional Output**: Detailed design reports and visual diagrams
|
| 30 |
+
|
| 31 |
+
## Usage
|
| 32 |
+
|
| 33 |
+
1. **Set Beam Properties**: Width, depth, concrete strength (f'c), steel strength (fy), cover
|
| 34 |
+
2. **Add Spans**: Enter span length and distributed load
|
| 35 |
+
3. **Add Point Loads** (optional): Use format `position,load; position,load`
|
| 36 |
+
- Example: `2.0,50; 4.0,30` means 50kN at 2m and 30kN at 4m
|
| 37 |
+
4. **Design Beam**: Get complete analysis and design results
|
| 38 |
+
|
| 39 |
+
## Technical Details
|
| 40 |
+
|
| 41 |
+
- **Analysis Method**: Finite Element Method with beam elements
|
| 42 |
+
- **Design Code**: ACI 318 (American Concrete Institute)
|
| 43 |
+
- **Capacity**: Up to 10 continuous spans
|
| 44 |
+
- **Load Types**: Distributed and concentrated loads
|
| 45 |
+
- **Output**: Moments, shears, reinforcement, stirrups
|
| 46 |
+
|
| 47 |
+
## Built With
|
| 48 |
+
|
| 49 |
+
- **Python**: Core calculations and finite element analysis
|
| 50 |
+
- **Gradio**: Web interface
|
| 51 |
+
- **NumPy**: Numerical computations
|
| 52 |
+
- **Matplotlib**: Plotting and visualization
|
| 53 |
+
- **Pandas**: Data handling
|
| 54 |
+
|
| 55 |
+
---
|
| 56 |
+
|
| 57 |
+
*Using advanced finite element analysis for accurate continuous beam behavior*
|
app.py
CHANGED
|
@@ -5,6 +5,13 @@ import matplotlib.pyplot as plt
|
|
| 5 |
import numpy as np
|
| 6 |
import io
|
| 7 |
import base64
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
|
| 9 |
class GradioBeamApp:
|
| 10 |
def __init__(self):
|
|
@@ -80,6 +87,10 @@ class GradioBeamApp:
|
|
| 80 |
return "No spans added. Please add at least one span.", None, None, None, None, None
|
| 81 |
|
| 82 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
# Update beam properties
|
| 84 |
self.beam.beam_width = float(width)
|
| 85 |
self.beam.beam_depth = float(depth)
|
|
@@ -88,7 +99,7 @@ class GradioBeamApp:
|
|
| 88 |
self.beam.cover = float(cover)
|
| 89 |
self.beam.d = self.beam.beam_depth - self.beam.cover
|
| 90 |
|
| 91 |
-
# Perform design
|
| 92 |
design_results = self.beam.design_beam()
|
| 93 |
|
| 94 |
# Generate report
|
|
@@ -114,15 +125,27 @@ class GradioBeamApp:
|
|
| 114 |
'Span', 'Location', 'Moment (kN-m)', 'Reinforcement', 'Shear (kN)', 'Stirrups'
|
| 115 |
])
|
| 116 |
|
| 117 |
-
# Generate plots
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
return report, df, bmd_sfd_plot, reinforcement_plot, stirrup_plot, "Design completed successfully!"
|
| 123 |
|
| 124 |
except Exception as e:
|
| 125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 126 |
|
| 127 |
def create_interface():
|
| 128 |
app = GradioBeamApp()
|
|
@@ -223,11 +246,15 @@ def create_interface():
|
|
| 223 |
|
| 224 |
def main():
|
| 225 |
interface = create_interface()
|
|
|
|
| 226 |
interface.launch(
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
|
|
|
|
|
|
|
|
|
| 231 |
)
|
| 232 |
|
| 233 |
if __name__ == "__main__":
|
|
|
|
| 5 |
import numpy as np
|
| 6 |
import io
|
| 7 |
import base64
|
| 8 |
+
import gc # Garbage collection for memory management
|
| 9 |
+
import warnings
|
| 10 |
+
warnings.filterwarnings('ignore') # Suppress warnings for cleaner output
|
| 11 |
+
|
| 12 |
+
# Configure matplotlib for cloud deployment
|
| 13 |
+
plt.style.use('default') # Use simple style
|
| 14 |
+
plt.rcParams['figure.max_open_warning'] = 0 # Disable figure warnings
|
| 15 |
|
| 16 |
class GradioBeamApp:
|
| 17 |
def __init__(self):
|
|
|
|
| 87 |
return "No spans added. Please add at least one span.", None, None, None, None, None
|
| 88 |
|
| 89 |
try:
|
| 90 |
+
# Limit spans for cloud deployment
|
| 91 |
+
if len(self.beam.spans) > 10:
|
| 92 |
+
return "Error: Maximum 10 spans allowed for cloud deployment.", None, None, None, None, "Error: Too many spans"
|
| 93 |
+
|
| 94 |
# Update beam properties
|
| 95 |
self.beam.beam_width = float(width)
|
| 96 |
self.beam.beam_depth = float(depth)
|
|
|
|
| 99 |
self.beam.cover = float(cover)
|
| 100 |
self.beam.d = self.beam.beam_depth - self.beam.cover
|
| 101 |
|
| 102 |
+
# Perform design with timeout protection
|
| 103 |
design_results = self.beam.design_beam()
|
| 104 |
|
| 105 |
# Generate report
|
|
|
|
| 125 |
'Span', 'Location', 'Moment (kN-m)', 'Reinforcement', 'Shear (kN)', 'Stirrups'
|
| 126 |
])
|
| 127 |
|
| 128 |
+
# Generate plots with error handling
|
| 129 |
+
try:
|
| 130 |
+
bmd_sfd_plot = self.beam.plot_bmd_sfd(design_results)
|
| 131 |
+
reinforcement_plot = self.beam.plot_reinforcement_layout(design_results)
|
| 132 |
+
stirrup_plot = self.beam.plot_stirrup_layout(design_results)
|
| 133 |
+
except Exception as plot_error:
|
| 134 |
+
print(f"Plotting error: {plot_error}")
|
| 135 |
+
# Return simplified results if plotting fails
|
| 136 |
+
return report, df, None, None, None, "Design completed (plots unavailable)"
|
| 137 |
+
|
| 138 |
+
# Force garbage collection to free memory
|
| 139 |
+
gc.collect()
|
| 140 |
|
| 141 |
return report, df, bmd_sfd_plot, reinforcement_plot, stirrup_plot, "Design completed successfully!"
|
| 142 |
|
| 143 |
except Exception as e:
|
| 144 |
+
gc.collect() # Clean up memory on error
|
| 145 |
+
error_msg = str(e)
|
| 146 |
+
if "memory" in error_msg.lower() or "allocation" in error_msg.lower():
|
| 147 |
+
return "Error: Insufficient memory. Try reducing the number of spans or load complexity.", None, None, None, None, "Memory Error"
|
| 148 |
+
return f"Design calculation failed: {error_msg}", None, None, None, None, f"Error: {error_msg}"
|
| 149 |
|
| 150 |
def create_interface():
|
| 151 |
app = GradioBeamApp()
|
|
|
|
| 246 |
|
| 247 |
def main():
|
| 248 |
interface = create_interface()
|
| 249 |
+
# Optimized for Hugging Face Spaces
|
| 250 |
interface.launch(
|
| 251 |
+
share=False,
|
| 252 |
+
debug=False, # Disable debug for production
|
| 253 |
+
show_error=True,
|
| 254 |
+
quiet=True, # Reduce console output
|
| 255 |
+
ssr_mode=False, # Disable SSR for compatibility
|
| 256 |
+
auth=None, # No authentication required
|
| 257 |
+
max_threads=10 # Limit concurrent threads
|
| 258 |
)
|
| 259 |
|
| 260 |
if __name__ == "__main__":
|
continuous_beam.py
CHANGED
|
@@ -1,8 +1,15 @@
|
|
| 1 |
import numpy as np
|
|
|
|
|
|
|
| 2 |
import matplotlib.pyplot as plt
|
| 3 |
from typing import List, Dict, Tuple
|
| 4 |
import math
|
| 5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
class ContinuousBeam:
|
| 7 |
"""
|
| 8 |
Continuous beam analysis and RC design according to ACI code
|
|
@@ -106,8 +113,10 @@ class ContinuousBeam:
|
|
| 106 |
h = self.beam_depth / 1000 # Convert mm to m
|
| 107 |
I = b * h**3 / 12 # m^4
|
| 108 |
|
| 109 |
-
# Create mesh -
|
| 110 |
-
|
|
|
|
|
|
|
| 111 |
total_elements = len(self.spans) * elements_per_span
|
| 112 |
total_nodes = total_elements + 1
|
| 113 |
|
|
@@ -253,7 +262,8 @@ class ContinuousBeam:
|
|
| 253 |
theta2 = self.displacements[2*node2+1] # rotation at node 2
|
| 254 |
|
| 255 |
# Calculate forces at multiple points within element
|
| 256 |
-
|
|
|
|
| 257 |
for i in range(n_points):
|
| 258 |
xi = i / (n_points - 1) # 0 to 1
|
| 259 |
x_local = xi * element_length
|
|
@@ -769,6 +779,12 @@ class ContinuousBeam:
|
|
| 769 |
ax2.plot(pos, 0, 'rs', markersize=8, label='Support' if pos == span_positions[0] else "")
|
| 770 |
|
| 771 |
plt.tight_layout()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 772 |
return fig
|
| 773 |
|
| 774 |
def plot_reinforcement_layout(self, design_results=None):
|
|
@@ -918,6 +934,12 @@ class ContinuousBeam:
|
|
| 918 |
ax.legend(handles=legend_elements, loc='upper right')
|
| 919 |
|
| 920 |
plt.tight_layout()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 921 |
return fig
|
| 922 |
|
| 923 |
def plot_stirrup_layout(self, design_results=None):
|
|
@@ -1033,4 +1055,10 @@ class ContinuousBeam:
|
|
| 1033 |
ax.legend(handles=legend_elements, loc='upper right')
|
| 1034 |
|
| 1035 |
plt.tight_layout()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1036 |
return fig
|
|
|
|
| 1 |
import numpy as np
|
| 2 |
+
import matplotlib
|
| 3 |
+
matplotlib.use('Agg') # Use non-interactive backend for cloud deployment
|
| 4 |
import matplotlib.pyplot as plt
|
| 5 |
from typing import List, Dict, Tuple
|
| 6 |
import math
|
| 7 |
|
| 8 |
+
# Configure matplotlib for cloud deployment
|
| 9 |
+
plt.ioff() # Turn off interactive mode
|
| 10 |
+
plt.rcParams['figure.dpi'] = 80 # Lower DPI for faster rendering
|
| 11 |
+
plt.rcParams['savefig.dpi'] = 80
|
| 12 |
+
|
| 13 |
class ContinuousBeam:
|
| 14 |
"""
|
| 15 |
Continuous beam analysis and RC design according to ACI code
|
|
|
|
| 113 |
h = self.beam_depth / 1000 # Convert mm to m
|
| 114 |
I = b * h**3 / 12 # m^4
|
| 115 |
|
| 116 |
+
# Create mesh - optimize for cloud deployment
|
| 117 |
+
# Reduce elements per span for better performance on limited resources
|
| 118 |
+
max_elements_per_span = min(8, max(4, int(40 / len(self.spans)))) # Scale down for many spans
|
| 119 |
+
elements_per_span = max_elements_per_span
|
| 120 |
total_elements = len(self.spans) * elements_per_span
|
| 121 |
total_nodes = total_elements + 1
|
| 122 |
|
|
|
|
| 262 |
theta2 = self.displacements[2*node2+1] # rotation at node 2
|
| 263 |
|
| 264 |
# Calculate forces at multiple points within element
|
| 265 |
+
# Reduce points for cloud deployment performance
|
| 266 |
+
n_points = 5 # Reduced from 10 to 5
|
| 267 |
for i in range(n_points):
|
| 268 |
xi = i / (n_points - 1) # 0 to 1
|
| 269 |
x_local = xi * element_length
|
|
|
|
| 779 |
ax2.plot(pos, 0, 'rs', markersize=8, label='Support' if pos == span_positions[0] else "")
|
| 780 |
|
| 781 |
plt.tight_layout()
|
| 782 |
+
|
| 783 |
+
# Close any other open figures to free memory
|
| 784 |
+
for i in plt.get_fignums():
|
| 785 |
+
if i != fig.number:
|
| 786 |
+
plt.close(i)
|
| 787 |
+
|
| 788 |
return fig
|
| 789 |
|
| 790 |
def plot_reinforcement_layout(self, design_results=None):
|
|
|
|
| 934 |
ax.legend(handles=legend_elements, loc='upper right')
|
| 935 |
|
| 936 |
plt.tight_layout()
|
| 937 |
+
|
| 938 |
+
# Close any other open figures to free memory
|
| 939 |
+
for i in plt.get_fignums():
|
| 940 |
+
if i != fig.number:
|
| 941 |
+
plt.close(i)
|
| 942 |
+
|
| 943 |
return fig
|
| 944 |
|
| 945 |
def plot_stirrup_layout(self, design_results=None):
|
|
|
|
| 1055 |
ax.legend(handles=legend_elements, loc='upper right')
|
| 1056 |
|
| 1057 |
plt.tight_layout()
|
| 1058 |
+
|
| 1059 |
+
# Close any other open figures to free memory
|
| 1060 |
+
for i in plt.get_fignums():
|
| 1061 |
+
if i != fig.number:
|
| 1062 |
+
plt.close(i)
|
| 1063 |
+
|
| 1064 |
return fig
|
example_design.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Example usage of the Continuous Beam RC Design application
|
| 4 |
+
This script demonstrates how to use the ContinuousBeam class programmatically
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from continuous_beam import ContinuousBeam
|
| 8 |
+
|
| 9 |
+
def example_design():
|
| 10 |
+
"""
|
| 11 |
+
Example: Design a 3-span continuous beam
|
| 12 |
+
"""
|
| 13 |
+
print("Continuous Beam RC Design Example")
|
| 14 |
+
print("="*50)
|
| 15 |
+
|
| 16 |
+
# Create beam instance
|
| 17 |
+
beam = ContinuousBeam()
|
| 18 |
+
|
| 19 |
+
# Set beam properties
|
| 20 |
+
beam.beam_width = 300 # mm
|
| 21 |
+
beam.beam_depth = 500 # mm
|
| 22 |
+
beam.fc = 28 # MPa
|
| 23 |
+
beam.fy = 420 # MPa
|
| 24 |
+
beam.cover = 40 # mm
|
| 25 |
+
beam.d = beam.beam_depth - beam.cover
|
| 26 |
+
|
| 27 |
+
print(f"Beam dimensions: {beam.beam_width} × {beam.beam_depth} mm")
|
| 28 |
+
print(f"Material properties: f'c = {beam.fc} MPa, fy = {beam.fy} MPa")
|
| 29 |
+
print(f"Effective depth: {beam.d} mm")
|
| 30 |
+
print()
|
| 31 |
+
|
| 32 |
+
# Add spans
|
| 33 |
+
beam.add_span(length=6.0, distributed_load=25.0) # Span 1: 6m, 25 kN/m
|
| 34 |
+
beam.add_span(length=8.0, distributed_load=30.0) # Span 2: 8m, 30 kN/m
|
| 35 |
+
beam.add_span(length=5.0, distributed_load=20.0) # Span 3: 5m, 20 kN/m
|
| 36 |
+
|
| 37 |
+
print("Spans added:")
|
| 38 |
+
for i, span in enumerate(beam.spans):
|
| 39 |
+
print(f" Span {i+1}: Length = {span['length']}m, Load = {span['distributed_load']} kN/m")
|
| 40 |
+
print()
|
| 41 |
+
|
| 42 |
+
# Perform design
|
| 43 |
+
try:
|
| 44 |
+
design_results = beam.design_beam()
|
| 45 |
+
|
| 46 |
+
# Generate report
|
| 47 |
+
report = beam.generate_report(design_results)
|
| 48 |
+
print(report)
|
| 49 |
+
|
| 50 |
+
# Additional analysis
|
| 51 |
+
print("\n" + "="*60)
|
| 52 |
+
print("DESIGN SUMMARY")
|
| 53 |
+
print("="*60)
|
| 54 |
+
|
| 55 |
+
total_steel = 0
|
| 56 |
+
max_moment = 0
|
| 57 |
+
max_shear = 0
|
| 58 |
+
|
| 59 |
+
for span_data in design_results:
|
| 60 |
+
span_num = span_data['span']
|
| 61 |
+
print(f"\nSpan {span_num} ({span_data['length']}m):")
|
| 62 |
+
|
| 63 |
+
for reinf in span_data['reinforcement']:
|
| 64 |
+
if reinf['As_required'] > 0:
|
| 65 |
+
total_steel += reinf['As_provided']
|
| 66 |
+
if abs(reinf['moment']) > abs(max_moment):
|
| 67 |
+
max_moment = reinf['moment']
|
| 68 |
+
print(f" {reinf['location']}: {reinf['bars']} (As = {reinf['As_provided']:.0f} mm²)")
|
| 69 |
+
|
| 70 |
+
for stirrup in span_data['stirrups']:
|
| 71 |
+
if stirrup['shear'] != 0 and abs(stirrup['shear']) > abs(max_shear):
|
| 72 |
+
max_shear = stirrup['shear']
|
| 73 |
+
|
| 74 |
+
print(f"\nOverall Summary:")
|
| 75 |
+
print(f" Total steel area: {total_steel:.0f} mm²")
|
| 76 |
+
print(f" Maximum moment: {max_moment:.2f} kN-m")
|
| 77 |
+
print(f" Maximum shear: {max_shear:.2f} kN")
|
| 78 |
+
print(f" Steel ratio: {total_steel/(beam.beam_width * beam.d * len(beam.spans))*100:.2f}%")
|
| 79 |
+
|
| 80 |
+
except Exception as e:
|
| 81 |
+
print(f"Design failed: {e}")
|
| 82 |
+
|
| 83 |
+
def run_gui():
|
| 84 |
+
"""
|
| 85 |
+
Launch the GUI application
|
| 86 |
+
"""
|
| 87 |
+
try:
|
| 88 |
+
from beam_design_app import main
|
| 89 |
+
print("Launching GUI application...")
|
| 90 |
+
main()
|
| 91 |
+
except ImportError as e:
|
| 92 |
+
print(f"GUI application not available: {e}")
|
| 93 |
+
print("Please install tkinter and matplotlib to use the GUI")
|
| 94 |
+
|
| 95 |
+
if __name__ == "__main__":
|
| 96 |
+
# Run example design
|
| 97 |
+
example_design()
|
| 98 |
+
|
| 99 |
+
# Ask user if they want to launch GUI
|
| 100 |
+
print("\n" + "="*60)
|
| 101 |
+
response = input("Would you like to launch the GUI application? (y/n): ").lower().strip()
|
| 102 |
+
if response in ['y', 'yes']:
|
| 103 |
+
run_gui()
|
test_design.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Test script for the Continuous Beam RC Design application
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
from continuous_beam import ContinuousBeam
|
| 7 |
+
|
| 8 |
+
def test_single_span():
|
| 9 |
+
"""Test single span beam"""
|
| 10 |
+
print("Testing Single Span Beam")
|
| 11 |
+
print("-" * 30)
|
| 12 |
+
|
| 13 |
+
beam = ContinuousBeam()
|
| 14 |
+
beam.add_span(length=8.0, distributed_load=30.0)
|
| 15 |
+
|
| 16 |
+
design_results = beam.design_beam()
|
| 17 |
+
report = beam.generate_report(design_results)
|
| 18 |
+
print(report)
|
| 19 |
+
|
| 20 |
+
def test_two_span():
|
| 21 |
+
"""Test two span continuous beam"""
|
| 22 |
+
print("\nTesting Two Span Continuous Beam")
|
| 23 |
+
print("-" * 35)
|
| 24 |
+
|
| 25 |
+
beam = ContinuousBeam()
|
| 26 |
+
beam.add_span(length=6.0, distributed_load=25.0)
|
| 27 |
+
beam.add_span(length=8.0, distributed_load=30.0)
|
| 28 |
+
|
| 29 |
+
design_results = beam.design_beam()
|
| 30 |
+
report = beam.generate_report(design_results)
|
| 31 |
+
print(report)
|
| 32 |
+
|
| 33 |
+
def test_custom_materials():
|
| 34 |
+
"""Test with custom material properties"""
|
| 35 |
+
print("\nTesting Custom Material Properties")
|
| 36 |
+
print("-" * 35)
|
| 37 |
+
|
| 38 |
+
beam = ContinuousBeam()
|
| 39 |
+
beam.fc = 35 # Higher strength concrete
|
| 40 |
+
beam.fy = 500 # Higher strength steel
|
| 41 |
+
beam.beam_width = 400
|
| 42 |
+
beam.beam_depth = 600
|
| 43 |
+
beam.d = beam.beam_depth - beam.cover
|
| 44 |
+
|
| 45 |
+
beam.add_span(length=10.0, distributed_load=40.0)
|
| 46 |
+
|
| 47 |
+
design_results = beam.design_beam()
|
| 48 |
+
report = beam.generate_report(design_results)
|
| 49 |
+
print(report)
|
| 50 |
+
|
| 51 |
+
if __name__ == "__main__":
|
| 52 |
+
test_single_span()
|
| 53 |
+
test_two_span()
|
| 54 |
+
test_custom_materials()
|