gangli71 commited on
Commit
93e020b
·
unverified ·
1 Parent(s): ff9a75e

Upload thermoforming.py

Browse files
Files changed (1) hide show
  1. thermoforming.py +368 -0
thermoforming.py ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #######################
2
+ # Import libraries
3
+ import streamlit as st
4
+ import pandas as pd
5
+ import altair as alt
6
+ import plotly.express as px
7
+ from PIL import Image # Used to open and handle image files
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+
11
+
12
+ #######################
13
+ # Page configuration
14
+ st.set_page_config(
15
+ page_title="Inverse Design of Thermoplastic Composites for Thermoforming",
16
+ # page_icon="🏂",
17
+ layout="wide",
18
+ initial_sidebar_state="collapsed")
19
+
20
+ alt.themes.enable('default')
21
+
22
+ #######################
23
+ # CSS styling
24
+
25
+ st.markdown("""
26
+ <style>
27
+ /* Target the input element within its container (adjust class name as needed via browser inspection) */
28
+ .stTextInput input {
29
+ border: 1px solid #333333; /* Set border width, style, and color */
30
+ border-radius: 6px; /* Optional: adds rounded corners */
31
+ padding: 10px; /* Optional: adds inner spacing */
32
+ }
33
+ </style>
34
+ """, unsafe_allow_html=True)
35
+
36
+ st.markdown("""
37
+ <style>
38
+
39
+ [data-testid="block-container"] {
40
+ padding-left: 2rem;
41
+ padding-right: 2rem;
42
+ padding-top: 1rem;
43
+ padding-bottom: 0rem;
44
+ margin-bottom: -7rem;
45
+ }
46
+
47
+ [data-testid="stVerticalBlock"] {
48
+ padding-left: 0rem;
49
+ padding-right: 0rem;
50
+ }
51
+
52
+ [data-testid="stMetric"] {
53
+ background-color: #393939;
54
+ text-align: center;
55
+ padding: 15px 0;
56
+ }
57
+
58
+ [data-testid="stMetricLabel"] {
59
+ display: flex;
60
+ justify-content: center;
61
+ align-items: center;
62
+ }
63
+
64
+ [data-testid="stMetricDeltaIcon-Up"] {
65
+ position: relative;
66
+ left: 38%;
67
+ -webkit-transform: translateX(-50%);
68
+ -ms-transform: translateX(-50%);
69
+ transform: translateX(-50%);
70
+ }
71
+
72
+ [data-testid="stMetricDeltaIcon-Down"] {
73
+ position: relative;
74
+ left: 38%;
75
+ -webkit-transform: translateX(-50%);
76
+ -ms-transform: translateX(-50%);
77
+ transform: translateX(-50%);
78
+ }
79
+
80
+ /* Main app + sidebar, target the label element itself */
81
+ [data-testid="stAppViewContainer"] label,
82
+ [data-testid="stWidgetLabel"] label {
83
+ font-size: 18px !important;
84
+ font-weight: 600 !important; /* optional */
85
+ color: #444 !important; /* optional */
86
+ }
87
+
88
+ /* Some versions wrap label text inside a <div><p> */
89
+ [data-testid="stAppViewContainer"] label > div > p,
90
+ [data-testid="stWidgetLabel"] label > div > p {
91
+ font-size: 18px !important;
92
+ font-weight: 600 !important;
93
+ }
94
+ </style>
95
+ """, unsafe_allow_html=True)
96
+
97
+ st.markdown("""
98
+ <style>
99
+ div.stButton > button:first-child {
100
+ background-color: #ee7700; /* background */
101
+ color: white; /* White text */
102
+ font-size: 20px;
103
+ border-radius: 10px;
104
+ # display: block; # this line and the next center the button horizontally
105
+ # margin: 0 auto;
106
+ }
107
+ </style>
108
+ """, unsafe_allow_html=True)
109
+
110
+ st.markdown("""
111
+ <style>
112
+ div[data-testid="stVirtualDropdown"] > div {
113
+ max-height: 10px !important; /* Adjust this value as needed */
114
+ overflow-y: auto;
115
+ }
116
+ </style>
117
+ """, unsafe_allow_html=True)
118
+
119
+
120
+ st.set_page_config(initial_sidebar_state="collapsed")
121
+
122
+ st.markdown(
123
+ """
124
+ <style>
125
+ [data-testid="collapsedControl"] {
126
+ display: none
127
+ }
128
+ </style>
129
+ """,
130
+ unsafe_allow_html=True,
131
+ )
132
+ #######################
133
+ if 'input_changed' not in st.session_state:
134
+ st.session_state.input_changed= False
135
+ def input_typed_in():
136
+ st.session_state.input_changed= True
137
+
138
+ if 'forming_input_changed' not in st.session_state:
139
+ st.session_state.forming_input_changed= False
140
+ def forming_typed_in():
141
+ st.session_state.forming_input_changed= True
142
+
143
+
144
+
145
+ if 'input_curve_button_clicked' not in st.session_state:
146
+ st.session_state.input_curve_button_clicked= False
147
+ def input_curve_click():
148
+ st.session_state.input_curve_button_clicked = True
149
+
150
+ if 'material_design_button_clicked' not in st.session_state:
151
+ st.session_state.material_design_button_clicked= False
152
+ def material_design_click():
153
+ st.session_state.material_design_button_clicked = True
154
+
155
+ if 'forming_input_button_clicked' not in st.session_state:
156
+ st.session_state.forming_input_button_clicked= False
157
+ def forming_input_click():
158
+ st.session_state.forming_input_button_clicked = True
159
+
160
+ if 'forming_design_button_clicked' not in st.session_state:
161
+ st.session_state.forming_design_button_clicked= False
162
+ def forming_design_click():
163
+ st.session_state.forming_design_button_clicked = True
164
+
165
+
166
+
167
+ #######################
168
+ # Load data
169
+ #df_reshaped = pd.read_csv('data/us-population-2010-2019-reshaped.csv')
170
+
171
+ ######## Initialize data #############
172
+ E1aV=0 # initial longitudinal stiffness
173
+ E1bV=0 # 10% strain longitudinal stiffness
174
+ G12aV=0 # initial longitudinal stiffness
175
+ G12bV=0 # 10% strain longitudinal stiffness
176
+ nlayers=4
177
+ vf=0.5
178
+ angle=30
179
+
180
+ #######################
181
+ # Main Panel
182
+
183
+ data_materials={
184
+ 'Matrix':['ABS','Polyurethane','Nylon 6','Nylon 6','Nylon 66','PE','PP'],
185
+ 'Filler':['Carbon Black','Glass Fiber','Glass Fiber','Carbon Fiber','Glass Fiber','Carbon Fiber','Glass Fiber'],
186
+ 'VF':['15%','20%','20%','40%','30%','20%','30%'],
187
+ 'Feature':['Blend','Extruded','Molded','Molded','Molded','Molded','Molded']
188
+ }
189
+
190
+ data_physical = {
191
+ 'Forming T (C)': ['180', '185', '190'],
192
+ 'Punch V (m/s)': ['1.05', '1.8','1.67'],
193
+ 'Cooling time (s)': ['45','80','120'],
194
+ 'Holding force (kN)': ['23','24','25']
195
+ }
196
+
197
+ st.title("Inverse Design of Thermoplastic Composites for Thermoforming")
198
+ st.write("")
199
+ st.write("")
200
+ st.write("")
201
+ st.write(r"$\textsf{\textbf{\Large Material Design Requirements}}$")
202
+ #st.text_input(r"$\textsf{\textbf{\Large Material Design Requirements}}$")
203
+
204
+ # First row with 3 columns
205
+ col1_row1, col2_row1, col3_row1 = st.columns([0.3,0.3,0.3])
206
+ with col1_row1:
207
+ with st.container(border=False): # Container with a border
208
+ E1aV= st.number_input("Initial tensile stiffness (MPa):", format="%.2f", width=250, key="E1a", on_change=input_typed_in)
209
+ E1bV= st.number_input("10% tensile stiffness (MPa):", format="%.2f", width=250, key="E1b", on_change=input_typed_in)
210
+
211
+ with col2_row1:
212
+ with st.container(border=False): # Container with a border
213
+ G12aV= st.number_input("Initial shear stiffness (MPa):", format="%.2f", width=250, key="G12a", on_change=input_typed_in)
214
+ G12bV= st.number_input("0.1 shear strain stiffness (MPa):", format="%.2f", width=250, key="G12b", on_change=input_typed_in)
215
+
216
+ with col3_row1:
217
+ with st.container(border=False): # Container with a border
218
+ EratioV= st.number_input("Anisotropicity (Ex/Ey):", format="%.2f", width=250, key="Eratio", on_change=input_typed_in)
219
+
220
+
221
+ st.write("")
222
+ if st.session_state.input_changed == True:
223
+ st.session_state.input_curve_button_clicked = False
224
+ st.session_state.material_design_button_clicked = False
225
+ st.session_state.forming_input_button_clicked = False
226
+ st.session_state.forming_design_button_clicked = False
227
+ st.session_state.input_changed = False
228
+
229
+ st.button("Generate required stress-strain curves", width=400, on_click=input_curve_click)
230
+
231
+ if st.session_state.input_curve_button_clicked == True:
232
+ #st.write(E1aV)
233
+ #st.write(E1bV)
234
+ x = np.linspace(0, 0.1, 20)
235
+ y1 = E1aV*x + (E1bV-E1aV)/0.2*x*x
236
+ y2 = G12aV*x + (G12bV-G12aV)/0.2*x*x
237
+ y3 = y1/EratioV
238
+ ylimit=np.max([np.max(y1),np.max(y2), np.max(y3)])
239
+ # 2nd row with 3 columns
240
+ col1_row2, col2_row2, col3_row2, col4_row2= st.columns([0.25,0.25,0.25,0.25])
241
+ with col1_row2:
242
+ with st.container(border=False): # Container with a border
243
+ fig, ax = plt.subplots()
244
+ ax.plot(x, y1)
245
+ ax.set_ylim([0, ylimit])
246
+ ax.set_xlabel('Stress (MPa)')
247
+ ax.set_ylabel('Strain')
248
+ ax.set_title('Longitudinal stress-strain')
249
+ st.pyplot(fig)
250
+ with col2_row2:
251
+ with st.container(border=False): # Container with a border
252
+ fig, ax = plt.subplots()
253
+ ax.plot(x, y2)
254
+ ax.set_ylim([0, ylimit])
255
+ ax.set_xlabel('Stress (MPa)')
256
+ ax.set_ylabel('Strain')
257
+ ax.set_title('Shear stress-strain')
258
+ st.pyplot(fig)
259
+ with col3_row2:
260
+ with st.container(border=False): # Container with a border
261
+ fig, ax = plt.subplots()
262
+ ax.plot(x, y3)
263
+ ax.set_ylim([0, ylimit])
264
+ ax.set_xlabel('Stress (MPa)')
265
+ ax.set_ylabel('Strain')
266
+ ax.set_title('Shear stress-strain')
267
+ st.pyplot(fig)
268
+
269
+ st.write("")
270
+ st.button("Material Inverse Design", width=400, on_click=material_design_click)
271
+ if st.session_state.material_design_button_clicked == True:
272
+ #st.write("")
273
+ # 3rd row with 3 columns
274
+ col1_row3, col2_row3, col3_row3, col4_row3, col5_row3= st.columns([0.15,0.15,0.23,0.23,0.23])
275
+ with col1_row3:
276
+ with st.container(border=False): # Container with a border
277
+ st.write("Number of layers=", nlayers)
278
+ st.write("Volume fraction=", vf)
279
+
280
+ with col2_row3:
281
+ with st.container(border=False): # Container with a border
282
+ df = pd.DataFrame({'Ply': [], 'Orientation': []})
283
+ plies = np.array([[1,90], [2,45], [3,-45], [4,-90]])
284
+ plies_df=pd.DataFrame(plies, columns=df.columns)
285
+ df = pd.concat([df, plies_df], ignore_index=True)
286
+ st.dataframe(df, hide_index=True)
287
+
288
+ with col3_row3:
289
+ with st.container(border=False): # Container with a border
290
+ image = Image.open('figures/material_res3.png')
291
+ new_image = image.resize((250, 200))
292
+ st.image(new_image, caption='')
293
+
294
+ with col4_row3:
295
+ with st.container(border=False): # Container with a border
296
+ image = Image.open('figures/material_res3.png')
297
+ new_image = image.resize((250, 200))
298
+ st.image(new_image, caption='')
299
+
300
+
301
+ with col5_row3:
302
+ with st.container(border=False): # Container with a border
303
+ image = Image.open('figures/material_res3.png')
304
+ new_image = image.resize((250, 200))
305
+ st.image(new_image, caption='')
306
+
307
+
308
+ st.write("")
309
+ st.button("Thermoforming Requirements", width=400, on_click=forming_input_click)
310
+ if st.session_state.forming_input_button_clicked == True:
311
+ #st.write("")
312
+ # 4th row with 3 columns
313
+ col1_row4, col2_row4, col3_row4, col4_row4, col5_row4 = st.columns([0.16,0.16,0.2,0.24,0.24])
314
+ with col1_row4:
315
+ with st.container(border=False): # Container with a border
316
+ st.write("Number of layers=", nlayers)
317
+ st.write("Volume fraction=", vf)
318
+ st.write("Fiber orientation=", angle)
319
+ with col2_row4:
320
+ with st.container(border=False): # Container with a border
321
+ df = pd.DataFrame({'Ply': [], 'Orientation': []})
322
+ plies = np.array([[1,90], [2,45], [3,-45], [4,-90]])
323
+ plies_df=pd.DataFrame(plies, columns=df.columns)
324
+ df = pd.concat([df, plies_df], ignore_index=True)
325
+ st.dataframe(df, hide_index=True)
326
+
327
+ with col3_row4:
328
+ with st.container(border=False): # Container with a border
329
+ image = Image.open('figures/forming_angle.png')
330
+ new_image = image.resize((250, 200))
331
+ st.image(new_image, caption='')
332
+
333
+ with col4_row4:
334
+ with st.container(border=False): # Container with a border
335
+ angleA= st.number_input("Maximum warpage angle A (degree):", format="%.2f", width=300, key="A", on_change=forming_typed_in)
336
+ angleB= st.number_input("Maximum warpage angle B (degree):", format="%.2f", width=300, key="B", on_change=forming_typed_in)
337
+
338
+
339
+ with col5_row4:
340
+ with st.container(border=False): # Container with a border
341
+ angleC= st.number_input("Maximum warpage angle C (degree):", format="%.2f", width=300, key="C", on_change=forming_typed_in)
342
+ max_stress= st.number_input("Maximum residual stress (MPa):", format="%.2f", width=300, key="max_stress", on_change=forming_typed_in)
343
+
344
+ st.write("")
345
+ if st.session_state.forming_input_changed == True:
346
+ st.session_state.forming_design_button_clicked = False
347
+ st.session_state.forming_input_changed = False
348
+ st.button("Thermoforming process design", width=400, on_click=forming_design_click)
349
+ if st.session_state.forming_design_button_clicked == True:
350
+ # 5th row with 3 columns
351
+ col1_row5, col2_row5,col3_row5 = st.columns([0.25,0.25,0.25])
352
+ with col1_row5:
353
+ with st.container(border=False): # Container with a border
354
+ st.write("Forming temperature (C)=", nlayers)
355
+ with col2_row5:
356
+ with st.container(border=False): # Container with a border
357
+ st.write("Punching velocity (mm/s)=", nlayers)
358
+ with col3_row5:
359
+ with st.container(border=False): # Container with a border
360
+ st.write("Cooling time (s)=", nlayers)
361
+
362
+
363
+
364
+
365
+
366
+
367
+
368
+