wenjun99 commited on
Commit
3edc1f3
·
verified ·
1 Parent(s): 7c4a2b2

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +133 -38
src/streamlit_app.py CHANGED
@@ -1,40 +1,135 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  import streamlit as st
2
+ import numpy as np
3
+
4
+ st.set_page_config(page_title="Tesla-Inspired Valve: Flow Modeling", layout="wide")
5
+
6
+ st.title("Tesla-Inspired Valve: Flow Modeling with Hemolysis Risk Indicator")
7
+ st.markdown("This tool allows you to model your Tesla valve design and estimate its performance, including hemolysis risk and overall efficiency. Adjust the parameters below to find an optimal configuration.")
8
+
9
+ # Constants (fixed)
10
+ rho = 1060 # Density (kg/m³)
11
+ mu = 0.0035 # Viscosity (Pa·s)
12
+ tau_limit = 150 # Pa, Hemolysis shear stress limit
13
+ D_annulus_cm = 3.5 # cm, Mitral valve annulus diameter
14
+
15
+ st.sidebar.title("🔒 Fixed Constants")
16
+ st.sidebar.markdown(f"**Blood Density (ρ):** {rho} kg/m³")
17
+ st.sidebar.markdown(f"**Viscosity (μ):** {mu} Pa·s")
18
+ st.sidebar.markdown(f"**Hemolysis Limit (τ):** {tau_limit} Pa")
19
+ st.sidebar.markdown(f"**Mitral Annulus Diameter:** {D_annulus_cm} cm")
20
+
21
+ # --- User Inputs ---
22
+ st.header("🔬 Design Parameters")
23
+ st.markdown("Adjust these sliders to define your Tesla valve's geometry and performance.")
24
+ col_design1, col_design2, col_design3 = st.columns(3)
25
+ with col_design1:
26
+ num_valves = st.slider("Number of Tesla Valve Units", 1, 100, 10, help="Total number of individual Tesla valve units.")
27
+ with col_design2:
28
+ valve_width_mm = st.slider("Single Valve Width (mm)", 4, 20, 12, help="The width of a single Tesla valve unit's footprint.")
29
+ with col_design3:
30
+ diodicity = st.slider("Diodicity (Di)", 1.0, 50.0, 20.0, help="The ratio of reverse pressure drop to forward pressure drop.")
31
+
32
+ # --- Physiological Parameters ---
33
+ st.header("🩺 Physiological Conditions")
34
+ st.markdown("These values represent typical heart function under which your device must operate.")
35
+ col_phys1, col_phys2 = st.columns(2)
36
+ with col_phys1:
37
+ deltaP_rev_mmHg = st.slider("Max Reverse Pressure (mmHg)", 60, 160, 100, help="The pressure drop across the valve during systole.")
38
+ deltaP_fwd_mmHg = st.slider("Forward Pressure (mmHg)", 2, 20, 5, help="The pressure gradient that drives forward flow (filling).")
39
+ t_rev = st.slider("Systole Time (s)", 0.2, 0.4, 0.3, 0.05, help="Duration of ventricular contraction.")
40
+ with col_phys2:
41
+ V_LV_mL = st.slider("Required Forward Volume (mL)", 50, 100, 70, help="The volume of blood the ventricle needs to fill.")
42
+ HR = st.slider("Heart Rate (BPM)", 50, 120, 70, help="The heart rate in beats per minute.")
43
+
44
+ # --- Calculations ---
45
+ t_fwd = (60 / HR) - t_rev
46
+ deltaP_rev = deltaP_rev_mmHg * 133.322 # Convert mmHg to Pa
47
+ deltaP_fwd = deltaP_fwd_mmHg * 133.322
48
+
49
+ # Calculate maximum possible valve width based on annulus area and valve count
50
+ valve_area_total_cm2 = np.pi * (D_annulus_cm / 2)**2
51
+ valve_width_max_mm = np.sqrt(valve_area_total_cm2 / (num_valves * np.pi)) * 2 * 10
52
+ # Note: This is a simplified calculation, but it provides a good estimate.
53
+
54
+ st.markdown("---")
55
+ st.header("🧮 Results & Analysis")
56
+
57
+ # --- Reverse Flow Calculations ---
58
+ st.subheader("🔁 Reverse Flow (Regurgitation)")
59
+ # We use Diodicity to calculate the reverse flow
60
+ # Assuming a simplified relationship based on the design parameters
61
+ # A_single is the equivalent cross-sectional area of a single valve's channels
62
+ A_valve_cross_section_mm2 = (np.pi * (D_annulus_cm / 2)**2 * 100) / num_valves
63
+ A_single = A_valve_cross_section_mm2 / 1000000
64
+
65
+ # Calculate equivalent pressure drop in forward flow
66
+ deltaP_fwd_equiv = deltaP_rev / diodicity
67
+
68
+ # Estimate reverse velocity based on forward pressure drop and equivalent area
69
+ # Using a simplified orifice flow model for the effective pressure drop
70
+ v_rev = np.sqrt(2 * deltaP_fwd_equiv / rho)
71
+
72
+ Q_rev = A_single * num_valves * v_rev
73
+ V_rev_L = Q_rev * t_rev * 1000
74
+
75
+ # Calculate Regurgitant Fraction (RF)
76
+ RF = (V_rev_L / (V_LV_mL / 1000)) * 100
77
+
78
+ # Hemolysis Risk (Shear Stress)
79
+ # This is a highly simplified model; real CFD is needed.
80
+ # We'll assume shear stress is proportional to velocity and inversely proportional to valve width
81
+ tau = rho * v_rev * v_rev / (valve_width_mm / 1000)
82
+
83
+ rf_status = "✅" if RF < 5 else "❌"
84
+ shear_status = "✅" if tau < tau_limit else "❌"
85
+
86
+ st.write(f"Total Reverse Flow Volume: **{V_rev_L:.2f} L**")
87
+ st.write(f"Regurgitant Fraction (RF): **{RF:.2f}%** {rf_status}")
88
+ st.write(f"Estimated Peak Shear Stress: **{tau:.1f} Pa** {shear_status}")
89
+
90
+ if tau >= tau_limit:
91
+ st.warning(f"**Warning:** The estimated shear stress ({tau:.1f} Pa) exceeds the hemolysis limit of {tau_limit} Pa. This could cause red blood cell damage. Consider increasing the valve width or the number of valves.")
92
+
93
+ # --- Forward Flow Calculations ---
94
+ st.subheader("✅ Forward Flow")
95
+
96
+ v_fwd = np.sqrt(2 * deltaP_fwd / rho)
97
+ Q_fwd = A_single * num_valves * v_fwd
98
+ V_fwd_L = Q_fwd * t_fwd * 1000
99
+
100
+ forward_status = "✅" if V_fwd_L * 1000 >= V_LV_mL else "❌"
101
+ tau_fwd = rho * v_fwd * v_fwd / (valve_width_mm / 1000)
102
+
103
+ st.write(f"Total Forward Flow Volume: **{V_fwd_L * 1000:.2f} mL**")
104
+ st.write(f"Required Volume to Fill: **{V_LV_mL:.2f} mL** {forward_status}")
105
+ st.write(f"Estimated Shear Stress: **{tau_fwd:.1f} Pa**")
106
+ if V_fwd_L * 1000 < V_LV_mL:
107
+ st.warning("The forward flow volume is insufficient. Consider increasing the number of valves or their width to improve heart filling.")
108
+
109
+ st.markdown("---")
110
+ st.subheader("📢 Design Guidance")
111
+ st.write(f"Maximum theoretical width for a single valve unit is **{valve_width_max_mm:.2f} mm** to fit all {num_valves} valves within the annulus.")
112
+ st.write("A good design will have all checkmarks (✅) and minimize the Regurgitant Fraction.")
113
+
114
+ st.markdown("---")
115
+ st.header("📖 Parameter Explanations")
116
+ st.subheader("User Inputs (Design & Physiological)")
117
+ st.markdown("""
118
+ - **Number of Tesla Valve Units:** The total number of individual Tesla valve units that make up the complete valve. More units can improve overall flow but require a smaller footprint for each.
119
+ - **Single Valve Width (mm):** The physical width of a single Tesla valve unit's footprint. This is a crucial design parameter that influences shear stress and manufacturability.
120
+ - **Diodicity (Di):** The primary performance metric for a Tesla valve. It's the ratio of the pressure drop in the reverse direction to the pressure drop in the forward direction. A higher number indicates a more effective valve.
121
+ - **Max Reverse Pressure (mmHg):** The maximum pressure difference between the left ventricle and left atrium during systole, which drives the regurgitant flow.
122
+ - **Forward Pressure (mmHg):** The pressure gradient that drives the flow of blood from the left atrium to the left ventricle during diastole. This should be minimal to ensure proper filling.
123
+ - **Systole Time (s):** The duration of the heart's contraction phase, during which regurgitation can occur.
124
+ - **Required Forward Volume (mL):** The volume of blood the left ventricle needs to receive from the left atrium in a single heartbeat to function effectively.
125
+ - **Heart Rate (BPM):** The number of times the heart beats per minute. This determines the total time for the cardiac cycle.
126
+ """)
127
 
128
+ st.subheader("Outputs (Results & Analysis)")
129
+ st.markdown("""
130
+ - **Total Reverse Flow Volume (L):** The total volume of blood that is estimated to leak back into the left atrium per heartbeat. This is what you want to minimize.
131
+ - **Regurgitant Fraction (RF):** The percentage of the total blood pumped by the heart that leaks backward. A value less than 5% is generally considered non-pathological.
132
+ - **Estimated Peak Shear Stress (Pa):** The estimated maximum shear force on red blood cells within the valve's channels. Values above 150 Pa are a significant hemolysis risk.
133
+ - **Total Forward Flow Volume (mL):** The total volume of blood that is estimated to flow from the left atrium into the left ventricle. This should be sufficient to meet the required forward volume.
134
+ - **Design Guidance:** Provides a maximum theoretical width for your valve units and summarizes the overall health of your design based on the chosen parameters.
135
+ """)