Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| import numpy as np | |
| import io | |
| # Load steam density CSV | |
| def load_density_data(): | |
| return pd.read_csv("steam_density.csv").round() | |
| density_df = load_density_data() | |
| # List of commercially available pipe sizes | |
| commercial_pipes = [15, 20, 25, 40, 50, 65, 80, 100, 125, 150] | |
| def get_nearest_commercial_size(size): | |
| """Find the nearest upper commercially available pipe size.""" | |
| for pipe in commercial_pipes: | |
| if size <= pipe: | |
| return pipe | |
| return "Not Available" # If size exceeds the largest available pipe | |
| # Function to calculate new pipe size | |
| def calculate_new_line_size(flow_kg_hr, pressure_bar, density_df): | |
| pressure_bar_new = round(float(pressure_bar)) | |
| # Interpolate density from CSV data | |
| density = np.interp(pressure_bar_new, density_df["Pressure (bar)"], density_df["Density Saturated (kg/m³)"]) | |
| # Convert flow to kg/s | |
| flow_kg_s = flow_kg_hr / 3600 | |
| # Velocity range for saturated steam | |
| velocity = 30 # Mid-range velocity in m/s | |
| # Calculate required pipe diameter (m) | |
| diameter_m = np.sqrt((4 * flow_kg_s) / (np.pi * velocity * density)) | |
| # Convert to mm | |
| return round(diameter_m * 1000, 1) | |
| # Streamlit UI | |
| st.title("Steam Pipe Line Size Validator") | |
| num_lines = st.number_input("Number of Lines to Validate", min_value=1, step=1) | |
| data = [] | |
| if num_lines: | |
| for i in range(num_lines): | |
| st.subheader(f"Line {i+1}") | |
| name = st.text_input(f"Line {i+1} Name", key=f"name_{i}") | |
| flow = st.number_input(f"Flow (Kg/hr) for Line {i+1}", min_value=1.0, step=0.1, key=f"flow_{i}") | |
| pressure = st.number_input(f"Pressure (bar) for Line {i+1}", min_value=1.0, step=0.1, key=f"pressure_{i}") | |
| present_size = st.number_input(f"Present Line Size (mm) for Line {i+1}", min_value=1.0, step=0.1, key=f"size_{i}") | |
| data.append([name, round(flow), round(pressure), round(present_size)]) | |
| if st.button("Validate All Lines"): | |
| validated_data = [] | |
| for entry in data: | |
| name, flow, pressure, present_size = entry | |
| new_size = calculate_new_line_size(flow, pressure, density_df) | |
| nearest_commercial_size = get_nearest_commercial_size(new_size) | |
| # Allow minor tolerance | |
| tolerance = 5 # ±5 mm | |
| status = "Yes" if abs(new_size - present_size) <= tolerance else "No" | |
| validated_data.append([name, flow, pressure, present_size, new_size, nearest_commercial_size, status]) | |
| df_result = pd.DataFrame(validated_data, columns=[ | |
| "Line Name", "Flow (Kg/hr)", "Pressure (bar)", "Present Size (mm)", | |
| "New Size (mm)", "Commercial Size (mm)", "Valid" | |
| ]) | |
| # Apply styling | |
| def highlight_status(val): | |
| return 'background-color: green; color: white;' if val == "Yes" else 'background-color: red; color: white;' | |
| st.dataframe(df_result.style.applymap(highlight_status, subset=["Valid"])) | |
| # Convert DataFrame to Excel file in-memory | |
| output = io.BytesIO() | |
| with pd.ExcelWriter(output, engine="xlsxwriter") as writer: | |
| df_result.to_excel(writer, index=False, sheet_name="Validated Lines") | |
| # Download button | |
| st.download_button( | |
| "Download Excel File", | |
| data=output.getvalue(), | |
| file_name="validated_steam_lines.xlsx", | |
| mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", | |
| ) | |