Files
Atomizer/optimization_engine/hooks/test_introspection.py
Antoine 602560c46a feat: Add MLP surrogate with Turbo Mode for 100x faster optimization
Neural Acceleration (MLP Surrogate):
- Add run_nn_optimization.py with hybrid FEA/NN workflow
- MLP architecture: 4-layer (64->128->128->64) with BatchNorm/Dropout
- Three workflow modes:
  - --all: Sequential export->train->optimize->validate
  - --hybrid-loop: Iterative Train->NN->Validate->Retrain cycle
  - --turbo: Aggressive single-best validation (RECOMMENDED)
- Turbo mode: 5000 NN trials + 50 FEA validations in ~12 minutes
- Separate nn_study.db to avoid overloading dashboard

Performance Results (bracket_pareto_3obj study):
- NN prediction errors: mass 1-5%, stress 1-4%, stiffness 5-15%
- Found minimum mass designs at boundary (angle~30deg, thick~30mm)
- 100x speedup vs pure FEA exploration

Protocol Operating System:
- Add .claude/skills/ with Bootstrap, Cheatsheet, Context Loader
- Add docs/protocols/ with operations (OP_01-06) and system (SYS_10-14)
- Update SYS_14_NEURAL_ACCELERATION.md with MLP Turbo Mode docs

NX Automation:
- Add optimization_engine/hooks/ for NX CAD/CAE automation
- Add study_wizard.py for guided study creation
- Fix FEM mesh update: load idealized part before UpdateFemodel()

New Study:
- bracket_pareto_3obj: 3-objective Pareto (mass, stress, stiffness)
- 167 FEA trials + 5000 NN trials completed
- Demonstrates full hybrid workflow

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 20:01:59 -05:00

122 lines
3.7 KiB
Python

"""Test model introspection module."""
import json
import glob
from pathlib import Path
# Add project root to path
import sys
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
from optimization_engine.hooks.nx_cad.model_introspection import (
introspect_op2,
introspect_study,
)
def test_op2_introspection():
"""Test OP2 introspection on bracket study."""
print("=" * 60)
print("OP2 INTROSPECTION TEST")
print("=" * 60)
# Find bracket OP2 files
op2_files = glob.glob(
"C:/Users/Antoine/Atomizer/studies/bracket_stiffness_optimization_V3/**/*.op2",
recursive=True
)
print(f"\nFound {len(op2_files)} OP2 files")
for f in op2_files[:5]:
print(f" - {Path(f).name}")
if not op2_files:
print("No OP2 files found!")
return
# Introspect first OP2
print(f"\nIntrospecting: {Path(op2_files[0]).name}")
result = introspect_op2(op2_files[0])
if not result["success"]:
print(f"ERROR: {result['error']}")
return
data = result["data"]
# Print results
print(f"\nFile Info:")
print(f" Size: {data['file_info']['size_mb']:.2f} MB")
print(f" Subcases: {data['subcases']}")
print(f"\nAvailable Results:")
for r_type, info in data["results"].items():
status = "YES" if info["available"] else "no"
extra = ""
if info["available"]:
if "element_types" in info and info["element_types"]:
extra = f" ({', '.join(info['element_types'][:3])})"
elif "subcases" in info and info["subcases"]:
extra = f" (subcases: {info['subcases'][:3]})"
print(f" {r_type:20s}: {status:4s} {extra}")
print(f"\nMesh Info:")
print(f" Nodes: {data['mesh']['node_count']}")
print(f" Elements: {data['mesh']['element_count']}")
if data['mesh']['element_types']:
print(f" Element types: {list(data['mesh']['element_types'].keys())[:5]}")
print(f"\nExtractable results: {data['extractable']}")
def test_study_introspection():
"""Test study directory introspection."""
print("\n" + "=" * 60)
print("STUDY INTROSPECTION TEST")
print("=" * 60)
study_dir = "C:/Users/Antoine/Atomizer/studies/bracket_stiffness_optimization_V3"
print(f"\nIntrospecting study: {study_dir}")
result = introspect_study(study_dir)
if not result["success"]:
print(f"ERROR: {result['error']}")
return
data = result["data"]
print(f"\nStudy Summary:")
print(f" Parts (.prt): {data['summary']['part_count']}")
print(f" Simulations (.sim): {data['summary']['simulation_count']}")
print(f" Results (.op2): {data['summary']['results_count']}")
print(f" Has config: {data['summary']['has_config']}")
print(f"\nParts found:")
for p in data["parts"][:5]:
print(f" - {Path(p['path']).name}")
print(f"\nSimulations found:")
for s in data["simulations"][:5]:
print(f" - {Path(s['path']).name}")
if data["config"]:
print(f"\nOptimization Config:")
config = data["config"]
if "variables" in config:
print(f" Variables: {len(config['variables'])}")
for v in config["variables"][:3]:
print(f" - {v.get('name', 'unnamed')}: [{v.get('lower')}, {v.get('upper')}]")
if "objectives" in config:
print(f" Objectives: {len(config['objectives'])}")
for o in config["objectives"][:3]:
print(f" - {o.get('name', 'unnamed')} ({o.get('direction', 'minimize')})")
if __name__ == "__main__":
test_op2_introspection()
test_study_introspection()
print("\n" + "=" * 60)
print("INTROSPECTION TESTS COMPLETE")
print("=" * 60)