manaskhan commited on
Commit
2984c2b
·
verified ·
1 Parent(s): cbfcd35

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -209
app.py DELETED
@@ -1,209 +0,0 @@
1
- import streamlit as st
2
- import pandas as pd
3
- from fpdf import FPDF
4
- import io
5
- import openai
6
-
7
- # ========== PAGE CONFIG ==========
8
- st.set_page_config(page_title="ASME Calculator", layout="wide")
9
-
10
- # App Title + Description
11
- st.markdown("<h1 style='text-align: center;'>🛠️ ASME CALCULATOR</h1>", unsafe_allow_html=True)
12
- st.markdown(
13
- "<p style='text-align: center;'>This tool calculates <b>required thicknesses, nozzle reinforcement, "
14
- "PWHT, and impact test requirements</b><br>using ASME Section VIII Division 1 formulas.</p>",
15
- unsafe_allow_html=True
16
- )
17
-
18
- # ========== API CLIENT ==========
19
- if "OPENAI_API_KEY" in st.secrets:
20
- openai.api_key = st.secrets["OPENAI_API_KEY"]
21
- else:
22
- openai.api_key = None
23
-
24
- # ========== PDF GENERATOR ==========
25
- class PDF(FPDF):
26
- def __init__(self):
27
- super().__init__()
28
- self.add_page()
29
- self.set_font("Helvetica", "", 12)
30
-
31
- def header(self):
32
- self.set_font("Helvetica", "B", 14)
33
- self.cell(0, 10, "ASME VIII Div.1 Vessel Design Report", 0, 1, "C")
34
-
35
- def chapter_title(self, title):
36
- self.set_font("Helvetica", "B", 12)
37
- self.cell(0, 10, title, 0, 1, "L")
38
-
39
- def chapter_body(self, body):
40
- self.set_font("Helvetica", "", 11)
41
- self.multi_cell(0, 8, body)
42
-
43
- # ========== CALCULATION FUNCTIONS ==========
44
- def shell_thickness(P, D, S, E, corrosion):
45
- R = D / 2 # convert diameter to radius
46
- return (P * R) / (S * E - 0.6 * P) + corrosion
47
-
48
- def head_thickness(P, D, S, E, corrosion, head_type):
49
- R = D / 2
50
- if head_type == "Ellipsoidal": # UG-32
51
- return (0.5 * P * R) / (S * E - 0.1 * P) + corrosion
52
- elif head_type == "Torispherical": # Approx formula
53
- return (0.885 * P * R) / (S * E - 0.1 * P) + corrosion
54
- elif head_type == "Hemispherical": # UG-32
55
- return (P * R) / (2 * S * E - 0.2 * P) + corrosion
56
- return None
57
-
58
- def nozzle_reinforcement(P, d, t_shell, t_nozzle, S, E):
59
- return (P * d) / (2 * S * E) <= (t_shell + t_nozzle)
60
-
61
- def pwht_required(thickness, material="CS"):
62
- return material == "CS" and thickness > 38
63
-
64
- def impact_test_required(thickness, MDMT=-20, material="CS"):
65
- return material == "CS" and (MDMT < -29 and thickness > 12)
66
-
67
- # ========== SESSION STATE ==========
68
- if "run_done" not in st.session_state:
69
- st.session_state.run_done = False
70
- if "ai_done" not in st.session_state:
71
- st.session_state.ai_done = False
72
-
73
- # ========== SIDEBAR INPUTS ==========
74
- with st.sidebar.expander("📥 Manual Design Inputs", expanded=True):
75
- input_mode = st.radio("Input Mode:", ["Manual Entry", "Upload CSV"])
76
- run_calculation = False
77
-
78
- if input_mode == "Manual Entry":
79
- P = st.number_input("Design Pressure (MPa)", value=2.0, format="%.2f")
80
- D = st.number_input("Internal Diameter (mm)", value=2000.0, format="%.1f")
81
- S = st.number_input("Allowable Stress (MPa)", value=120.0, format="%.1f")
82
- corrosion = st.number_input("Corrosion Allowance (mm)", value=1.5, format="%.2f")
83
-
84
- joint_method = st.radio("Joint Efficiency Selection", ["Preset (UW-12)", "Manual Entry"])
85
- if joint_method == "Preset (UW-12)":
86
- E = st.selectbox("Select E (Joint Efficiency)", [1.0, 0.85, 0.7, 0.65, 0.6, 0.45])
87
- else:
88
- E = st.number_input("Manual Joint Efficiency (0-1)", value=0.85, min_value=0.1, max_value=1.0)
89
-
90
- head_type = st.selectbox("Head Type", ["Ellipsoidal", "Torispherical", "Hemispherical"])
91
- d_nozzle = st.number_input("Nozzle Diameter (mm)", value=200.0, format="%.1f")
92
- t_shell = st.number_input("Shell Thickness Provided (mm)", value=12.0, format="%.1f")
93
- t_nozzle = st.number_input("Nozzle Thickness Provided (mm)", value=10.0, format="%.1f")
94
- thickness = st.number_input("Governing Thickness (mm)", value=40.0, format="%.1f")
95
- MDMT = st.number_input("MDMT (°C)", value=-20.0, format="%.1f")
96
-
97
- if st.button("🚀 Run Calculation", use_container_width=True):
98
- st.session_state.run_done = True
99
- run_calculation = True
100
-
101
- if st.session_state.run_done:
102
- st.success("✅ Calculations completed! See results in the tabs.")
103
-
104
- else:
105
- uploaded_file = st.file_uploader("Upload CSV File", type=["csv"])
106
- if uploaded_file:
107
- df = pd.read_csv(uploaded_file)
108
- st.dataframe(df.head())
109
- if st.button("🚀 Run Calculation", use_container_width=True):
110
- st.session_state.run_done = True
111
- run_calculation = True
112
-
113
- if st.session_state.run_done:
114
- st.success("✅ Calculations completed! See results in the tabs.")
115
-
116
- # ========== TABS ==========
117
- tabs = st.tabs(["Shell", "Head", "Nozzle", "PWHT", "Impact Test", "Summary", "AI Explanation"])
118
-
119
- if st.session_state.run_done:
120
- # --- SHELL TAB ---
121
- with tabs[0]:
122
- t_shell_calc = shell_thickness(P, D, S, E, corrosion)
123
- st.metric("Required Shell Thickness (mm) [UG-27]", f"{t_shell_calc:.2f}")
124
-
125
- # --- HEAD TAB ---
126
- with tabs[1]:
127
- t_head_calc = head_thickness(P, D, S, E, corrosion, head_type)
128
- st.metric(f"Required {head_type} Head Thickness (mm) [UG-32]", f"{t_head_calc:.2f}")
129
-
130
- # --- NOZZLE TAB ---
131
- with tabs[2]:
132
- safe_nozzle = nozzle_reinforcement(P, d_nozzle, t_shell, t_nozzle, S, E)
133
- st.write("Nozzle Reinforcement Check [UG-37]:", "✅ Safe" if safe_nozzle else "❌ Not Safe")
134
-
135
- # --- PWHT TAB ---
136
- with tabs[3]:
137
- st.write("PWHT Required:", "✅ Yes" if pwht_required(thickness) else "❌ No")
138
-
139
- # --- IMPACT TEST TAB ---
140
- with tabs[4]:
141
- st.write("Impact Test Required:", "✅ Yes" if impact_test_required(thickness, MDMT) else "❌ No")
142
-
143
- # --- SUMMARY TAB ---
144
- with tabs[5]:
145
- summary_data = {
146
- "Shell Thickness (UG-27)": round(t_shell_calc, 2),
147
- "Head Thickness (UG-32)": round(t_head_calc, 2),
148
- "Nozzle Safe (UG-37)": safe_nozzle,
149
- "PWHT Required": pwht_required(thickness),
150
- "Impact Test Required": impact_test_required(thickness, MDMT),
151
- }
152
- df_summary = pd.DataFrame([summary_data])
153
- st.dataframe(df_summary)
154
-
155
- # CSV export
156
- csv = df_summary.to_csv(index=False).encode("utf-8")
157
- st.download_button("📥 Download Results (CSV)", csv, "results.csv")
158
-
159
- # PDF export
160
- pdf = PDF()
161
- pdf.chapter_title("Calculation Summary")
162
- for k, v in summary_data.items():
163
- pdf.chapter_body(f"{k}: {v}")
164
- pdf_bytes = pdf.output(dest="S").encode("latin1")
165
- st.download_button("📄 Download PDF Report", pdf_bytes, "results.pdf", "application/pdf")
166
-
167
- # --- AI EXPLANATION TAB ---
168
- with tabs[6]:
169
- st.markdown("### 🤖 Ask AI for Explanation")
170
- if not openai.api_key:
171
- st.warning("⚠️ Add your OpenAI API key in Streamlit secrets to enable AI explanations.")
172
- else:
173
- if st.button("✨ Ask AI", use_container_width=True):
174
- st.session_state.ai_done = True
175
- with st.spinner("AI is preparing explanation..."):
176
- prompt = f"Explain these ASME vessel design results in simple terms: {summary_data}"
177
-
178
- try:
179
- chat_completion = openai.ChatCompletion.create(
180
- model="gpt-4o-mini",
181
- messages=[
182
- {"role": "system", "content": "You are an ASME design expert who explains results clearly."},
183
- {"role": "user", "content": prompt}
184
- ],
185
- temperature=0.3
186
- )
187
- explanation = chat_completion["choices"][0]["message"]["content"]
188
- st.success("✅ AI Explanation Generated Below")
189
- st.write(explanation)
190
-
191
- except Exception as e:
192
- st.error(f"⚠️ Error generating AI explanation: {e}")
193
-
194
- if st.session_state.ai_done:
195
- st.info("✨ AI explanation already generated. Rerun to refresh.")
196
-
197
- else:
198
- # Placeholders
199
- for i, msg in enumerate([
200
- "Shell results", "Head results", "Nozzle results",
201
- "PWHT decision", "Impact Test decision",
202
- "Summary", "AI explanation"
203
- ]):
204
- with tabs[i]:
205
- st.info(f"Run calculation to see {msg}.")
206
-
207
- # ========== FOOTER ==========
208
- st.markdown("---")
209
- st.caption("Disclaimer: This tool is for demo/educational purposes. Final design must be verified by a qualified engineer per ASME VIII Div.1.")