# -*- 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)