| |
| |
| 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", width=400, 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) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|