Files
Atomizer/examples/optimization_config_zernike_mirror.json
Antoine ec5e42d733 feat: Add M1 mirror Zernike optimization with correct RMS calculation
Major improvements to telescope mirror optimization workflow:

Assembly FEM Workflow (solve_simulation.py):
- Fixed multi-part assembly FEM update sequence
- Use ImportFromFile() for reliable expression updates
- Add DuplicateNodesCheckBuilder with MergeOccurrenceNodes=True
- Switch to Foreground solve mode for multi-subcase solutions
- Add detailed logging and diagnostics for node merge operations

Zernike RMS Calculation:
- CRITICAL FIX: Use correct surface-based RMS formula
  - Global RMS = sqrt(mean(W^2)) from actual WFE values
  - Filtered RMS = sqrt(mean(W_residual^2)) after removing low-order fit
  - This matches zernike_Post_Script_NX.py (optical standard)
- Previous WRONG formula was: sqrt(sum(coeffs^2))
- Add compute_rms_filter_j1to3() for optician workload metric

Subcase Mapping:
- Fix subcase mapping to match NX model:
  - Subcase 1 = 90 deg (polishing orientation)
  - Subcase 2 = 20 deg (reference)
  - Subcase 3 = 40 deg
  - Subcase 4 = 60 deg

New Study: M1 Mirror Zernike Optimization
- Full optimization config with 11 design variables
- 3 objectives: rel_filtered_rms_40_vs_20, rel_filtered_rms_60_vs_20, mfg_90_optician_workload
- Neural surrogate support for accelerated optimization

Documentation:
- Update ZERNIKE_INTEGRATION.md with correct RMS formula
- Update ASSEMBLY_FEM_WORKFLOW.md with expression import and node merge details
- Add reference scripts from original zernike_Post_Script_NX.py

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 16:30:15 -05:00

125 lines
3.0 KiB
JSON

{
"$schema": "Atomizer Optimization Config - Telescope Mirror Zernike Optimization",
"_description": "Example configuration for optimizing telescope mirror support structures using Zernike wavefront error metrics",
"study_name": "mirror_wfe_optimization",
"design_variables": [
{
"name": "support_ring_radius",
"expression_name": "support_radius",
"min": 150.0,
"max": 250.0,
"units": "mm",
"description": "Radial position of support ring"
},
{
"name": "support_count",
"expression_name": "n_supports",
"min": 3,
"max": 12,
"type": "integer",
"units": "count",
"description": "Number of support points"
},
{
"name": "support_stiffness",
"expression_name": "k_support",
"min": 1000.0,
"max": 50000.0,
"units": "N/mm",
"description": "Support spring stiffness"
}
],
"objectives": [
{
"name": "filtered_rms_20deg",
"description": "Filtered RMS WFE at 20 deg elevation (operational)",
"direction": "minimize",
"extractor": "zernike",
"extractor_config": {
"subcase": "20",
"metric": "filtered_rms_nm",
"displacement_unit": "mm",
"n_modes": 50,
"filter_orders": 4
}
},
{
"name": "mass",
"description": "Total mirror assembly mass",
"direction": "minimize",
"extractor": "mass_from_expression",
"extractor_config": {
"expression_name": "total_mass"
}
}
],
"constraints": [
{
"name": "max_stress",
"description": "Maximum von Mises stress in mirror",
"type": "upper_bound",
"threshold": 5.0,
"units": "MPa",
"extractor": "von_mises_stress",
"extractor_config": {
"subcase": "90"
}
},
{
"name": "astigmatism_limit",
"description": "Astigmatism RMS at polishing orientation",
"type": "upper_bound",
"threshold": 50.0,
"units": "nm",
"extractor": "zernike",
"extractor_config": {
"subcase": "90",
"metric": "astigmatism_rms_nm"
}
}
],
"optimization_settings": {
"n_trials": 200,
"sampler": "NSGA-II",
"protocol": 11,
"n_startup_trials": 30,
"seed": 42
},
"simulation_settings": {
"solver": "NX Nastran",
"solution_name": null,
"required_subcases": [20, 40, 60, 90],
"op2_pattern": "*-solution_1.op2"
},
"zernike_settings": {
"_description": "Global Zernike analysis settings",
"n_modes": 50,
"filter_low_orders": 4,
"displacement_unit": "mm",
"reference_subcase": "20",
"polishing_subcase": "90",
"operational_subcases": ["20", "40", "60"],
"metrics_to_log": [
"global_rms_nm",
"filtered_rms_nm",
"astigmatism_rms_nm",
"coma_rms_nm",
"trefoil_rms_nm",
"spherical_nm"
]
},
"output_settings": {
"save_zernike_coefficients": true,
"generate_html_reports": true,
"export_exp_file": true
}
}