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>
6.2 KiB
Assembly FEM Optimization Workflow
This document describes the multi-part assembly FEM workflow used when optimizing complex assemblies with .afm (Assembly FEM) files.
Overview
Assembly FEMs have a more complex dependency chain than single-part simulations:
.prt (geometry) → _fem1.fem (component mesh) → .afm (assembly mesh) → .sim (solution)
Each level must be updated in sequence when design parameters change.
When This Workflow Applies
This workflow is automatically triggered when:
- The working directory contains
.afmfiles - Multiple
.femfiles exist (component meshes) - Multiple
.prtfiles exist (component geometry)
Examples:
- M1 Mirror assembly (M1_Blank + M1_Vertical_Support_Skeleton)
- Multi-component mechanical assemblies
- Any NX assembly where components have separate FEM files
The 4-Step Workflow
Step 1: Update Expressions in Geometry Part (.prt)
Open M1_Blank.prt
├── Find and update design expressions
│ ├── whiffle_min = 42.5
│ ├── whiffle_outer_to_vertical = 75.0
│ └── inner_circular_rib_dia = 550.0
├── Rebuild geometry (DoUpdate)
└── Save part
The .prt file contains the parametric CAD model with expressions that drive dimensions. These expressions are updated with new design parameter values, then the geometry is rebuilt.
Step 2: Update Component FEM Files (.fem)
For each component FEM:
├── Open M1_Blank_fem1.fem
│ ├── UpdateFemodel() - regenerates mesh from updated geometry
│ └── Save FEM
├── Open M1_Vertical_Support_Skeleton_fem1.fem
│ ├── UpdateFemodel()
│ └── Save FEM
└── ... (repeat for all component FEMs)
Each component FEM is linked to its source geometry. UpdateFemodel() regenerates the mesh based on the updated geometry.
Step 3: Update Assembly FEM (.afm)
Open ASSY_M1_assyfem1.afm
├── UpdateFemodel() - updates assembly mesh
├── Merge coincident nodes (at component interfaces)
├── Resolve labeling conflicts (duplicate node/element IDs)
└── Save AFM
The assembly FEM combines component meshes. This step:
- Reconnects meshes at shared interfaces
- Resolves numbering conflicts between component meshes
- Ensures mesh continuity for accurate analysis
Step 4: Solve Simulation (.sim)
Open ASSY_M1_assyfem1_sim1.sim
├── Execute solve
│ ├── Foreground mode for all solutions
│ └── or Background mode for specific solution
└── Save simulation
The simulation file references the assembly FEM and contains solution setup (loads, constraints, subcases).
File Dependencies
M1 Mirror Example:
M1_Blank.prt ─────────────────────> M1_Blank_fem1.fem ─────────┐
│ │ │
│ (expressions) │ (component mesh) │
↓ ↓ │
M1_Vertical_Support_Skeleton.prt ──> M1_..._Skeleton_fem1.fem ─┤
│
↓
ASSY_M1_assyfem1.afm ──> ASSY_M1_assyfem1_sim1.sim
(assembly mesh) (solution)
API Functions Used
| Step | NX API Call | Purpose |
|---|---|---|
| 1 | OpenBase() |
Open .prt file |
| 1 | ImportFromFile() |
Import expressions from .exp file (preferred) |
| 1 | DoUpdate() |
Rebuild geometry |
| 2-3 | UpdateFemodel() |
Regenerate mesh from geometry |
| 3 | DuplicateNodesCheckBuilder |
Merge coincident nodes at interfaces |
| 3 | MergeOccurrenceNodes = True |
Critical: enables cross-component merge |
| 4 | SolveAllSolutions() |
Execute FEA (Foreground mode recommended) |
Expression Update Method
The recommended approach uses expression file import:
# Write expressions to .exp file
with open(exp_path, 'w') as f:
for name, value in expressions.items():
unit = get_unit_for_expression(name)
f.write(f"[{unit}]{name}={value}\n")
# Import into part
modified, errors = workPart.Expressions.ImportFromFile(
exp_path,
NXOpen.ExpressionCollection.ImportMode.Replace
)
This is more reliable than EditExpressionWithUnits() for batch updates.
Error Handling
Common issues and solutions:
"Update undo happened"
- Geometry update failed due to constraint violations
- Check expression values are within valid ranges
- May need to adjust parameter bounds
"This operation can only be done on the work part"
- Work part not properly set before operation
- Use
SetWork()to make target part the work part
Node merge warnings
- Manual intervention may be needed for complex interfaces
- Check mesh connectivity in NX after solve
"Billion nm" RMS values
- Indicates node merging failed - coincident nodes not properly merged
- Check
MergeOccurrenceNodes = Trueis set - Verify tolerance (0.01 mm recommended)
- Run node merge after every FEM update, not just once
Configuration
The workflow auto-detects assembly FEMs, but you can configure behavior:
{
"nx_settings": {
"expression_part": "M1_Blank", // Override auto-detection
"component_fems": [ // Explicit list of FEMs to update
"M1_Blank_fem1.fem",
"M1_Vertical_Support_Skeleton_fem1.fem"
],
"afm_file": "ASSY_M1_assyfem1.afm"
}
}
Implementation Reference
See optimization_engine/solve_simulation.py for the full implementation:
detect_assembly_fem()- Detects if assembly workflow neededupdate_expressions_in_part()- Step 1 implementationupdate_fem_part()- Step 2 implementationupdate_assembly_fem()- Step 3 implementationsolve_simulation_file()- Step 4 implementation
Tips
- Start with baseline solve: Before optimization, manually verify the full workflow completes in NX
- Check mesh quality: Poor mesh quality after updates can cause solve failures
- Monitor memory: Assembly FEMs with many components use significant memory
- Use Foreground mode: For multi-subcase solutions, Foreground mode ensures all subcases complete