# Bracket Stiffness Optimization Study Multi-objective optimization to maximize bracket stiffness while minimizing mass. ## Objectives 1. **Maximize Stiffness** (Primary) - Structural stiffness calculated as k = F/δ - Units: N/mm - Higher is better 2. **Minimize Mass** (Secondary + Constraint) - Total bracket mass - Units: kg - **Hard Constraint**: Mass ≤ 0.2 kg (200 grams) ## Design Variables | Variable | Min | Max | Initial | Unit | Description | |----------|-----|-----|---------|------|-------------| | `support_angle` | 30.0 | 90.0 | 60.0 | degrees | Angle of support arm relative to base | | `tip_thickness` | 15.0 | 40.0 | 25.0 | mm | Thickness of bracket tip where load is applied | ## Study Structure ``` bracket_stiffness_optimization/ ├── README.md # This file ├── optimization_config.json # Optimization settings ├── workflow_config.json # Workflow definition ├── run_optimization.py # Main runner script ├── bracket_stiffness_extractor.py # Results extractor │ ├── 1_setup/ │ └── model/ │ ├── Bracket.prt # NX part file │ ├── Bracket_fem1_i.prt # Idealized geometry │ ├── Bracket_fem1.fem # FEM definition │ ├── Bracket_sim1.sim # Simulation file │ └── export_displacement_field.py # NX journal for field export │ └── 2_results/ ├── study.db # Optuna study database ├── optimization_summary.json # Results summary ├── workflow.log # Execution log └── errors.log # Error log ``` ## Generic Extractors Used This study uses **reusable generic extractors** from `optimization_engine/extractors/`: 1. **`field_data_extractor.py`** - Parses NX exported field data (.fld files) - Works for: displacement, stress, strain, temperature, any scalar field - Multiple aggregation methods: max_abs, max, min, mean, std 2. **`op2_extractor.py`** - Extracts data from Nastran OP2 files using pyNastran - Mass properties (with unit conversion ton→kg) - Grid point forces (fx, fy, fz, resultant) - ~10000x faster than F06 parsing 3. **`stiffness_calculator.py`** - Generic stiffness calculator: k = F/δ - Works for any structure: bracket, beam, plate, etc. - Combines field data and OP2 extractors The `bracket_stiffness_extractor.py` is a thin wrapper that orchestrates these generic tools with bracket-specific parameters. ## Workflow Each optimization trial follows these steps: 1. **Update Design Variables** - Modify NX model expressions: `support_angle`, `tip_thickness` 2. **Solve Simulation** - Run NX Nastran SOL 101 (linear static analysis) - Output: `.op2` and `.f06` files 3. **Export Displacement Field** - Execute NX journal to export z-displacement - Output: `export_field_dz.fld` 4. **Extract Results** - Parse displacement field (max absolute z-displacement) - Extract applied force from OP2 - Calculate stiffness: k = Force / Displacement - Extract mass from OP2 grid point weight 5. **Evaluate Constraints** - Check: mass ≤ 0.2 kg - If violated: prune trial 6. **Report Results** - Send to Optuna study database - Broadcast to dashboard via WebSocket ## Running the Optimization ### Basic Usage ```bash cd studies/bracket_stiffness_optimization python run_optimization.py ``` ### Advanced Options ```bash # Custom number of trials python run_optimization.py --trials 100 # Enable real-time dashboard python run_optimization.py --dashboard # Both python run_optimization.py --trials 50 --dashboard ``` ### Testing Before Full Run Test the extractors with a single trial first: ```bash # Test extractor independently python bracket_stiffness_extractor.py ``` ## Results Analysis ### View in Dashboard The React dashboard provides real-time monitoring: - Convergence plot (stiffness over trials) - Parameter space exploration - Pareto front visualization - Mass constraint violations Access at: `http://localhost:3001` ### Database Query Results are stored in SQLite database `2_results/study.db`: ```python import optuna study = optuna.load_study( study_name="bracket_stiffness_optimization", storage="sqlite:///2_results/study.db" ) # Get Pareto-optimal solutions best_trials = study.best_trials for trial in best_trials: stiffness_neg, mass = trial.values stiffness = -stiffness_neg print(f"Trial {trial.number}: Stiffness={stiffness:.2f} N/mm, Mass={mass:.6f} kg") print(f" Params: {trial.params}") ``` ### Export Results ```python # Export to CSV import pandas as pd df = study.trials_dataframe() df.to_csv('2_results/trials.csv', index=False) # Export to JSON import json with open('2_results/trials.json', 'w') as f: json.dump([t.params | {'values': t.values} for t in study.trials], f, indent=2) ``` ## Optimization Settings - **Framework**: Protocol 10 - Intelligent Multi-Strategy Optimization (IMSO) - **Adaptive Features**: - Landscape characterization (analyzes problem structure) - Strategy selection (picks best algorithm automatically) - Dynamic switching (changes strategy when stagnating) - Adaptive surrogate modeling - **Strategies Available**: TPE, CMA-ES, QMC, Random, NSGA-II - **Default trials**: 50 - **Parallelization**: 1 job (sequential) ### How Protocol 10 Works: 1. **Characterization Phase** (first 10 trials) - Random sampling to explore landscape - Analyzes: smoothness, multimodality, noise, dimensionality 2. **Strategy Selection** - Automatically picks best optimizer based on landscape - Example: Smooth → CMA-ES, Multimodal → TPE 3. **Adaptive Optimization** - Monitors progress every 10 trials - Switches strategies if stagnating - All history kept for surrogate modeling ## Expected Performance - **Trial duration**: ~2-5 minutes (depends on mesh size) - **50 trials**: ~2-4 hours - **Infeasibility rate**: ~20-30% (trials violating mass constraint, but kept for surrogate) ## Constraints 1. **Mass Constraint**: mass ≤ 0.2 kg - Trials exceeding this are **NOT pruned** - they complete normally - Kept in history for surrogate modeling (valuable search information) - Marked as infeasible in database with `constraint_satisfied=False` attribute - **Not eligible for Pareto front** - only feasible solutions reported as optimal - This approach preserves knowledge while enforcing hard constraints ## Notes - Simulation uses NX Nastran SOL 101 (linear static) - Force units: Newtons (N) - Displacement units: millimeters (mm) - Mass units: kilograms (kg), converted from ton-mm-sec system - Stiffness units: N/mm ## Troubleshooting ### NX Session Issues If NX hangs or crashes: ```bash # Kill all NX processes taskkill /F /IM NXBIN.exe ``` ### Extractor Failures Check that: - ResultProbe is defined in simulation for z-displacement - OP2 file is generated (check solver settings) - Field export journal has correct path ### Database Locked If database is locked: ```bash # Close all connections and restart rm 2_results/study.db-journal ``` ## References - Generic extractors: `optimization_engine/extractors/` - NX solver: `optimization_engine/nx_solver.py` - pyNastran docs: https://pynastran-git.readthedocs.io/