| | |
| | |
| | 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_fdm 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 Additive Manufacturing") |
| | st.write("") |
| | st.write("") |
| | st.write("") |
| |
|
| | st.write("") |
| | st.write(r"$\textsf{\textbf{\Large Additive Manufacturing Requirements}}$") |
| |
|
| | col1_row1, col2_row1, col3_row1, col4_row1 = st.columns([0.25,0.25,0.25,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/Hat_Section_AM1.png') |
| | new_image = image.resize((350, 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("AM process design", use_container_width=True, 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'], |
| | 'Build direction': ['Vertical']}) |
| | |
| | y_target = np.array([angleA, angleB, angleC, max_stress]) |
| | best = inverse_design(material_base="PP", fiber="GF", fiber_vf=45.0, |
| | y_target=y_target, n_restarts=20, epochs=100, use_lbfgs=True) |
| | |
| | |
| | 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=500) |
| | |
| | data2 = pd.DataFrame({ |
| | 'Nozzel velocity (cm/s)': [best['input'][0]], |
| | 'Extruder temperature (C)': [best['input'][1]], |
| | 'Bed temperature (C)': [best['input'][2]]}) |
| | st.dataframe(data2, hide_index=True, width=500) |
| | |
| | data3 = pd.DataFrame({ |
| | 'Maximum angle A (degree)': [best['output'][0]], |
| | 'Maximum angle B (degree)': [best['output'][1]], |
| | 'Maximum angle C (degree)': [best['output'][2]], |
| | 'Maximum residual stress': [best['output'][3]] |
| | }) |
| | st.dataframe(data3, hide_index=True, width=700) |
| |
|
| |
|
| |
|
| |
|
| |
|