# Atomizer Canvas - Visual Workflow Builder **Last Updated**: January 16, 2026 **Version**: 3.0 **Status**: Production --- ## Overview The Atomizer Canvas is a visual, node-based workflow builder for designing optimization studies. It provides a drag-and-drop interface for configuring FEA optimizations that integrates with Claude to validate and execute workflows. ### Key Features - **Visual Workflow Design**: Drag-and-drop nodes to build optimization pipelines - **Professional Lucide Icons**: Clean, consistent iconography throughout the interface - **Auto-Load from Studies**: Import existing optimization_config.json files - **NX Model Introspection**: Automatically extract expressions from .prt/.sim/.fem files - **File Browser**: Browse and select model files with type filtering - **Expression Search**: Searchable dropdown for design variable configuration - **One-Click Add**: Add discovered expressions as design variables instantly - **Claude Integration**: "Process with Claude" button for AI-assisted study creation - **Responsive Layout**: Full-screen canvas that adapts to window size ### What's New in V3 | Feature | Description | |---------|-------------| | **File Browser** | Browse studies directory for .sim/.prt/.fem/.afem files | | **Introspection Panel** | View discovered expressions, extractors, and dependencies | | **One-Click Add** | Add expressions as design variables with a single click | | **Claude Fixes** | Fixed SQL errors, WebSocket reconnection issues | | **Health Check** | `/api/health` endpoint for database monitoring | --- ## Architecture ### Frontend Stack | Component | Technology | Purpose | |-----------|------------|---------| | Flow Engine | React Flow | Node-based graph rendering | | State Management | Zustand | Canvas state (nodes, edges, selection) | | Icons | Lucide React | Professional icon library | | Styling | Tailwind CSS | Dark theme (Atomaster palette) | | Chat | WebSocket | Real-time Claude communication | ### Node Types (8) | Node | Icon | Description | Color | |------|------|-------------|-------| | **Model** | `Cube` | NX model file (.prt, .sim, .fem) | Blue | | **Solver** | `Cpu` | Nastran solution type (SOL101, SOL103, etc.) | Violet | | **Design Variable** | `SlidersHorizontal` | Parameter to optimize with bounds | Emerald | | **Extractor** | `FlaskConical` | Physics result extraction (E1-E10) | Cyan | | **Objective** | `Target` | Optimization goal (minimize/maximize) | Rose | | **Constraint** | `ShieldAlert` | Design constraint (upper/lower bounds) | Amber | | **Algorithm** | `BrainCircuit` | Optimization method (TPE, CMA-ES, NSGA-II) | Indigo | | **Surrogate** | `Rocket` | Neural acceleration (optional) | Pink | ### File Structure ``` atomizer-dashboard/frontend/src/ ├── components/canvas/ │ ├── AtomizerCanvas.tsx # Main canvas component │ ├── nodes/ │ │ ├── index.ts # Node type registry │ │ ├── BaseNode.tsx # Base node with handles │ │ ├── ModelNode.tsx # Model file node │ │ ├── SolverNode.tsx # Solver type node │ │ ├── DesignVarNode.tsx # Design variable node │ │ ├── ExtractorNode.tsx # Extractor node │ │ ├── ObjectiveNode.tsx # Objective node │ │ ├── ConstraintNode.tsx # Constraint node │ │ ├── AlgorithmNode.tsx # Algorithm node │ │ └── SurrogateNode.tsx # Surrogate node │ ├── panels/ │ │ ├── NodeConfigPanel.tsx # Node configuration sidebar │ │ ├── ValidationPanel.tsx # Validation toast display │ │ ├── ExecuteDialog.tsx # Execute confirmation modal │ │ ├── ChatPanel.tsx # Claude chat sidebar │ │ ├── ConfigImporter.tsx # Study import dialog │ │ ├── TemplateSelector.tsx # Workflow template chooser │ │ ├── FileBrowser.tsx # File picker modal (V3) │ │ ├── IntrospectionPanel.tsx # Model introspection results (V3) │ │ └── ExpressionSelector.tsx # Expression search dropdown (V3) │ └── palette/ │ └── NodePalette.tsx # Draggable node palette ├── hooks/ │ ├── useCanvasStore.ts # Zustand store for canvas state │ └── useCanvasChat.ts # Claude chat integration ├── lib/canvas/ │ ├── schema.ts # TypeScript type definitions │ ├── intent.ts # Intent serialization (174 lines) │ ├── validation.ts # Graph validation logic │ └── templates.ts # Workflow templates └── pages/ └── CanvasView.tsx # Canvas page (/canvas route) ``` --- ## User Interface ### Layout ``` ┌───────────────────────────────────────────────────────────────────┐ │ Canvas Builder Templates Import│ ├──────────┬────────────────────────────────────────────┬───────────┤ │ │ │ │ │ Node │ Canvas Area │ Config │ │ Palette │ │ Panel │ │ │ ┌─────┐ ┌─────┐ ┌─────┐ │ │ │ [Model] │ │Model├──────│Solver├──────│Algo │ │ Label: │ │ [Solver]│ └─────┘ └──┬──┘ └─────┘ │ [____] │ │ [DVar] │ │ │ │ │ [Extr] │ ┌─────┐ ┌──┴──┐ ┌─────┐ │ Type: │ │ [Obj] │ │ DVar├──────│Extr ├──────│ Obj │ │ [____] │ │ [Const] │ └─────┘ └─────┘ └─────┘ │ │ │ [Algo] │ │ │ │ [Surr] │ │ │ │ │ │ │ ├──────────┴────────────────────────────────────────────┴───────────┤ │ [Validate] [Process with Claude] │ └───────────────────────────────────────────────────────────────────┘ ``` ### Dark Theme (Atomaster Palette) | Element | Color | Tailwind Class | |---------|-------|----------------| | Background | `#050A12` | `bg-dark-900` | | Surface | `#0A1525` | `bg-dark-850` | | Card | `#0F1E32` | `bg-dark-800` | | Border | `#1A2F4A` | `border-dark-700` | | Muted Text | `#5A7A9A` | `text-dark-400` | | Primary | `#00D4E6` | `text-primary-400` | --- ## Core Workflows ### 1. Building a Workflow 1. **Drag nodes** from the left palette onto the canvas 2. **Connect nodes** by dragging from output handle to input handle 3. **Configure nodes** by clicking to open the config panel 4. **Validate** using the Validate button 5. **Process with Claude** to create the study ### 2. Importing from Existing Study 1. Click **Import** in the header 2. Select the **Load Study** tab 3. **Search** for your study by name 4. **Select** a study with an optimization_config.json 5. Click **Load Study** to populate the canvas ### 3. Using Templates 1. Click **Templates** in the header 2. Browse available workflow templates: - **Mass Minimization**: Single-objective mass reduction - **Multi-Objective**: Pareto optimization (mass + displacement) - **Turbo Mode**: Neural-accelerated optimization - **Mirror WFE**: Zernike wavefront error optimization - **Frequency Target**: Natural frequency optimization 3. Click a template to load it ### 4. Processing with Claude 1. Build and configure your workflow 2. Click **Validate** to check for errors 3. Click **Process with Claude** to: - Validate the configuration against Atomizer protocols - Receive recommendations (method selection, trial count) - Create the optimization study --- ## Node Configuration ### Model Node | Field | Description | Example | |-------|-------------|---------| | File Path | Path to NX model | `models/bracket.sim` | | File Type | prt, sim, or fem | `sim` | When loading a `.sim` file, the system introspects to find: - Linked `.prt` (geometry part) - Linked `.fem` (FEM file) - Solver type (SOL101, SOL103, etc.) - Available expressions ### Design Variable Node | Field | Description | Example | |-------|-------------|---------| | Expression Name | NX expression to vary | `thickness` | | Min Value | Lower bound | `5.0` | | Max Value | Upper bound | `15.0` | | Unit | Engineering unit | `mm` | **Expression Selector**: Click the dropdown to: - **Search** through available expressions - **Filter** by name - **Refresh** to reload from model - **Enter manually** if expression not found ### Extractor Node | Field | Description | Options | |-------|-------------|---------| | Extractor ID | Protocol E1-E10 | E1 (Displacement), E2 (Frequency), etc. | | Name | Display name | `max_displacement` | | Config | Extractor-specific settings | Node ID, component, etc. | **Available Extractors** (SYS_12): | ID | Physics | Function | |----|---------|----------| | E1 | Displacement | `extract_displacement()` | | E2 | Frequency | `extract_frequency()` | | E3 | Stress | `extract_solid_stress()` | | E4 | BDF Mass | `extract_mass_from_bdf()` | | E5 | CAD Mass | `extract_mass_from_expression()` | | E8 | Zernike | `extract_zernike_coefficients()` | | E9 | Zernike | `extract_zernike_rms()` | | E10 | Zernike | `extract_zernike_wfe()` | ### Objective Node | Field | Description | Options | |-------|-------------|---------| | Name | Objective identifier | `mass`, `displacement` | | Direction | Optimization goal | `minimize`, `maximize` | | Weight | Multi-objective weight | `1.0` (0.0-10.0) | ### Constraint Node | Field | Description | Example | |-------|-------------|---------| | Name | Constraint identifier | `max_stress` | | Operator | Comparison type | `<=`, `>=`, `==` | | Value | Threshold value | `250.0` | ### Algorithm Node | Field | Description | Options | |-------|-------------|---------| | Method | Optimization algorithm | TPE, CMA-ES, NSGA-II, GP-BO | | Max Trials | Number of trials | `100` | | Timeout | Optional time limit | `3600` (seconds) | **Method Selection** (SYS_15): | Method | Best For | Design Vars | Objectives | |--------|----------|-------------|------------| | TPE | General purpose | 1-10 | 1 | | CMA-ES | Many variables | 5-100 | 1 | | NSGA-II | Multi-objective | 1-20 | 2-4 | | GP-BO | Expensive evaluations | 1-10 | 1 | ### Surrogate Node | Field | Description | Options | |-------|-------------|---------| | Enabled | Toggle acceleration | true/false | | Model Type | Surrogate architecture | MLP, GNN, Auto | | Min Trials | Trials before activation | `20` | --- ## File Browser (V3) The File Browser allows you to navigate the studies directory to select model files. ### Features - **Directory Navigation**: Browse folder hierarchy with breadcrumbs - **Type Filtering**: Filters to `.sim`, `.prt`, `.fem`, `.afem` by default - **Search**: Quick search by file name - **Single-Click Select**: Click a file to select and close ### Usage 1. Click the **Browse** button (folder icon) next to the Model file path input 2. Navigate to your study folder 3. Click a model file to select it 4. The path is automatically populated in the Model node --- ## Model Introspection (V3) Model Introspection analyzes NX model files to discover expressions, solver type, and dependencies. ### Features - **Expression Discovery**: Lists all expressions found in the model - **Solver Detection**: Infers solver type from file contents (SOL101, SOL103, etc.) - **Dependency Tracking**: Shows related .prt, .fem, .afem files - **Extractor Suggestions**: Recommends extractors based on solver type - **One-Click Add**: Add expressions as Design Variables instantly ### Usage 1. Configure a **Model** node with a valid file path 2. Click **Introspect Model** button 3. View discovered expressions, extractors, and files 4. Click **+** next to any expression to add as Design Variable 5. Click **+** next to any extractor to add to canvas ### Discovered Information | Section | Contents | |---------|----------| | **Solver Type** | Detected solver (SOL101, SOL103, etc.) | | **Expressions** | Name, current value, unit | | **Extractors** | Available extractors for this solver | | **Dependent Files** | Related .prt, .fem, .afem files | --- ## API Integration ### Backend Endpoints #### Study Configuration ``` GET /api/studies/ # List all studies GET /api/studies/{path}/config # Get optimization_config.json ``` #### File Browser (V3) ``` GET /api/files/list # List files in directory Query: path=subdir&types=.sim,.prt,.fem,.afem Returns: { files: [{name, path, isDirectory}], path } ``` #### NX Introspection (V3) ``` POST /api/nx/introspect # Introspect NX model file Body: { file_path: string } Returns: { file_path, file_type, expressions, solver_type, dependent_files, extractors_available, warnings } GET /api/nx/expressions # Get expressions from model Query: file_path=path/to/model.sim Returns: { expressions: [{name, value, unit, type}] } ``` #### Health Check (V3) ``` GET /api/health # Check database and service health Returns: { status: "healthy", database: "connected" } ``` ### MCP Canvas Tools The Canvas integrates with the MCP server for Claude tool use: #### `validate_canvas_intent` Validates an optimization intent from the Canvas. ```typescript { intent: OptimizationIntent // The canvas workflow as JSON } // Returns: { valid, errors, warnings, recommendations } ``` #### `execute_canvas_intent` Creates an optimization study from a validated intent. ```typescript { intent: OptimizationIntent, study_name: string, // snake_case name auto_run?: boolean // Start optimization immediately } // Returns: { study_path, config_path, status } ``` #### `interpret_canvas_intent` Analyzes a Canvas intent and provides recommendations. ```typescript { intent: OptimizationIntent } // Returns: { // problem_type: "single-objective" | "multi-objective", // complexity: "low" | "medium" | "high", // recommended_method: string, // recommended_trials: number, // surrogate_recommended: boolean, // notes: string[] // } ``` --- ## OptimizationIntent Schema The Canvas serializes workflows to the `OptimizationIntent` JSON format: ```typescript interface OptimizationIntent { model: { path: string; type: 'prt' | 'sim' | 'fem'; }; solver: { type: string; // SOL101, SOL103, etc. }; design_variables: Array<{ name: string; expression: string; min: number; max: number; unit?: string; }>; extractors: Array<{ id: string; // E1, E2, etc. name: string; config?: Record; }>; objectives: Array<{ name: string; extractor: string; direction: 'minimize' | 'maximize'; weight?: number; }>; constraints?: Array<{ name: string; extractor: string; operator: '<=' | '>=' | '=='; value: number; }>; optimization: { method: string; max_trials: number; timeout?: number; }; surrogate?: { enabled: boolean; model_type?: string; min_trials?: number; }; } ``` --- ## Validation Rules The Canvas validates workflows against these rules: ### Required Components - At least 1 **Model** node - At least 1 **Solver** node - At least 1 **Design Variable** node - At least 1 **Objective** node - At least 1 **Algorithm** node ### Configuration Rules - All nodes must be **configured** (no empty fields) - Design variable **min < max** - Objective must connect to an **Extractor** - Extractor ID must be valid (E1-E10) ### Connection Rules - Model → Solver (required) - Solver → Extractor (required for each extractor) - Extractor → Objective (required for each objective) - Extractor → Constraint (optional) ### Recommendations - Multi-objective (2+ objectives) should use **NSGA-II** - Many variables (5+) may benefit from **surrogate** - High trial count (100+) should consider **neural acceleration** --- ## Templates ### Mass Minimization Single-objective mass reduction with stress constraint. - **Nodes**: 6 (Model, Solver, DVar, Extractor, Objective, Algorithm) - **Objective**: Minimize mass - **Constraint**: Max stress < limit - **Method**: TPE (100 trials) ### Multi-Objective Pareto optimization for mass vs. displacement trade-off. - **Nodes**: 7 - **Objectives**: Minimize mass, Minimize displacement - **Method**: NSGA-II (150 trials) ### Turbo Mode Neural-accelerated optimization with surrogate. - **Nodes**: 8 (includes Surrogate) - **Objective**: User-defined - **Method**: TPE + MLP Surrogate - **Trials**: 50 FEA + 5000 surrogate ### Mirror WFE Zernike wavefront error optimization for optics. - **Nodes**: 7 - **Objective**: Minimize WFE (E10) - **Method**: CMA-ES (200 trials) ### Frequency Target Natural frequency optimization with modal analysis. - **Nodes**: 6 - **Objective**: Target frequency (E2) - **Method**: TPE (100 trials) --- ## Keyboard Shortcuts | Key | Action | |-----|--------| | `Delete` / `Backspace` | Delete selected node | | `Escape` | Deselect all | | `Ctrl+Z` | Undo (future) | | `Ctrl+Shift+Z` | Redo (future) | | `Space` (hold) | Pan canvas | | Scroll | Zoom in/out | --- ## Troubleshooting ### Canvas Not Visible - Ensure you're on the `/canvas` route - Check for JavaScript errors in browser console - Verify React Flow is properly initialized ### Nodes Not Draggable - Check that drag-and-drop events are being captured - Ensure `onDragStart` sets the correct data type ### Config Panel Not Updating - Verify Zustand store is properly connected - Check that `updateNodeData` is being called ### Claude Chat Not Working - Check WebSocket connection status (green indicator) - Verify backend is running on port 8000 - Check `/api/chat/` endpoint is accessible ### Expression Dropdown Empty - Ensure a Model node is configured with a file path - Check `/api/nx/expressions` endpoint is working - Try the "Refresh" button to reload expressions --- ## Development ### Running Locally ```bash # Frontend cd atomizer-dashboard/frontend npm install npm run dev # Backend cd atomizer-dashboard/backend python -m uvicorn api.main:app --reload --port 8000 # MCP Server cd mcp-server/atomizer-tools npm run build npm run dev ``` ### Building for Production ```bash # Frontend cd atomizer-dashboard/frontend npm run build # MCP Server cd mcp-server/atomizer-tools npm run build ``` ### Adding New Node Types 1. Create node component in `components/canvas/nodes/` 2. Add type to `schema.ts` 3. Register in `nodes/index.ts` 4. Add to `NodePalette.tsx` 5. Update validation rules in `validation.ts` 6. Add serialization logic to `intent.ts` --- ## References - **React Flow Documentation**: https://reactflow.dev/ - **Lucide Icons**: https://lucide.dev/icons/ - **Zustand**: https://github.com/pmndrs/zustand - **Atomizer Protocols**: See `docs/protocols/` - **Extractor Library**: See `SYS_12_EXTRACTOR_LIBRARY.md` - **Method Selector**: See `SYS_15_METHOD_SELECTOR.md` --- *Canvas Builder: Design optimizations visually, execute with AI.*