Files
Atomizer/.claude/skills/analyze-model.md
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

12 KiB

Analyze Model Skill

Last Updated: December 6, 2025 Version: 2.0 - Added Comprehensive Model Introspection

You are helping the user understand their NX model's structure and identify optimization opportunities.

Purpose

Extract and present information about an NX model to help the user:

  1. Identify available parametric expressions (potential design variables)
  2. Understand the simulation setup (analysis types, boundary conditions)
  3. Discover material properties
  4. Identify extractable results from OP2 files
  5. Recommend optimization strategies based on model characteristics

Triggers

  • "analyze this model"
  • "what can I optimize"
  • "show me the expressions"
  • "look at my NX model"
  • "what parameters are available"
  • "introspect my model"
  • "what results are available"

Prerequisites

  • User must provide path to NX model files (.prt, .sim, .fem) or study directory
  • NX must be available on the system for part/sim introspection
  • OP2 introspection works without NX (pure Python)

Information Gathering

Ask these questions if not already provided:

  1. Model Location:

    • "Where is your NX model? (path to .prt file or study directory)"
    • Default: Look in studies/*/1_setup/model/
  2. Analysis Interest:

    • "What type of optimization are you considering?" (optional)
    • This helps focus the analysis on relevant aspects

MANDATORY: Model Introspection

ALWAYS use the introspection module for comprehensive model analysis:

from optimization_engine.hooks.nx_cad.model_introspection import (
    introspect_part,
    introspect_simulation,
    introspect_op2,
    introspect_study
)

# Option 1: Introspect entire study directory (recommended)
study_info = introspect_study("studies/my_study/")

# Option 2: Introspect individual files
part_info = introspect_part("path/to/model.prt")
sim_info = introspect_simulation("path/to/model.sim")
op2_info = introspect_op2("path/to/results.op2")

What Introspection Extracts

Source Information Extracted
.prt Expressions (count, values, types), bodies, mass, material, features
.sim Solutions, boundary conditions, loads, materials, mesh info, output requests
.op2 Available results (displacement, stress, strain, SPC forces, etc.), subcases

Introspection Report Generation

MANDATORY: Generate MODEL_INTROSPECTION.md for every study:

# Generate and save introspection report
study_info = introspect_study(study_dir)

# Create markdown report
report = generate_introspection_report(study_info)
with open(study_dir / "MODEL_INTROSPECTION.md", "w") as f:
    f.write(report)

Execution Steps

Step 1: Run Comprehensive Introspection

Use the introspection module (MANDATORY):

from optimization_engine.hooks.nx_cad.model_introspection import introspect_study

# Introspect the entire study
result = introspect_study("studies/my_study/")

if result["success"]:
    # Part information
    for part in result["data"]["parts"]:
        print(f"Part: {part['file']}")
        print(f"  Expressions: {part['data'].get('expression_count', 0)}")
        print(f"  Bodies: {part['data'].get('body_count', 0)}")

    # Simulation information
    for sim in result["data"]["simulations"]:
        print(f"Simulation: {sim['file']}")
        print(f"  Solutions: {sim['data'].get('solution_count', 0)}")

    # OP2 results
    for op2 in result["data"]["results"]:
        print(f"OP2: {op2['file']}")
        available = op2['data'].get('available_results', {})
        print(f"  Displacement: {available.get('displacement', False)}")
        print(f"  Stress: {available.get('stress', False)}")

Step 2: Validate Model Files

Check that required files exist:

from pathlib import Path

def validate_model_files(model_path: Path) -> dict:
    """Validate NX model files exist."""
    prt_file = model_path
    base_name = prt_file.stem
    parent_dir = prt_file.parent

    result = {
        'prt_exists': prt_file.exists(),
        'sim_file': None,
        'fem_file': None,
        'errors': []
    }

    # Look for simulation file
    sim_patterns = [
        f"{base_name}_sim1.sim",
        f"{base_name}_sim.sim",
        f"{base_name}.sim"
    ]
    for pattern in sim_patterns:
        sim_path = parent_dir / pattern
        if sim_path.exists():
            result['sim_file'] = sim_path
            break

    # Look for FEM file
    fem_patterns = [
        f"{base_name}_fem1.fem",
        f"{base_name}_fem.fem",
        f"{base_name}.fem"
    ]
    for pattern in fem_patterns:
        fem_path = parent_dir / pattern
        if fem_path.exists():
            result['fem_file'] = fem_path
            break

    if not result['prt_exists']:
        result['errors'].append(f"Part file not found: {prt_file}")
    if not result['sim_file']:
        result['errors'].append("No simulation file (.sim) found")
    if not result['fem_file']:
        result['errors'].append("No FEM file (.fem) found - will be created on first solve")

    return result

Step 3: Extract Expressions (via Introspection)

The introspection module extracts expressions automatically:

from optimization_engine.hooks.nx_cad.model_introspection import introspect_part

result = introspect_part("path/to/model.prt")
if result["success"]:
    expressions = result["data"].get("expressions", [])
    for expr in expressions:
        print(f"  {expr['name']}: {expr['value']} {expr.get('unit', '')}")

Step 4: Classify Expressions

Categorize expressions by likely purpose:

Pattern Category Optimization Relevance
*_thickness, *_t, wall_* Structural High - affects mass & stiffness
*_diameter, *_d, hole_* Geometric High - affects mass & stress
*_radius, *_r, fillet_* Geometric Medium - affects stress concentration
*_count, n_*, num_* Discrete Medium - affects mass & complexity
*_length, *_l, span_* Dimensional Context-dependent
*_angle, *_deg Orientation Low-Medium
material_*, mat_* Material Special handling required

Step 4: Analyze Simulation Setup

If .sim file exists, analyze:

  1. Solution Types:

    • SOL 101 (Static) → Displacement, Stress
    • SOL 103 (Modal) → Natural Frequencies
    • SOL 105 (Buckling) → Buckling Load Factor
    • SOL 106 (Nonlinear Static) → Large deformation
    • SOL 112 (Transient) → Dynamic response
  2. Load Cases: Identify applied loads and boundary conditions

  3. Material Properties: Extract material definitions

Step 5: Generate Recommendations

Based on analysis, recommend:

  1. Design Variables: Which expressions are good candidates
  2. Objectives: What can be optimized
  3. Constraints: What should be bounded
  4. Protocol: Which optimization protocol fits best

Output Format

Present analysis using the MODEL_INTROSPECTION.md format:

# Model Introspection Report

**Study**: {study_name}
**Generated**: {date}
**Introspection Version**: 1.0

---

## 1. Files Discovered

| Type | File | Status |
|------|------|--------|
| Part (.prt) | {prt_file} | ✓ Found |
| Simulation (.sim) | {sim_file} | ✓ Found |
| FEM (.fem) | {fem_file} | ✓ Found |
| Results (.op2) | {op2_file} | ✓ Found |

---

## 2. Part Information

### Expressions (Potential Design Variables)

| Name | Value | Unit | Type | Optimization Candidate |
|------|-------|------|------|------------------------|
| thickness | 2.0 | mm | User | ✓ High |
| hole_diameter | 10.0 | mm | User | ✓ High |
| p173_mass | 0.125 | kg | Reference | Read-only |

### Mass Properties

| Property | Value | Unit |
|----------|-------|------|
| Mass | 0.125 | kg |
| Material | Aluminum 6061-T6 | - |

---

## 3. Simulation Information

### Solutions

| Solution | Type | Nastran SOL | Status |
|----------|------|-------------|--------|
| Solution 1 | Static | SOL 101 | ✓ Active |
| Solution 2 | Modal | SOL 103 | ✓ Active |

### Boundary Conditions

| Name | Type | Applied To |
|------|------|------------|
| Fixed_Root | SPC | Face_1 |

### Loads

| Name | Type | Magnitude | Direction |
|------|------|-----------|-----------|
| Tip_Force | FORCE | 500 N | -Z |

---

## 4. Available Results (from OP2)

| Result Type | Available | Subcases |
|-------------|-----------|----------|
| Displacement | ✓ | 1 |
| SPC Forces | ✓ | 1 |
| Stress (CHEXA) | ✓ | 1 |
| Stress (CPENTA) | ✓ | 1 |
| Strain Energy | ✗ | - |
| Frequencies | ✓ | 2 |

---

## 5. Optimization Recommendations

### Suggested Objectives

| Objective | Extractor | Source |
|-----------|-----------|--------|
| Minimize mass | E4: `extract_mass_from_bdf` | .dat |
| Maximize stiffness | E1: `extract_displacement` → k=F/δ | .op2 |

### Suggested Constraints

| Constraint | Type | Threshold | Extractor |
|------------|------|-----------|-----------|
| Max stress | less_than | 250 MPa | E3: `extract_solid_stress` |

### Recommended Protocol

- **Protocol 11 (Multi-Objective NSGA-II)** - Multiple competing objectives
- Multi-Solution: **Yes** (static + modal)

---

*Ready to create optimization study? Say "create study" to proceed.*

Saving the Report

MANDATORY: Save the introspection report to the study directory:

from pathlib import Path

def save_introspection_report(study_dir: Path, report_content: str):
    """Save MODEL_INTROSPECTION.md to study directory."""
    report_path = study_dir / "MODEL_INTROSPECTION.md"
    with open(report_path, 'w') as f:
        f.write(report_content)
    print(f"Saved introspection report: {report_path}")

## Error Handling

| Error | Recovery |
|-------|----------|
| File not found | Ask user for correct path |
| Invalid NX format | Suggest checking NX version compatibility |
| No expressions found | Guide user to create expressions in NX |
| Simulation incomplete | List missing components |

## Integration with Other Skills

After analysis, can chain to:
- `/create-study` - Create optimization based on findings
- `/configure-surrogate` - Setup NN if large-scale optimization needed

## Example Conversation

USER: Look at my NX model at studies/uav_arm_optimization/1_setup/model/Beam.prt

CLAUDE: I'll analyze your UAV arm model. Let me examine its structure...

[Runs analysis]

MODEL ANALYSIS REPORT

Model: Beam Location: studies/uav_arm_optimization/1_setup/model/

PARAMETRIC EXPRESSIONS

Found 4 controllable parameters:

Name Value Bounds Suggestion
beam_half_core_thickness 15.0 mm [5, 25]
beam_face_thickness 2.0 mm [1, 5]
holes_diameter 30.0 mm [10, 50]
hole_count 8 [4, 12]

SIMULATION SETUP

✓ Static Analysis (SOL 101) - for stress/displacement ✓ Modal Analysis (SOL 103) - for natural frequencies Material: Aluminum sandwich panel

RECOMMENDATION

This model is well-suited for multi-objective optimization:

  • Objective 1: Minimize mass
  • Objective 2: Maximize first natural frequency
  • Constraint: Keep stress below yield strength

Would you like me to create an optimization study with these settings?

USER: Yes, but add a displacement constraint of 5mm max

CLAUDE: [Invokes create-study skill with analyzed parameters + user constraint]


## Notes

- Expression extraction requires NX to be running or using file parsing
- Some expressions may be formula-driven (not directly editable)
- Material properties may need separate handling
- Consider mesh quality when recommending optimization bounds