Rui Wan commited on
Commit
487ee3e
·
1 Parent(s): 6166657

render layout

Browse files
Files changed (2) hide show
  1. app.py +161 -12
  2. model_inverse.py +1 -1
app.py CHANGED
@@ -4,6 +4,18 @@ import gradio as gr
4
  from model_inverse import inverse_design
5
 
6
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  def run_inverse_design(ply_number, a1, b1, c1, stress, n_restarts, epochs, use_lbfgs):
8
  y_target = np.array([a1, b1, c1, stress], dtype=np.float32)
9
  best = inverse_design(
@@ -14,7 +26,7 @@ def run_inverse_design(ply_number, a1, b1, c1, stress, n_restarts, epochs, use_l
14
  use_lbfgs=bool(use_lbfgs),
15
  )
16
  if best["input"] is None or best["output"] is None:
17
- return {"Initial Temp": None, "Punch Velocity": None, "Cooling Time": None}, {"A1": None, "B1": None, "C1": None, "Stress": None}
18
 
19
  input_vals = {
20
  "Initial Temp": float(best["input"][0]),
@@ -27,10 +39,148 @@ def run_inverse_design(ply_number, a1, b1, c1, stress, n_restarts, epochs, use_l
27
  "C1": float(best["output"][2]),
28
  "Stress": float(best["output"][3]),
29
  }
30
- return input_vals, output_vals
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
 
33
- with gr.Blocks(title="Inverse Design Demo") as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  gr.Markdown("# Inverse Design Demo")
35
  gr.Markdown("Enter a target output; the model finds processing parameters.")
36
 
@@ -38,26 +188,25 @@ with gr.Blocks(title="Inverse Design Demo") as demo:
38
  with gr.Column():
39
  gr.Markdown("## Target Output")
40
  ply_number = gr.Number(label="Ply number", value=2, precision=0)
41
- a1 = gr.Number(label="A1", value=0.89, precision=4)
42
- b1 = gr.Number(label="B1", value=0.83, precision=4)
43
- c1 = gr.Number(label="C1", value=0.12, precision=4)
44
- stress = gr.Number(label="Stress", value=180.2, precision=4)
45
  with gr.Column():
46
  gr.Markdown("## Optimization Settings")
47
  n_restarts = gr.Number(label="Restarts", value=5, precision=0)
48
  epochs = gr.Number(label="Epochs of Optimization", value=100, precision=0)
49
- use_lbfgs = gr.Checkbox(label="Use LBFGS", value=True)
50
 
51
  run_btn = gr.Button("Run Inverse Design")
52
 
53
- with gr.Row():
54
- best_input = gr.JSON(label="Best Input")
55
- best_output = gr.JSON(label="Predicted Output")
56
 
57
  run_btn.click(
58
  run_inverse_design,
59
  inputs=[ply_number, a1, b1, c1, stress, n_restarts, epochs, use_lbfgs],
60
- outputs=[best_input, best_output],
61
  )
62
 
63
 
 
4
  from model_inverse import inverse_design
5
 
6
 
7
+ def format_number(value):
8
+ if value is None:
9
+ return "--"
10
+ return f"{value:,.4f}"
11
+
12
+
13
+ def format_percent(value):
14
+ if value is None:
15
+ return "--"
16
+ return f"{value * 100:.2f}%"
17
+
18
+
19
  def run_inverse_design(ply_number, a1, b1, c1, stress, n_restarts, epochs, use_lbfgs):
20
  y_target = np.array([a1, b1, c1, stress], dtype=np.float32)
21
  best = inverse_design(
 
26
  use_lbfgs=bool(use_lbfgs),
27
  )
28
  if best["input"] is None or best["output"] is None:
29
+ return "<div class='empty-state'>No valid solution found.</div>"
30
 
31
  input_vals = {
32
  "Initial Temp": float(best["input"][0]),
 
39
  "C1": float(best["output"][2]),
40
  "Stress": float(best["output"][3]),
41
  }
42
+ def rel_err(pred, target):
43
+ target = float(target)
44
+ if target == 0.0:
45
+ return None
46
+ return abs(float(pred) - target) / abs(target)
47
+
48
+ output_rows = [
49
+ ("A1", output_vals["A1"], rel_err(output_vals["A1"], a1)),
50
+ ("B1", output_vals["B1"], rel_err(output_vals["B1"], b1)),
51
+ ("C1", output_vals["C1"], rel_err(output_vals["C1"], c1)),
52
+ ("Stress", output_vals["Stress"], rel_err(output_vals["Stress"], stress)),
53
+ ]
54
+
55
+ input_html = "".join(
56
+ f"<div class='kv-row'><span class='kv-key'>{k}</span><span class='kv-val'>{format_number(v)}</span></div>"
57
+ for k, v in input_vals.items()
58
+ )
59
+ output_html = "".join(
60
+ "<div class='out-row'>"
61
+ f"<div class='out-name'>{name}</div>"
62
+ f"<div class='out-pred'>{format_number(pred)}</div>"
63
+ f"<div class='out-err'>{format_percent(err)}</div>"
64
+ "</div>"
65
+ for name, pred, err in output_rows
66
+ )
67
+ return (
68
+ "<div class='results-grid'>"
69
+ "<div class='panel'>"
70
+ "<div class='panel-title'>Best Input</div>"
71
+ f"{input_html}"
72
+ "</div>"
73
+ "<div class='panel'>"
74
+ "<div class='panel-title'>Predicted Output</div>"
75
+ f"<div class='out-grid'>{output_html}</div>"
76
+ "</div>"
77
+ "</div>"
78
+ )
79
 
80
 
81
+ custom_css = """
82
+ :root {
83
+ --ink: #1d1a16;
84
+ --muted: #6b625a;
85
+ --sand: #f6f1e7;
86
+ --clay: #e8dfd2;
87
+ --accent: #c65b2a;
88
+ --card: #fffaf1;
89
+ }
90
+ .page-wrap {
91
+ background: radial-gradient(1200px 600px at 10% -10%, #fbe9cf 0%, #f6f1e7 45%, #efe7dc 100%);
92
+ border-radius: 18px;
93
+ padding: 18px;
94
+ }
95
+ .panel {
96
+ background: var(--card);
97
+ border: 1px solid var(--clay);
98
+ border-radius: 16px;
99
+ padding: 16px;
100
+ box-shadow: 0 8px 24px rgba(57, 44, 30, 0.08);
101
+ }
102
+ .panel-title {
103
+ font-size: 16px;
104
+ letter-spacing: 0.5px;
105
+ text-transform: uppercase;
106
+ color: var(--muted);
107
+ margin-bottom: 10px;
108
+ }
109
+ .kv-row {
110
+ display: flex;
111
+ justify-content: space-between;
112
+ align-items: center;
113
+ padding: 10px 12px;
114
+ background: #fdf7ec;
115
+ border: 1px dashed #e3d5c4;
116
+ border-radius: 12px;
117
+ margin-bottom: 10px;
118
+ }
119
+ .kv-key {
120
+ color: var(--ink);
121
+ font-weight: 600;
122
+ }
123
+ .kv-val {
124
+ color: var(--accent);
125
+ font-weight: 700;
126
+ }
127
+ .results-grid {
128
+ display: grid;
129
+ grid-template-columns: 1fr 1fr;
130
+ gap: 18px;
131
+ }
132
+ .out-grid {
133
+ display: grid;
134
+ grid-template-columns: 1fr 1fr 1fr;
135
+ gap: 10px;
136
+ }
137
+ .out-row {
138
+ background: #fff3e2;
139
+ border: 1px solid #f0d2b7;
140
+ border-radius: 12px;
141
+ padding: 12px;
142
+ display: grid;
143
+ grid-template-columns: 1fr;
144
+ gap: 6px;
145
+ }
146
+ .out-name {
147
+ font-weight: 700;
148
+ color: var(--ink);
149
+ }
150
+ .out-pred {
151
+ font-size: 18px;
152
+ color: var(--accent);
153
+ font-weight: 700;
154
+ }
155
+ .out-err {
156
+ color: var(--muted);
157
+ font-size: 13px;
158
+ }
159
+ @media (max-width: 1000px) {
160
+ .results-grid {
161
+ grid-template-columns: 1fr;
162
+ }
163
+ .out-grid {
164
+ grid-template-columns: 1fr 1fr;
165
+ }
166
+ }
167
+ @media (max-width: 600px) {
168
+ .out-grid {
169
+ grid-template-columns: 1fr;
170
+ }
171
+ }
172
+ .empty-state {
173
+ padding: 16px;
174
+ border-radius: 12px;
175
+ border: 1px dashed #e3d5c4;
176
+ color: var(--muted);
177
+ text-align: center;
178
+ background: #fff7ea;
179
+ }
180
+ """
181
+
182
+
183
+ with gr.Blocks(title="Inverse Design Demo", css=custom_css) as demo:
184
  gr.Markdown("# Inverse Design Demo")
185
  gr.Markdown("Enter a target output; the model finds processing parameters.")
186
 
 
188
  with gr.Column():
189
  gr.Markdown("## Target Output")
190
  ply_number = gr.Number(label="Ply number", value=2, precision=0)
191
+ a1 = gr.Number(label="A1 (Angle)", value=0.89, precision=4)
192
+ b1 = gr.Number(label="B1 (Angle)", value=0.83, precision=4)
193
+ c1 = gr.Number(label="C1 (Angle)", value=0.12, precision=4)
194
+ stress = gr.Number(label="Max Stress (MPa)", value=180.2, precision=4)
195
  with gr.Column():
196
  gr.Markdown("## Optimization Settings")
197
  n_restarts = gr.Number(label="Restarts", value=5, precision=0)
198
  epochs = gr.Number(label="Epochs of Optimization", value=100, precision=0)
199
+ use_lbfgs = gr.Checkbox(label="Use LBFGS Optimization", value=True)
200
 
201
  run_btn = gr.Button("Run Inverse Design")
202
 
203
+ with gr.Row(elem_classes=["page-wrap"]):
204
+ results_html = gr.HTML()
 
205
 
206
  run_btn.click(
207
  run_inverse_design,
208
  inputs=[ply_number, a1, b1, c1, stress, n_restarts, epochs, use_lbfgs],
209
+ outputs=[results_html],
210
  )
211
 
212
 
model_inverse.py CHANGED
@@ -101,7 +101,7 @@ def inverse_design(ply_number, y_target, n_restarts=20, epochs=1000, use_lbfgs=F
101
  output_std = torch.tensor(data.output_std)
102
 
103
  weights = torch.tensor([1.0, 1.0, 1.0, 0.0], dtype=torch.float32)
104
- bounds = torch.tensor([[100., 600.], [100., 600.], [100., 600.]], dtype=torch.float32) # Initial_Temp, Punch_Velocity, Cooling_Time
105
  best = {"loss": float('inf'), "input": None, "output": None}
106
 
107
  for restart in range(n_restarts):
 
101
  output_std = torch.tensor(data.output_std)
102
 
103
  weights = torch.tensor([1.0, 1.0, 1.0, 0.0], dtype=torch.float32)
104
+ bounds = torch.tensor([[1., 1000.], [1., 1000.], [1., 1000.]], dtype=torch.float32) # Initial_Temp, Punch_Velocity, Cooling_Time
105
  best = {"loss": float('inf'), "input": None, "output": None}
106
 
107
  for restart in range(n_restarts):