Files
Atomizer/studies
Anto01 8b14f6e800 feat: Add robust NX expression import system for all expression types
Major Enhancement:
- Implemented .exp file-based expression updates via NX journal scripts
- Fixes critical issue with feature-linked expressions (e.g., hole_count)
- Supports ALL NX expression types including binary-stored ones
- Full 4D design space validation completed successfully

New Components:
1. import_expressions.py - NX journal for .exp file import
   - Uses NXOpen.ExpressionCollection.ImportFromFile()
   - Replace mode overwrites existing values
   - Automatic model update and save
   - Comprehensive error handling

2. export_expressions.py - NX journal for .exp file export
   - Exports all expressions to text format
   - Used for unit detection and verification

3. Enhanced nx_updater.py
   - New update_expressions_via_import() method
   - Automatic unit detection from .exp export
   - Creates study-variable-only .exp files
   - Replaces fragile binary .prt editing

Technical Details:
- .exp Format: [Units]name=value (e.g., [MilliMeter]beam_length=5000)
- Unitless expressions: name=value (e.g., hole_count=10)
- Robustness: Native NX functionality, no regex failures
- Performance: < 1 second per update operation

Validation:
- Simple Beam Optimization study (4D design space)
  * beam_half_core_thickness: 10-40 mm
  * beam_face_thickness: 10-40 mm
  * holes_diameter: 150-450 mm
  * hole_count: 5-15 (integer)

Results:
 3-trial validation completed successfully
 All 4 variables update correctly in all trials
 Mesh adaptation verified (hole_count: 6, 15, 11 → different mesh sizes)
 Trial 0: 5373 CQUAD4 elements (6 holes)
 Trial 1: 5158 CQUAD4 + 1 CTRIA3 (15 holes)
 Trial 2: 5318 CQUAD4 (11 holes)

Problem Solved:
- hole_count expression was not updating with binary .prt editing
- Expression stored in feature parameter, not accessible via text regex
- Binary format prevented reliable text-based updates

Solution:
- Use NX native expression import/export
- Works for ALL expressions (text and binary-stored)
- Automatic unit handling
- Model update integrated in journal

Documentation:
- New: docs/NX_EXPRESSION_IMPORT_SYSTEM.md (comprehensive guide)
- Updated: CHANGELOG.md with Phase 3.2 progress
- Study: studies/simple_beam_optimization/ (complete example)

Files Added:
- optimization_engine/import_expressions.py
- optimization_engine/export_expressions.py
- docs/NX_EXPRESSION_IMPORT_SYSTEM.md
- studies/simple_beam_optimization/ (full study)

Files Modified:
- optimization_engine/nx_updater.py
- CHANGELOG.md

Compatibility:
- NX 2412 tested and verified
- Python 3.10+
- Works with all NX expression types

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-17 12:34:06 -05:00
..

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_minimization not test1
  • 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 logs
  • optimization_engine/plugins/pre_solve/optimization_logger.py - Creates high-level optimization.log
  • optimization_engine/plugins/post_extraction/log_results.py - Appends results to trial logs
  • optimization_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