File size: 9,132 Bytes
0be7e4d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext
from continuous_beam import ContinuousBeam
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np

class BeamDesignApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Continuous Beam RC Design - ACI Code")
        self.root.geometry("1200x800")
        
        self.beam = ContinuousBeam()
        self.setup_ui()
        
    def setup_ui(self):
        # Create main frame
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # Configure grid weights
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        main_frame.rowconfigure(3, weight=1)
        
        # Title
        title_label = ttk.Label(main_frame, text="Continuous Beam RC Design", 
                               font=('Arial', 16, 'bold'))
        title_label.grid(row=0, column=0, columnspan=2, pady=(0, 20))
        
        # Input frame
        input_frame = ttk.LabelFrame(main_frame, text="Beam Properties", padding="10")
        input_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # Beam properties
        ttk.Label(input_frame, text="Beam Width (mm):").grid(row=0, column=0, sticky=tk.W)
        self.width_var = tk.StringVar(value="300")
        ttk.Entry(input_frame, textvariable=self.width_var, width=10).grid(row=0, column=1, sticky=tk.W, padx=(5, 20))
        
        ttk.Label(input_frame, text="Beam Depth (mm):").grid(row=0, column=2, sticky=tk.W)
        self.depth_var = tk.StringVar(value="500")
        ttk.Entry(input_frame, textvariable=self.depth_var, width=10).grid(row=0, column=3, sticky=tk.W, padx=(5, 20))
        
        ttk.Label(input_frame, text="f'c (MPa):").grid(row=1, column=0, sticky=tk.W)
        self.fc_var = tk.StringVar(value="28")
        ttk.Entry(input_frame, textvariable=self.fc_var, width=10).grid(row=1, column=1, sticky=tk.W, padx=(5, 20))
        
        ttk.Label(input_frame, text="fy (MPa):").grid(row=1, column=2, sticky=tk.W)
        self.fy_var = tk.StringVar(value="420")
        ttk.Entry(input_frame, textvariable=self.fy_var, width=10).grid(row=1, column=3, sticky=tk.W, padx=(5, 20))
        
        ttk.Label(input_frame, text="Cover (mm):").grid(row=2, column=0, sticky=tk.W)
        self.cover_var = tk.StringVar(value="40")
        ttk.Entry(input_frame, textvariable=self.cover_var, width=10).grid(row=2, column=1, sticky=tk.W, padx=(5, 20))
        
        # Spans frame
        spans_frame = ttk.LabelFrame(main_frame, text="Spans Configuration", padding="10")
        spans_frame.grid(row=2, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # Span input
        ttk.Label(spans_frame, text="Span Length (m):").grid(row=0, column=0, sticky=tk.W)
        self.span_length_var = tk.StringVar(value="6.0")
        ttk.Entry(spans_frame, textvariable=self.span_length_var, width=10).grid(row=0, column=1, sticky=tk.W, padx=(5, 20))
        
        ttk.Label(spans_frame, text="Distributed Load (kN/m):").grid(row=0, column=2, sticky=tk.W)
        self.load_var = tk.StringVar(value="25.0")
        ttk.Entry(spans_frame, textvariable=self.load_var, width=10).grid(row=0, column=3, sticky=tk.W, padx=(5, 20))
        
        # Buttons
        button_frame = ttk.Frame(spans_frame)
        button_frame.grid(row=1, column=0, columnspan=4, pady=10)
        
        ttk.Button(button_frame, text="Add Span", command=self.add_span).pack(side=tk.LEFT, padx=(0, 10))
        ttk.Button(button_frame, text="Clear All", command=self.clear_spans).pack(side=tk.LEFT, padx=(0, 10))
        ttk.Button(button_frame, text="Design Beam", command=self.design_beam).pack(side=tk.LEFT, padx=(0, 10))
        
        # Spans list
        self.spans_listbox = tk.Listbox(spans_frame, height=4)
        self.spans_listbox.grid(row=2, column=0, columnspan=4, sticky=(tk.W, tk.E), pady=(10, 0))
        spans_frame.columnconfigure(0, weight=1)
        spans_frame.columnconfigure(1, weight=1)
        spans_frame.columnconfigure(2, weight=1)
        spans_frame.columnconfigure(3, weight=1)
        
        # Results frame
        results_frame = ttk.LabelFrame(main_frame, text="Design Results", padding="10")
        results_frame.grid(row=3, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S))
        results_frame.columnconfigure(0, weight=1)
        results_frame.rowconfigure(0, weight=1)
        
        # Results text area
        self.results_text = scrolledtext.ScrolledText(results_frame, width=80, height=20, font=('Courier', 9))
        self.results_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
    def add_span(self):
        try:
            length = float(self.span_length_var.get())
            load = float(self.load_var.get())
            
            if length <= 0 or load < 0:
                messagebox.showerror("Error", "Please enter valid values (length > 0, load >= 0)")
                return
            
            self.beam.add_span(length, load)
            
            # Update spans list
            span_text = f"Span {len(self.beam.spans)}: L={length}m, w={load}kN/m"
            self.spans_listbox.insert(tk.END, span_text)
            
            # Clear input fields
            self.span_length_var.set("")
            self.load_var.set("")
            
        except ValueError:
            messagebox.showerror("Error", "Please enter valid numeric values")
    
    def clear_spans(self):
        self.beam = ContinuousBeam()
        self.spans_listbox.delete(0, tk.END)
        self.results_text.delete('1.0', tk.END)
    
    def design_beam(self):
        if not self.beam.spans:
            messagebox.showwarning("Warning", "Please add at least one span")
            return
        
        try:
            # Update beam properties
            self.beam.beam_width = float(self.width_var.get())
            self.beam.beam_depth = float(self.depth_var.get())
            self.beam.fc = float(self.fc_var.get())
            self.beam.fy = float(self.fy_var.get())
            self.beam.cover = float(self.cover_var.get())
            self.beam.d = self.beam.beam_depth - self.beam.cover
            
            # Perform design
            design_results = self.beam.design_beam()
            
            # Generate and display report
            report = self.beam.generate_report(design_results)
            
            self.results_text.delete('1.0', tk.END)
            self.results_text.insert('1.0', report)
            
            # Show summary dialog
            self.show_summary(design_results)
            
        except Exception as e:
            messagebox.showerror("Error", f"Design calculation failed: {str(e)}")
    
    def show_summary(self, design_results):
        """Show design summary in a popup window"""
        summary_window = tk.Toplevel(self.root)
        summary_window.title("Design Summary")
        summary_window.geometry("600x400")
        
        # Create treeview for summary
        tree = ttk.Treeview(summary_window, columns=('Span', 'Location', 'Moment', 'Reinforcement', 'Shear', 'Stirrups'))
        tree.heading('#0', text='', anchor='w')
        tree.heading('Span', text='Span')
        tree.heading('Location', text='Location')
        tree.heading('Moment', text='Moment (kN-m)')
        tree.heading('Reinforcement', text='Reinforcement')
        tree.heading('Shear', text='Shear (kN)')
        tree.heading('Stirrups', text='Stirrups')
        
        tree.column('#0', width=0, stretch=False)
        tree.column('Span', width=60)
        tree.column('Location', width=100)
        tree.column('Moment', width=100)
        tree.column('Reinforcement', width=120)
        tree.column('Shear', width=80)
        tree.column('Stirrups', width=120)
        
        for span_data in design_results:
            span_num = span_data['span']
            for i, (reinf, stirrup) in enumerate(zip(span_data['reinforcement'], span_data['stirrups'])):
                if reinf['moment'] != 0 or stirrup['shear'] != 0:
                    tree.insert('', 'end', values=(
                        span_num if i == 0 else '',
                        reinf['location'],
                        f"{reinf['moment']:.2f}" if reinf['moment'] != 0 else '-',
                        reinf['bars'] if reinf['moment'] != 0 else '-',
                        f"{stirrup['shear']:.2f}" if stirrup['shear'] != 0 else '-',
                        stirrup['stirrup_spacing'] if stirrup['shear'] != 0 else '-'
                    ))
        
        tree.pack(expand=True, fill='both', padx=10, pady=10)
        
        # Close button
        ttk.Button(summary_window, text="Close", 
                  command=summary_window.destroy).pack(pady=10)

def main():
    root = tk.Tk()
    app = BeamDesignApp(root)
    root.mainloop()

if __name__ == "__main__":
    main()