import streamlit as st import pandas as pd import numpy as np import io # Load steam density CSV @st.cache_data 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", )