|
|
|
|
|
|
|
|
import streamlit as st |
|
|
import pandas as pd |
|
|
import altair as alt |
|
|
|
|
|
from PIL import Image |
|
|
import matplotlib |
|
|
import matplotlib.pyplot as plt |
|
|
import numpy as np |
|
|
|
|
|
from model_inverse import inverse_design |
|
|
|
|
|
|
|
|
|
|
|
st.set_page_config( |
|
|
page_title="Inverse Design of Thermoplastic Composites for Thermoforming", |
|
|
|
|
|
layout="wide", |
|
|
initial_sidebar_state="collapsed") |
|
|
|
|
|
alt.themes.enable('default') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
/* Target the input element within its container (adjust class name as needed via browser inspection) */ |
|
|
.stTextInput input { |
|
|
border: 1px solid #333333; /* Set border width, style, and color */ |
|
|
border-radius: 6px; /* Optional: adds rounded corners */ |
|
|
padding: 10px; /* Optional: adds inner spacing */ |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
|
|
|
[data-testid="block-container"] { |
|
|
padding-left: 2rem; |
|
|
padding-right: 2rem; |
|
|
padding-top: 1rem; |
|
|
padding-bottom: 0rem; |
|
|
margin-bottom: -7rem; |
|
|
} |
|
|
|
|
|
[data-testid="stVerticalBlock"] { |
|
|
padding-left: 0rem; |
|
|
padding-right: 0rem; |
|
|
} |
|
|
|
|
|
[data-testid="stMetric"] { |
|
|
background-color: #393939; |
|
|
text-align: center; |
|
|
padding: 15px 0; |
|
|
} |
|
|
|
|
|
[data-testid="stMetricLabel"] { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
} |
|
|
|
|
|
[data-testid="stMetricDeltaIcon-Up"] { |
|
|
position: relative; |
|
|
left: 38%; |
|
|
-webkit-transform: translateX(-50%); |
|
|
-ms-transform: translateX(-50%); |
|
|
transform: translateX(-50%); |
|
|
} |
|
|
|
|
|
[data-testid="stMetricDeltaIcon-Down"] { |
|
|
position: relative; |
|
|
left: 38%; |
|
|
-webkit-transform: translateX(-50%); |
|
|
-ms-transform: translateX(-50%); |
|
|
transform: translateX(-50%); |
|
|
} |
|
|
|
|
|
/* Main app + sidebar, target the label element itself */ |
|
|
[data-testid="stAppViewContainer"] label, |
|
|
[data-testid="stWidgetLabel"] label { |
|
|
font-size: 18px !important; |
|
|
font-weight: 600 !important; /* optional */ |
|
|
color: #444 !important; /* optional */ |
|
|
} |
|
|
|
|
|
/* Some versions wrap label text inside a <div><p> */ |
|
|
[data-testid="stAppViewContainer"] label > div > p, |
|
|
[data-testid="stWidgetLabel"] label > div > p { |
|
|
font-size: 18px !important; |
|
|
font-weight: 600 !important; |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
div.stButton > button:first-child { |
|
|
background-color: #ee7700; /* background */ |
|
|
color: white; /* White text */ |
|
|
font-size: 20px; |
|
|
border-radius: 10px; |
|
|
# display: block; # this line and the next center the button horizontally |
|
|
# margin: 0 auto; |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
div[data-testid="stVirtualDropdown"] > div { |
|
|
max-height: 10px !important; /* Adjust this value as needed */ |
|
|
overflow-y: auto; |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
st.set_page_config(initial_sidebar_state="collapsed") |
|
|
|
|
|
st.markdown( |
|
|
""" |
|
|
<style> |
|
|
[data-testid="collapsedControl"] { |
|
|
display: none |
|
|
} |
|
|
</style> |
|
|
""", |
|
|
unsafe_allow_html=True, |
|
|
) |
|
|
|
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
/* Target all table cells and headers */ |
|
|
table, th, td { |
|
|
border: 2px solid #333333; /* Change to your desired color */ |
|
|
border-collapse: collapse; /* Ensure borders touch */ |
|
|
} |
|
|
/* Optional: adjust padding */ |
|
|
th, td { |
|
|
padding: 8px; |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
st.markdown(""" |
|
|
<style> |
|
|
/* Targets the table headers */ |
|
|
.stDataFrame table th { |
|
|
font-size: 26px; |
|
|
} |
|
|
/* Targets the table data cells */ |
|
|
.stDataFrame table td { |
|
|
font-size: 24px; |
|
|
} |
|
|
</style> |
|
|
""", unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
font = {'size' : 18} |
|
|
|
|
|
matplotlib.rc('font', **font) |
|
|
|
|
|
|
|
|
if 'input_changed' not in st.session_state: |
|
|
st.session_state.input_changed= False |
|
|
def input_typed_in(): |
|
|
st.session_state.input_changed= True |
|
|
|
|
|
if 'AM_input_changed' not in st.session_state: |
|
|
st.session_state.AM_input_changed= False |
|
|
def AM_typed_in(): |
|
|
st.session_state.AM_input_changed= True |
|
|
|
|
|
|
|
|
|
|
|
if 'AM_input_button_clicked' not in st.session_state: |
|
|
st.session_state.AM_input_button_clicked= False |
|
|
def AM_input_click(): |
|
|
st.session_state.AM_input_button_clicked = True |
|
|
|
|
|
if 'AM_design_button_clicked' not in st.session_state: |
|
|
st.session_state.AM_design_button_clicked= False |
|
|
def AM_design_click(): |
|
|
st.session_state.AM_design_button_clicked = True |
|
|
|
|
|
|
|
|
def style_dataframe_borders(df): |
|
|
return df.style.set_table_styles([ |
|
|
{'selector': 'td, th', 'props': [('border', '2px solid #000000')]} |
|
|
]) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nlayers=4 |
|
|
vf=0.5 |
|
|
angle=30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
data_materials={ |
|
|
'Matrix':['ABS','Polyurethane','Nylon 6','Nylon 6','Nylon 66','PE','PP'], |
|
|
'Filler':['Carbon Black','Glass Fiber','Glass Fiber','Carbon Fiber','Glass Fiber','Carbon Fiber','Glass Fiber'], |
|
|
'VF':['15%','20%','20%','40%','30%','20%','30%'], |
|
|
'Feature':['Blend','Extruded','Molded','Molded','Molded','Molded','Molded'] |
|
|
} |
|
|
|
|
|
data_physical = { |
|
|
'Forming T (C)': ['180', '185', '190'], |
|
|
'Punch V (m/s)': ['1.05', '1.8','1.67'], |
|
|
'Cooling time (s)': ['45','80','120'], |
|
|
'Holding force (kN)': ['23','24','25'] |
|
|
} |
|
|
|
|
|
st.title("Inverse Design of Thermoplastic Composites for Injection Molding") |
|
|
st.write("") |
|
|
st.write("") |
|
|
st.write("") |
|
|
|
|
|
st.write("") |
|
|
st.write(r"$\textsf{\textbf{\Large Injection Molding Requirements}}$") |
|
|
|
|
|
col1_row1, col2_row1, col3_row1, col4_row1 = st.columns([0.25,0.25,0.15,0.25]) |
|
|
with col1_row1: |
|
|
with st.container(border=False): |
|
|
angleA= st.number_input("Maximum warpage angle A (degree):", format="%.2f", width=300, value=1.0, key="A", on_change=AM_typed_in) |
|
|
angleB= st.number_input("Maximum warpage angle B (degree):", format="%.2f", width=300, value=1.0, key="B", on_change=AM_typed_in) |
|
|
|
|
|
with col2_row1: |
|
|
with st.container(border=False): |
|
|
angleC= st.number_input("Maximum warpage angle C (degree):", format="%.2f", width=300, value=1.0, key="C", on_change=AM_typed_in) |
|
|
max_stress= st.number_input("Maximum residual stress (MPa):", format="%.2f", width=300, value=100.0, key="max_stress", on_change=AM_typed_in) |
|
|
|
|
|
with col3_row1: |
|
|
with st.container(border=False): |
|
|
image = Image.open('figures/image001.png') |
|
|
new_image = image.resize((150, 200)) |
|
|
st.image(new_image, caption='') |
|
|
|
|
|
with col4_row1: |
|
|
with st.container(border=False): |
|
|
image = Image.open('figures/Hat_Section_AM2.png') |
|
|
new_image = image.resize((350, 200)) |
|
|
st.image(new_image, caption='') |
|
|
|
|
|
|
|
|
st.write("") |
|
|
if st.session_state.AM_input_changed == True: |
|
|
st.session_state.AM_design_button_clicked = False |
|
|
st.session_state.AM_input_changed = False |
|
|
|
|
|
st.button("Injection molding process design", on_click=AM_design_click) |
|
|
if st.session_state.AM_design_button_clicked == True: |
|
|
st.write("Process parameters") |
|
|
data1 = pd.DataFrame({ |
|
|
'Matrix material': ['PP'], |
|
|
'Fiber material': ['Glass'], |
|
|
'Fiber volume fraction (%)': [10], |
|
|
'Gate location': [1] |
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
styles = [ |
|
|
dict(selector="th", props=[('font-size', '14px')]), |
|
|
dict(selector="td", props=[('font-size', '12px')]) |
|
|
] |
|
|
styled_df = style_dataframe_borders(data1) |
|
|
|
|
|
st.dataframe(data1, hide_index=True, width=600) |
|
|
|
|
|
best = inverse_design(gate_loc=1, matrix='PP', fiber='GF', fiber_vf=0.1, y_target=np.array([angleA, angleB, angleC]), n_restarts=5, epochs=100, use_lbfgs=True) |
|
|
|
|
|
data2 = pd.DataFrame({ |
|
|
'Packing pressure (MPa)': [best["input"][0]], |
|
|
'Packing time (s)': [best["input"][1]], |
|
|
'Mold temperature (C)': [best["input"][2]], |
|
|
'Injection speed (cm^3/s)': [best["input"][3]] |
|
|
}) |
|
|
st.dataframe(data2, hide_index=True, width=600) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|