Documentation: - Add docs/06_PHYSICS/ with Zernike fundamentals and OPD method docs - Add docs/guides/CMA-ES_EXPLAINED.md optimization guide - Update CLAUDE.md and ATOMIZER_CONTEXT.md with current architecture - Update OP_01_CREATE_STUDY protocol Planning: - Add DYNAMIC_RESPONSE plans for random vibration/PSD support - Add OPTIMIZATION_ENGINE_MIGRATION_PLAN for code reorganization Insights System: - Update design_space, modal_analysis, stress_field, thermal_field insights - Improve error handling and data validation NX Journals: - Add analyze_wfe_zernike.py for Zernike WFE analysis - Add capture_study_images.py for automated screenshots - Add extract_expressions.py and introspect_part.py utilities - Add user_generated_journals/journal_top_view_image_taking.py Tests & Tools: - Add comprehensive Zernike OPD test suite - Add audit_v10 tests for WFE validation - Add tools for Pareto graphs and mirror data extraction - Add migrate_studies_to_topics.py utility Knowledge Base: - Initialize LAC (Learning Atomizer Core) with failure/success patterns Dashboard: - Update Setup.tsx and launch_dashboard.py - Add restart-dev.bat helper script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
"""Debug script to compare figure.dat vs BDF node coordinates."""
|
|
import sys
|
|
from pathlib import Path
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
|
import numpy as np
|
|
import logging
|
|
logging.disable(logging.WARNING)
|
|
|
|
study_dir = Path(r"c:\Users\antoi\Atomizer\studies\M1_Mirror\m1_mirror_cost_reduction_V9")
|
|
|
|
# Load figure.dat
|
|
from optimization_engine.extractors.extract_zernike_figure import load_figure_geometry
|
|
fig_geo = load_figure_geometry(study_dir / "1_setup/model/figure.dat")
|
|
fig_nids = set(fig_geo.keys())
|
|
|
|
# Find OP2 and BDF
|
|
op2_file = list(study_dir.glob("3_results/best_design_archive/**/*.op2"))[0]
|
|
bdf_file = op2_file.with_suffix(".dat")
|
|
|
|
# Load BDF
|
|
from pyNastran.bdf.bdf import BDF
|
|
bdf = BDF(log=None, debug=False)
|
|
bdf.read_bdf(str(bdf_file))
|
|
bdf_nids = set(bdf.nodes.keys())
|
|
|
|
# Load OP2
|
|
from pyNastran.op2.op2 import OP2
|
|
op2 = OP2(log=None, debug=False)
|
|
op2.read_op2(str(op2_file))
|
|
disps = op2.displacements
|
|
first_key = list(disps.keys())[0]
|
|
op2_nids = set(int(n) for n in disps[first_key].node_gridtype[:,0])
|
|
|
|
print(f"Figure.dat nodes: {len(fig_nids)}")
|
|
print(f"BDF nodes: {len(bdf_nids)}")
|
|
print(f"OP2 nodes: {len(op2_nids)}")
|
|
|
|
print()
|
|
print(f"Figure ^ BDF: {len(fig_nids & bdf_nids)}")
|
|
print(f"Figure ^ OP2: {len(fig_nids & op2_nids)}")
|
|
print(f"BDF ^ OP2: {len(bdf_nids & op2_nids)}")
|
|
|
|
# Sample coords - use a node in all three
|
|
common_nids = list(fig_nids & bdf_nids & op2_nids)[:5]
|
|
print()
|
|
print("Sample common node coords comparison:")
|
|
z_diffs = []
|
|
for nid in common_nids:
|
|
fig_pos = fig_geo[nid]
|
|
bdf_pos = bdf.nodes[nid].get_position()
|
|
diff = np.array(fig_pos) - bdf_pos
|
|
z_diffs.append(diff[2])
|
|
print(f" Node {nid}:")
|
|
print(f" Figure: ({fig_pos[0]:.6f}, {fig_pos[1]:.6f}, {fig_pos[2]:.9f})")
|
|
print(f" BDF: ({bdf_pos[0]:.6f}, {bdf_pos[1]:.6f}, {bdf_pos[2]:.9f})")
|
|
print(f" Z diff: {diff[2]*1e6:.3f} nm")
|
|
|
|
# Statistics on all matching nodes
|
|
all_common = fig_nids & bdf_nids
|
|
all_z_diffs = []
|
|
all_xy_diffs = []
|
|
for nid in all_common:
|
|
fig_pos = np.array(fig_geo[nid])
|
|
bdf_pos = bdf.nodes[nid].get_position()
|
|
diff = fig_pos - bdf_pos
|
|
all_z_diffs.append(diff[2])
|
|
all_xy_diffs.append(np.sqrt(diff[0]**2 + diff[1]**2))
|
|
|
|
all_z_diffs = np.array(all_z_diffs)
|
|
all_xy_diffs = np.array(all_xy_diffs)
|
|
|
|
print()
|
|
print(f"=== ALL {len(all_common)} COMMON NODES ===")
|
|
print(f"Z difference (figure - BDF):")
|
|
print(f" Min: {all_z_diffs.min()*1e6:.3f} nm")
|
|
print(f" Max: {all_z_diffs.max()*1e6:.3f} nm")
|
|
print(f" Mean: {all_z_diffs.mean()*1e6:.3f} nm")
|
|
print(f" RMS: {np.sqrt(np.mean(all_z_diffs**2))*1e6:.3f} nm")
|
|
print()
|
|
print(f"XY difference (figure - BDF):")
|
|
print(f" Max: {all_xy_diffs.max()*1e3:.6f} um")
|
|
print(f" RMS: {np.sqrt(np.mean(all_xy_diffs**2))*1e3:.6f} um")
|