Files
Atomizer/studies/M1_Mirror/m1_mirror_cost_reduction
Anto01 cb6b130908 feat(config): Add AtomizerSpec v2.0 schema and migrate all studies
Added JSON Schema:
- optimization_engine/schemas/atomizer_spec_v2.json

Migrated 28 studies to AtomizerSpec v2.0 format:
- Drone_Gimbal studies (1)
- M1_Mirror studies (21)
- M2_Mirror studies (2)
- SheetMetal_Bracket studies (4)

Each atomizer_spec.json is the unified configuration containing:
- Design variables with bounds and expressions
- Extractors (standard and custom)
- Objectives and constraints
- Optimization algorithm settings
- Canvas layout information
2026-01-20 13:11:23 -05:00
..

M1 Mirror Cost Reduction Optimization

TPE single-objective optimization targeting mass reduction while maintaining optical performance.

Created: 2025-12-17 Protocol: TPE (Tree-structured Parzen Estimator) with Weighted Sum Status: Ready to Run Baseline: Best design from V11-V15 campaign (Trial #725, WS=121.72)


1. Engineering Problem

1.1 Objective

Reduce the mass of the M1 telescope primary mirror while maintaining acceptable wavefront error (WFE) performance across operational elevation angles and manufacturing orientation.

1.2 Physical System

  • Component: M1 Primary Mirror Assembly with whiffle-tree support
  • Material: Zerodur Class 2 glass ceramic (E=91 GPa, density=2.53 g/cm³, CTE~0)
  • Baseline Mass: 91.02 kg
  • Loading: Self-weight gravity at multiple elevation angles
  • Boundary Conditions: 18-point whiffle-tree axial support, 3-point lateral support
  • Analysis Type: Linear static (Nastran SOL 101) with 4 subcases (20, 40, 60, 90 deg)

1.3 Optical Workflow

Reference: 20 deg (interferometer baseline)

Operational Tracking:
  - 40 deg - 20 deg = tracking deformation at 40 deg
  - 60 deg - 20 deg = tracking deformation at 60 deg

Manufacturing:
  - 90 deg - 20 deg = polishing correction needed

1.4 Cost Reduction Strategy

This study explores geometry parameters that affect mass:

  • blank_backface_angle: Increases blank taper, reducing material volume
  • inner_circular_rib_dia: Controls rib structure extent
  • whiffle_*: Support geometry (indirect mass effect via blank shape)

2. Mathematical Formulation

2.1 Objectives

Objective Goal Weight Formula Target Units
Operational 40-20 minimize 5.0 \text{RMS}_{filt}(Z_{40} - Z_{20}) 4.0 nm
Operational 60-20 minimize 5.0 \text{RMS}_{filt}(Z_{60} - Z_{20}) 10.0 nm
Manufacturing 90-20 minimize 2.0 \text{RMS}_{J1-J3}(Z_{90} - Z_{20}) 20.0 nm
Mass minimize 1.0 M1_Blank part mass - kg

Where:

  • Z_\theta = Zernike coefficients at elevation angle \theta
  • \text{RMS}_{filt} = RMS with J1-J4 (piston, tip, tilt, defocus) removed
  • \text{RMS}_{J1-J3} = RMS with only J1-J3 (piston, tip, tilt) removed

2.2 Weighted Sum Objective

f(\mathbf{x}) = 5 \cdot O_{40-20} + 5 \cdot O_{60-20} + 2 \cdot O_{mfg} + 1 \cdot M_{kg}

This formulation:

  • Prioritizes optical performance (5+5=10 weight on tracking)
  • Includes manufacturing workload (2 weight)
  • Adds mass as secondary objective (1 weight)

2.3 Design Variables

Parameter Symbol Bounds Baseline Units Enabled Description
whiffle_min w_{min} [30.0, 72.0] 58.63 mm Yes Whiffle tree minimum extent
whiffle_outer_to_vertical w_{ov} [60.0, 80.0] 77.96 deg Yes Whiffle outer to vertical angle
whiffle_triangle_closeness w_{tc} [65.0, 80.0] 67.33 mm Yes Whiffle triangle spacing
blank_backface_angle \beta [4.5, 5.0] 4.50 deg Yes Mirror blank backface taper
inner_circular_rib_dia d_{rib} [480.0, 620.0] 537.86 mm Yes Inner rib diameter
lateral_inner_angle \alpha_i [25.0, 30.0] 27.70 deg No (Fixed)
lateral_outer_angle \alpha_o [11.0, 17.0] 13.03 deg No (Fixed)
lateral_outer_pivot p_o [9.0, 12.0] 11.24 mm No (Fixed)
lateral_inner_pivot p_i [5.0, 12.0] 8.16 mm No (Fixed)
lateral_middle_pivot p_m [15.0, 27.0] 22.88 mm No (Fixed)
lateral_closeness c_l [9.5, 12.5] 9.84 mm No (Fixed)

Active Design Space: \mathbf{x} \in \mathbb{R}^{5} (5 enabled parameters)


3. Optimization Algorithm

3.1 TPE Configuration

Parameter Value Description
Algorithm TPE Tree-structured Parzen Estimator
n_trials 150 Total FEA simulations
n_startup_trials 15 Random exploration before TPE
multivariate True Model parameter correlations
n_ei_candidates 24 Expected improvement candidates
gamma 0.25 Good/bad split threshold
seed 42 Reproducibility

3.2 Explore/Exploit Balance

Trials 1-15:   Random sampling (exploration)
Trials 16-150: TPE-guided sampling (exploitation with adaptive exploration)

TPE dynamically balances exploration vs exploitation based on:
- Parzen estimator of "good" trials (top 25%)
- Expected improvement acquisition function
- Multivariate modeling of parameter correlations

3.3 Optimization Flow

┌─────────────────────────────────────────────────────────────────────┐
│                    TPE OPTIMIZATION LOOP                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  FOR trial = 1 to 150:                                              │
│  │                                                                   │
│  ├─ 1. SAMPLE PARAMETERS                                            │
│  │      └─ trial 1-15: Random (uniform)                             │
│  │      └─ trial 16+: TPE (Expected Improvement)                    │
│  │                                                                   │
│  ├─ 2. UPDATE NX GEOMETRY                                           │
│  │      └─ Import expressions to M1_Blank.prt                       │
│  │      └─ Rebuild geometry with DoUpdate()                         │
│  │                                                                   │
│  ├─ 3. EXTRACT MASS                                                 │
│  │      └─ MeasureManager.NewMassProperties()                       │
│  │      └─ Write _temp_mass.txt                                     │
│  │                                                                   │
│  ├─ 4. RUN FEA SIMULATION                                           │
│  │      └─ Update FEM mesh                                          │
│  │      └─ Solve Nastran SOL 101 (4 subcases)                       │
│  │      └─ Generate .op2 results                                    │
│  │                                                                   │
│  ├─ 5. EXTRACT OBJECTIVES                                           │
│  │      └─ Parse OP2 with ZernikeExtractor                          │
│  │      └─ Compute relative filtered RMS                            │
│  │      └─ Read mass from temp file                                 │
│  │                                                                   │
│  ├─ 6. COMPUTE WEIGHTED SUM                                         │
│  │      └─ WS = 5*obj40 + 5*obj60 + 2*mfg + 1*mass                  │
│  │                                                                   │
│  ├─ 7. ARCHIVE IF BEST                                              │
│  │      └─ Copy iteration folder to best_design_archive/            │
│  │                                                                   │
│  └─ 8. UPDATE OPTUNA STUDY                                          │
│         └─ Record trial value and user attributes                   │
│                                                                      │
│  END FOR                                                             │
│                                                                      │
│  SAVE FINAL RESULTS                                                  │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

4. Result Extraction Methods

4.1 Zernike WFE Extraction

Attribute Value
Extractor ZernikeExtractor.extract_relative()
Module optimization_engine.extractors.extract_zernike
Source .op2 file from NX Nastran
Output nm (nanometers)

Algorithm:

  1. Parse OP2 displacement results for target and reference subcases
  2. Fit Zernike polynomials (Noll indexing, J1-J50)
  3. Compute difference: \Delta Z_j = Z_j^{target} - Z_j^{ref}
  4. Filter low orders (J1-J4 for operational, J1-J3 for manufacturing)
  5. Compute RMS: \text{RMS} = \sqrt{\sum_{j} \Delta Z_j^2}

4.2 Part Mass Extraction

Attribute Value
Extractor MeasureManager.NewMassProperties()
Source M1_Blank.prt (NX part file)
Output kg (kilograms)

Algorithm:

  1. Get all solid bodies from M1_Blank part
  2. Create mass properties measurement with 99% accuracy
  3. Extract mass from measureBodies.Mass
  4. Write to _temp_mass.txt in iteration folder

Code:

# Mass extraction (in solve_simulation.py)
measureManager = part.MeasureManager
uc = part.UnitCollection
mass_units = [uc.GetBase("Area"), uc.GetBase("Volume"),
              uc.GetBase("Mass"), uc.GetBase("Length")]
measureBodies = measureManager.NewMassProperties(mass_units, 0.99, bodies)
mass_kg = measureBodies.Mass

5. Baseline Design (V11-V15 Best)

5.1 Source

Attribute Value
Study m1_mirror_adaptive_V14
Trial #725
Iteration iter242
Source FEA
Archived 2025-12-12

5.2 Baseline Objectives

Objective Value Target Status
40-20 5.99 nm 4.0 nm Above target
60-20 13.10 nm 10.0 nm Above target
MFG 26.28 nm 20.0 nm Above target
Mass 91.02 kg - Baseline
Weighted Sum 121.72 - -

5.3 Baseline Parameters

Parameter Value Units
lateral_inner_angle 27.70 deg
lateral_outer_angle 13.03 deg
lateral_outer_pivot 11.24 mm
lateral_inner_pivot 8.16 mm
lateral_middle_pivot 22.88 mm
lateral_closeness 9.84 mm
whiffle_min 58.63 mm
whiffle_outer_to_vertical 77.96 deg
whiffle_triangle_closeness 67.33 mm
blank_backface_angle 4.31 deg
inner_circular_rib_dia 537.86 mm

6. Study File Structure

m1_mirror_cost_reduction/
│
├── 1_setup/                              # INPUT CONFIGURATION
│   ├── model/                            # NX Model Files
│   │   ├── ASSY_M1.prt                   # Assembly
│   │   ├── M1_Blank.prt                  # Mirror blank (mass source)
│   │   ├── M1_Blank_fem1.fem             # FEM mesh
│   │   ├── M1_Blank_fem1_i.prt           # Idealized part
│   │   ├── M1_Vertical_Support_Skeleton.prt
│   │   ├── M1_Vertical_Support_Skeleton_fem1.fem
│   │   ├── M1_Vertical_Support_Skeleton_fem1_i.prt
│   │   ├── ASSY_M1_assyfem1.afm          # Assembly FEM
│   │   └── ASSY_M1_assyfem1_sim1.sim     # Simulation file
│   └── optimization_config.json          # Study configuration
│
├── 2_iterations/                         # FEA iteration folders
│   └── iter{N}/                          # Per-trial working directory
│       ├── [model files]                 # Copied NX files
│       ├── params.exp                    # Expression values
│       ├── _temp_mass.txt                # Extracted mass
│       ├── _temp_part_properties.json    # Full mass properties
│       ├── *.dat                         # Nastran input deck
│       ├── *.op2                         # Results (binary)
│       ├── *.f06                         # Results (text)
│       └── results/                      # Processed outputs
│
├── 3_results/                            # OUTPUT
│   ├── study.db                          # Optuna SQLite database
│   ├── optimization.log                  # Execution log
│   ├── optimization_summary.json         # Final results summary
│   └── best_design_archive/              # Archived best designs
│       └── {timestamp}/                  # Per-improvement snapshot
│           ├── [model files]
│           ├── params.exp
│           └── _archive_info.json
│
├── run_optimization.py                   # Main entry point
└── README.md                             # This documentation

7. Quick Start

7.1 Run Commands

# Navigate to study
cd C:\Users\antoi\Atomizer\studies\m1_mirror_cost_reduction

# Activate environment
conda activate atomizer

# Run optimization (150 trials)
python run_optimization.py --start --trials 150

# Resume if interrupted
python run_optimization.py --start --trials 150 --resume

# Single test trial
python run_optimization.py --test

7.2 Command Line Options

Option Default Description
--start - Required to begin optimization
--trials 100 Number of FEA trials to run
--resume False Resume from existing study.db
--test False Run single test trial

8. Expected Runtime

Phase Time per Trial Total (150 trials)
Geometry update ~45s ~1.9 hr
FEA solve ~90s ~3.8 hr
Extraction ~15s ~0.6 hr
Total ~2.5 min ~6-7 hours

9. Configuration Reference

File: 1_setup/optimization_config.json

Section Key Description
optimization.algorithm TPE Single-objective optimizer
optimization.n_trials 150 Total trials planned
optimization.n_startup_trials 15 Random exploration phase
optimization.multivariate true Model correlations
design_variables[] 11 params 5 enabled, 6 fixed
objectives[] 4 objectives WFE (3) + Mass (1)
nx_settings.nx_install_path DesigncenterNX2512 NX version

10. Success Criteria

Metric Target Priority
Mass reduction >3 kg (to <88 kg) Primary
40-20 degradation <2 nm increase Secondary
60-20 degradation <3 nm increase Secondary
MFG impact Acceptable increase Tertiary

11. References

  • Optuna Documentation: Tree-structured Parzen Estimator (TPE)
  • Noll, R.J. (1976). Zernike polynomials and atmospheric turbulence. JOSA.
  • V11-V15 Campaign: Previous optimization studies establishing baseline

Generated by Atomizer Framework - M1 Mirror Cost Reduction Study