# Analyze Model Skill

**Last Updated**: November 25, 2025
**Version**: 1.0 - Model Analysis and Feature Extraction

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. 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"

## Prerequisites

- User must provide path to NX model files (.prt, .sim, .fem)
- NX must be available on the system (configured in config.py)
- Model files must be valid NX format

## Information Gathering

Ask these questions if not already provided:

1. **Model Location**:
   - "Where is your NX model? (path to .prt file)"
   - 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

## Execution Steps

### Step 1: Validate Model Files

Check that required files exist:

```python
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 2: Extract Expressions

Use NX Python API to extract all parametric expressions:

```python
# This requires running a journal inside NX
# Use the expression extractor from optimization_engine

from optimization_engine.extractors.expression_extractor import extract_all_expressions

expressions = extract_all_expressions(prt_file)
# Returns: [{'name': 'thickness', 'value': 2.0, 'unit': 'mm', 'formula': None}, ...]
```

**Manual Extraction Method** (if NX API not available):
1. Read the .prt file header for expression metadata
2. Look for common parameter naming patterns
3. Ask user to provide expression names from NX

### Step 3: 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 in structured format:

```
MODEL ANALYSIS REPORT
=====================

Model: {model_name}
Location: {model_path}

FILES FOUND
-----------
✓ Part file: {prt_file}
✓ Simulation: {sim_file}
✓ FEM mesh: {fem_file}

PARAMETRIC EXPRESSIONS
----------------------
| Name | Current Value | Unit | Category | Optimization Candidate |
|------|---------------|------|----------|----------------------|
| thickness | 2.0 | mm | Structural | ✓ High |
| hole_diameter | 10.0 | mm | Geometric | ✓ High |
| fillet_radius | 3.0 | mm | Geometric | ✓ Medium |
| length | 100.0 | mm | Dimensional | ? Check constraints |

SIMULATION SETUP
----------------
Analysis Types: Static (SOL 101), Modal (SOL 103)
Material: Aluminum 6061-T6 (E=68.9 GPa, ρ=2700 kg/m³)
Loads:
  - Force: 500 N at tip
  - Constraint: Fixed at root

RECOMMENDATIONS
---------------
Suggested Objectives:
  - Minimize mass (extract from p173 expression or FEM)
  - Maximize first natural frequency

Suggested Constraints:
  - Max von Mises stress < 276 MPa (Al 6061 yield)
  - Max displacement < {user to specify}

Recommended Protocol: Protocol 11 (Multi-Objective NSGA-II)
  - Reason: Multiple competing objectives (mass vs frequency)

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

## 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
