feiyang-cai's picture
Initial ZeroGPU Gradio Space
01a8278
Raw
History Blame Contribute Delete
11.3 kB
from __future__ import annotations
from typing import Dict, Optional, Tuple
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
from .cubic_curves import (
EPS33_ROW,
LATERAL_ROW,
MODE_TO_ROW,
default_x_for_mode,
evaluate_cubic_no_intercept,
fit_cubic_no_intercept,
)
def _set_axis_limits(
ax: plt.Axes,
y: np.ndarray,
*,
force_min: Optional[float] = None,
force_max: Optional[float] = None,
min_floor: Optional[float] = None,
max_ceiling: Optional[float] = None,
pad_frac: float = 0.2,
) -> None:
y = np.asarray(y, dtype=np.float32).reshape(-1)
if y.size == 0:
return
y_min = float(np.min(y))
y_max = float(np.max(y))
if force_min is not None:
y_min = min(y_min, float(force_min))
if force_max is not None:
y_max = max(y_max, float(force_max))
if min_floor is not None:
y_min = min(y_min, float(min_floor))
if max_ceiling is not None:
y_max = max(y_max, float(max_ceiling))
span = y_max - y_min
pad = span * pad_frac if span > 0 else max(abs(y_max), abs(y_min), 1.0) * 0.1
bottom = y_min - pad
top = y_max + pad
if force_min is not None:
bottom = float(force_min)
if force_max is not None:
top = float(force_max)
ax.set_ylim(bottom, top)
def plot_single_curve(coeffs: np.ndarray, mode: str, title: str, ylabel: str) -> plt.Figure:
x = default_x_for_mode(mode)
y = evaluate_cubic_no_intercept(coeffs, x)
fig, ax = plt.subplots(figsize=(3.2, 2.5))
ax.plot(x, y, color="k", linewidth=2)
ax.set_title(title)
ax.set_xlabel("strain")
ax.set_ylabel(ylabel)
ax.grid(True, alpha=0.25)
fig.tight_layout()
return fig
def plot_required_curves(cond_coeffs_7x3: np.ndarray) -> plt.Figure:
cond = np.asarray(cond_coeffs_7x3, dtype=np.float32).reshape(7, 3)
fig, axes = plt.subplots(3, 3, figsize=(14, 12))
modes = ["11", "22", "12"]
for col, mode in enumerate(modes):
x = default_x_for_mode(mode)
stress_row = MODE_TO_ROW[mode]
axes[0, col].plot(x, evaluate_cubic_no_intercept(cond[stress_row], x), color="k", linewidth=2)
axes[0, col].set_title(f"Mode {mode} stress")
axes[0, col].set_xlabel("strain")
axes[0, col].set_ylabel("stress (MPa)")
axes[0, col].grid(True, alpha=0.25)
if mode in ("11", "22"):
lat_row = int(LATERAL_ROW[mode])
e33_row = int(EPS33_ROW[mode])
axes[1, col].plot(x, evaluate_cubic_no_intercept(cond[lat_row], x), color="k", linewidth=2)
axes[1, col].set_title(f"Mode {mode} lateral")
axes[1, col].set_xlabel("strain")
axes[1, col].set_ylabel("lateral strain")
axes[1, col].grid(True, alpha=0.25)
axes[2, col].plot(x, evaluate_cubic_no_intercept(cond[e33_row], x), color="k", linewidth=2)
axes[2, col].set_title(f"Mode {mode} eps33")
axes[2, col].set_xlabel("strain")
axes[2, col].set_ylabel("eps33")
axes[2, col].grid(True, alpha=0.25)
else:
axes[1, col].axis("off")
axes[2, col].axis("off")
fig.tight_layout()
return fig
def plot_required_curves_from_series(curves: Dict[str, np.ndarray]) -> plt.Figure:
fig, axes = plt.subplots(3, 3, figsize=(14, 12))
axes[0, 0].plot(curves["eps11"], curves["sig11_mpa"], color="k", linewidth=2)
axes[0, 0].set_title("Mode 11 stress")
axes[0, 0].set_xlabel("strain")
axes[0, 0].set_ylabel("stress (MPa)")
axes[0, 0].grid(True, alpha=0.25)
_set_axis_limits(axes[0, 0], curves["sig11_mpa"])
axes[1, 0].plot(curves["eps11"], curves["eps22_from_eps11"], color="k", linewidth=2)
axes[1, 0].set_title("Mode 11 lateral")
axes[1, 0].set_xlabel("strain")
axes[1, 0].set_ylabel("lateral strain")
axes[1, 0].grid(True, alpha=0.25)
_set_axis_limits(axes[1, 0], curves["eps22_from_eps11"], min_floor=-0.01, max_ceiling=0.0, pad_frac=0.0)
axes[2, 0].plot(curves["eps11"], curves["eps33_from_eps11"], color="k", linewidth=2)
axes[2, 0].set_title("Mode 11 eps33")
axes[2, 0].set_xlabel("strain")
axes[2, 0].set_ylabel("eps33")
axes[2, 0].grid(True, alpha=0.25)
_set_axis_limits(axes[2, 0], curves["eps33_from_eps11"])
axes[0, 1].plot(curves["eps22"], curves["sig22_mpa"], color="k", linewidth=2)
axes[0, 1].set_title("Mode 22 stress")
axes[0, 1].set_xlabel("strain")
axes[0, 1].set_ylabel("stress (MPa)")
axes[0, 1].grid(True, alpha=0.25)
_set_axis_limits(axes[0, 1], curves["sig22_mpa"])
axes[1, 1].plot(curves["eps22"], curves["eps11_from_eps22"], color="k", linewidth=2)
axes[1, 1].set_title("Mode 22 lateral")
axes[1, 1].set_xlabel("strain")
axes[1, 1].set_ylabel("lateral strain")
axes[1, 1].grid(True, alpha=0.25)
_set_axis_limits(axes[1, 1], curves["eps11_from_eps22"], min_floor=-0.01, max_ceiling=0.0, pad_frac=0.0)
axes[2, 1].plot(curves["eps22"], curves["eps33_from_eps22"], color="k", linewidth=2)
axes[2, 1].set_title("Mode 22 eps33")
axes[2, 1].set_xlabel("strain")
axes[2, 1].set_ylabel("eps33")
axes[2, 1].grid(True, alpha=0.25)
_set_axis_limits(axes[2, 1], curves["eps33_from_eps22"])
axes[0, 2].plot(curves["eps12"], curves["sig12_mpa"], color="k", linewidth=2)
axes[0, 2].set_title("Mode 12 stress")
axes[0, 2].set_xlabel("strain")
axes[0, 2].set_ylabel("stress (MPa)")
axes[0, 2].grid(True, alpha=0.25)
_set_axis_limits(axes[0, 2], curves["sig12_mpa"])
axes[1, 2].axis("off")
axes[2, 2].axis("off")
fig.tight_layout()
return fig
def plot_condition_and_simulations_v5(
cond_coeffs_7x3: np.ndarray,
simulations_by_design: Dict[int, Dict[str, Dict[str, np.ndarray]]],
) -> plt.Figure:
cond = np.asarray(cond_coeffs_7x3, dtype=np.float32).reshape(7, 3)
fig, axes = plt.subplots(3, 3, figsize=(14, 12))
modes = ["11", "22", "12"]
colors = ["b", "c", "m", "g", "r"]
for col, mode in enumerate(modes):
x_cond = default_x_for_mode(mode)
stress_ys = [evaluate_cubic_no_intercept(cond[MODE_TO_ROW[mode]], x_cond)]
lateral_ys = []
eps33_ys = []
x_min, x_max = None, None
for _, sim in sorted(simulations_by_design.items()):
if mode in sim:
x = sim[mode]["strain"]
x_min = float(np.min(x))
x_max = float(np.max(x))
break
stress_row = MODE_TO_ROW[mode]
axes[0, col].plot(
x_cond,
evaluate_cubic_no_intercept(cond[stress_row], x_cond),
color="k",
linewidth=2,
label="Condition",
)
if mode in ("11", "22"):
lat_row = int(LATERAL_ROW[mode])
e33_row = int(EPS33_ROW[mode])
lateral_ys.append(evaluate_cubic_no_intercept(cond[lat_row], x_cond))
eps33_ys.append(evaluate_cubic_no_intercept(cond[e33_row], x_cond))
axes[1, col].plot(
x_cond,
lateral_ys[-1],
color="k",
linewidth=2,
label="Condition",
)
axes[2, col].plot(
x_cond,
eps33_ys[-1],
color="k",
linewidth=2,
label="Condition",
)
else:
axes[1, col].axis("off")
axes[2, col].axis("off")
for idx, (design_idx, sim) in enumerate(sorted(simulations_by_design.items(), key=lambda kv: kv[0])):
if mode not in sim:
continue
color = colors[idx % len(colors)]
data = sim[mode]
strain = np.asarray(data["strain"], dtype=np.float32)
stress = np.asarray(data["stress"], dtype=np.float32)
stress_ys.append(stress)
axes[0, col].plot([], [], color=color, linewidth=2, label=f"Gen {design_idx}")
axes[0, col].scatter(strain, stress, color=color, s=22, alpha=0.85, label="_nolegend_")
stress_coeffs = fit_cubic_no_intercept(strain, stress, degree=3)
if stress_coeffs is not None:
x_sim = np.linspace(float(np.min(strain)), float(np.max(strain)), 200, dtype=np.float32)
axes[0, col].plot(x_sim, evaluate_cubic_no_intercept(stress_coeffs, x_sim), color=color, linewidth=2, alpha=0.9, label="_nolegend_")
if mode in ("11", "22") and data.get("lateral") is not None:
lateral = np.asarray(data["lateral"], dtype=np.float32)
lateral_ys.append(lateral)
axes[1, col].plot([], [], color=color, linewidth=2, label=f"Gen {design_idx}")
axes[1, col].scatter(strain, lateral, color=color, s=22, alpha=0.85, label="_nolegend_")
lat_coeffs = fit_cubic_no_intercept(strain, lateral, degree=3)
if lat_coeffs is not None:
axes[1, col].plot(x_sim, evaluate_cubic_no_intercept(lat_coeffs, x_sim), color=color, linewidth=2, alpha=0.9, label="_nolegend_")
if mode in ("11", "22") and data.get("eps33") is not None:
eps33 = np.asarray(data["eps33"], dtype=np.float32)
eps33_ys.append(eps33)
axes[2, col].plot([], [], color=color, linewidth=2, label=f"Gen {design_idx}")
axes[2, col].scatter(strain, eps33, color=color, s=22, alpha=0.85, label="_nolegend_")
e33_coeffs = fit_cubic_no_intercept(strain, eps33, degree=3)
if e33_coeffs is not None:
axes[2, col].plot(x_sim, evaluate_cubic_no_intercept(e33_coeffs, x_sim), color=color, linewidth=2, alpha=0.9, label="_nolegend_")
if x_min is None or x_max is None or x_max <= x_min:
x_min = float(np.min(x_cond))
x_max = float(np.max(x_cond))
else:
x_min = min(float(np.min(x_cond)), x_min)
x_max = max(float(np.max(x_cond)), x_max)
axes[0, col].set_xlim(x_min, x_max)
if mode in ("11", "22"):
axes[1, col].set_xlim(x_min, x_max)
axes[2, col].set_xlim(x_min, x_max)
axes[0, col].set_title(f"Mode {mode} stress")
axes[0, col].set_xlabel("strain")
axes[0, col].set_ylabel("stress (MPa)")
axes[0, col].grid(True, alpha=0.25)
axes[0, col].legend(fontsize=8)
_set_axis_limits(axes[0, col], np.concatenate(stress_ys))
if mode in ("11", "22"):
axes[1, col].set_title(f"Mode {mode} lateral")
axes[1, col].set_xlabel("strain")
axes[1, col].set_ylabel("lateral strain")
axes[1, col].grid(True, alpha=0.25)
axes[1, col].legend(fontsize=8)
_set_axis_limits(axes[1, col], np.concatenate(lateral_ys), min_floor=-0.01, max_ceiling=0.0, pad_frac=0.0)
axes[2, col].set_title(f"Mode {mode} eps33")
axes[2, col].set_xlabel("strain")
axes[2, col].set_ylabel("eps33")
axes[2, col].grid(True, alpha=0.25)
axes[2, col].legend(fontsize=8)
_set_axis_limits(axes[2, col], np.concatenate(eps33_ys))
fig.tight_layout()
return fig