Spaces:
Sleeping
Sleeping
Upload 7 files
Browse files- README.md +4 -4
- continuous_beam.py +76 -15
README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
---
|
| 2 |
-
title: Continuous Beam RC Design - Thai Standards
|
| 3 |
-
emoji: 🏗️
|
| 4 |
colorFrom: blue
|
| 5 |
colorTo: green
|
| 6 |
sdk: gradio
|
| 7 |
-
sdk_version:
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
---
|
|
@@ -57,4 +57,4 @@ A comprehensive continuous beam reinforced concrete design application using fin
|
|
| 57 |
|
| 58 |
---
|
| 59 |
|
| 60 |
-
*Using advanced finite element analysis for accurate continuous beam behavior*
|
|
|
|
| 1 |
---
|
| 2 |
+
title: "Continuous Beam RC Design - Thai Standards"
|
| 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 |
---
|
|
|
|
| 57 |
|
| 58 |
---
|
| 59 |
|
| 60 |
+
*Using advanced finite element analysis for accurate continuous beam behavior*
|
continuous_beam.py
CHANGED
|
@@ -496,7 +496,13 @@ class ContinuousBeam:
|
|
| 496 |
Rn = Mu / (phi * b * d**2)
|
| 497 |
|
| 498 |
# Calculate reinforcement ratio
|
| 499 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 500 |
|
| 501 |
# Minimum reinforcement ratio
|
| 502 |
rho_min = max(1.4 / fy, 0.25 * math.sqrt(fc) / fy)
|
|
@@ -612,27 +618,79 @@ class ContinuousBeam:
|
|
| 612 |
if moment != 0:
|
| 613 |
As_required = self.calculate_required_reinforcement(moment)
|
| 614 |
|
| 615 |
-
# Select reinforcement bars - Thai DB bars
|
| 616 |
-
|
| 617 |
-
12: 113,
|
| 618 |
-
16: 201,
|
| 619 |
-
20: 314,
|
| 620 |
-
24: 452,
|
| 621 |
-
32: 804
|
| 622 |
}
|
| 623 |
|
| 624 |
-
#
|
| 625 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 626 |
num_bars = math.ceil(As_required / bar_area)
|
| 627 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 628 |
As_provided = num_bars * bar_area
|
|
|
|
| 629 |
break
|
| 630 |
-
|
| 631 |
-
|
|
|
|
| 632 |
bar_size = 32
|
| 633 |
-
bar_area =
|
| 634 |
-
|
|
|
|
| 635 |
As_provided = num_bars * bar_area
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 636 |
|
| 637 |
reinforcement = {
|
| 638 |
'location': moment_locations[j],
|
|
@@ -640,6 +698,7 @@ class ContinuousBeam:
|
|
| 640 |
'As_required': As_required,
|
| 641 |
'As_provided': As_provided,
|
| 642 |
'bars': f"{num_bars}-DB{bar_size}",
|
|
|
|
| 643 |
'ratio': As_provided / (self.beam_width * self.d) * 100
|
| 644 |
}
|
| 645 |
else:
|
|
@@ -649,6 +708,7 @@ class ContinuousBeam:
|
|
| 649 |
'As_required': 0,
|
| 650 |
'As_provided': 0,
|
| 651 |
'bars': "No reinforcement",
|
|
|
|
| 652 |
'ratio': 0
|
| 653 |
}
|
| 654 |
|
|
@@ -692,6 +752,7 @@ class ContinuousBeam:
|
|
| 692 |
report.append(f" As required: {reinf['As_required']:.0f} mm²")
|
| 693 |
report.append(f" As provided: {reinf['As_provided']:.0f} mm²")
|
| 694 |
report.append(f" Reinforcement: {reinf['bars']}")
|
|
|
|
| 695 |
report.append(f" Reinforcement ratio: {reinf['ratio']:.2f}%")
|
| 696 |
report.append("")
|
| 697 |
|
|
|
|
| 496 |
Rn = Mu / (phi * b * d**2)
|
| 497 |
|
| 498 |
# Calculate reinforcement ratio
|
| 499 |
+
# Check for domain error in sqrt
|
| 500 |
+
discriminant = 1 - 2 * Rn / (0.85 * fc)
|
| 501 |
+
if discriminant < 0:
|
| 502 |
+
# Moment exceeds capacity - increase beam size or use compression reinforcement
|
| 503 |
+
raise ValueError(f"Moment exceeds beam capacity. Increase beam size or use compression reinforcement.")
|
| 504 |
+
|
| 505 |
+
rho = (0.85 * fc / fy) * (1 - math.sqrt(discriminant))
|
| 506 |
|
| 507 |
# Minimum reinforcement ratio
|
| 508 |
rho_min = max(1.4 / fy, 0.25 * math.sqrt(fc) / fy)
|
|
|
|
| 618 |
if moment != 0:
|
| 619 |
As_required = self.calculate_required_reinforcement(moment)
|
| 620 |
|
| 621 |
+
# Select reinforcement bars - Thai DB bars with spacing check
|
| 622 |
+
bar_data = {
|
| 623 |
+
12: {'area': 113, 'diameter': 12}, # DB12
|
| 624 |
+
16: {'area': 201, 'diameter': 16}, # DB16
|
| 625 |
+
20: {'area': 314, 'diameter': 20}, # DB20
|
| 626 |
+
24: {'area': 452, 'diameter': 24}, # DB24
|
| 627 |
+
32: {'area': 804, 'diameter': 32} # DB32
|
| 628 |
}
|
| 629 |
|
| 630 |
+
# Calculate minimum spacing requirements
|
| 631 |
+
cover = self.cover
|
| 632 |
+
stirrup_dia = 9 # Assume RB9 stirrups
|
| 633 |
+
|
| 634 |
+
# Try different bar sizes with spacing check
|
| 635 |
+
selected = False
|
| 636 |
+
for bar_size in sorted(bar_data.keys()):
|
| 637 |
+
bar_info = bar_data[bar_size]
|
| 638 |
+
bar_area = bar_info['area']
|
| 639 |
+
bar_diameter = bar_info['diameter']
|
| 640 |
+
|
| 641 |
num_bars = math.ceil(As_required / bar_area)
|
| 642 |
+
|
| 643 |
+
# Check practical limits
|
| 644 |
+
if num_bars > 8: # Too many bars
|
| 645 |
+
continue
|
| 646 |
+
|
| 647 |
+
if num_bars < 2: # Minimum 2 bars
|
| 648 |
+
num_bars = 2
|
| 649 |
+
|
| 650 |
+
# Calculate required spacing
|
| 651 |
+
# Available width = beam_width - 2×cover - 2×stirrup_dia
|
| 652 |
+
available_width = self.beam_width - 2*cover - 2*stirrup_dia
|
| 653 |
+
|
| 654 |
+
# Required spacing = (available_width - num_bars×bar_diameter) / (num_bars-1)
|
| 655 |
+
if num_bars > 1:
|
| 656 |
+
required_spacing = (available_width - num_bars * bar_diameter) / (num_bars - 1)
|
| 657 |
+
else:
|
| 658 |
+
required_spacing = available_width # Single bar case
|
| 659 |
+
|
| 660 |
+
# Minimum spacing = max(25mm, bar_diameter, aggregate_size)
|
| 661 |
+
# Use conservative 25mm minimum
|
| 662 |
+
min_spacing = max(25, bar_diameter)
|
| 663 |
+
|
| 664 |
+
# Check if spacing is adequate
|
| 665 |
+
if required_spacing >= min_spacing:
|
| 666 |
As_provided = num_bars * bar_area
|
| 667 |
+
selected = True
|
| 668 |
break
|
| 669 |
+
|
| 670 |
+
if not selected:
|
| 671 |
+
# If no bar size works, use largest bars and warn
|
| 672 |
bar_size = 32
|
| 673 |
+
bar_area = bar_data[32]['area']
|
| 674 |
+
bar_diameter = bar_data[32]['diameter']
|
| 675 |
+
num_bars = max(2, math.ceil(As_required / bar_area))
|
| 676 |
As_provided = num_bars * bar_area
|
| 677 |
+
|
| 678 |
+
# Calculate actual spacing for warning
|
| 679 |
+
available_width = self.beam_width - 2*cover - 2*stirrup_dia
|
| 680 |
+
if num_bars > 1:
|
| 681 |
+
actual_spacing = (available_width - num_bars * bar_diameter) / (num_bars - 1)
|
| 682 |
+
else:
|
| 683 |
+
actual_spacing = available_width
|
| 684 |
+
|
| 685 |
+
if actual_spacing < 25:
|
| 686 |
+
print(f"Warning: Tight bar spacing ({actual_spacing:.1f}mm) at {moment_locations[j]}. Consider increasing beam width.")
|
| 687 |
+
|
| 688 |
+
# Calculate final spacing for display
|
| 689 |
+
available_width = self.beam_width - 2*cover - 2*stirrup_dia
|
| 690 |
+
if num_bars > 1:
|
| 691 |
+
final_spacing = (available_width - num_bars * bar_diameter) / (num_bars - 1)
|
| 692 |
+
else:
|
| 693 |
+
final_spacing = available_width
|
| 694 |
|
| 695 |
reinforcement = {
|
| 696 |
'location': moment_locations[j],
|
|
|
|
| 698 |
'As_required': As_required,
|
| 699 |
'As_provided': As_provided,
|
| 700 |
'bars': f"{num_bars}-DB{bar_size}",
|
| 701 |
+
'spacing': f"{final_spacing:.0f}mm",
|
| 702 |
'ratio': As_provided / (self.beam_width * self.d) * 100
|
| 703 |
}
|
| 704 |
else:
|
|
|
|
| 708 |
'As_required': 0,
|
| 709 |
'As_provided': 0,
|
| 710 |
'bars': "No reinforcement",
|
| 711 |
+
'spacing': "N/A",
|
| 712 |
'ratio': 0
|
| 713 |
}
|
| 714 |
|
|
|
|
| 752 |
report.append(f" As required: {reinf['As_required']:.0f} mm²")
|
| 753 |
report.append(f" As provided: {reinf['As_provided']:.0f} mm²")
|
| 754 |
report.append(f" Reinforcement: {reinf['bars']}")
|
| 755 |
+
report.append(f" Bar spacing: {reinf['spacing']}")
|
| 756 |
report.append(f" Reinforcement ratio: {reinf['ratio']:.2f}%")
|
| 757 |
report.append("")
|
| 758 |
|