feat: Add Zernike GNN surrogate module and M1 mirror V12/V13 studies

This commit introduces the GNN-based surrogate for Zernike mirror optimization
and the M1 mirror study progression from V12 (GNN validation) to V13 (pure NSGA-II).

## GNN Surrogate Module (optimization_engine/gnn/)

New module for Graph Neural Network surrogate prediction of mirror deformations:

- `polar_graph.py`: PolarMirrorGraph - fixed 3000-node polar grid structure
- `zernike_gnn.py`: ZernikeGNN with design-conditioned message passing
- `differentiable_zernike.py`: GPU-accelerated Zernike fitting and objectives
- `train_zernike_gnn.py`: ZernikeGNNTrainer with multi-task loss
- `gnn_optimizer.py`: ZernikeGNNOptimizer for turbo mode (~900k trials/hour)
- `extract_displacement_field.py`: OP2 to HDF5 field extraction
- `backfill_field_data.py`: Extract fields from existing FEA trials

Key innovation: Design-conditioned convolutions that modulate message passing
based on structural design parameters, enabling accurate field prediction.

## M1 Mirror Studies

### V12: GNN Field Prediction + FEA Validation
- Zernike GNN trained on V10/V11 FEA data (238 samples)
- Turbo mode: 5000 GNN predictions → top candidates → FEA validation
- Calibration workflow for GNN-to-FEA error correction
- Scripts: run_gnn_turbo.py, validate_gnn_best.py, compute_full_calibration.py

### V13: Pure NSGA-II FEA (Ground Truth)
- Seeds 217 FEA trials from V11+V12
- Pure multi-objective NSGA-II without any surrogate
- Establishes ground-truth Pareto front for GNN accuracy evaluation
- Narrowed blank_backface_angle range to [4.0, 5.0]

## Documentation Updates

- SYS_14: Added Zernike GNN section with architecture diagrams
- CLAUDE.md: Added GNN module reference and quick start
- V13 README: Study documentation with seeding strategy

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Antoine
2025-12-10 08:44:04 -05:00
parent c6f39bfd6c
commit 96b196de58
22 changed files with 8329 additions and 2 deletions

View File

@@ -0,0 +1,194 @@
{
"$schema": "Atomizer M1 Mirror NSGA-II Pure FEA Optimization V13",
"study_name": "m1_mirror_adaptive_V13",
"description": "V13 - Pure NSGA-II multi-objective optimization with FEA only. No surrogate. Seeds from V11+V12 FEA data.",
"source_studies": {
"v11": {
"database": "../m1_mirror_adaptive_V11/3_results/study.db",
"description": "V11 FEA trials (107 from V10 + V11)"
},
"v12": {
"database": "../m1_mirror_adaptive_V12/3_results/study.db",
"description": "V12 FEA trials from GNN validation"
}
},
"design_variables": [
{
"name": "lateral_inner_angle",
"expression_name": "lateral_inner_angle",
"min": 25.0,
"max": 28.5,
"baseline": 26.79,
"units": "degrees",
"enabled": true
},
{
"name": "lateral_outer_angle",
"expression_name": "lateral_outer_angle",
"min": 13.0,
"max": 17.0,
"baseline": 14.64,
"units": "degrees",
"enabled": true
},
{
"name": "lateral_outer_pivot",
"expression_name": "lateral_outer_pivot",
"min": 9.0,
"max": 12.0,
"baseline": 10.40,
"units": "mm",
"enabled": true
},
{
"name": "lateral_inner_pivot",
"expression_name": "lateral_inner_pivot",
"min": 9.0,
"max": 12.0,
"baseline": 10.07,
"units": "mm",
"enabled": true
},
{
"name": "lateral_middle_pivot",
"expression_name": "lateral_middle_pivot",
"min": 18.0,
"max": 23.0,
"baseline": 20.73,
"units": "mm",
"enabled": true
},
{
"name": "lateral_closeness",
"expression_name": "lateral_closeness",
"min": 9.5,
"max": 12.5,
"baseline": 11.02,
"units": "mm",
"enabled": true
},
{
"name": "whiffle_min",
"expression_name": "whiffle_min",
"min": 35.0,
"max": 55.0,
"baseline": 40.55,
"units": "mm",
"enabled": true
},
{
"name": "whiffle_outer_to_vertical",
"expression_name": "whiffle_outer_to_vertical",
"min": 68.0,
"max": 80.0,
"baseline": 75.67,
"units": "degrees",
"enabled": true
},
{
"name": "whiffle_triangle_closeness",
"expression_name": "whiffle_triangle_closeness",
"min": 50.0,
"max": 65.0,
"baseline": 60.00,
"units": "mm",
"enabled": true
},
{
"name": "blank_backface_angle",
"expression_name": "blank_backface_angle",
"min": 4,
"max": 5.0,
"baseline": 4.23,
"units": "degrees",
"enabled": true
},
{
"name": "inner_circular_rib_dia",
"expression_name": "inner_circular_rib_dia",
"min": 480.0,
"max": 620.0,
"baseline": 534.00,
"units": "mm",
"enabled": true
}
],
"objectives": [
{
"name": "rel_filtered_rms_40_vs_20",
"description": "Filtered RMS WFE at 40 deg relative to 20 deg reference (operational tracking)",
"direction": "minimize",
"weight": 5.0,
"target": 4.0,
"units": "nm",
"extractor_config": {
"target_subcase": "3",
"reference_subcase": "2",
"metric": "relative_filtered_rms_nm"
}
},
{
"name": "rel_filtered_rms_60_vs_20",
"description": "Filtered RMS WFE at 60 deg relative to 20 deg reference (operational tracking)",
"direction": "minimize",
"weight": 5.0,
"target": 10.0,
"units": "nm",
"extractor_config": {
"target_subcase": "4",
"reference_subcase": "2",
"metric": "relative_filtered_rms_nm"
}
},
{
"name": "mfg_90_optician_workload",
"description": "Manufacturing deformation at 90 deg polishing (J1-J3 filtered RMS)",
"direction": "minimize",
"weight": 1.0,
"target": 20.0,
"units": "nm",
"extractor_config": {
"target_subcase": "1",
"reference_subcase": "2",
"metric": "relative_rms_filter_j1to3"
}
}
],
"zernike_settings": {
"n_modes": 50,
"filter_low_orders": 4,
"displacement_unit": "mm",
"subcases": ["1", "2", "3", "4"],
"subcase_labels": {"1": "90deg", "2": "20deg", "3": "40deg", "4": "60deg"},
"reference_subcase": "2"
},
"nsga2_settings": {
"population_size": 20,
"n_generations": 50,
"crossover_prob": 0.9,
"mutation_prob": 0.1,
"seed_from_prior": true
},
"nx_settings": {
"nx_install_path": "C:\\Program Files\\Siemens\\NX2506",
"sim_file": "ASSY_M1_assyfem1_sim1.sim",
"solution_name": "Solution 1",
"op2_pattern": "*-solution_1.op2",
"simulation_timeout_s": 600,
"journal_timeout_s": 120,
"op2_timeout_s": 1800,
"auto_start_nx": true
},
"dashboard_settings": {
"trial_source_tag": true,
"fea_marker": "circle",
"fea_color": "#4CAF50"
}
}