Sompote commited on
Commit
376535d
·
verified ·
1 Parent(s): 57e625a

Upload 7 files

Browse files
Files changed (2) hide show
  1. README.md +4 -4
  2. 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: 5.34.2
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
- rho = (0.85 * fc / fy) * (1 - math.sqrt(1 - 2 * Rn / (0.85 * fc)))
 
 
 
 
 
 
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
- bar_areas = {
617
- 12: 113, # DB12: π×(12/2)² = 113 mm²
618
- 16: 201, # DB16: π×(16/2)² = 201 mm²
619
- 20: 314, # DB20: π×(20/2)² = 314 mm²
620
- 24: 452, # DB24: π×(24/2)² = 452 mm²
621
- 32: 804 # DB32: π×(32/2)² = 804 mm²
622
  }
623
 
624
- # Try different bar sizes
625
- for bar_size, bar_area in bar_areas.items():
 
 
 
 
 
 
 
 
 
626
  num_bars = math.ceil(As_required / bar_area)
627
- if num_bars <= 8: # Practical limit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
628
  As_provided = num_bars * bar_area
 
629
  break
630
- else:
631
- # Use largest bars if can't fit
 
632
  bar_size = 32
633
- bar_area = 804
634
- num_bars = math.ceil(As_required / bar_area)
 
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