inverse_design_demo / thermoforming.py
gangli71's picture
Upload thermoforming.py
93e020b unverified
Raw
History Blame Contribute Delete
13.4 kB
#######################
# Import libraries
import streamlit as st
import pandas as pd
import altair as alt
import plotly.express as px
from PIL import Image # Used to open and handle image files
import matplotlib.pyplot as plt
import numpy as np
#######################
# Page configuration
st.set_page_config(
page_title="Inverse Design of Thermoplastic Composites for Thermoforming",
# page_icon="🏂",
layout="wide",
initial_sidebar_state="collapsed")
alt.themes.enable('default')
#######################
# CSS styling
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,
)
#######################
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 'forming_input_changed' not in st.session_state:
st.session_state.forming_input_changed= False
def forming_typed_in():
st.session_state.forming_input_changed= True
if 'input_curve_button_clicked' not in st.session_state:
st.session_state.input_curve_button_clicked= False
def input_curve_click():
st.session_state.input_curve_button_clicked = True
if 'material_design_button_clicked' not in st.session_state:
st.session_state.material_design_button_clicked= False
def material_design_click():
st.session_state.material_design_button_clicked = True
if 'forming_input_button_clicked' not in st.session_state:
st.session_state.forming_input_button_clicked= False
def forming_input_click():
st.session_state.forming_input_button_clicked = True
if 'forming_design_button_clicked' not in st.session_state:
st.session_state.forming_design_button_clicked= False
def forming_design_click():
st.session_state.forming_design_button_clicked = True
#######################
# Load data
#df_reshaped = pd.read_csv('data/us-population-2010-2019-reshaped.csv')
######## Initialize data #############
E1aV=0 # initial longitudinal stiffness
E1bV=0 # 10% strain longitudinal stiffness
G12aV=0 # initial longitudinal stiffness
G12bV=0 # 10% strain longitudinal stiffness
nlayers=4
vf=0.5
angle=30
#######################
# Main Panel
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 Thermoforming")
st.write("")
st.write("")
st.write("")
st.write(r"$\textsf{\textbf{\Large Material Design Requirements}}$")
#st.text_input(r"$\textsf{\textbf{\Large Material Design Requirements}}$")
# First row with 3 columns
col1_row1, col2_row1, col3_row1 = st.columns([0.3,0.3,0.3])
with col1_row1:
with st.container(border=False): # Container with a border
E1aV= st.number_input("Initial tensile stiffness (MPa):", format="%.2f", width=250, key="E1a", on_change=input_typed_in)
E1bV= st.number_input("10% tensile stiffness (MPa):", format="%.2f", width=250, key="E1b", on_change=input_typed_in)
with col2_row1:
with st.container(border=False): # Container with a border
G12aV= st.number_input("Initial shear stiffness (MPa):", format="%.2f", width=250, key="G12a", on_change=input_typed_in)
G12bV= st.number_input("0.1 shear strain stiffness (MPa):", format="%.2f", width=250, key="G12b", on_change=input_typed_in)
with col3_row1:
with st.container(border=False): # Container with a border
EratioV= st.number_input("Anisotropicity (Ex/Ey):", format="%.2f", width=250, key="Eratio", on_change=input_typed_in)
st.write("")
if st.session_state.input_changed == True:
st.session_state.input_curve_button_clicked = False
st.session_state.material_design_button_clicked = False
st.session_state.forming_input_button_clicked = False
st.session_state.forming_design_button_clicked = False
st.session_state.input_changed = False
st.button("Generate required stress-strain curves", width=400, on_click=input_curve_click)
if st.session_state.input_curve_button_clicked == True:
#st.write(E1aV)
#st.write(E1bV)
x = np.linspace(0, 0.1, 20)
y1 = E1aV*x + (E1bV-E1aV)/0.2*x*x
y2 = G12aV*x + (G12bV-G12aV)/0.2*x*x
y3 = y1/EratioV
ylimit=np.max([np.max(y1),np.max(y2), np.max(y3)])
# 2nd row with 3 columns
col1_row2, col2_row2, col3_row2, col4_row2= st.columns([0.25,0.25,0.25,0.25])
with col1_row2:
with st.container(border=False): # Container with a border
fig, ax = plt.subplots()
ax.plot(x, y1)
ax.set_ylim([0, ylimit])
ax.set_xlabel('Stress (MPa)')
ax.set_ylabel('Strain')
ax.set_title('Longitudinal stress-strain')
st.pyplot(fig)
with col2_row2:
with st.container(border=False): # Container with a border
fig, ax = plt.subplots()
ax.plot(x, y2)
ax.set_ylim([0, ylimit])
ax.set_xlabel('Stress (MPa)')
ax.set_ylabel('Strain')
ax.set_title('Shear stress-strain')
st.pyplot(fig)
with col3_row2:
with st.container(border=False): # Container with a border
fig, ax = plt.subplots()
ax.plot(x, y3)
ax.set_ylim([0, ylimit])
ax.set_xlabel('Stress (MPa)')
ax.set_ylabel('Strain')
ax.set_title('Shear stress-strain')
st.pyplot(fig)
st.write("")
st.button("Material Inverse Design", width=400, on_click=material_design_click)
if st.session_state.material_design_button_clicked == True:
#st.write("")
# 3rd row with 3 columns
col1_row3, col2_row3, col3_row3, col4_row3, col5_row3= st.columns([0.15,0.15,0.23,0.23,0.23])
with col1_row3:
with st.container(border=False): # Container with a border
st.write("Number of layers=", nlayers)
st.write("Volume fraction=", vf)
with col2_row3:
with st.container(border=False): # Container with a border
df = pd.DataFrame({'Ply': [], 'Orientation': []})
plies = np.array([[1,90], [2,45], [3,-45], [4,-90]])
plies_df=pd.DataFrame(plies, columns=df.columns)
df = pd.concat([df, plies_df], ignore_index=True)
st.dataframe(df, hide_index=True)
with col3_row3:
with st.container(border=False): # Container with a border
image = Image.open('figures/material_res3.png')
new_image = image.resize((250, 200))
st.image(new_image, caption='')
with col4_row3:
with st.container(border=False): # Container with a border
image = Image.open('figures/material_res3.png')
new_image = image.resize((250, 200))
st.image(new_image, caption='')
with col5_row3:
with st.container(border=False): # Container with a border
image = Image.open('figures/material_res3.png')
new_image = image.resize((250, 200))
st.image(new_image, caption='')
st.write("")
st.button("Thermoforming Requirements", width=400, on_click=forming_input_click)
if st.session_state.forming_input_button_clicked == True:
#st.write("")
# 4th row with 3 columns
col1_row4, col2_row4, col3_row4, col4_row4, col5_row4 = st.columns([0.16,0.16,0.2,0.24,0.24])
with col1_row4:
with st.container(border=False): # Container with a border
st.write("Number of layers=", nlayers)
st.write("Volume fraction=", vf)
st.write("Fiber orientation=", angle)
with col2_row4:
with st.container(border=False): # Container with a border
df = pd.DataFrame({'Ply': [], 'Orientation': []})
plies = np.array([[1,90], [2,45], [3,-45], [4,-90]])
plies_df=pd.DataFrame(plies, columns=df.columns)
df = pd.concat([df, plies_df], ignore_index=True)
st.dataframe(df, hide_index=True)
with col3_row4:
with st.container(border=False): # Container with a border
image = Image.open('figures/forming_angle.png')
new_image = image.resize((250, 200))
st.image(new_image, caption='')
with col4_row4:
with st.container(border=False): # Container with a border
angleA= st.number_input("Maximum warpage angle A (degree):", format="%.2f", width=300, key="A", on_change=forming_typed_in)
angleB= st.number_input("Maximum warpage angle B (degree):", format="%.2f", width=300, key="B", on_change=forming_typed_in)
with col5_row4:
with st.container(border=False): # Container with a border
angleC= st.number_input("Maximum warpage angle C (degree):", format="%.2f", width=300, key="C", on_change=forming_typed_in)
max_stress= st.number_input("Maximum residual stress (MPa):", format="%.2f", width=300, key="max_stress", on_change=forming_typed_in)
st.write("")
if st.session_state.forming_input_changed == True:
st.session_state.forming_design_button_clicked = False
st.session_state.forming_input_changed = False
st.button("Thermoforming process design", width=400, on_click=forming_design_click)
if st.session_state.forming_design_button_clicked == True:
# 5th row with 3 columns
col1_row5, col2_row5,col3_row5 = st.columns([0.25,0.25,0.25])
with col1_row5:
with st.container(border=False): # Container with a border
st.write("Forming temperature (C)=", nlayers)
with col2_row5:
with st.container(border=False): # Container with a border
st.write("Punching velocity (mm/s)=", nlayers)
with col3_row5:
with st.container(border=False): # Container with a border
st.write("Cooling time (s)=", nlayers)