Refactor manuscript title and enhance clarity in results discussion

- Updated manuscript title to reflect a focus on comparison of surrogate strategies for damage-aware optimization. - Improved clarity in the results section by refining descriptions of surrogate model performance and validation metrics. - Enhanced the discussion on the adaptive validation loop and its impact on optimization outcomes. - Clarified the interpretation of objective-function values and the implications of damage control in the optimization framework. - Added figures to illustrate the evolution of optimized window thicknesses and RBF objective surfaces during the optimization process.
parent 1ac5a43f
...@@ -22,6 +22,9 @@ Code/**/*.png ...@@ -22,6 +22,9 @@ Code/**/*.png
Code/**/*.html Code/**/*.html
Code/**/*.svg Code/**/*.svg
# Local browser used by Plotly/Kaleido static image export
.plotly_chrome/
# GiD results # GiD results
*.post.lst *.post.lst
*.post.bin *.post.bin
family,height_cm,width_cm,surrogate,iteration,source_model,window,window_index,thickness_mm,objective_surrogate
H30_B29,30,29,RBF,1,opt1,tw1,1,12.34,0.0
H30_B29,30,29,RBF,1,opt1,tw2,2,14.34,0.0
H30_B29,30,29,RBF,2,opt2,tw1,1,12.68,0.0
H30_B29,30,29,RBF,2,opt2,tw2,2,14.91,0.0
H30_B29,30,29,RBF,3,opt3,tw1,1,12.56,0.0
H30_B29,30,29,RBF,3,opt3,tw2,2,14.79,0.0
H30_B29,30,29,Supervised ML,1,opt1,tw1,1,12.6,0.0
H30_B29,30,29,Supervised ML,1,opt1,tw2,2,14.64,0.0
H30_B29,30,29,Supervised ML,2,opt2,tw1,1,12.53,0.0
H30_B29,30,29,Supervised ML,2,opt2,tw2,2,14.75,0.0
H30_B34,30,34,RBF,1,opt1,tw1,1,15.5,507.37762
H30_B34,30,34,RBF,1,opt1,tw2,2,20.0,507.37762
H30_B34,30,34,RBF,2,opt2,tw1,1,14.8,700.7361
H30_B34,30,34,RBF,2,opt2,tw2,2,18.93,700.7361
H30_B34,30,34,RBF,3,opt3,tw1,1,14.77,688.53041
H30_B34,30,34,RBF,3,opt3,tw2,2,18.95,688.53041
H30_B34,30,34,Supervised ML,1,opt1,tw1,1,15.69,541.94744
H30_B34,30,34,Supervised ML,1,opt1,tw2,2,20.0,541.94744
H30_B34,30,34,Supervised ML,2,opt2,tw1,1,15.14,830.19116
H30_B34,30,34,Supervised ML,2,opt2,tw2,2,20.0,830.19116
H30_B34,30,34,Supervised ML,3,opt3,tw1,1,15.2,796.29365
H30_B34,30,34,Supervised ML,3,opt3,tw2,2,20.0,796.29365
H45_B29,45,29,RBF,1,opt1,tw1,1,5.94,0.0
H45_B29,45,29,RBF,1,opt1,tw2,2,8.38,0.0
H45_B29,45,29,RBF,1,opt1,tw3,3,9.28,0.0
H45_B29,45,29,RBF,2,opt2,tw1,1,5.69,0.0
H45_B29,45,29,RBF,2,opt2,tw2,2,7.97,0.0
H45_B29,45,29,RBF,2,opt2,tw3,3,9.02,0.0
H45_B29,45,29,RBF,3,opt3,tw1,1,5.81,0.0
H45_B29,45,29,RBF,3,opt3,tw2,2,7.88,0.0
H45_B29,45,29,RBF,3,opt3,tw3,3,8.98,0.0
H45_B29,45,29,Supervised ML,1,opt1,tw1,1,5.96,0.0
H45_B29,45,29,Supervised ML,1,opt1,tw2,2,8.23,0.0
H45_B29,45,29,Supervised ML,1,opt1,tw3,3,9.47,0.0
H45_B29,45,29,Supervised ML,2,opt2,tw1,1,5.7,0.0
H45_B29,45,29,Supervised ML,2,opt2,tw2,2,7.9,0.0
H45_B29,45,29,Supervised ML,2,opt2,tw3,3,9.02,0.0
H45_B29,45,29,Supervised ML,3,opt3,tw1,1,5.72,0.0
H45_B29,45,29,Supervised ML,3,opt3,tw2,2,7.87,0.0
H45_B29,45,29,Supervised ML,3,opt3,tw3,3,8.96,0.0
H45_B34,45,34,RBF,1,opt1,tw1,1,7.21,0.0
H45_B34,45,34,RBF,1,opt1,tw2,2,9.27,0.0
H45_B34,45,34,RBF,1,opt1,tw3,3,9.82,0.0
H45_B34,45,34,RBF,2,opt2,tw1,1,6.81,0.0
H45_B34,45,34,RBF,2,opt2,tw2,2,9.02,0.0
H45_B34,45,34,RBF,2,opt2,tw3,3,9.65,0.0
H45_B34,45,34,Supervised ML,1,opt1,tw1,1,7.34,0.0
H45_B34,45,34,Supervised ML,1,opt1,tw2,2,9.28,0.0
H45_B34,45,34,Supervised ML,1,opt1,tw3,3,10.13,0.0
H45_B34,45,34,Supervised ML,2,opt2,tw1,1,6.87,0.0
H45_B34,45,34,Supervised ML,2,opt2,tw2,2,9.08,0.0
H45_B34,45,34,Supervised ML,2,opt2,tw3,3,9.86,0.0
H45_B34,45,34,Supervised ML,3,opt3,tw1,1,6.84,0.0
H45_B34,45,34,Supervised ML,3,opt3,tw2,2,9.05,0.0
H45_B34,45,34,Supervised ML,3,opt3,tw3,3,9.73,0.0
H60_B34,60,34,RBF,1,opt1,tw1,1,5.98,15.02082
H60_B34,60,34,RBF,1,opt1,tw2,2,7.29,15.02082
H60_B34,60,34,RBF,1,opt1,tw3,3,8.53,15.02082
H60_B34,60,34,RBF,1,opt1,tw4,4,6.73,15.02082
H60_B34,60,34,RBF,1,opt1,tw5,5,5.0,15.02082
H60_B34,60,34,RBF,2,opt2,tw1,1,5.71,16.67562
H60_B34,60,34,RBF,2,opt2,tw2,2,7.44,16.67562
H60_B34,60,34,RBF,2,opt2,tw3,3,8.51,16.67562
H60_B34,60,34,RBF,2,opt2,tw4,4,6.15,16.67562
H60_B34,60,34,RBF,2,opt2,tw5,5,5.0,16.67562
H60_B34,60,34,RBF,3,opt3,tw1,1,5.77,17.74124
H60_B34,60,34,RBF,3,opt3,tw2,2,7.38,17.74124
H60_B34,60,34,RBF,3,opt3,tw3,3,8.37,17.74124
H60_B34,60,34,RBF,3,opt3,tw4,4,6.18,17.74124
H60_B34,60,34,RBF,3,opt3,tw5,5,5.0,17.74124
H60_B34,60,34,Supervised ML,1,opt1,tw1,1,5.97,10.58275
H60_B34,60,34,Supervised ML,1,opt1,tw2,2,7.38,10.58275
H60_B34,60,34,Supervised ML,1,opt1,tw3,3,8.56,10.58275
H60_B34,60,34,Supervised ML,1,opt1,tw4,4,6.7,10.58275
H60_B34,60,34,Supervised ML,1,opt1,tw5,5,5.0,10.58275
H60_B34,60,34,Supervised ML,2,opt2,tw1,1,5.76,16.96082
H60_B34,60,34,Supervised ML,2,opt2,tw2,2,7.37,16.96082
H60_B34,60,34,Supervised ML,2,opt2,tw3,3,8.46,16.96082
H60_B34,60,34,Supervised ML,2,opt2,tw4,4,6.67,16.96082
H60_B34,60,34,Supervised ML,2,opt2,tw5,5,5.0,16.96082
H60_B34,60,34,Supervised ML,3,opt3,tw1,1,5.74,16.90444
H60_B34,60,34,Supervised ML,3,opt3,tw2,2,7.46,16.90444
H60_B34,60,34,Supervised ML,3,opt3,tw3,3,8.5,16.90444
H60_B34,60,34,Supervised ML,3,opt3,tw4,4,6.37,16.90444
H60_B34,60,34,Supervised ML,3,opt3,tw5,5,5.0,16.90444
#!/usr/bin/env python3
"""Plot optimized window thickness evolution in a single combined figure.
Input CSV expected columns:
family, surrogate, iteration, window, window_index, thickness_mm
The plot groups the x-axis by geometry family and shows adaptive iterations
inside each family block. Window color identifies each thickness variable, and
line style identifies the surrogate strategy:
solid = RBF, dashed = Supervised ML.
"""
from __future__ import annotations
import csv
from pathlib import Path
import matplotlib.pyplot as plt
from matplotlib.lines import Line2D
plt.rcParams.update(
{
"font.family": "serif",
"font.serif": ["Times New Roman", "DejaVu Serif"],
"mathtext.fontset": "stix",
"font.size": 12,
"axes.labelsize": 12,
"axes.titlesize": 11,
"xtick.labelsize": 12,
"ytick.labelsize": 12,
"axes.linewidth": 0.7,
"axes.spines.top": False,
"axes.spines.right": False,
"figure.dpi": 300,
"savefig.dpi": 300,
}
)
BASE_DIR = Path(__file__).resolve().parent
INPUT_CSV = BASE_DIR / "optimized_window_thickness_evolution.csv"
FIG_PATH = BASE_DIR / "optimized_window_thickness_evolution"
SURROGATE_LINESTYLES = {
"RBF": "-",
"Supervised ML": "--",
}
SURROGATE_ORDER = ["RBF", "Supervised ML"]
WINDOW_COLORS = {
"tw1": "#1a6faf",
"tw2": "#E07060",
"tw3": "#4D9A57",
"tw4": "#8B6BBE",
"tw5": "#D49A2A",
}
COLOR_GRID = "#d8d8d8"
ITERATION_STEP = 0.78
FAMILY_GAP = 1.05
def load_rows(path: Path):
with path.open(newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
rows = []
for row in reader:
row["iteration"] = int(row["iteration"])
row["window_index"] = int(row["window_index"])
row["thickness_mm"] = float(row["thickness_mm"])
rows.append(row)
return rows
def style_axis(ax, *, include_x_grid: bool = False) -> None:
ax.grid(
True,
axis="both" if include_x_grid else "y",
color=COLOR_GRID,
linewidth=0.55,
alpha=0.75,
)
ax.tick_params(axis="both", which="major", direction="in", length=4, width=0.7)
ax.tick_params(axis="both", which="minor", direction="in", length=2.5, width=0.6)
ax.tick_params(axis="x", which="both", length=0)
ax.minorticks_on()
def save_figure_all_formats(fig, out_base: Path) -> None:
fig.savefig(f"{out_base}.png", format="png", bbox_inches="tight", dpi=300)
fig.savefig(f"{out_base}.svg", format="svg", bbox_inches="tight")
fig.savefig(f"{out_base}.pdf", format="pdf", bbox_inches="tight")
def family_sort_key(family: str) -> tuple[int, int, str]:
height_text, width_text = family.split("_")
return int(height_text.replace("H", "")), int(width_text.replace("B", "")), family
def window_sort_key(window: str) -> int:
return int(window.replace("tw", ""))
def plot_all_families(rows: list[dict], out_base: Path):
rows = sorted(
rows,
key=lambda r: (
family_sort_key(r["family"]),
r["window_index"],
SURROGATE_ORDER.index(r["surrogate"])
if r["surrogate"] in SURROGATE_ORDER
else len(SURROGATE_ORDER),
r["iteration"],
),
)
families = sorted({r["family"] for r in rows}, key=family_sort_key)
windows = sorted({r["window"] for r in rows}, key=window_sort_key)
surrogates = [s for s in SURROGATE_ORDER if s in {r["surrogate"] for r in rows}]
fig, ax = plt.subplots(figsize=(10.2, 4.85))
fig.subplots_adjust(left=0.075, right=0.985, bottom=0.3, top=0.95)
family_centers = {}
tick_positions = []
tick_labels = []
family_start_positions = []
x_by_family_iteration = {}
current_x = 0.0
for family in families:
iterations = sorted({r["iteration"] for r in rows if r["family"] == family})
family_start_positions.append(current_x)
family_positions = []
for offset, iteration in enumerate(iterations):
x = current_x + offset * ITERATION_STEP
x_by_family_iteration[(family, iteration)] = x
family_positions.append(x)
tick_positions.append(x)
tick_labels.append(f"it{iteration}")
family_centers[family] = (family_positions[0] + family_positions[-1]) / 2
current_x = family_positions[-1] + FAMILY_GAP
for family_start in family_start_positions[1:]:
ax.axvline(
family_start - FAMILY_GAP / 2,
color=COLOR_GRID,
linewidth=0.7,
zorder=0,
)
for family in families:
family_rows = [r for r in rows if r["family"] == family]
for window in sorted({r["window"] for r in family_rows}, key=window_sort_key):
for surrogate in surrogates:
subset = [
r
for r in family_rows
if r["window"] == window and r["surrogate"] == surrogate
]
if not subset:
continue
subset = sorted(subset, key=lambda r: r["iteration"])
ax.plot(
[x_by_family_iteration[(family, r["iteration"])] for r in subset],
[r["thickness_mm"] for r in subset],
marker="o",
color=WINDOW_COLORS.get(window, "#555555"),
markerfacecolor="white",
markeredgewidth=0.8,
linewidth=1.5,
markersize=4.2,
linestyle=SURROGATE_LINESTYLES.get(surrogate, "-"),
zorder=3,
)
ax.set_ylabel("Window thickness [mm]")
ax.set_xticks(tick_positions)
ax.set_xticklabels(tick_labels)
ax.tick_params(axis="x", labelsize=10, pad=3)
ax.set_xlim(min(tick_positions) - 0.35, max(tick_positions) + 0.35)
style_axis(ax)
y_values = [r["thickness_mm"] for r in rows]
y_margin = (max(y_values) - min(y_values)) * 0.06
ax.set_ylim(max(0, min(y_values) - y_margin), max(y_values) + y_margin)
for family, center in family_centers.items():
ax.text(
center,
-0.115,
family,
transform=ax.get_xaxis_transform(),
ha="center",
va="top",
fontsize=12,
clip_on=False,
)
window_handles = [
Line2D(
[0],
[0],
color=WINDOW_COLORS.get(window, "#555555"),
marker="o",
markerfacecolor="white",
markeredgewidth=0.8,
linewidth=1.5,
markersize=4.2,
label=window,
)
for window in windows
]
surrogate_handles = [
Line2D(
[0],
[0],
color="#444444",
linestyle=SURROGATE_LINESTYLES.get(surrogate, "-"),
linewidth=1.5,
label=surrogate,
)
for surrogate in surrogates
]
fig.legend(
window_handles + surrogate_handles,
[h.get_label() for h in window_handles + surrogate_handles],
loc="lower center",
ncol=len(window_handles) + len(surrogate_handles),
frameon=False,
bbox_to_anchor=(0.5, 0.035),
columnspacing=1.4,
handlelength=2.0,
)
save_figure_all_formats(fig, out_base)
plt.close(fig)
return out_base
def main():
rows = load_rows(INPUT_CSV)
created = plot_all_families(rows, FIG_PATH)
print(f"Saved: {created}.png/.svg/.pdf")
if __name__ == "__main__":
main()
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment