feat: Add comprehensive study creation Claude skill

- New create-study.md skill for complete study scaffolding
- Interactive discovery process for problem understanding
- Automated generation of all study infrastructure:
  - optimization_config.json with protocol selection
  - workflow_config.json for future intelligent workflows
  - run_optimization.py with proper multi-objective/multi-solution support
  - reset_study.py for database management
  - README.md with comprehensive documentation
  - NX_FILE_MODIFICATIONS_REQUIRED.md when needed
- Protocol selection guidance (Protocol 10 vs 11)
- Extractor mapping to centralized library
- Multi-solution workflow detection
- Dashboard integration instructions
- User interaction best practices with confirmation steps
- Common patterns and critical reminders
- Reference to existing studies as templates

Enables users to create complete, working optimization studies
from natural language descriptions with proper Claude-guided workflow.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-24 07:55:00 -05:00
parent dd7f0c0f82
commit 46515475cb

View File

@@ -0,0 +1,514 @@
# Create Optimization Study Skill
**Last Updated**: November 24, 2025
**Version**: 1.0 - Complete Study Scaffolding
You are helping the user create a complete Atomizer optimization study from a natural language description.
## Your Role
Guide the user through an interactive conversation to:
1. Understand their optimization problem
2. Classify objectives, constraints, and design variables
3. Create the complete study infrastructure
4. Generate all required files with proper configuration
5. Provide clear next steps for running the optimization
## Study Structure
A complete Atomizer study has this structure:
```
studies/{study_name}/
├── 1_setup/
│ ├── model/
│ │ ├── {Model}.prt # NX Part file (user provides)
│ │ ├── {Model}_sim1.sim # NX Simulation file (user provides)
│ │ └── {Model}_fem1.fem # FEM mesh file (auto-generated by NX)
│ ├── optimization_config.json # YOU GENERATE THIS
│ └── workflow_config.json # YOU GENERATE THIS
├── 2_results/ # Created automatically during optimization
│ ├── study.db # Optuna SQLite database
│ ├── optimization_history_incremental.json
│ └── [various analysis files]
├── run_optimization.py # YOU GENERATE THIS
├── reset_study.py # YOU GENERATE THIS
├── README.md # YOU GENERATE THIS
└── NX_FILE_MODIFICATIONS_REQUIRED.md # YOU GENERATE THIS (if needed)
```
## Interactive Discovery Process
### Step 1: Problem Understanding
Ask clarifying questions to understand:
**Engineering Context**:
- "What component are you optimizing?"
- "What is the engineering application or scenario?"
- "What are the real-world requirements or constraints?"
**Objectives**:
- "What do you want to optimize?" (minimize/maximize)
- "Is this single-objective or multi-objective?"
- "What are the target values or acceptable ranges?"
**Constraints**:
- "What limits must be satisfied?"
- "What are the threshold values?"
- "Are these hard constraints (must satisfy) or soft constraints (prefer to satisfy)?"
**Design Variables**:
- "What parameters can be changed?"
- "What are the min/max bounds for each parameter?"
- "Are these NX expressions, geometry features, or material properties?"
**Simulation Setup**:
- "What NX model files do you have?"
- "What analysis types are needed?" (static, modal, thermal, etc.)
- "What results need to be extracted?" (stress, displacement, frequency, mass, etc.)
### Step 2: Classification & Analysis
Use the `analyze-workflow` skill to classify the problem:
```bash
# Invoke the analyze-workflow skill with user's description
# This returns JSON with classified engineering features, extractors, etc.
```
Review the classification with the user and confirm:
- Are the objectives correctly identified?
- Are constraints properly classified?
- Are extractors mapped to the right result types?
- Is the protocol selection appropriate?
### Step 3: Protocol Selection
Based on analysis, recommend protocol:
**Protocol 11 (Multi-Objective NSGA-II)**:
- Use when: 2-3 conflicting objectives
- Algorithm: NSGAIISampler
- Output: Pareto front of optimal trade-offs
- Example: Minimize mass + Maximize frequency
**Protocol 10 (Single-Objective with Intelligent Strategies)**:
- Use when: 1 objective with constraints
- Algorithm: TPE, CMA-ES, or adaptive
- Output: Single optimal solution
- Example: Minimize stress subject to displacement < 1.5mm
**Legacy (Basic TPE)**:
- Use when: Simple single-objective problem
- Algorithm: TPE
- Output: Single optimal solution
- Example: Quick exploration or testing
### Step 4: Extractor Mapping
Map each result extraction to centralized extractors:
| User Need | Extractor | Parameters |
|-----------|-----------|------------|
| Displacement | `extract_displacement` | `op2_file`, `subcase` |
| Von Mises Stress | `extract_solid_stress` | `op2_file`, `subcase`, `element_type` |
| Natural Frequency | `extract_frequency` | `op2_file`, `subcase`, `mode_number` |
| FEM Mass | `extract_mass_from_bdf` | `bdf_file` |
| CAD Mass | `extract_mass_from_expression` | `prt_file`, `expression_name` |
### Step 5: Multi-Solution Detection
Check if multi-solution workflow is needed:
**Indicators**:
- Extracting both static results (stress, displacement) AND modal results (frequency)
- User mentions "static + modal analysis"
- Objectives/constraints require different solution types
**Action**:
- Set `solution_name=None` in `run_optimization.py` to solve all solutions
- Document requirement in `NX_FILE_MODIFICATIONS_REQUIRED.md`
- Use `SolveAllSolutions()` protocol (see [NX_MULTI_SOLUTION_PROTOCOL.md](../docs/NX_MULTI_SOLUTION_PROTOCOL.md))
## File Generation
### 1. optimization_config.json
```json
{
"study_name": "{study_name}",
"description": "{concise description}",
"engineering_context": "{detailed real-world context}",
"optimization_settings": {
"protocol": "protocol_11_multi_objective", // or protocol_10, etc.
"n_trials": 30,
"sampler": "NSGAIISampler", // or "TPESampler"
"pruner": null,
"timeout_per_trial": 600
},
"design_variables": [
{
"parameter": "{nx_expression_name}",
"bounds": [min, max],
"description": "{what this controls}"
}
],
"objectives": [
{
"name": "{objective_name}",
"goal": "minimize", // or "maximize"
"weight": 1.0,
"description": "{what this measures}",
"target": {target_value},
"extraction": {
"action": "extract_{type}",
"domain": "result_extraction",
"params": {
"result_type": "{type}",
"metric": "{specific_metric}"
}
}
}
],
"constraints": [
{
"name": "{constraint_name}",
"type": "less_than", // or "greater_than"
"threshold": {value},
"description": "{engineering justification}",
"extraction": {
"action": "extract_{type}",
"domain": "result_extraction",
"params": {
"result_type": "{type}",
"metric": "{specific_metric}"
}
}
}
],
"simulation": {
"model_file": "{Model}.prt",
"sim_file": "{Model}_sim1.sim",
"fem_file": "{Model}_fem1.fem",
"solver": "nastran",
"analysis_types": ["static", "modal"] // or just ["static"]
},
"reporting": {
"generate_plots": true,
"save_incremental": true,
"llm_summary": false
}
}
```
### 2. workflow_config.json
```json
{
"workflow_id": "{study_name}_workflow",
"description": "{workflow description}",
"steps": [] // Can be empty for now, used by future intelligent workflow system
}
```
### 3. run_optimization.py
Generate a complete Python script based on protocol:
**Key sections**:
- Import statements (centralized extractors, NXSolver, Optuna)
- Configuration loading
- Objective function with proper:
- Design variable sampling
- Simulation execution with multi-solution support
- Result extraction using centralized extractors
- Constraint checking
- Return format (tuple for multi-objective, float for single-objective)
- Study creation with proper:
- Directions for multi-objective (`['minimize', 'maximize']`)
- Sampler selection (NSGAIISampler or TPESampler)
- Storage location
- Results display and dashboard instructions
**Template**: Use [studies/drone_gimbal_arm_optimization/run_optimization.py](../studies/drone_gimbal_arm_optimization/run_optimization.py:1) as reference
### 4. reset_study.py
Simple script to delete Optuna database:
```python
"""Reset {study_name} optimization study by deleting database."""
import optuna
from pathlib import Path
study_dir = Path(__file__).parent
storage = f"sqlite:///{study_dir / '2_results' / 'study.db'}"
study_name = "{study_name}"
try:
optuna.delete_study(study_name=study_name, storage=storage)
print(f"[OK] Deleted study: {study_name}")
except KeyError:
print(f"[WARNING] Study '{study_name}' not found (database may not exist)")
except Exception as e:
print(f"[ERROR] Error: {e}")
```
### 5. README.md
Comprehensive documentation including:
- Engineering scenario and context
- Problem statement with real-world constraints
- Multi-objective trade-offs (if applicable)
- Design variables and their effects
- Expected outcomes
- Study configuration details
- File structure explanation
- Running instructions
- Dashboard monitoring guide
- Results interpretation guide
- Comparison with other studies
- Technical notes
**Template**: Use [studies/drone_gimbal_arm_optimization/README.md](../studies/drone_gimbal_arm_optimization/README.md:1) as reference
### 6. NX_FILE_MODIFICATIONS_REQUIRED.md (if needed)
If multi-solution workflow or specific NX setup is required:
```markdown
# NX File Modifications Required
Before running this optimization, you must modify the NX simulation files.
## Required Changes
### 1. Add Modal Analysis Solution (if needed)
Current: Only static analysis (SOL 101)
Required: Static + Modal (SOL 101 + SOL 103)
Steps:
1. Open `{Model}_sim1.sim` in NX
2. Solution → Create → Modal Analysis
3. Set frequency extraction parameters
4. Save simulation
### 2. Update Load Cases (if needed)
Current: [describe current loads]
Required: [describe required loads]
Steps: [specific instructions]
### 3. Verify Material Properties
Required: [material name and properties]
## Verification
After modifications:
1. Run simulation manually in NX
2. Verify OP2 files are generated
3. Check solution_1.op2 and solution_2.op2 exist (if multi-solution)
```
## User Interaction Best Practices
### Ask Before Generating
Always confirm with user:
1. "Here's what I understand about your optimization problem: [summary]. Is this correct?"
2. "I'll use Protocol {X} because [reasoning]. Does this sound right?"
3. "I'll create extractors for: [list]. Are these the results you need?"
4. "Should I generate the complete study structure now?"
### Provide Clear Next Steps
After generating files:
```
✓ Created study: studies/{study_name}/
✓ Generated optimization config
✓ Generated run_optimization.py with {protocol}
✓ Generated README.md with full documentation
Next Steps:
1. Place your NX files in studies/{study_name}/1_setup/model/
- {Model}.prt
- {Model}_sim1.sim
2. [If NX modifications needed] Read NX_FILE_MODIFICATIONS_REQUIRED.md
3. Test with 3 trials: cd studies/{study_name} && python run_optimization.py --trials 3
4. Monitor in dashboard: http://localhost:3003
5. Full run: python run_optimization.py --trials {n_trials}
```
### Handle Edge Cases
**User has incomplete information**:
- Suggest reasonable defaults based on similar studies
- Document assumptions clearly in README
- Mark as "REQUIRES USER INPUT" in generated files
**User wants custom extractors**:
- Explain centralized extractor library
- If truly custom, guide them to create in `optimization_engine/extractors/`
- Inherit from `OP2Extractor` base class
**User unsure about bounds**:
- Recommend conservative bounds based on engineering judgment
- Suggest iterative approach: "Start with [bounds], then refine based on initial results"
**User doesn't have NX files yet**:
- Generate all Python/JSON files anyway
- Create placeholder model directory
- Provide clear instructions for adding NX files later
## Integration with Dashboard
Always mention dashboard capabilities:
**For Multi-Objective Studies**:
- "You'll see the Pareto front in real-time on the dashboard"
- "Use parallel coordinates plot to explore trade-offs"
- "Green lines = feasible, red lines = constraint violations"
**For Single-Objective Studies**:
- "Monitor convergence in real-time"
- "See best value improving over trials"
- "Check parameter space exploration"
**Dashboard Access**:
```bash
# Terminal 1: Backend
cd atomizer-dashboard/backend && python -m uvicorn api.main:app --reload
# Terminal 2: Frontend
cd atomizer-dashboard/frontend && npm run dev
# Browser: http://localhost:3003
```
## Common Patterns
### Pattern 1: Mass Minimization with Constraints
```
Objective: Minimize mass
Constraints: Stress < limit, Displacement < limit, Frequency > limit
Protocol: Protocol 10 (single-objective TPE)
Extractors: extract_mass_from_expression, extract_solid_stress,
extract_displacement, extract_frequency
Multi-Solution: Yes (static + modal)
```
### Pattern 2: Mass vs Frequency Trade-off
```
Objectives: Minimize mass, Maximize frequency
Constraints: Stress < limit, Displacement < limit
Protocol: Protocol 11 (multi-objective NSGA-II)
Extractors: extract_mass_from_expression, extract_frequency,
extract_solid_stress, extract_displacement
Multi-Solution: Yes (static + modal)
```
### Pattern 3: Stress Minimization
```
Objective: Minimize stress
Constraints: Displacement < limit
Protocol: Protocol 10 (single-objective TPE)
Extractors: extract_solid_stress, extract_displacement
Multi-Solution: No (static only)
```
## Critical Reminders
### Multi-Objective Return Format
```python
# ✅ CORRECT: Return tuple with proper semantic directions
study = optuna.create_study(
directions=['minimize', 'maximize'], # Semantic directions
sampler=NSGAIISampler()
)
def objective(trial):
return (mass, frequency) # Return positive values
```
```python
# ❌ WRONG: Using negative values
return (mass, -frequency) # Creates degenerate Pareto front
```
### Multi-Solution NX Protocol
```python
# ✅ CORRECT: Solve all solutions
result = nx_solver.run_simulation(
sim_file=sim_file,
working_dir=model_dir,
expression_updates=design_vars,
solution_name=None # None = solve ALL solutions
)
```
```python
# ❌ WRONG: Only solves first solution
solution_name="Solution 1" # Multi-solution workflows will fail
```
### Extractor Selection
Always use centralized extractors from `optimization_engine/extractors/`:
- Standardized error handling
- Consistent return formats
- Well-tested and documented
- No code duplication
## Output Format
After completing study creation, provide:
1. **Summary Table**:
```
Study Created: {study_name}
Protocol: {protocol}
Objectives: {list}
Constraints: {list}
Design Variables: {list}
Multi-Solution: {Yes/No}
```
2. **File Checklist**:
```
✓ studies/{study_name}/1_setup/optimization_config.json
✓ studies/{study_name}/1_setup/workflow_config.json
✓ studies/{study_name}/run_optimization.py
✓ studies/{study_name}/reset_study.py
✓ studies/{study_name}/README.md
[✓] studies/{study_name}/NX_FILE_MODIFICATIONS_REQUIRED.md (if needed)
```
3. **Next Steps** (as shown earlier)
## Remember
- Be conversational and helpful
- Ask clarifying questions early
- Confirm understanding before generating
- Provide context for technical decisions
- Make next steps crystal clear
- Anticipate common mistakes
- Reference existing studies as examples
- Always test-run your generated code mentally
The goal is for the user to have a COMPLETE, WORKING study that they can run immediately after placing their NX files.