108 lines
4.5 KiB
Python
108 lines
4.5 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""Generate chart images for summary PPT."""
|
||
from pathlib import Path
|
||
import matplotlib.pyplot as plt
|
||
import matplotlib.patches as mpatches
|
||
import numpy as np
|
||
|
||
OUT = Path(__file__).parent
|
||
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei", "SimHei", "Arial"]
|
||
plt.rcParams["axes.unicode_minus"] = False
|
||
|
||
BLUE = "#4874CB"
|
||
ORANGE = "#EE822F"
|
||
DARK = "#44546A"
|
||
LIGHT = "#E7E6E6"
|
||
|
||
|
||
def workflow():
|
||
fig, ax = plt.subplots(figsize=(10, 4.2), facecolor="white")
|
||
ax.set_xlim(0, 10)
|
||
ax.set_ylim(0, 4.2)
|
||
ax.axis("off")
|
||
boxes = [
|
||
(0.3, 2.8, "JSON 配置\nsbc3d / eigen3d"),
|
||
(2.0, 2.8, "Mesh_3D\nSBCmesh.dat"),
|
||
(3.7, 2.8, "kernel 组装\nA / B 或 A,b"),
|
||
(5.4, 2.8, "求解器\ncomplexsolver / MATLAB"),
|
||
(7.1, 2.8, "post 后处理\nnormE / Ex/Ey/Ez"),
|
||
]
|
||
for i, (x, y, t) in enumerate(boxes):
|
||
ax.add_patch(mpatches.FancyBboxPatch((x, y), 1.4, 0.9, boxstyle="round,pad=0.05",
|
||
facecolor=BLUE if i < 3 else ORANGE, edgecolor=DARK, alpha=0.9))
|
||
ax.text(x + 0.7, y + 0.45, t, ha="center", va="center", fontsize=9, color="white", weight="bold")
|
||
if i < len(boxes) - 1:
|
||
ax.annotate("", xy=(x + 1.55, y + 0.45), xytext=(x + 1.4, y + 0.45),
|
||
arrowprops=dict(arrowstyle="->", color=DARK, lw=2))
|
||
ax.text(0.3, 1.5, "散射 FemType=4", fontsize=11, weight="bold", color=BLUE)
|
||
ax.text(0.3, 0.9, "Assemble → complexsolver(Ax=b) → Post → normE", fontsize=10, color=DARK)
|
||
ax.text(0.3, 0.2, "本征 FemType=5:Assemble → 导出 A/B COO → MATLAB eigs(A,B) → get_ele", fontsize=10, color=DARK)
|
||
fig.savefig(OUT / "workflow.png", dpi=150, bbox_inches="tight", facecolor="white")
|
||
plt.close(fig)
|
||
|
||
|
||
def metrics_bar():
|
||
labels = ["自由度 DOF", "nnz(A)", "nnz(B)", "残差 |r|"]
|
||
scatter_vals = [43632, 695844, 0, 6.2e-13]
|
||
# normalize for display - use log scale for nnz
|
||
fig, axes = plt.subplots(1, 2, figsize=(10, 3.8), facecolor="white")
|
||
|
||
ax = axes[0]
|
||
names = ["DOF", "nnz(A)", "|r| (log)"]
|
||
vals = [43632, 695844, 6.2e-13]
|
||
colors = [BLUE, ORANGE, "#75BD42"]
|
||
bars = ax.bar(names, [43632, 695844, 1e-12], color=colors, edgecolor=DARK)
|
||
ax.set_yscale("log")
|
||
ax.set_title("散射算例 FemType=4(SBCmesh)", fontsize=11, weight="bold", color=DARK)
|
||
ax.set_ylabel("数值(对数轴)")
|
||
for b, v in zip(bars, vals):
|
||
ax.text(b.get_x() + b.get_width() / 2, b.get_height() * 1.2, f"{v:.1e}" if v < 1 else f"{int(v)}",
|
||
ha="center", fontsize=9)
|
||
|
||
ax2 = axes[1]
|
||
names2 = ["nnz(A)", "nnz(B)", "顶点数"]
|
||
vals2 = [1289952, 43632, 6595] # approx from Av.txt lines
|
||
bars2 = ax2.bar(names2, vals2, color=[BLUE, ORANGE, "#30C0B4"], edgecolor=DARK)
|
||
ax2.set_title("本征算例 FemType=5(矩阵导出)", fontsize=11, weight="bold", color=DARK)
|
||
ax2.set_ylabel("非零元 / 节点数")
|
||
for b, v in zip(bars2, vals2):
|
||
ax2.text(b.get_x() + b.get_width() / 2, b.get_height() + max(vals2) * 0.02, f"{int(v)}",
|
||
ha="center", fontsize=9)
|
||
|
||
fig.tight_layout()
|
||
fig.savefig(OUT / "metrics.png", dpi=150, bbox_inches="tight", facecolor="white")
|
||
plt.close(fig)
|
||
|
||
|
||
def status_table():
|
||
fig, ax = plt.subplots(figsize=(9, 3.5), facecolor="white")
|
||
ax.axis("off")
|
||
cols = ["模块", "散射 FemType=4", "本征 FemType=5"]
|
||
rows = [
|
||
["3D 网格读取", "已完成 SBCmesh.dat", "已完成 SBCmesh.dat"],
|
||
["矩阵组装", "已完成 体积分+SBC+入射", "已完成 刚度A+质量B"],
|
||
["数值求解", "已完成 complexsolver", "进行中 MATLAB eigs"],
|
||
["后处理输出", "已完成 normE/Ex/Ey/Ez", "进行中 仅COO导出"],
|
||
["参考验证", "已完成 |r|~6e-13", "已完成 与MATLAB一致"],
|
||
]
|
||
table = ax.table(cellText=rows, colLabels=cols, loc="center", cellLoc="center")
|
||
table.auto_set_font_size(False)
|
||
table.set_fontsize(10)
|
||
table.scale(1, 1.6)
|
||
for (r, c), cell in table.get_celld().items():
|
||
if r == 0:
|
||
cell.set_facecolor(BLUE)
|
||
cell.set_text_props(color="white", weight="bold")
|
||
else:
|
||
cell.set_facecolor(LIGHT if r % 2 == 0 else "white")
|
||
ax.set_title("完成情况对照", fontsize=12, weight="bold", color=DARK, pad=20)
|
||
fig.savefig(OUT / "status_table.png", dpi=150, bbox_inches="tight", facecolor="white")
|
||
plt.close(fig)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
workflow()
|
||
metrics_bar()
|
||
status_table()
|
||
print("charts saved to", OUT)
|