Files
Atomizer/.claude/skills/analyze-workflow.md
Anto01 dd7f0c0f82 Phase 3.3: Multi-objective optimization fix, updated docs & Claude skill
- Fixed drone gimbal optimization to use proper semantic directions
- Changed from ['minimize', 'minimize'] to ['minimize', 'maximize']
- Updated Claude skill (v2.0) with Phase 3.3 integration
- Added centralized extractor library documentation
- Added multi-objective optimization (Protocol 11) section
- Added NX multi-solution protocol documentation
- Added dashboard integration documentation
- Fixed Pareto front degenerate issue with proper NSGA-II configuration

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-24 07:49:48 -05:00

9.8 KiB

Analyze Optimization Workflow Skill

Last Updated: November 23, 2025 Version: 2.0 - Phase 3.3 Integration

You are analyzing a structural optimization request for the Atomizer system.

When the user provides a request, break it down into atomic workflow steps and classify each step intelligently.

Step Types

1. ENGINEERING FEATURES - Complex FEA/CAE operations needing specialized knowledge:

  • Extract results from OP2 files using centralized extractors
  • Modify FEA properties (CBUSH/CBAR stiffness, PCOMP layup, material properties)
  • Run simulations (SOL101 static, SOL103 modal, etc.)
  • Create/modify geometry in NX
  • Multi-solution workflows (static + modal, thermal + structural)

2. INLINE CALCULATIONS - Simple math operations (auto-generate Python):

  • Calculate average, min, max, sum
  • Compare values, compute ratios
  • Statistical operations

3. POST-PROCESSING HOOKS - Custom calculations between FEA steps:

  • Custom objective functions combining multiple results
  • Data transformations
  • Filtering/aggregation logic

4. OPTIMIZATION - Algorithm and configuration:

  • Single-objective: Optuna TPE, CMA-ES, Random Search
  • Multi-objective: NSGA-II (Protocol 11), NSGA-III, MOEA/D
  • Design variables and their ranges
  • Constraints and objectives

Centralized Extractor Library

Location: optimization_engine/extractors/

Use these standardized extractors instead of custom OP2 code:

Available Extractors:

  1. extract_displacement.py

    • extract_displacement(op2_file, subcase) → max displacement in mm
    • Returns: {'max_displacement': float, 'node_id': int}
  2. extract_von_mises_stress.py

    • extract_solid_stress(op2_file, subcase, element_type) → max von Mises stress in MPa
    • Element types: 'ctetra', 'chexa', 'cquad4', 'ctria3'
    • Returns: {'max_von_mises': float, 'element_id': int}
  3. extract_frequency.py

    • extract_frequency(op2_file, subcase, mode_number) → frequency in Hz
    • Returns: {'frequency': float, 'mode': int, 'eigenvalue': float}
  4. extract_mass_from_bdf.py

    • extract_mass_from_bdf(bdf_file) → FEM mass in kg
    • Returns: {'mass_kg': float, 'cg': [x, y, z], 'inertia': [[...]]}
  5. extract_mass_from_expression.py

    • extract_mass_from_expression(prt_file, expression_name) → CAD mass in kg
    • Returns: float (mass value from NX expression)
  6. op2_extractor.py (Base Class)

    • OP2Extractor - Base class for custom extractors
    • Provides common OP2 file handling and error management

Extractor Selection Guide:

  • Displacement → Use extract_displacement
  • Von Mises Stress (solids/shells) → Use extract_solid_stress
  • Natural Frequency (modal analysis) → Use extract_frequency
  • Mass (from FEM) → Use extract_mass_from_bdf
  • Mass (from CAD geometry) → Use extract_mass_from_expression

Multi-Objective Optimization (Protocol 11)

NSGA-II Configuration:

from optuna.samplers import NSGAIISampler

study = optuna.create_study(
    study_name="study_name",
    storage="sqlite:///study.db",
    directions=['minimize', 'maximize'],  # Semantic directions
    sampler=NSGAIISampler()
)

Key Concepts:

  • Pareto Front: Set of non-dominated solutions
  • Semantic Directions: ['minimize', 'maximize'] - NEVER use negative values
  • Trade-offs: Conflicting objectives (e.g., minimize mass vs maximize stiffness)
  • Feasibility: Solutions must satisfy all constraints
  • Visualization: Parallel Coordinates Plot + Pareto Front scatter plot

Multi-Objective Return Format:

def objective(trial: optuna.Trial) -> tuple:
    """
    Returns:
        (obj1, obj2): Tuple for NSGA-II
    """
    # Extract objectives
    mass = extract_mass(...)  # to minimize
    freq = extract_frequency(...)  # to maximize

    # Return POSITIVE values - directions handled by study config
    return (mass, freq)

Common Pitfall - AVOID:

# ❌ WRONG: Using negative values to simulate maximization
return (mass, -frequency)  # Creates degenerate Pareto front

# ✅ CORRECT: Use proper semantic directions
return (mass, frequency)  # Study configured with ['minimize', 'maximize']

NX Multi-Solution Protocol

Critical Protocol: When simulations have multiple solutions (e.g., Solution 1 = Static, Solution 2 = Modal):

Required API:

# ✅ CORRECT: Use SolveAllSolutions() with Foreground mode
result = nx_solver.run_simulation(
    sim_file=sim_file,
    working_dir=model_dir,
    expression_updates=design_vars,
    solution_name=None  # Solve ALL solutions
)

Why This Matters:

  • SolveChainOfSolutions() with Background mode only solves the first solution
  • Causes stale OP2 files and identical results across trials
  • SolveAllSolutions() ensures all solutions complete before returning
  • See: docs/NX_MULTI_SOLUTION_PROTOCOL.md

Dashboard Integration

Visualization Features:

  1. Parallel Coordinates Plot

    • Structure: Design Variables → Objectives → Constraints
    • Color-coded axes (blue/green/yellow)
    • Interactive trial selection
    • Feasibility coloring (green = feasible, red = infeasible)
  2. Pareto Front Plot

    • 2D scatter for bi-objective problems
    • Shows trade-offs between objectives
    • Highlights non-dominated solutions
  3. Real-Time Updates

    • WebSocket connection for live monitoring
    • Backend: FastAPI (port 8000)
    • Frontend: React + Vite (port 3003)

Dashboard Access:

# Backend
cd atomizer-dashboard/backend && python -m uvicorn api.main:app --reload

# Frontend
cd atomizer-dashboard/frontend && npm run dev

# Access: http://localhost:3003

Important Distinctions

Element Types:

  • CBUSH vs CBAR vs CBEAM are different 1D elements
  • CQUAD4 vs CTRIA3 are shell elements
  • CTETRA vs CHEXA are solid elements

Result Types:

  • Element forces vs Reaction forces are DIFFERENT
  • Von Mises stress vs Principal stress
  • Displacement magnitude vs Component displacement

Data Sources:

  • OP2 file (FEA results) → Use extractors
  • .prt expression (CAD parameters) → Use extract_mass_from_expression
  • .fem/.bdf file (FEM model) → Use extract_mass_from_bdf
  • Multi-solution OP2 files: solution_1.op2, solution_2.op2

Optimization Algorithms:

  • TPE (Tree-structured Parzen Estimator): Single-objective, adaptive
  • NSGA-II: Multi-objective, Pareto-based
  • CMA-ES: Single-objective, gradient-free
  • Random Search: Baseline comparison

Output Format

Return a detailed JSON analysis with this structure:

{
  "engineering_features": [
    {
      "action": "extract_frequency",
      "domain": "result_extraction",
      "description": "Extract fundamental frequency from modal analysis using centralized extractor",
      "params": {
        "extractor": "extract_frequency",
        "op2_file": "solution_2.op2",
        "subcase": 1,
        "mode_number": 1
      },
      "why_engineering": "Uses centralized extractor library for standardized OP2 extraction"
    },
    {
      "action": "extract_mass",
      "domain": "result_extraction",
      "description": "Extract mass from CAD expression p173",
      "params": {
        "extractor": "extract_mass_from_expression",
        "prt_file": "Model.prt",
        "expression_name": "p173"
      },
      "why_engineering": "Reads NX expression value directly from part file"
    }
  ],
  "inline_calculations": [
    {
      "action": "convert_units",
      "description": "Convert mass from kg to grams",
      "params": {
        "input": "mass_kg",
        "operation": "multiply",
        "factor": 1000.0
      },
      "code_hint": "mass_g = mass_kg * 1000.0"
    }
  ],
  "post_processing_hooks": [],
  "optimization": {
    "protocol": "protocol_11_multi_objective",
    "algorithm": "NSGAIISampler",
    "type": "multi_objective",
    "design_variables": [
      {
        "parameter": "beam_thickness",
        "type": "NX_expression",
        "bounds": [5.0, 10.0],
        "unit": "mm"
      }
    ],
    "objectives": [
      {
        "name": "mass",
        "type": "minimize",
        "target": "mass_g",
        "unit": "g"
      },
      {
        "name": "frequency",
        "type": "maximize",
        "target": "fundamental_freq",
        "unit": "Hz"
      }
    ],
    "constraints": [
      {
        "name": "max_displacement",
        "type": "less_than",
        "threshold": 1.5,
        "unit": "mm"
      }
    ],
    "multi_solution_workflow": {
      "required": true,
      "solutions": ["static", "modal"],
      "protocol": "SolveAllSolutions with Foreground mode"
    }
  },
  "dashboard": {
    "visualization": "parallel_coordinates + pareto_front",
    "backend_port": 8000,
    "frontend_port": 3003
  },
  "summary": {
    "total_steps": 3,
    "engineering_needed": 2,
    "auto_generate": 1,
    "uses_centralized_extractors": true,
    "multi_objective": true,
    "multi_solution_workflow": true,
    "research_needed": []
  }
}

Analysis Guidelines

Be intelligent about:

  1. Extractor Selection

    • Always prefer centralized extractors over custom OP2 code
    • Match extractor to result type (displacement, stress, frequency, mass)
  2. Multi-Objective Optimization

    • Identify conflicting objectives requiring Pareto analysis
    • Use NSGA-II for 2-3 objectives
    • Use proper semantic directions (no negative values)
  3. Multi-Solution Workflows

    • Detect when static + modal analysis is needed
    • Flag requirement for SolveAllSolutions() protocol
    • Identify separate OP2 files per solution
  4. Dashboard Integration

    • Suggest parallel coordinates for high-dimensional problems
    • Recommend Pareto front visualization for multi-objective
    • Note real-time monitoring capability
  5. Protocol Selection

    • Protocol 11: Multi-objective NSGA-II
    • Protocol 10: Single-objective with intelligent strategies
    • Legacy: Basic single-objective TPE

Return ONLY the JSON analysis, no other text.