Critical bug fix for LLM mode optimization: **Problem**: - NXParameterUpdater.update_expressions() uses NX journal to import expressions (default use_nx_import=True) - The NX journal directly updates the PRT file on disk and saves it - But then run_optimization.py was calling updater.save() afterwards - save() writes self.content (loaded at initialization) back to file - This overwrote the NX journal changes with stale binary content! **Result**: All optimization trials produced identical FEM results because the model was never actually updated. **Fixes**: 1. Removed updater.save() call from model_updater closure in run_optimization.py 2. Added theSession.Parts.CloseAll() in import_expressions.py to ensure changes are flushed and file is released 3. Fixed test_phase_3_2_e2e.py variable name (best_trial_file → results_file) **Testing**: Verified expressions persist to disk correctly with standalone test. Next step: Address remaining issue where FEM results are still identical (likely solve journal not reloading updated PRT).
Atomizer Studies Directory
This directory contains optimization studies for the Atomizer framework. Each study is a self-contained workspace for running NX optimization campaigns.
Directory Structure
studies/
├── README.md # This file
├── _templates/ # Study templates for quick setup
│ ├── basic_stress_optimization/
│ ├── multi_objective/
│ └── constrained_optimization/
├── _archive/ # Completed/old studies
│ └── YYYY-MM-DD_study_name/
└── [active_studies]/ # Your active optimization studies
└── bracket_stress_minimization/ # Example study
Study Folder Structure
Each study should follow this standardized structure:
study_name/
├── README.md # Study description, objectives, notes
├── optimization_config.json # Atomizer configuration file
│
├── model/ # FEA model files (NX or other solvers)
│ ├── model.prt # NX part file
│ ├── model.sim # NX Simcenter simulation file
│ ├── model.fem # FEM file
│ └── assembly.asm # NX assembly (if applicable)
│
├── optimization_results/ # Generated by Atomizer (DO NOT COMMIT)
│ ├── optimization.log # High-level optimization progress log
│ ├── trial_logs/ # Detailed iteration logs (one per trial)
│ │ ├── trial_000_YYYYMMDD_HHMMSS.log
│ │ ├── trial_001_YYYYMMDD_HHMMSS.log
│ │ └── ...
│ ├── history.json # Complete optimization history
│ ├── history.csv # CSV format for analysis
│ ├── optimization_summary.json # Best results summary
│ ├── study_*.db # Optuna database files
│ └── study_*_metadata.json # Study metadata for resumption
│
├── analysis/ # Post-optimization analysis
│ ├── plots/ # Generated visualizations
│ ├── reports/ # Generated PDF/HTML reports
│ └── sensitivity_analysis.md # Analysis notes
│
└── notes.md # Engineering notes, decisions, insights
Creating a New Study
Option 1: From Template
# Copy a template
cp -r studies/_templates/basic_stress_optimization studies/my_new_study
cd studies/my_new_study
# Edit the configuration
# - Update optimization_config.json
# - Place your .sim, .prt, .fem files in model/
# - Update README.md with study objectives
Option 2: Manual Setup
# Create study directory
mkdir -p studies/my_study/{model,analysis/plots,analysis/reports}
# Create config file
# (see _templates/ for examples)
# Add your files
# - Place all FEA files (.prt, .sim, .fem) in model/
# - Edit optimization_config.json
Running an Optimization
# Navigate to project root
cd /path/to/Atomizer
# Run optimization for a study
python run_study.py --study studies/my_study
# Or use the full path to config
python -c "from optimization_engine.runner import OptimizationRunner; ..."
Configuration File Format
The optimization_config.json file defines the optimization setup:
{
"design_variables": [
{
"name": "thickness",
"type": "continuous",
"bounds": [3.0, 8.0],
"units": "mm",
"initial_value": 5.0
}
],
"objectives": [
{
"name": "minimize_stress",
"description": "Minimize maximum von Mises stress",
"extractor": "stress_extractor",
"metric": "max_von_mises",
"direction": "minimize",
"weight": 1.0,
"units": "MPa"
}
],
"constraints": [
{
"name": "displacement_limit",
"description": "Maximum allowable displacement",
"extractor": "displacement_extractor",
"metric": "max_displacement",
"type": "upper_bound",
"limit": 1.0,
"units": "mm"
}
],
"optimization_settings": {
"n_trials": 50,
"sampler": "TPE",
"n_startup_trials": 20,
"tpe_n_ei_candidates": 24,
"tpe_multivariate": true
},
"model_info": {
"sim_file": "model/model.sim",
"note": "Brief description"
}
}
Results Organization
All optimization results are stored in optimization_results/ within each study folder.
Optimization Log (optimization.log)
High-level overview of the entire optimization run:
- Optimization configuration (design variables, objectives, constraints)
- One compact line per trial showing design variables and results
- Easy to scan and monitor optimization progress
- Perfect for quick reviews and debugging
Example format:
[08:15:35] Trial 0 START | tip_thickness=20.450, support_angle=32.100
[08:15:42] Trial 0 COMPLETE | max_von_mises=245.320, max_displacement=0.856
[08:15:45] Trial 1 START | tip_thickness=18.230, support_angle=28.900
[08:15:51] Trial 1 COMPLETE | max_von_mises=268.450, max_displacement=0.923
Trial Logs (trial_logs/)
Detailed per-trial logs showing complete iteration trace:
- Design variable values for the trial
- Complete optimization configuration
- Execution timeline (pre_solve, solve, post_solve, extraction)
- Extracted results (stress, displacement, etc.)
- Constraint evaluations
- Hook execution trace
- Solver output and warnings
Example: trial_005_20251116_143022.log
These logs are invaluable for:
- Debugging failed trials
- Understanding what happened in specific iterations
- Verifying solver behavior
- Tracking hook execution
History Files
Structured data for analysis and visualization:
- history.json: Complete trial-by-trial results in JSON format
- history.csv: Same data in CSV for Excel/plotting
- optimization_summary.json: Best parameters and final results
Optuna Database
Study persistence for resuming optimizations:
- study_NAME.db: SQLite database storing all trial data
- study_NAME_metadata.json: Study metadata and configuration hash
The database allows you to:
- Resume interrupted optimizations
- Add more trials to a completed study
- Query optimization history programmatically
Best Practices
Study Naming
- Use descriptive names:
bracket_stress_minimizationnottest1 - Include objective:
wing_mass_displacement_tradeoff - Version if iterating:
bracket_v2_reduced_mesh
Documentation
- Always fill out README.md in each study folder
- Document design decisions in notes.md
- Keep analysis/ folder updated with plots and reports
Version Control
Add to .gitignore:
studies/*/optimization_results/
studies/*/analysis/plots/
studies/*/__pycache__/
Commit to git:
studies/*/README.md
studies/*/optimization_config.json
studies/*/notes.md
studies/*/model/*.sim
studies/*/model/*.prt (optional - large CAD files)
studies/*/model/*.fem
Archiving Completed Studies
When a study is complete:
# Archive the study
mv studies/completed_study studies/_archive/2025-11-16_completed_study
# Update _archive/README.md with study summary
Study Templates
Basic Stress Optimization
- Single objective: minimize stress
- Single design variable
- Simple mesh
- Good for learning/testing
Multi-Objective Optimization
- Multiple competing objectives (stress, mass, displacement)
- Pareto front analysis
- Weighted sum approach
Constrained Optimization
- Objectives with hard constraints
- Demonstrates constraint handling
- Pruned trials when constraints violated
Troubleshooting
Study won't resume
Check that optimization_config.json hasn't changed. The config hash is stored in metadata and verified on resume.
Missing trial logs or optimization.log
Ensure logging plugins are enabled:
optimization_engine/plugins/pre_solve/detailed_logger.py- Creates detailed trial logsoptimization_engine/plugins/pre_solve/optimization_logger.py- Creates high-level optimization.logoptimization_engine/plugins/post_extraction/log_results.py- Appends results to trial logsoptimization_engine/plugins/post_extraction/optimization_logger_results.py- Appends results to optimization.log
Results directory missing
The directory is created automatically on first run. Check file permissions.
Advanced: Custom Hooks
Studies can include custom hooks in a hooks/ folder:
my_study/
├── hooks/
│ ├── pre_solve/
│ │ └── custom_parameterization.py
│ └── post_extraction/
│ └── custom_objective.py
└── ...
These hooks are automatically loaded if present.
Questions?
- See main README.md for Atomizer documentation
- See DEVELOPMENT_ROADMAP.md for planned features
- Check docs/ for detailed guides