feat: add Atomizer HQ multi-agent cluster infrastructure
- 8-agent OpenClaw cluster (Manager, Tech-Lead, Secretary, Auditor, Optimizer, Study-Builder, NX-Expert, Webster) - Orchestration engine: orchestrate.py (sync delegation + handoffs) - Workflow engine: YAML-defined multi-step pipelines - Agent workspaces: SOUL.md, AGENTS.md, MEMORY.md per agent - Shared skills: delegate, orchestrate, atomizer-protocols - Capability registry (AGENTS_REGISTRY.json) - Cluster management: cluster.sh, systemd template - All secrets replaced with env var references
This commit is contained in:
667
hq/skills/atomizer-protocols/protocols/OP_01_CREATE_STUDY.md
Normal file
667
hq/skills/atomizer-protocols/protocols/OP_01_CREATE_STUDY.md
Normal file
@@ -0,0 +1,667 @@
|
||||
# OP_01: Create Optimization Study
|
||||
|
||||
<!--
|
||||
PROTOCOL: Create Optimization Study
|
||||
LAYER: Operations
|
||||
VERSION: 1.2
|
||||
STATUS: Active
|
||||
LAST_UPDATED: 2026-01-13
|
||||
PRIVILEGE: user
|
||||
LOAD_WITH: [core/study-creation-core.md]
|
||||
-->
|
||||
|
||||
## Overview
|
||||
|
||||
This protocol guides you through creating a complete Atomizer optimization study from scratch. It covers gathering requirements, generating configuration files, and validating setup.
|
||||
|
||||
**Skill to Load**: `.claude/skills/core/study-creation-core.md`
|
||||
|
||||
---
|
||||
|
||||
## When to Use
|
||||
|
||||
| Trigger | Action |
|
||||
|---------|--------|
|
||||
| "new study", "create study" | Follow this protocol |
|
||||
| "set up optimization" | Follow this protocol |
|
||||
| "optimize my design" | Follow this protocol |
|
||||
| User provides NX model | Assess and follow this protocol |
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### MANDATORY: Use TodoWrite for Study Creation
|
||||
|
||||
**BEFORE creating any files**, add ALL required outputs to TodoWrite:
|
||||
|
||||
```
|
||||
TodoWrite([
|
||||
{"content": "Create optimization_config.json", "status": "pending", "activeForm": "Creating config"},
|
||||
{"content": "Create run_optimization.py", "status": "pending", "activeForm": "Creating run script"},
|
||||
{"content": "Create README.md", "status": "pending", "activeForm": "Creating README"},
|
||||
{"content": "Create STUDY_REPORT.md", "status": "pending", "activeForm": "Creating report template"}
|
||||
])
|
||||
```
|
||||
|
||||
**Mark each item complete ONLY after the file is created.** Study is NOT complete until all 4 items are checked off.
|
||||
|
||||
> **WHY**: This requirement exists because README.md was forgotten TWICE (2025-12-17, 2026-01-13) despite being listed as mandatory. TodoWrite provides visible enforcement.
|
||||
|
||||
---
|
||||
|
||||
**Required Outputs** (ALL MANDATORY - study is INCOMPLETE without these):
|
||||
| File | Purpose | Location | Priority |
|
||||
|------|---------|----------|----------|
|
||||
| `optimization_config.json` | Design vars, objectives, constraints | `1_setup/` | 1 |
|
||||
| `run_optimization.py` | Execution script | Study root | 2 |
|
||||
| **`README.md`** | Engineering documentation | Study root | **3 - NEVER SKIP** |
|
||||
| `STUDY_REPORT.md` | Results template | Study root | 4 |
|
||||
|
||||
**CRITICAL**: README.md is MANDATORY for every study. A study without README.md is INCOMPLETE.
|
||||
|
||||
**Study Structure**:
|
||||
```
|
||||
studies/{geometry_type}/{study_name}/
|
||||
├── 1_setup/
|
||||
│ ├── model/ # NX files (.prt, .sim, .fem)
|
||||
│ └── optimization_config.json
|
||||
├── 2_iterations/ # FEA trial folders (iter1, iter2, ...)
|
||||
├── 3_results/ # Optimization outputs (study.db, logs)
|
||||
├── README.md # MANDATORY
|
||||
├── STUDY_REPORT.md # MANDATORY
|
||||
└── run_optimization.py
|
||||
```
|
||||
|
||||
**IMPORTANT: Studies are organized by geometry type**:
|
||||
| Geometry Type | Folder | Examples |
|
||||
|---------------|--------|----------|
|
||||
| M1 Mirror | `studies/M1_Mirror/` | m1_mirror_adaptive_V14, m1_mirror_cost_reduction_V3 |
|
||||
| Simple Bracket | `studies/Simple_Bracket/` | bracket_stiffness_optimization |
|
||||
| UAV Arm | `studies/UAV_Arm/` | uav_arm_optimization |
|
||||
| Drone Gimbal | `studies/Drone_Gimbal/` | drone_gimbal_arm_optimization |
|
||||
| Simple Beam | `studies/Simple_Beam/` | simple_beam_optimization |
|
||||
| Other/Test | `studies/_Other/` | training_data_export_test |
|
||||
|
||||
When creating a new study:
|
||||
1. Identify the geometry type (mirror, bracket, beam, etc.)
|
||||
2. Place study under the appropriate `studies/{geometry_type}/` folder
|
||||
3. For new geometry types, create a new folder with descriptive name
|
||||
|
||||
---
|
||||
|
||||
## README Hierarchy (Parent-Child Documentation)
|
||||
|
||||
**Two-level documentation system**:
|
||||
|
||||
```
|
||||
studies/{geometry_type}/
|
||||
├── README.md # PARENT: Project-level context
|
||||
│ ├── Project overview # What is this geometry/component?
|
||||
│ ├── Physical system specs # Material, dimensions, constraints
|
||||
│ ├── Optical/mechanical specs # Domain-specific requirements
|
||||
│ ├── Design variables catalog # ALL possible variables with descriptions
|
||||
│ ├── Objectives catalog # ALL possible objectives
|
||||
│ ├── Campaign history # Summary of all sub-studies
|
||||
│ └── Sub-studies index # Links to each sub-study
|
||||
│
|
||||
├── sub_study_V1/
|
||||
│ └── README.md # CHILD: Study-specific details
|
||||
│ ├── Link to parent # "See ../README.md for context"
|
||||
│ ├── Study focus # What THIS study optimizes
|
||||
│ ├── Active variables # Which params enabled
|
||||
│ ├── Algorithm config # Sampler, trials, settings
|
||||
│ ├── Baseline/seeding # Starting point
|
||||
│ └── Results summary # Best trial, learnings
|
||||
│
|
||||
└── sub_study_V2/
|
||||
└── README.md # CHILD: References parent, adds specifics
|
||||
```
|
||||
|
||||
### Parent README Content (Geometry-Level)
|
||||
|
||||
| Section | Content |
|
||||
|---------|---------|
|
||||
| Project Overview | What the component is, purpose, context |
|
||||
| Physical System | Material, mass targets, loading conditions |
|
||||
| Domain Specs | Optical prescription (mirrors), structural limits (brackets) |
|
||||
| Design Variables | Complete catalog with ranges and descriptions |
|
||||
| Objectives | All possible metrics with formulas |
|
||||
| Campaign History | Evolution across sub-studies |
|
||||
| Sub-Studies Index | Table with links, status, best results |
|
||||
| Technical Notes | Domain-specific implementation details |
|
||||
|
||||
### Child README Content (Study-Level)
|
||||
|
||||
| Section | Content |
|
||||
|---------|---------|
|
||||
| Parent Reference | `> See [../README.md](../README.md) for project context` |
|
||||
| Study Focus | What differentiates THIS study |
|
||||
| Active Variables | Which parameters are enabled (subset of parent catalog) |
|
||||
| Algorithm Config | Sampler, n_trials, sigma, seed |
|
||||
| Baseline | Starting point (seeded from prior study or default) |
|
||||
| Results | Best trial, improvement metrics |
|
||||
| Key Learnings | What was discovered |
|
||||
|
||||
### When to Create Parent README
|
||||
|
||||
- **First study** for a geometry type → Create parent README immediately
|
||||
- **Subsequent studies** → Add to parent's sub-studies index
|
||||
- **New geometry type** → Create both parent and child READMEs
|
||||
|
||||
### Example Reference
|
||||
|
||||
See `studies/M1_Mirror/README.md` for a complete parent README example.
|
||||
|
||||
---
|
||||
|
||||
## Interview Mode (DEFAULT)
|
||||
|
||||
**Study creation now uses Interview Mode by default.** This provides guided study creation with intelligent validation.
|
||||
|
||||
### Triggers (Any of These Start Interview Mode)
|
||||
|
||||
- "create a study", "new study", "set up study"
|
||||
- "create a study for my bracket"
|
||||
- "optimize this model"
|
||||
- "I want to minimize mass"
|
||||
- Any study creation request without "skip interview" or "manual"
|
||||
|
||||
### When to Skip Interview Mode (Manual)
|
||||
|
||||
Use manual mode only when:
|
||||
- Power user who knows the exact configuration
|
||||
- Recreating a known study configuration
|
||||
- User explicitly says "skip interview", "quick setup", or "manual config"
|
||||
|
||||
### Starting Interview Mode
|
||||
|
||||
```python
|
||||
from optimization_engine.interview import StudyInterviewEngine
|
||||
|
||||
engine = StudyInterviewEngine(study_path)
|
||||
|
||||
# Run introspection first (if model available)
|
||||
introspection = {
|
||||
"expressions": [...], # From part introspection
|
||||
"model_path": "...",
|
||||
"sim_path": "..."
|
||||
}
|
||||
|
||||
session = engine.start_interview(study_name, introspection=introspection)
|
||||
action = engine.get_first_question()
|
||||
|
||||
# Present action.message to user
|
||||
# Process answers with: action = engine.process_answer(user_response)
|
||||
```
|
||||
|
||||
### Interview Benefits
|
||||
|
||||
- **Material-aware validation**: Checks stress limits against yield
|
||||
- **Anti-pattern detection**: Warns about mass minimization without constraints
|
||||
- **Auto extractor mapping**: Maps goals to correct extractors (E1-E10)
|
||||
- **State persistence**: Resume interrupted interviews
|
||||
- **Blueprint generation**: Creates validated configuration
|
||||
|
||||
See `.claude/skills/modules/study-interview-mode.md` for full documentation.
|
||||
|
||||
---
|
||||
|
||||
## Detailed Steps (Manual Mode - Power Users Only)
|
||||
|
||||
### Step 1: Gather Requirements
|
||||
|
||||
**Ask the user**:
|
||||
1. What are you trying to optimize? (objective)
|
||||
2. What can you change? (design variables)
|
||||
3. What limits must be respected? (constraints)
|
||||
4. Where are your NX files?
|
||||
|
||||
**Example Dialog**:
|
||||
```
|
||||
User: "I want to optimize my bracket"
|
||||
You: "What should I optimize for - minimum mass, maximum stiffness,
|
||||
target frequency, or something else?"
|
||||
User: "Minimize mass while keeping stress below 250 MPa"
|
||||
```
|
||||
|
||||
### Step 2: Analyze Model (Introspection)
|
||||
|
||||
**MANDATORY**: When user provides NX files, run comprehensive introspection:
|
||||
|
||||
```python
|
||||
from optimization_engine.hooks.nx_cad.model_introspection import (
|
||||
introspect_part,
|
||||
introspect_simulation,
|
||||
introspect_op2,
|
||||
introspect_study
|
||||
)
|
||||
|
||||
# Introspect the part file to get expressions, mass, features
|
||||
part_info = introspect_part("C:/path/to/model.prt")
|
||||
|
||||
# Introspect the simulation to get solutions, BCs, loads
|
||||
sim_info = introspect_simulation("C:/path/to/model.sim")
|
||||
|
||||
# If OP2 exists, check what results are available
|
||||
op2_info = introspect_op2("C:/path/to/results.op2")
|
||||
|
||||
# Or introspect entire study directory at once
|
||||
study_info = introspect_study("studies/my_study/")
|
||||
```
|
||||
|
||||
**Introspection Report Contents**:
|
||||
|
||||
| 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 |
|
||||
|
||||
**Generate Introspection Report** at study creation:
|
||||
1. Save report to `studies/{study_name}/MODEL_INTROSPECTION.md`
|
||||
2. Include summary of what's available for optimization
|
||||
3. List potential design variables (expressions)
|
||||
4. List extractable results (from OP2)
|
||||
|
||||
**Key Questions Answered by Introspection**:
|
||||
- What expressions exist? (potential design variables)
|
||||
- What solution types? (static, modal, etc.)
|
||||
- What results are available in OP2? (displacement, stress, SPC forces)
|
||||
- Multi-solution required? (static + modal = set `solution_name=None`)
|
||||
|
||||
### Step 3: Select Protocol
|
||||
|
||||
Based on objectives:
|
||||
|
||||
| Scenario | Protocol | Sampler |
|
||||
|----------|----------|---------|
|
||||
| Single objective | Protocol 10 (IMSO) | TPE, CMA-ES, or GP |
|
||||
| 2-3 objectives | Protocol 11 | NSGA-II |
|
||||
| >50 trials, need speed | Protocol 14 | + Neural acceleration |
|
||||
|
||||
See [SYS_10_IMSO](../system/SYS_10_IMSO.md), [SYS_11_MULTI_OBJECTIVE](../system/SYS_11_MULTI_OBJECTIVE.md).
|
||||
|
||||
### Step 4: Select Extractors
|
||||
|
||||
Match physics to extractors from [SYS_12_EXTRACTOR_LIBRARY](../system/SYS_12_EXTRACTOR_LIBRARY.md):
|
||||
|
||||
| Need | Extractor ID | Function |
|
||||
|------|--------------|----------|
|
||||
| Max displacement | E1 | `extract_displacement()` |
|
||||
| Natural frequency | E2 | `extract_frequency()` |
|
||||
| Von Mises stress | E3 | `extract_solid_stress()` |
|
||||
| Mass from BDF | E4 | `extract_mass_from_bdf()` |
|
||||
| Mass from NX | E5 | `extract_mass_from_expression()` |
|
||||
| Wavefront error | E8-E10 | Zernike extractors |
|
||||
|
||||
### Step 5: Generate Configuration
|
||||
|
||||
Create `optimization_config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"study_name": "bracket_optimization",
|
||||
"description": "Minimize bracket mass while meeting stress constraint",
|
||||
|
||||
"design_variables": [
|
||||
{
|
||||
"name": "thickness",
|
||||
"type": "continuous",
|
||||
"min": 2.0,
|
||||
"max": 10.0,
|
||||
"unit": "mm",
|
||||
"description": "Wall thickness"
|
||||
}
|
||||
],
|
||||
|
||||
"objectives": [
|
||||
{
|
||||
"name": "mass",
|
||||
"type": "minimize",
|
||||
"unit": "kg",
|
||||
"description": "Total bracket mass"
|
||||
}
|
||||
],
|
||||
|
||||
"constraints": [
|
||||
{
|
||||
"name": "max_stress",
|
||||
"type": "less_than",
|
||||
"value": 250.0,
|
||||
"unit": "MPa",
|
||||
"description": "Maximum allowable von Mises stress"
|
||||
}
|
||||
],
|
||||
|
||||
"simulation": {
|
||||
"model_file": "1_setup/model/bracket.prt",
|
||||
"sim_file": "1_setup/model/bracket.sim",
|
||||
"solver": "nastran",
|
||||
"solution_name": null
|
||||
},
|
||||
|
||||
"optimization_settings": {
|
||||
"protocol": "protocol_10_single_objective",
|
||||
"sampler": "TPESampler",
|
||||
"n_trials": 50
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Step 6: Generate run_optimization.py
|
||||
|
||||
**CRITICAL**: Always use the `FEARunner` class pattern with proper `NXSolver` initialization.
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
{study_name} - Optimization Runner
|
||||
Generated by Atomizer LLM
|
||||
"""
|
||||
import sys
|
||||
import re
|
||||
import json
|
||||
from pathlib import Path
|
||||
from typing import Dict, Optional, Any
|
||||
|
||||
# Add optimization engine to path
|
||||
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
||||
|
||||
import optuna
|
||||
from optimization_engine.nx_solver import NXSolver
|
||||
from optimization_engine.utils import ensure_nx_running
|
||||
from optimization_engine.extractors import extract_solid_stress
|
||||
|
||||
# Paths
|
||||
STUDY_DIR = Path(__file__).parent
|
||||
SETUP_DIR = STUDY_DIR / "1_setup"
|
||||
ITERATIONS_DIR = STUDY_DIR / "2_iterations"
|
||||
RESULTS_DIR = STUDY_DIR / "3_results"
|
||||
CONFIG_PATH = SETUP_DIR / "optimization_config.json"
|
||||
|
||||
# Ensure directories exist
|
||||
ITERATIONS_DIR.mkdir(exist_ok=True)
|
||||
RESULTS_DIR.mkdir(exist_ok=True)
|
||||
|
||||
|
||||
class FEARunner:
|
||||
"""Runs actual FEA simulations. Always use this pattern!"""
|
||||
|
||||
def __init__(self, config: Dict[str, Any]):
|
||||
self.config = config
|
||||
self.nx_solver = None
|
||||
self.nx_manager = None
|
||||
self.master_model_dir = SETUP_DIR / "model"
|
||||
|
||||
def setup(self):
|
||||
"""Setup NX and solver. Called lazily on first use."""
|
||||
study_name = self.config.get('study_name', 'my_study')
|
||||
|
||||
# Ensure NX is running
|
||||
self.nx_manager, nx_was_started = ensure_nx_running(
|
||||
session_id=study_name,
|
||||
auto_start=True,
|
||||
start_timeout=120
|
||||
)
|
||||
|
||||
# CRITICAL: Initialize NXSolver with named parameters, NOT config dict
|
||||
nx_settings = self.config.get('nx_settings', {})
|
||||
nx_install_dir = nx_settings.get('nx_install_path', 'C:\\Program Files\\Siemens\\NX2506')
|
||||
|
||||
# Extract version from path
|
||||
version_match = re.search(r'NX(\d+)', nx_install_dir)
|
||||
nastran_version = version_match.group(1) if version_match else "2506"
|
||||
|
||||
self.nx_solver = NXSolver(
|
||||
master_model_dir=str(self.master_model_dir),
|
||||
nx_install_dir=nx_install_dir,
|
||||
nastran_version=nastran_version,
|
||||
timeout=nx_settings.get('simulation_timeout_s', 600),
|
||||
use_iteration_folders=True,
|
||||
study_name=study_name
|
||||
)
|
||||
|
||||
def run_fea(self, params: Dict[str, float], iter_num: int) -> Optional[Dict]:
|
||||
"""Run FEA simulation and extract results."""
|
||||
if self.nx_solver is None:
|
||||
self.setup()
|
||||
|
||||
# Create expression updates
|
||||
expressions = {var['expression_name']: params[var['name']]
|
||||
for var in self.config['design_variables']}
|
||||
|
||||
# Create iteration folder with model copies
|
||||
iter_folder = self.nx_solver.create_iteration_folder(
|
||||
iterations_base_dir=ITERATIONS_DIR,
|
||||
iteration_number=iter_num,
|
||||
expression_updates=expressions
|
||||
)
|
||||
|
||||
# Run simulation
|
||||
nx_settings = self.config.get('nx_settings', {})
|
||||
sim_file = iter_folder / nx_settings.get('sim_file', 'model.sim')
|
||||
|
||||
result = self.nx_solver.run_simulation(
|
||||
sim_file=sim_file,
|
||||
working_dir=iter_folder,
|
||||
expression_updates=expressions,
|
||||
solution_name=nx_settings.get('solution_name', 'Solution 1'),
|
||||
cleanup=False
|
||||
)
|
||||
|
||||
if not result['success']:
|
||||
return None
|
||||
|
||||
# Extract results
|
||||
op2_file = result['op2_file']
|
||||
stress_result = extract_solid_stress(op2_file)
|
||||
|
||||
return {
|
||||
'params': params,
|
||||
'max_stress': stress_result['max_von_mises'],
|
||||
'op2_file': op2_file
|
||||
}
|
||||
|
||||
|
||||
# Optimizer class would use FEARunner...
|
||||
# See m1_mirror_adaptive_V14/run_optimization.py for full example
|
||||
```
|
||||
|
||||
**WRONG** - causes `TypeError: expected str, bytes or os.PathLike object, not dict`:
|
||||
```python
|
||||
self.nx_solver = NXSolver(self.config) # ❌ NEVER DO THIS
|
||||
```
|
||||
|
||||
**Reference implementations**:
|
||||
- `studies/m1_mirror_adaptive_V14/run_optimization.py` (TPE single-objective)
|
||||
- `studies/m1_mirror_adaptive_V15/run_optimization.py` (NSGA-II multi-objective)
|
||||
|
||||
### Step 7: Generate Documentation
|
||||
|
||||
**README.md** (11 sections required):
|
||||
1. Engineering Problem
|
||||
2. Mathematical Formulation
|
||||
3. Optimization Algorithm
|
||||
4. Simulation Pipeline
|
||||
5. Result Extraction Methods
|
||||
6. Neural Acceleration (if applicable)
|
||||
7. Study File Structure
|
||||
8. Results Location
|
||||
9. Quick Start
|
||||
10. Configuration Reference
|
||||
11. References
|
||||
|
||||
**STUDY_REPORT.md** (template):
|
||||
```markdown
|
||||
# Study Report: {study_name}
|
||||
|
||||
## Executive Summary
|
||||
- Trials completed: _pending_
|
||||
- Best objective: _pending_
|
||||
- Constraint satisfaction: _pending_
|
||||
|
||||
## Optimization Progress
|
||||
_To be filled after run_
|
||||
|
||||
## Best Designs Found
|
||||
_To be filled after run_
|
||||
|
||||
## Recommendations
|
||||
_To be filled after analysis_
|
||||
```
|
||||
|
||||
### Step 7b: Capture Baseline Geometry Images (Recommended)
|
||||
|
||||
For better documentation, capture images of the starting geometry using the NX journal:
|
||||
|
||||
```bash
|
||||
# Capture baseline images for study documentation
|
||||
"C:\Program Files\Siemens\DesigncenterNX2512\NXBIN\run_journal.exe" ^
|
||||
"C:\Users\antoi\Atomizer\nx_journals\capture_study_images.py" ^
|
||||
-args "path/to/model.prt" "1_setup/" "model_name"
|
||||
```
|
||||
|
||||
This generates:
|
||||
- `1_setup/{model_name}_Top.png` - Top view
|
||||
- `1_setup/{model_name}_iso.png` - Isometric view
|
||||
|
||||
**Include in README.md**:
|
||||
```markdown
|
||||
## Baseline Geometry
|
||||
|
||||

|
||||
*Top view description*
|
||||
|
||||

|
||||
*Isometric view description*
|
||||
```
|
||||
|
||||
**Journal location**: `nx_journals/capture_study_images.py`
|
||||
|
||||
### Step 8: Validate NX Model File Chain
|
||||
|
||||
**CRITICAL**: NX simulation files have parent-child dependencies. ALL linked files must be copied to the study folder.
|
||||
|
||||
**Required File Chain Check**:
|
||||
```
|
||||
.sim (Simulation)
|
||||
└── .fem (FEM)
|
||||
└── _i.prt (Idealized Part) ← OFTEN MISSING!
|
||||
└── .prt (Geometry Part)
|
||||
```
|
||||
|
||||
**Validation Steps**:
|
||||
1. Open the `.sim` file in NX
|
||||
2. Go to **Assemblies → Assembly Navigator** or check **Part Navigator**
|
||||
3. Identify ALL child components (especially `*_i.prt` idealized parts)
|
||||
4. Copy ALL linked files to `1_setup/model/`
|
||||
|
||||
**Common Issue**: The `_i.prt` (idealized part) is often forgotten. Without it:
|
||||
- `UpdateFemodel()` runs but mesh doesn't change
|
||||
- Geometry changes don't propagate to FEM
|
||||
- All optimization trials produce identical results
|
||||
|
||||
**File Checklist**:
|
||||
| File Pattern | Description | Required |
|
||||
|--------------|-------------|----------|
|
||||
| `*.prt` | Geometry part | ✅ Always |
|
||||
| `*_i.prt` | Idealized part | ✅ If FEM uses idealization |
|
||||
| `*.fem` | FEM file | ✅ Always |
|
||||
| `*.sim` | Simulation file | ✅ Always |
|
||||
|
||||
**Introspection should report**:
|
||||
- List of all parts referenced by .sim
|
||||
- Warning if any referenced parts are missing from study folder
|
||||
|
||||
### Step 9: Final Validation Checklist
|
||||
|
||||
**CRITICAL**: Study is NOT complete until ALL items are checked:
|
||||
|
||||
- [ ] NX files exist in `1_setup/model/`
|
||||
- [ ] **ALL child parts copied** (especially `*_i.prt`)
|
||||
- [ ] Expression names match model
|
||||
- [ ] Config validates (JSON schema)
|
||||
- [ ] `run_optimization.py` has no syntax errors
|
||||
- [ ] **README.md exists** (MANDATORY - study is incomplete without it!)
|
||||
- [ ] README.md contains: Overview, Objectives, Constraints, Design Variables, Settings, Usage, Structure
|
||||
- [ ] STUDY_REPORT.md template exists
|
||||
|
||||
**README.md Minimum Content**:
|
||||
1. Overview/Purpose
|
||||
2. Objectives with weights
|
||||
3. Constraints (if any)
|
||||
4. Design variables with ranges
|
||||
5. Optimization settings
|
||||
6. Usage commands
|
||||
7. Directory structure
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Simple Bracket
|
||||
|
||||
```
|
||||
User: "Optimize my bracket.prt for minimum mass, stress < 250 MPa"
|
||||
|
||||
Generated config:
|
||||
- 1 design variable (thickness)
|
||||
- 1 objective (minimize mass)
|
||||
- 1 constraint (stress < 250)
|
||||
- Protocol 10, TPE sampler
|
||||
- 50 trials
|
||||
```
|
||||
|
||||
### Example 2: Multi-Objective Beam
|
||||
|
||||
```
|
||||
User: "Minimize mass AND maximize stiffness for my beam"
|
||||
|
||||
Generated config:
|
||||
- 2 design variables (width, height)
|
||||
- 2 objectives (minimize mass, maximize stiffness)
|
||||
- Protocol 11, NSGA-II sampler
|
||||
- 50 trials (Pareto front)
|
||||
```
|
||||
|
||||
### Example 3: Telescope Mirror
|
||||
|
||||
```
|
||||
User: "Minimize wavefront error at 40deg vs 20deg reference"
|
||||
|
||||
Generated config:
|
||||
- Multiple design variables (mount positions)
|
||||
- 1 objective (minimize relative WFE)
|
||||
- Zernike extractor E9
|
||||
- Protocol 10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Cause | Solution |
|
||||
|---------|-------|----------|
|
||||
| "Expression not found" | Name mismatch | Verify expression names in NX |
|
||||
| "No feasible designs" | Constraints too tight | Relax constraint values |
|
||||
| Config validation fails | Missing required field | Check JSON schema |
|
||||
| Import error | Wrong path | Check sys.path setup |
|
||||
|
||||
---
|
||||
|
||||
## Cross-References
|
||||
|
||||
- **Depends On**: [SYS_12_EXTRACTOR_LIBRARY](../system/SYS_12_EXTRACTOR_LIBRARY.md)
|
||||
- **Next Step**: [OP_02_RUN_OPTIMIZATION](./OP_02_RUN_OPTIMIZATION.md)
|
||||
- **Skill**: `.claude/skills/core/study-creation-core.md`
|
||||
|
||||
---
|
||||
|
||||
## Version History
|
||||
|
||||
| Version | Date | Changes |
|
||||
|---------|------|---------|
|
||||
| 1.2 | 2026-01-13 | Added MANDATORY TodoWrite requirement for study creation (README forgotten twice) |
|
||||
| 1.1 | 2025-12-12 | Added FEARunner class pattern, NXSolver initialization warning |
|
||||
| 1.0 | 2025-12-05 | Initial release |
|
||||
Reference in New Issue
Block a user